packages feed

hackage2twitter (empty) → 0.2.1

raw patch · 4 files changed

+147/−0 lines, 4 filesdep +basedep +feeddep +feed2twittersetup-changed

Dependencies added: base, feed, feed2twitter

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2009,  Tom Lokhorst++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,4 @@+#! /usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain
+ hackage2twitter.cabal view
@@ -0,0 +1,33 @@+name:                hackage2twitter+version:             0.2.1+synopsis:            Send new Hackage releases to Twitter+description:         Build on the `feed2twitter` library, this program reads+                     the Hackage RSS feed and tweets each new release to+                     Twitter.+                     .+                     The Hackage feed is read only once. To keep updating, call+                     this program every few minutes in a cron job.+                     .+                     A local cache of the last 20 tweets is kept in a file to+                     make sure no duplicates are sent.+                     .+                     Usage:+                     .+                     > $ hackage2twitter username password cache-file [--debug-mode]+license:             BSD3+license-file:        LICENSE+author:              Tom Lokhorst+maintainer:          Tom Lokhorst <tom@lokhorst.eu>+homepage:            http://github.com/tomlokhorst/hackage2twitter+stability:           Experimental+category:            Distribution, Web+build-type:          Simple+cabal-version:       >= 1.6++executable hackage2twitter+  build-depends:     base >= 4,+                     feed >= 0.3.6,+                     feed2twitter >= 0.2+  main-is:           Main.hs+  hs-source-dirs:    src+
+ src/Main.hs view
@@ -0,0 +1,83 @@+-------------------------------------------------------------------------------+-- |+-- Module      : Main+-- Copyright   : (c) 2009, Tom Lokhorst+-- License     : BSD3+--+-- Maintainer  : Tom Lokhorst <tom@lokhorst.eu>+-- Stability   : Experimental+--+-- Main module for the `hackage2twitter` executable.+-- Contains `rssItem2Tweet` function to parse Hackage RSS items.+--+-------------------------------------------------------------------------------+module Main where++import Text.RSS.Syntax+import Web.Feed2Twitter++import Data.Maybe+import Data.List+import System.Console.GetOpt+import System.Environment++main :: IO ()+main = do+  args <- getArgs+  (cfg, rest) <- processArgs defaultConfig options header args+  if length rest /= 3+   then putStrLn $ usageInfo header options+   else do+        let cfg' = cfg { username  = rest !! 0+                       , password  = rest !! 1+                       , cacheFile = rest !! 2+                       }+        rss2twitter cfg' rssItem2tweet+  where+    header = "Usage: hackage2twitter USERNAME PASSWORD CACHE-FILE [OPTIONS...]"+              ++ ", with the following options:"++-- Map a RSS item to a tweet.+-- This function will fail on a few `fromJust`s if the Hackage RSS feed ever changes.+rssItem2tweet :: RSSItem -> Tweet+rssItem2tweet ri = trunc4url (title ++ ", added by " ++ uploader+                               ++ maybe "." (": " ++) blurb) ++ url+  where+    title     = filter (/='\n') . fromJust . rssItemTitle $ ri+    uploader  = take (fromJust $ elemIndex ',' uploader') uploader'+    blurb     = fmap (\x -> drop (x + 3) desc) (findSubList "<p>" desc)+    url       = fromJust . rssItemLink $ ri+    guid      = rssGuidValue . fromJust . rssItemGuid $ ri+    desc      = map (\x -> if x == '\n' then ' ' else x)+                  . fromJust . rssItemDescription $ ri+    uploader' = drop 12 desc++findSubList :: Eq a => [a] -> [a] -> Maybe Int+findSubList [] s2 = Nothing+findSubList s1 s2 = listToMaybe $ filter (\x -> isPrefixOf s1 $ drop x s2) xs+  where+    xs = elemIndices (head s1) s2++defaultConfig :: Config+defaultConfig = Config+  { feedUrl = "http://hackage.haskell.org/packages/archive/recent.rss"+  , username = ""+  , password = ""+  , cacheFile = ""+  , cacheSize = 20+  , debugMode = False+  }++options :: [OptDescr (Config -> Config)]+options =+  [ Option ['d'] ["debug-mode"] (NoArg (\c -> c { debugMode = True })) "Debug mode, send tweets to stdout."+  -- , Option ['V'] ["version"] (NoArg (\c -> c { showVersion = True })) "Show program version."+  ]++-- Seems like this function should already exist somewhere in a package.+processArgs :: a -> [OptDescr (a -> a)] -> String -> [String] -> IO (a, [String])+processArgs defaultConfig options header args =+  case getOpt Permute options args of+    (oargs, nonopts, []    ) -> return (foldl (flip ($)) defaultConfig oargs, nonopts)+    (_    , _      , errors) -> ioError $ userError $ (concat errors) ++ usageInfo header options+