tweet-hs 0.5.2.0 → 0.5.3.0
raw patch · 5 files changed
+123/−68 lines, 5 filesdep ~tweet-hs
Dependency ranges changed: tweet-hs
Files
- README.md +2/−0
- src/Web/Tweet/API.hs +40/−3
- src/Web/Tweet/Exec.hs +77/−55
- src/Web/Tweet/Utils.hs +0/−6
- tweet-hs.cabal +4/−4
README.md view
@@ -1,5 +1,7 @@ # Command Line Interface Tweeter +[](https://travis-ci.org/vmchale/command-line-tweeter)+  ## Config Generate a token to authorize access to your twitter account by following the guide [here](https://dev.twitter.com/oauth/overview/application-owner-access-tokens)
src/Web/Tweet/API.hs view
@@ -41,7 +41,7 @@ -- | Gets user profile with max_id set. getProfileMax :: String -> Int -> FilePath -> Maybe Int -> IO (Either (ParseError Char Dec) Timeline)-getProfileMax screenName count filepath maxId = getTweets . BSL.toStrict <$> getProfileRaw screenName count filepath maxId+getProfileMax = fmap (getTweets . BSL.toStrict) .*** getProfileRaw -- | Gets user profile with max_id set. getProfileRaw :: String -> Int -> FilePath -> Maybe Int -> IO BSL.ByteString@@ -50,6 +50,15 @@ (Just id) -> "?screen_name=" ++ screenName ++ "&count=" ++ (show count) ++ "&max_id=" ++ (show id) ; Nothing -> "?screen_name=" ++ screenName ++ "&count=" ++ (show count) } +-- | Get mentions and parse response as a list of tweets+mentions :: Int -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+mentions = fmap (getTweets . BSL.toStrict) .* mentionsRaw++-- | Gets mentions+mentionsRaw :: Int -> FilePath -> IO BSL.ByteString+mentionsRaw count filepath = getRequest ("https://api.twitter.com/1.1/statuses/user_timeline.json" ++ requestString) filepath+ where requestString = "?count=" ++ (show count)+ -- | Get user profile given screen name and how many tweets to return getProfile :: String -> Int -> FilePath -> IO (Either (ParseError Char Dec) Timeline) getProfile screenName count filepath = getProfileMax screenName count filepath Nothing@@ -57,11 +66,11 @@ -- | Show a user profile given screen name, how many tweets to return, -- and whether to print them in color. showProfile :: String -> Int -> Bool -> FilePath -> IO String-showProfile screenName count color filepath = showTweets color <$> getProfile screenName count filepath+showProfile screenName count color = fmap (showTweets color) . getProfile screenName count -- | Show the most successful tweets by a given user, given their screen name. showBest :: String -> Int -> Bool -> FilePath -> IO String-showBest screenName n color filepath = showTweets color . pure . (take n . hits) <$> getAll screenName Nothing filepath +showBest screenName n color = fmap (showTweets color . pure . (take n . hits)) . getAll screenName Nothing -- | Display user timeline showTimeline :: Int -> Bool -> FilePath -> IO String@@ -88,18 +97,34 @@ deleteTweet :: Integer -> FilePath -> IO () deleteTweet = (fmap void) . deleteTweetRaw +-- | Get response, i.e. the tweet deleted+deleteTweetResponse :: Integer -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+deleteTweetResponse = fmap (getTweets . BSL.toStrict) .* deleteTweetRaw+ -- | Favorite a tweet given its id favoriteTweet :: Integer -> FilePath -> IO () favoriteTweet = (fmap void) . favoriteTweetRaw +-- | Favorite a tweet and returned the (parsed) response+favoriteTweetResponse :: Integer -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+favoriteTweetResponse = fmap (getTweets . BSL.toStrict) .* favoriteTweetRaw+ -- | Unfavorite a tweet given its id unfavoriteTweet :: Integer -> FilePath -> IO () unfavoriteTweet = (fmap void) . unfavoriteTweetRaw +-- | Unfavorite a tweet and returned the (parsed) response+unfavoriteTweetResponse :: Integer -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+unfavoriteTweetResponse = fmap (getTweets . BSL.toStrict) .* unfavoriteTweetRaw+ -- | Unretweet a tweet given its id unretweetTweet :: Integer -> FilePath -> IO () unretweetTweet = (fmap void) . unretweetTweetRaw +-- | Unretweet a tweet and returned the (parsed) response+unretweetTweetResponse :: Integer -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+unretweetTweetResponse = fmap (getTweets . BSL.toStrict) .* unretweetTweetRaw+ -- | Unfollow a user given their screen name unfollow :: String -> FilePath -> IO () unfollow = (fmap void) . unfollowUserRaw@@ -108,9 +133,21 @@ follow :: String -> FilePath -> IO () follow = (fmap void) . followUserRaw +-- | Block a user given their screen name+block :: String -> FilePath -> IO ()+block = (fmap void) . blockUserRaw++-- | Unblock a user given their screen name+unblock :: String -> FilePath -> IO ()+unblock = (fmap void) . unblockUserRaw+ -- | Retweet a tweet given its id retweetTweet :: Integer -> FilePath -> IO () retweetTweet = (fmap void) . retweetTweetRaw++-- | Retweet a tweet and returned the (parsed) response+retweetTweetResponse :: Integer -> FilePath -> IO (Either (ParseError Char Dec) Timeline)+retweetTweetResponse = fmap (getTweets . BSL.toStrict) .* retweetTweetRaw -- | Favorite a tweet given its id; return bytestring response favoriteTweetRaw :: Integer -> FilePath -> IO BSL.ByteString
src/Web/Tweet/Exec.hs view
@@ -14,16 +14,17 @@ import System.Directory -- | Data type for our program: one optional path to a credential file, (optionally) the number of tweetInputs to make, the id of the status you're replying to, and a list of users you wish to mention.-data Program = Program { subcommand :: Command , cred :: Maybe FilePath }+data Program = Program { subcommand :: Command , cred :: Maybe FilePath , color :: Bool } -- | Data type for a command -- TODO add boolean option to show ids alongside tweets-data Command = Timeline { count :: Maybe Int , color :: Bool }+data Command = Timeline { count :: Maybe Int } | SendInput { tweetInputs :: Maybe Int, replyId :: Maybe String, replyHandles :: Maybe [String] }- | Profile { count :: Maybe Int , color :: Bool , screenName :: String }+ | Profile { count :: Maybe Int , screenName :: String }+ | Mentions { count :: Maybe Int } | Markov { screenName :: String } | Send { tweets :: Maybe Int , replyId :: Maybe String , replyHandles :: Maybe [String] , userInput :: String }- | Sort { color :: Bool , screenName :: String , count :: Maybe Int }+ | Sort { screenName :: String , count :: Maybe Int } | Delete { twId :: Integer } | Fav { twId :: Integer } | Unfav { twId :: Integer }@@ -31,6 +32,8 @@ | Unretweet { twId :: Integer } | Follow { screenName :: String } | Unfollow { screenName :: String }+ | Block { screenName :: String }+ | Unblock { screenName :: String } | Dump { screenName :: String } -- | query twitter to post stdin with no fancy options@@ -58,48 +61,55 @@ -- | Executes program given parsed `Program` select :: Program -> IO ()-select (Program com maybeFile) = case maybeFile of- (Just file) -> selectCommand com file- _ -> selectCommand com =<< (++ "/.cred") <$> getHomeDirectory+select (Program com maybeFile color) = case maybeFile of+ (Just file) -> selectCommand com color file+ _ -> selectCommand com color =<< (++ "/.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 maybeNum) file = putStrLn =<< showBest name (maybe 11 id maybeNum) color file-selectCommand (Markov name) file = do+selectCommand :: Command -> Bool -> 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 (Mentions maybeNum) color file = putStrLn =<< showTweets color <$> mentions (maybe 11 id maybeNum) file+selectCommand (Profile maybeNum name) color file = putStrLn =<< showProfile name (maybe 11 id maybeNum) color file+selectCommand (Sort name maybeNum) color file = putStrLn =<< showBest name (maybe 11 id maybeNum) 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+selectCommand (Delete n) color file = do+ putStrLn "Deleted:\n"+ putStrLn =<< showTweets color <$> deleteTweetResponse n file+selectCommand (Fav n) color file = do+ putStrLn "Favorited:\n"+ putStrLn =<< showTweets color <$> favoriteTweetResponse n file+selectCommand (Unfav n) color file = do+ putStrLn "Unfavorited:\n"+ putStrLn =<< showTweets color <$> unfavoriteTweetResponse n file+selectCommand (Retweet n) color file = do+ putStrLn "Retweeted:\n"+ putStrLn =<< showTweets color <$> retweetTweetResponse n file+selectCommand (Unretweet n) color file = do+ putStrLn "Unretweeted:\n"+ putStrLn =<< showTweets color <$> unretweetTweetResponse n file+selectCommand (Follow screenName) _ file = do follow screenName file putStrLn ("..." ++ screenName ++ " followed successfully!")-selectCommand (Unfollow screenName) file = do+selectCommand (Unfollow screenName) _ file = do unfollow screenName file putStrLn ("..." ++ screenName ++ " unfollowed successfully!")-selectCommand (Dump screenName) file = BSL.putStrLn =<< (getProfileRaw screenName 3200 file Nothing)+selectCommand (Block screenName) color file = do+ block screenName file+ putStrLn ("..." ++ screenName ++ " blocked successfully")+selectCommand (Unblock screenName) color file = do+ unblock screenName file+ putStrLn ("..." ++ screenName ++ " unblocked successfully")+selectCommand (Dump screenName) color file = BSL.putStrLn =<< (getProfileRaw screenName 3200 file Nothing) -- | Parser to return a program datatype program :: Parser Program@@ -118,12 +128,19 @@ <> 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)"))))+ <> command "dump" (info dump (progDesc "Dump tweets (for debugging)"))+ <> command "block" (info blockParser (progDesc "Block a user"))+ <> command "unblock" (info unblockParser (progDesc "Unblock a user"))+ <> command "mention" (info mentionsParser (progDesc "Fetch mentions")))) <*> (optional $ strOption (long "cred" <> short 'c' <> metavar "CREDENTIALS" <> help "path to credentials"))+ <*> switch+ (long "color"+ <> short 'l'+ <> help "Display timeline with colorized terminal output.") -- | Parser for the view subcommand timeline :: Parser Command@@ -133,24 +150,28 @@ <> short 'n' <> metavar "NUM" <> help "number of tweetInputs to fetch, default 5"))- <*> switch- (long "color"- <> short 'l'- <> help "Display timeline with colorized terminal output.") --- | Parser for the raw subcommand+-- | Parser for the markov subcommand markov :: Parser Command markov = Markov <$> user --- | Parser for the raw subcommand+-- | Parser for the follow subcommand fol :: Parser Command fol = Follow <$> user --- | Parser for the raw subcommand+-- | Parser for the block subcommand+blockParser :: Parser Command+blockParser = Block <$> user++-- | Parser for the unblock subcommand+unblockParser :: Parser Command+unblockParser = Unblock <$> user++-- | Parser for the dump subcommand dump :: Parser Command dump = Dump <$> user --- | Parser for the raw subcommand+-- | Parser for the unfollow subcommand unfol :: Parser Command unfol = Unfollow <$> user @@ -194,22 +215,23 @@ <> short 'n' <> metavar "NUM" <> help "Number of tweetInputs to fetch, default 12"))- <*> switch- (long "color"- <> short 'l'- <> help "Whether to display profile with colorized terminal output") <*> argument str (metavar "SCREEN_NAME" <> help "Screen name of user you want to view.") +-- | Parser for the mention subcommand+mentionsParser :: Parser Command+mentionsParser = Mentions+ <$> (optional $ read <$> strOption+ (long "count"+ <> short 'n'+ <> metavar "NUM"+ <> help "Number of tweetInputs to fetch, default 12"))+ -- | Parse best tweets best :: Parser Command best = Sort- <$> switch- (long "color"- <> short 'l'- <> help "Display timeline with colorized terminal output.")- <*> argument str+ <$> argument str (metavar "SCREEN_NAME" <> help "Screen name of user you want to view.") <*> (optional $ read <$> strOption
src/Web/Tweet/Utils.hs view
@@ -3,9 +3,6 @@ import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString as BS2-import qualified Data.ByteString.Lazy as BSL-import qualified Data.Text as T-import Data.Text.Encoding import Data.Char import Data.List import Web.Tweet.Types@@ -16,9 +13,6 @@ import Data.List.Extra import Web.Tweet.Parser import Text.Megaparsec--bytestringToText :: BSL.ByteString -> T.Text-bytestringToText = decodeUtf8 . BSL.toStrict -- | filter out retweets, and sort by most successful. hits :: Timeline -> Timeline
tweet-hs.cabal view
@@ -1,5 +1,5 @@ name: tweet-hs-version: 0.5.2.0+version: 0.5.3.0 cabal-version: >=1.10 build-type: Simple license: BSD3@@ -70,7 +70,7 @@ main-is: Main.hs build-depends: base >=4.9.1.0 && <4.10,- tweet-hs >=0.5.2.0 && <0.6+ tweet-hs >=0.5.3.0 && <0.6 default-language: Haskell2010 hs-source-dirs: app @@ -79,7 +79,7 @@ main-is: Spec.hs build-depends: base >=4.9.1.0 && <4.10,- tweet-hs >=0.5.2.0 && <0.6,+ tweet-hs >=0.5.3.0 && <0.6, hspec >=2.4.2 && <2.5, hspec-megaparsec >=0.3.1 && <0.4, megaparsec >=5.2.0 && <5.3,@@ -99,7 +99,7 @@ build-depends: base >=4.9.1.0 && <4.10, criterion >=1.1.4.0 && <1.2,- tweet-hs >=0.5.2.0 && <0.6,+ tweet-hs >=0.5.3.0 && <0.6, megaparsec >=5.2.0 && <5.3, bytestring >=0.10.8.1 && <0.11 default-language: Haskell2010