X-Git-Url: http://gitweb.michael.orlitzky.com/?p=dead%2Fhalcyon.git;a=blobdiff_plain;f=src%2FTwitter%2FStatus.hs;h=e40bc6a6a718aa4b68e62902125859b128fc91ad;hp=a2e6255f98990e31890beaec1ba4184459da3a60;hb=606371fece618f28d3fedf182165ef3a56bf4159;hpb=69b8af30f49aaad0f5c051998d2556b9ec291df7 diff --git a/src/Twitter/Status.hs b/src/Twitter/Status.hs index a2e6255..e40bc6a 100644 --- a/src/Twitter/Status.hs +++ b/src/Twitter/Status.hs @@ -3,8 +3,13 @@ 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 Text.XML.HaXml.Posn (noPos) +import StringUtils (listify) import Twitter.User import Twitter.Xml @@ -18,7 +23,7 @@ data Status = Status { status_id :: Integer, -- |Given some XML content, create a 'Status' from it. -status_from_content :: Content -> (Maybe Status) +status_from_content :: Content i -> (Maybe Status) status_from_content content = if (length status_ids) == 0 @@ -55,6 +60,19 @@ status_from_content content = first_user = user_from_content (users !! 0) +-- |Takes an XML String as an argument, and returns the +-- status that was parsed from it. Should only be used +-- on XML string where a is a top-level element. +parse_status :: String -> [Status] +parse_status xml_data = + catMaybes maybe_status + where + (Document _ _ root _) = xmlParse xml_file_name xml_data + root_elem = CElem root noPos + status_element = (single_status root_elem) + maybe_status = map status_from_content status_element + + -- |Takes an XML String as an argument, and returns the list of -- statuses that can be parsed from it. parse_statuses :: String -> [Status] @@ -62,7 +80,7 @@ parse_statuses xml_data = catMaybes maybe_statuses where (Document _ _ root _) = xmlParse xml_file_name xml_data - root_elem = CElem root + root_elem = CElem root noPos status_elements = (all_statuses root_elem) maybe_statuses = map status_from_content status_elements @@ -84,10 +102,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 @@ -97,3 +117,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"]