Add referenced users' timeline URLs to the bottom of each message.
authorMichael Orlitzky <michael@orlitzky.com>
Mon, 14 Feb 2011 20:23:08 +0000 (15:23 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Mon, 14 Feb 2011 20:23:08 +0000 (15:23 -0500)
src/StringUtils.hs [new file with mode: 0644]
src/Twitter/Status.hs
src/Twitter/User.hs
test/TestSuite.hs

diff --git a/src/StringUtils.hs b/src/StringUtils.hs
new file mode 100644 (file)
index 0000000..b7d291c
--- /dev/null
@@ -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" ]
index 59b98761fce86d62ed6fdaab46d8c950c19fb174..6416232ebff9499bfc2d25e5bd258e8340e19ef0 100644 (file)
@@ -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"]
index a6fd3f6a459f1d547c10b736a853014964c59101..ffa01ba747a8a7d7b13e684d6e0204c6c20acaa4 100644 (file)
@@ -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
index 09087b9de99cd4742e75509c13ad61bd451f61ad..f583ca19ac464bbcf89d232b92c2d8028b00acaa 100644 (file)
@@ -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