packages feed

tweet-hs 0.5.1.0 → 0.5.1.2

raw patch · 7 files changed

+194/−93 lines, 7 filesdep ~tweet-hs

Dependency ranges changed: tweet-hs

Files

src/Web/Tweet.hs view
@@ -67,7 +67,7 @@     let f = \str i -> tweetData (Tweet { _status = str, _handles = hs, _replyID = if i == 0 then Nothing else Just i }) filepath     let initial = f (head content)     last <- foldr ((>=>) . f) initial (content) $ fromMaybe 0 idNum-    deleteTweet last filepath+    deleteTweet (fromIntegral last) filepath  -- | Reply with a single tweet. Works the same as `thread` but doesn't take the fourth argument. --
src/Web/Tweet/API.hs view
@@ -63,7 +63,6 @@ -- | Show the most successful tweets by a given user, given their screen name.  showBest :: String -> Bool -> FilePath -> IO String showBest screenName color filepath = showTweets color . pure . (take 13 . hits) <$> getAll screenName Nothing filepath --- (fmap (take 13 . hits)) <$> getProfile screenName 3200 filepath  -- | Display user timeline showTimeline :: Int -> Bool -> FilePath -> IO String@@ -87,31 +86,39 @@     where requestString = "?count=" ++ (show count)  -- | Delete a tweet given its id-deleteTweet :: Int -> FilePath -> IO ()+deleteTweet :: Integer -> FilePath -> IO () deleteTweet = (fmap void) . deleteTweetRaw  -- | Favorite a tweet given its id-favoriteTweet :: Int -> FilePath -> IO ()+favoriteTweet :: Integer -> FilePath -> IO () favoriteTweet = (fmap void) . favoriteTweetRaw  -- | Unfavorite a tweet given its id-unfavoriteTweet :: Int -> FilePath -> IO ()+unfavoriteTweet :: Integer -> FilePath -> IO () unfavoriteTweet = (fmap void) . unfavoriteTweetRaw  -- | Unretweet a tweet given its id-unretweetTweet :: Int -> FilePath -> IO ()+unretweetTweet :: Integer -> FilePath -> IO () unretweetTweet = (fmap void) . unretweetTweetRaw +-- | Unfollow a user given their screen name+unfollow :: String -> FilePath -> IO ()+unfollow = (fmap void) . unfollowUserRaw++-- | Follow a user given their screen name+follow :: String -> FilePath -> IO ()+follow = (fmap void) . followUserRaw+ -- | Retweet a tweet given its id-retweetTweet :: Int -> FilePath -> IO ()+retweetTweet :: Integer -> FilePath -> IO () retweetTweet = (fmap void) . retweetTweetRaw  -- | Favorite a tweet given its id; return bytestring response-favoriteTweetRaw :: Int -> FilePath -> IO BSL.ByteString-favoriteTweetRaw id = postRequest ("https://api.twitter.com/1.1/favorites/destroy/" ++ (show id) ++ ".json")+favoriteTweetRaw :: Integer -> FilePath -> IO BSL.ByteString+favoriteTweetRaw id = postRequest ("https://api.twitter.com/1.1/favorites/create.json?id=" ++ (show id))  -- | Retweet a tweet given its id; return bytestring response-retweetTweetRaw :: Int -> FilePath -> IO BSL.ByteString+retweetTweetRaw :: Integer -> FilePath -> IO BSL.ByteString retweetTweetRaw id = postRequest ("https://api.twitter.com/1.1/statuses/retweet/" ++ (show id) ++ ".json")  -- | Send a DM given text, screen name of recipient.@@ -119,21 +126,21 @@     where encoded = strEncode $ txt  -- | Follow a user given their screen name-followUser :: String -> FilePath -> IO BSL.ByteString-followUser screenName = postRequest("https://api.twitter.com/1.1/friendships/create.json?screen_name=" ++ screenName)+followUserRaw :: String -> FilePath -> IO BSL.ByteString+followUserRaw screenName = postRequest("https://api.twitter.com/1.1/friendships/create.json?screen_name=" ++ screenName)  -- | Follow a user given their screen name-unfollowUser :: String -> FilePath -> IO BSL.ByteString-unfollowUser screenName = postRequest("https://api.twitter.com/1.1/friendships/destroy.json?screen_name=" ++ screenName)+unfollowUserRaw :: String -> FilePath -> IO BSL.ByteString+unfollowUserRaw screenName = postRequest("https://api.twitter.com/1.1/friendships/destroy.json?screen_name=" ++ screenName)  -- | Unretweet a tweet given its id; return bytestring response-unretweetTweetRaw :: Int -> FilePath -> IO BSL.ByteString+unretweetTweetRaw :: Integer -> FilePath -> IO BSL.ByteString unretweetTweetRaw id = postRequest ("https://api.twitter.com/1.1/statuses/unretweet/" ++ (show id) ++ ".json")  -- | Favorite a tweet given its id; return bytestring response-unfavoriteTweetRaw :: Int -> FilePath -> IO BSL.ByteString-unfavoriteTweetRaw id = postRequest ("https://api.twitter.com/1.1/favorites/destroy/" ++ (show id) ++ ".json")+unfavoriteTweetRaw :: Integer -> FilePath -> IO BSL.ByteString+unfavoriteTweetRaw id = postRequest ("https://api.twitter.com/1.1/favorites/destroy.json?id=" ++ (show id))  -- | Delete a tweet given its id; return bytestring response-deleteTweetRaw :: Int -> FilePath -> IO BSL.ByteString+deleteTweetRaw :: Integer -> FilePath -> IO BSL.ByteString deleteTweetRaw id = postRequest ("https://api.twitter.com/1.1/statuses/destroy/" ++ (show id) ++ ".json")
src/Web/Tweet/Exec.hs view
@@ -6,6 +6,7 @@ import Web.Tweet import Options.Applicative import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BSL import Control.Monad import Data.Foldable (fold) import Data.List hiding (delete)@@ -16,6 +17,7 @@ data Program = Program { subcommand :: Command , cred :: Maybe FilePath }  -- | Data type for a command+-- TODO add boolean option to show ids alongside tweets data Command = Timeline { count :: Maybe Int , color :: Bool }     | SendInput { tweetInputs :: Maybe Int, replyId :: Maybe String, replyHandles :: Maybe [String] }     | Profile { count :: Maybe Int , color :: Bool , screenName :: String }@@ -23,6 +25,13 @@     | Send { tweets :: Maybe Int , replyId :: Maybe String , replyHandles :: Maybe [String] , userInput :: String }     | Sort { color :: Bool , screenName :: String }     | Delete { twId :: Integer }+    | Fav { twId :: Integer }+    | Unfav { twId :: Integer }+    | Retweet { twId :: Integer }+    | Unretweet { twId :: Integer }+    | Follow { screenName :: String }+    | Unfollow { screenName :: String }+    | Dump { screenName :: String }  -- | query twitter to post stdin with no fancy options fromStdIn :: Int -> FilePath -> IO ()@@ -49,58 +58,48 @@  -- | Executes program given parsed `Program` select :: Program -> IO ()-select (Program (Send (Just n) Nothing Nothing input) Nothing) = fromCLI input n =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send Nothing Nothing Nothing input) Nothing) = fromCLI input 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send (Just n) Nothing Nothing input) (Just file))  = fromCLI input n file-select (Program (Send Nothing Nothing Nothing input) (Just file)) = fromCLI input 15 file-select (Program (Send (Just n) (Just id) (Just handles) input) Nothing) = thread input handles (read id) n  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send (Just n) (Just id) (Just handles) input) (Just file)) = thread input handles (pure . read $ id) n file-select (Program (Send Nothing (Just id) (Just handles) input) (Just file)) = thread input handles (pure . read $ id) 15 file-select (Program (Send (Just n) (Just id) Nothing input) Nothing) = (thread input [] (pure . read $ id) n)  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send Nothing (Just id) Nothing input) Nothing) = thread input [] (pure . read $ id) 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send Nothing (Just id) (Just handles) input) Nothing) = thread input handles (pure . read $ id) 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Send (Just n) (Just id) Nothing input) (Just file)) = thread input [] (pure . read $ id) n file-select (Program (Send (Just n) Nothing (Just handles) input) (Just file)) = thread input handles Nothing n file-select (Program (SendInput (Just n) Nothing Nothing) Nothing) = fromStdIn n =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput Nothing Nothing Nothing) Nothing) = fromStdIn 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput (Just n) Nothing Nothing) (Just file))  = fromStdIn n file-select (Program (SendInput Nothing Nothing Nothing) (Just file) ) = fromStdIn 15 file-select (Program (SendInput (Just n) (Just id) (Just handles)) Nothing) = threadStdIn handles (read id) n  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput (Just n) (Just id) (Just handles)) (Just file)) = threadStdIn handles (pure . read $ id) n file-select (Program (SendInput Nothing (Just id) (Just handles)) (Just file))  = threadStdIn handles (pure . read $ id) 15 file-select (Program (SendInput (Just n) (Just id) Nothing) Nothing) = threadStdIn [] (pure . read $ id) n  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput Nothing (Just id) Nothing) Nothing) = threadStdIn [] (pure . read $ id) 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput Nothing (Just id) (Just handles)) Nothing) = threadStdIn handles (pure . read $ id) 15  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (SendInput (Just n) (Just id) Nothing) (Just file)) = threadStdIn [] (pure . read $ id) n file-select (Program (SendInput (Just n) Nothing (Just handles)) (Just file)) = threadStdIn handles Nothing n file-select (Program (Timeline Nothing False) Nothing) = putStrLn =<< showTimeline 8 False  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Timeline Nothing False) (Just file)) = putStrLn =<< showTimeline 8 False file-select (Program (Timeline (Just n) False) (Just file)) = putStrLn =<< showTimeline 8 False file-select (Program (Timeline (Just n) False) Nothing) = putStrLn =<< showTimeline 8 False  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Timeline Nothing True) Nothing) = putStrLn =<< showTimeline 8 True  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Timeline Nothing True) (Just file)) = putStrLn =<< showTimeline 8 True file-select (Program (Timeline (Just n) True) (Just file)) = putStrLn =<< showTimeline 8 True file-select (Program (Timeline (Just n) True) Nothing) = putStrLn =<< showTimeline 8 True  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Profile (Just n) True name) (Just file)) = putStrLn =<< showProfile name n True file-select (Program (Profile Nothing True name) (Just file)) = putStrLn =<< showProfile name 12 True file-select (Program (Profile (Just n) True name) Nothing) = putStrLn =<< showProfile name n True  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Profile Nothing True name) Nothing) = putStrLn =<< showProfile name 12 True  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Profile (Just n) False name) (Just file)) = putStrLn =<< showProfile name n False file-select (Program (Profile Nothing False name) (Just file)) = putStrLn =<< showProfile name 12 False file-select (Program (Profile (Just n) False name) Nothing) = putStrLn =<< showProfile name n False  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Profile Nothing False name) Nothing) = putStrLn =<< showProfile name 12 False  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Sort True name) (Just file)) = putStrLn =<< showBest name True file-select (Program (Sort True name) Nothing) = putStrLn =<< showBest name True  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Sort False name) (Just file)) = putStrLn =<< showBest name False file-select (Program (Sort False name) Nothing) = putStrLn =<< showBest name False  =<< (++ "/.cred") <$> getHomeDirectory-select (Program (Markov name) Nothing) = do-    raw <- getMarkov name Nothing =<< (++ "/.cred") <$> getHomeDirectory-    writeFile (name ++ ".txt") (unlines raw)-    putStrLn $ "Written output to: " ++ name ++ ".txt"-select (Program (Markov name) (Just file)) = do+select (Program com maybeFile) = case maybeFile of+    (Just file) -> selectCommand com file+    _ -> selectCommand com =<< (++ "/.cred") <$> getHomeDirectory++-- | Executes subcommand given subcommand + filepath to configuration file+selectCommand :: Command -> FilePath -> IO ()+selectCommand (Send maybeNum Nothing Nothing input) file = fromCLI input (maybe 15 id maybeNum) file+selectCommand (Send maybeNum (Just replyId) Nothing input) file = thread input [] (pure . read $ replyId) (maybe 15 id maybeNum) file+selectCommand (Send maybeNum Nothing (Just handles) input) file = thread input handles Nothing (maybe 15 id maybeNum) file+selectCommand (SendInput maybeNum Nothing Nothing) file  = fromStdIn (maybe 15 id maybeNum) file+selectCommand (SendInput maybeNum (Just replyId) (Just handles)) file = threadStdIn handles (pure . read $ replyId) (maybe 15 id maybeNum) file+selectCommand (SendInput maybeNum (Just replyId) Nothing) file = threadStdIn [] (pure . read $ replyId) (maybe 15 id maybeNum) file+selectCommand (SendInput maybeNum Nothing (Just handles)) file = threadStdIn handles Nothing (maybe 15 id maybeNum) file+selectCommand (Timeline maybeNum color) file = putStrLn =<< showTimeline (maybe 11 id maybeNum) color file+selectCommand (Profile maybeNum color name) file = putStrLn =<< showProfile name (maybe 11 id maybeNum) color file+selectCommand (Sort color name) file = putStrLn =<< showBest name color file+selectCommand (Markov name) file = do     raw <- getMarkov name Nothing file     writeFile (name ++ ".txt") (unlines raw)     putStrLn $ "Written output to: " ++ name ++ ".txt"+selectCommand (Delete n) file = do+    deleteTweet n file+    putStrLn "...tweet deleted successfully!"+selectCommand (Fav n) file = do+    favoriteTweet n file+    putStrLn "...tweet favorited successfully!"+selectCommand (Unfav n) file = do+    unfavoriteTweet n file+    putStrLn "...tweet unfavorited successfully!"+selectCommand (Retweet n) file = do+    retweetTweet n file+    putStrLn "...tweet retweeted successfully!"+selectCommand (Unretweet n) file = do+    unretweetTweet n file+    putStrLn "...tweet retweeted successfully!"+selectCommand (Follow screenName) file = do+    follow screenName file+    putStrLn ("..." ++ screenName ++ " followed successfully!")+selectCommand (Unfollow screenName) file = do+    unfollow screenName file+    putStrLn ("..." ++ screenName ++ " unfollowed successfully!")+selectCommand (Dump screenName) file = BSL.putStrLn =<< (getProfileRaw screenName 3200 file Nothing)  -- | Parser to return a program datatype program :: Parser Program@@ -112,7 +111,14 @@         <> command "user" (info profile (progDesc "Get a user's profile"))         <> command "markov" (info markov (progDesc "Grab tweets en masse."))         <> command "hits" (info best (progDesc "View a user's top tweets."))-        <> command "del" (info delete (progDesc "View a user's top tweets."))))+        <> command "del" (info delete (progDesc "Delete a tweet.")) -- TODO delete/favorite in bunches!+        <> command "fav" (info fav (progDesc "Favorite a tweet"))+        <> command "ufav" (info unfav (progDesc "Unfavorite a tweet"))+        <> command "urt" (info unrt (progDesc "Un-retweet a tweet"))+        <> command "rt" (info rt (progDesc "Retweet a tweet"))+        <> command "follow" (info fol (progDesc "Follow a user"))+        <> command "unfollow" (info unfol (progDesc "Unfollow a user"))+        <> command "dump" (info dump (progDesc "Dump tweets (for debugging)"))))     <*> (optional $ strOption         (long "cred"         <> short 'c'@@ -134,17 +140,51 @@  -- | Parser for the raw subcommand markov :: Parser Command-markov = Markov-  <$> argument str-    (metavar "SCREEN_NAME"-    <> help "Screen name of user whose tweets you want in bulk.")+markov = Markov <$> user  -- | Parser for the raw subcommand+fol :: Parser Command+fol = Follow <$> user++-- | Parser for the raw subcommand+dump :: Parser Command+dump = Dump <$> user++-- | Parser for the raw subcommand+unfol :: Parser Command+unfol = Unfollow <$> user++-- | Parse a user screen name+user :: Parser String+user = argument str+    (metavar "SCREEN_NAME"+    <> help "Screen name of user.")++-- | Parser for the del subcommand delete :: Parser Command-delete = Delete-  <$> read <$> (argument str+delete = Delete <$> getInt++-- | Parser for the fav subcommand+fav :: Parser Command+fav = Fav <$> getInt++-- | Parser for the fav subcommand+unfav :: Parser Command+unfav = Unfav <$> getInt++-- | Parser for the fav subcommand+unrt :: Parser Command+unrt = Unretweet <$> getInt++-- | Parser for the fav subcommand+rt :: Parser Command+rt = Retweet <$> getInt++-- | Parser for the del subcommand+getInt :: Parser Integer+getInt = read <$> (argument str     (metavar "TWEET_ID"-    <> help "ID of tweet to delete"))+    <> help "ID of tweet"))  -- | Parser for the user subcommand profile :: Parser Command@@ -162,6 +202,7 @@         (metavar "SCREEN_NAME"         <> help "Screen name of user you want to view.") +-- | Parse best tweets best :: Parser Command best = Sort     <$> switch
src/Web/Tweet/Parser.hs view
@@ -9,6 +9,8 @@ import Data.Monoid import Data.Maybe import Control.Monad+--+import System.IO.Unsafe  -- | Parse some number of tweets parseTweet :: Parser Timeline@@ -29,16 +31,20 @@             faves <- read <$> filterStr "favorite_count"             pure (TweetEntity text name screenName id Nothing rts faves)         "true" -> do-            idQuoted <- read <$> filterStr "id"-            textQuoted <- filterStr "text"-            skipMentions-            nameQuoted <- filterStr "name"-            screenNameQuoted <- filterStr "screen_name"-            rtsQuoted <- read <$> filterStr "retweet_count"-            favesQuoted <- read <$> filterStr "favorite_count"+            quoted <- parseQuoted             rts <- read <$> filterStr "retweet_count"             faves <- read <$> filterStr "favorite_count"-            pure $ TweetEntity text name screenName id (Just (TweetEntity textQuoted nameQuoted screenNameQuoted idQuoted Nothing rtsQuoted favesQuoted)) rts faves+            pure $ TweetEntity text name screenName id quoted rts faves+++parseQuoted :: Parser (Maybe TweetEntity)+parseQuoted = do+    optional (string ",\"quoted_status_id" >> filterStr "quoted_status_id_str") -- FIXME it's skipping too many? No prob is when two in a row twitter just dives in to RTs ALSO something wonky with it flipping rts/faves?+    contents <- optional $ string "\",\"quoted_status"+    case contents of+        (Just contents) -> pure <$> getData+        _ -> pure Nothing+      -- | Skip a set of square brackets [] skipInsideBrackets :: Parser ()
src/Web/Tweet/Types.hs view
@@ -26,7 +26,7 @@     , _quoted :: Maybe TweetEntity     , _retweets :: Int     , _favorites :: Int-    } deriving (Generic, Default)+    } deriving (Generic, Default, Eq)  -- | Stores data like (name, text, favoriteCount, retweetCount) type Timeline = [TweetEntity]
src/Web/Tweet/Utils.hs view
@@ -4,7 +4,6 @@ import qualified Data.ByteString.Char8 as BS import Data.Char import Data.List-import Data.Monoid import Web.Tweet.Types import Control.Lens.Tuple import Control.Lens hiding (noneOf)@@ -16,26 +15,74 @@  -- | filter out retweets, and sort by most successful. hits :: Timeline -> Timeline-hits = sortTweets . filterRTs+hits = sortTweets . filterRTs   -- | Filter out retweets filterRTs :: Timeline -> Timeline filterRTs = filter ((/="RT @") . take 4 . (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 :: String -> Either (ParseError Char Dec) Timeline getTweets = parse parseTweet ""   -- | Display Timeline without color displayTimeline :: Timeline -> String-displayTimeline ((TweetEntity content user _ _ Nothing fave rts):rest) = (user <> ":\n    " <> (fixNewline content)) <> "\n    " <> "♥ " <> (show fave) <> " ♺ " <> (show rts) <> "\n\n" <> (displayTimeline rest) -displayTimeline ((TweetEntity content user _ _ (Just quoted) fave rts):rest) = (user <> ":\n    " <> (fixNewline content)) <> "\n    " <> "♥ " <> (show fave) <> " ♺ " <> (show rts) <> "\n    " <> (_name quoted) <> ": " <> (_text quoted) <> "\n\n" <> (displayTimeline rest) +displayTimeline ((TweetEntity content user _ _ Nothing rts fave):rest) = concat [user+    ,":\n    " +    ,fixNewline content +    ,"\n    " +    ,"♥ " +    ,show fave +    ," ♺ " +    ,show rts +    ,"\n\n" +    ,displayTimeline rest]+displayTimeline ((TweetEntity content user _ _ (Just quoted) rts fave):rest) = concat [user +    , ":\n    " +    , fixNewline content +    , "\n    " +    , "♥ " +    , show fave +    , " ♺ " +    , show rts +    , "\n    " +    , _name quoted +    , ": " +    , _text quoted +    , "\n\n" +    , displayTimeline rest] displayTimeline [] = []  -- | Display Timeline in color displayTimelineColor :: Timeline -> String-displayTimelineColor ((TweetEntity content user _ _ Nothing fave rts):rest) = ((toYellow user) <> ":\n    " <> (fixNewline content)) <> "\n    " <> (toRed "♥ ") <> (show fave) <> (toGreen " ♺ ") <> (show rts) <> "\n\n" <> (displayTimelineColor rest) -displayTimelineColor ((TweetEntity content user _ _ (Just quoted) fave rts):rest) = ((toYellow user) <> ":\n    " <> (fixNewline content)) <> "\n    " <> (toRed "♥ ") <> (show fave) <> (toGreen " ♺ ") <> (show rts) <> "\n    " <> (toYellow $ _name quoted) <> ": " <> (_text quoted) <> "\n\n" <> (displayTimelineColor rest) +displayTimelineColor ((TweetEntity content user _ _ Nothing rts fave):rest) = concat [toYellow user +    , ":\n    " +    , fixNewline content+    , "\n    " +    , toRed "♥ " +    , show fave +    , toGreen " ♺ " +    , show rts +    , "\n\n" +    , displayTimelineColor rest]+displayTimelineColor ((TweetEntity content user _ _ (Just quoted) rts fave):rest) = concat [toYellow user +    , ":\n    " +    , fixNewline content +    , "\n    " +    , toRed "♥ " +    , show fave +    , toGreen " ♺ " +    , show rts +    , "\n    " +    , toYellow $ _name quoted +    , ": " +    , _text quoted +    , "\n\n" +    , displayTimelineColor rest] displayTimelineColor [] = []  -- | When displaying, newlines should include indentation.@@ -45,7 +92,7 @@ -- | sort tweets by most successful sortTweets :: Timeline -> Timeline sortTweets = sortBy compareTweet-    where compareTweet (TweetEntity _ _ _ _ _ f1 r1) (TweetEntity _ _ _ _ _ f2 r2) = compare (2*r2 + f2) (2*r1 + f1)+    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
tweet-hs.cabal view
@@ -1,5 +1,5 @@ name: tweet-hs-version: 0.5.1.0+version: 0.5.1.2 cabal-version: >=1.10 build-type: Simple license: BSD3@@ -69,7 +69,7 @@     main-is: Main.hs     build-depends:         base >=4.9.1.0 && <4.10,-        tweet-hs >=0.5.1.0 && <0.6+        tweet-hs >=0.5.1.2 && <0.6     default-language: Haskell2010     hs-source-dirs: app