From e13f2a1eced5f388b37bc0ed12e9db72eba4b5d4 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 14 Feb 2011 15:23:08 -0500 Subject: [PATCH] Add referenced users' timeline URLs to the bottom of each message. --- src/StringUtils.hs | 31 +++++++++++++++++++++++++ src/Twitter/Status.hs | 53 ++++++++++++++++++++++++++++++++++++++++++- src/Twitter/User.hs | 6 +++++ test/TestSuite.hs | 4 +++- 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/StringUtils.hs diff --git a/src/StringUtils.hs b/src/StringUtils.hs new file mode 100644 index 0000000..b7d291c --- /dev/null +++ b/src/StringUtils.hs @@ -0,0 +1,31 @@ +-- |Miscellaneous functions for manipulating string. +module StringUtils +where + +import Test.HUnit + + +-- |Takes a list of strings, call them string1, string2, etc. and +-- numbers them like a list. So, +-- 1. string1 +-- 2. string2 +-- 3. etc. +listify :: [String] -> [String] +listify items = + zipWith (++) list_numbers items + where + list_numbers = map show_with_dot [1::Integer ..] + show_with_dot x = (show x) ++ ". " + + + +string_utils_tests :: [Test] +string_utils_tests = [ test_listify ] + + +test_listify :: Test +test_listify = + TestCase $ assertEqual "All items are numbered correctly." expected_items actual_items + where + actual_items = listify [ "item1", "item2" ] + expected_items = ["1. item1", "2. item2" ] diff --git a/src/Twitter/Status.hs b/src/Twitter/Status.hs index 59b9876..6416232 100644 --- a/src/Twitter/Status.hs +++ b/src/Twitter/Status.hs @@ -3,8 +3,12 @@ module Twitter.Status where import Data.Maybe +import Data.String.Utils (join, splitWs) +import Test.HUnit +import Text.Regex (matchRegex, mkRegex) import Text.XML.HaXml +import StringUtils (listify) import Twitter.User import Twitter.Xml @@ -97,10 +101,12 @@ pretty_print status = replicate ((length name) + 3 + (length (created_at status))) '-', "\n", replace_entities (text status), + "\n\n", + join "\n" user_timeline_urls, "\n" ] where name = screen_name (user status) - + user_timeline_urls = listify (make_user_timeline_urls status) -- |Given a list of statuses, returns the greatest status_id belonging @@ -110,3 +116,48 @@ get_max_status_id statuses = maximum status_ids where status_ids = map status_id statuses + + +-- |Parse one username from a word. +parse_username :: String -> Maybe String +parse_username word = + case matches of + Nothing -> Nothing + Just [] -> Nothing + Just (first_match:_) -> Just first_match + where + username_regex = mkRegex "@([a-zA-Z0-9_]+)" + matches = matchRegex username_regex word + + +-- |Parse all usernames of the form @username from a status. +parse_usernames_from_status :: Status -> [String] +parse_usernames_from_status status = + catMaybes (map parse_username status_words) + where + status_words = splitWs (text status) + +-- |Get all referenced users' timeline URLs. +make_user_timeline_urls :: Status -> [String] +make_user_timeline_urls status = + map screen_name_to_timeline_url usernames + where + usernames = parse_usernames_from_status status + + +status_tests :: [Test] +status_tests = [ test_parse_usernames ] + + +test_parse_usernames :: Test +test_parse_usernames = + TestCase $ assertEqual "All usernames are parsed." expected_usernames actual_usernames + where + dummy_user = User { screen_name = "nobody" } + dummy_status = Status { status_id = 1, + created_at = "never", + text = "Hypothesis: @donsbot and @bonus500 are two personalities belonging to the same person.", + user = dummy_user } + + actual_usernames = parse_usernames_from_status dummy_status + expected_usernames = ["donsbot", "bonus500"] diff --git a/src/Twitter/User.hs b/src/Twitter/User.hs index a6fd3f6..ffa01ba 100644 --- a/src/Twitter/User.hs +++ b/src/Twitter/User.hs @@ -25,3 +25,9 @@ user_from_content c = where names = user_screen_name c + + +-- |Get the URL for the given screen name's timeline. +screen_name_to_timeline_url :: String -> String +screen_name_to_timeline_url sn = + "http://twitter.com/" ++ sn diff --git a/test/TestSuite.hs b/test/TestSuite.hs index 09087b9..f583ca1 100644 --- a/test/TestSuite.hs +++ b/test/TestSuite.hs @@ -1,9 +1,11 @@ import Test.HUnit +import StringUtils (string_utils_tests) +import Twitter.Status(status_tests) import Twitter.Xml(xml_tests) -- The list of HUnit tests. -test_suite = TestList (concat [xml_tests]) +test_suite = TestList (concat [xml_tests, status_tests, string_utils_tests]) main :: IO () main = do -- 2.43.2