-- | Miscellaneous functions that don't fit the project directly module Web.Tweet.Utils ( hits , hits' , getTweets , displayTimeline , displayTimelineColor , lineByKey , bird , getConfigData , filterQuotes , filterReplies , filterRTs ) where import Control.Composition import qualified Data.ByteString as BS2 import qualified Data.ByteString.Char8 as BS import Data.List import Data.List.Extra import Data.Void import Lens.Micro.Extras import Text.Megaparsec import Web.Tweet.Parser import Web.Tweet.Types import Web.Tweet.Utils.Colors -- | filter out retweets, and sort by most successful. hits :: Timeline -> Timeline hits = sortTweets . filterRTs -- | Filter out retweets and replies, and sort by most sucessful. hits' :: Timeline -> Timeline hits' = hits . filterReplies -- | Filter out retweets filterRTs :: Timeline -> Timeline filterRTs = filter ((/="RT @") . take 4 . view text) -- | Filter out replies filterReplies :: Timeline -> Timeline filterReplies = filter ((/="@") . take 1 . view text) -- | Filter out quotes filterQuotes :: Timeline -> Timeline filterQuotes = filter ((==Nothing) . view quoted) -- | Get a list of tweets from a response, returning author, favorites, retweets, and content. getTweets :: BS2.ByteString -> Either (ParseErrorBundle String Void) Timeline getTweets = parse parseTweet "" . BS.unpack -- | Display Timeline without color displayTimeline :: Timeline -> String displayTimeline (TweetEntity content _ u sn idTweet _ Nothing rts fave:rest) = concat [u , " (" , sn , ")" ,":\n " ,fixNewline content ,"\n " , "💜" -- , "♥ " ,show fave , " \61561 " -- ," ♺ " ,show rts , " " , show idTweet ,"\n\n" ,displayTimeline rest] displayTimeline (TweetEntity content _ u sn idTweet _ (Just q) rts fave:rest) = concat [u , " (" , sn , ")" , ":\n " , fixNewline content , "\n " , "💜" , show fave , " \61561 " , show rts , " " , show idTweet , "\n " , _name q , " (" , _screenName q , ")" , ": " , _text q , "\n\n" , displayTimeline rest] displayTimeline [] = [] bird :: String bird = toPlainBlue "🐦\n" -- | Display Timeline in color displayTimelineColor :: Timeline -> String displayTimelineColor (TweetEntity content _ u sn idTweet _ Nothing rts fave:rest) = concat [toYellow u , " (" , sn , ")" , ":\n " , fixNewline content , "\n " , toRed "💜" , " " , show fave , toGreen " \61561 " -- ♺ " , show rts , " " , toBlue (show idTweet) , "\n\n" , displayTimelineColor rest] displayTimelineColor (TweetEntity content _ u sn idTweet _ (Just q) rts fave:rest) = concat [toYellow u , " (" , sn , ")" , ":\n " , fixNewline content , "\n " , toRed "💜" , " " , show fave , toGreen " \61561 " , show rts , " " , toBlue (show idTweet) , "\n " , toYellow $ _name q , " (" , _screenName q , ")" , ": " , _text q , "\n\n" , displayTimelineColor rest] displayTimelineColor [] = [] -- | When displaying, newlines should include indentation. fixNewline :: String -> String fixNewline = replace "\n" "\n " -- | sort tweets by most successful sortTweets :: Timeline -> Timeline sortTweets = sortBy compareTweet where compareTweet (TweetEntity _ _ _ _ _ _ _ r1 f1) (TweetEntity _ _ _ _ _ _ _ r2 f2) = compare (2*r2 + f2) (2*r1 + f1) -- | helper function to get the key as read from a file keyLinePie :: String -> String keyLinePie = takeWhile (/=':') -- | Pick out a key value from a key lineByKey :: BS.ByteString -> [(BS.ByteString, BS.ByteString)] -> BS.ByteString lineByKey = snd .* head .* (filter . (fst .@ (==))) -- | Filter a line of a file for only the actual data and no descriptors filterLine :: String -> String filterLine = reverse . takeWhile (not . (`elem` (" :" :: String))) . reverse -- | Get pairs of "key" to search for and actual values getConfigData :: FilePath -> IO [(BS.ByteString, BS.ByteString)] getConfigData filepath = zip <$> keys <*> content where content = map (BS.pack . filterLine) . lines <$> file keys = map (BS.pack . keyLinePie) . lines <$> file file = readFile filepath