packages feed

ureader 0.1.0.0 → 0.2.0.0

raw patch · 7 files changed

+167/−30 lines, 7 filesdep +deepseqdep +opml

Dependencies added: deepseq, opml

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013, Sam T.+Copyright (c) 2013, Sam Truzjan  All rights reserved. @@ -13,7 +13,7 @@       disclaimer in the documentation and/or other materials provided       with the distribution. -    * Neither the name of Sam T. nor the names of other+    * Neither the name of Sam Truzjan nor the names of other       contributors may be used to endorse or promote products derived       from this software without specific prior written permission. 
src/Main.hs view
@@ -1,5 +1,7 @@ module Main (main) where +import Prelude as P+ import Control.Applicative as A import Control.Concurrent import Control.Concurrent.Async@@ -8,6 +10,7 @@ import Data.Default import Data.List as L import Data.Maybe+import Data.Monoid import Data.Time import Data.Time.Clock.POSIX import Data.Version (showVersion)@@ -22,27 +25,21 @@  import UReader.Localization import UReader.Options+import UReader.Outline import UReader.Rendering import UReader.RSS  -parseFeedList :: String -> [URI]-parseFeedList = mapMaybe parseURI . L.lines--getFeedList :: FilePath -> IO [URI]-getFeedList feedList = parseFeedList <$> Prelude.readFile feedList-- getLastSeen :: FilePath -> IO UTCTime getLastSeen lastPath = do     exist <- doesFileExist lastPath     if exist       then do-        !mLastSeen <- parsePubDate <$> Prelude.readFile lastPath-        Prelude.writeFile lastPath . formatPubDate =<< getCurrentTime+        !mLastSeen <- parsePubDate <$> P.readFile lastPath+        P.writeFile lastPath . formatPubDate =<< getCurrentTime         return $ fromMaybe epochStart mLastSeen       else do-        Prelude.writeFile lastPath . formatPubDate =<< getCurrentTime+        P.writeFile lastPath . formatPubDate =<< getCurrentTime         return epochStart   where     epochStart = posixSecondsToUTCTime 0@@ -69,7 +66,8 @@   let userFeeds  =  L.map (filterItems isNew) feeds   unless (L.all emptyFeed userFeeds) $ do     localTime <- utcToLocalTime <$> getCurrentTimeZone <*> pure lastSeen-    print $ green $ "Showed from:" <+> text (formatPubDate localTime)+    print $ green $ linebreak <>+      "Showed from:" <+> text (formatPubDate localTime)   return userFeeds  previewFeed :: URI -> IO ()@@ -79,6 +77,7 @@ showBatch style @ Style {..} feedList uris = do   renderRSS style =<< setCurrentZone =<<     (if newOnly then filterNew feedList else fetch Nothing) uris+  putStrLn ([] :: String)  streamStyle :: Style streamStyle = Style@@ -105,12 +104,24 @@ streamFeeds feedList interval uris =   pollBy interval $ do updateStream feedList uris +addFeed :: FilePath -> URI -> String -> String -> IO ()+addFeed filePath uri grp topic+  = modifyOPML filePath (insertURI [grp, topic] uri)++putVersion :: IO ()+putVersion = P.putStrLn $ "ureader version " ++ showVersion version+ run :: Options -> IO ()-run Add     {..} = appendFile feedList $ show feedURI ++ "\n"-run Batch   {..} = getFeedList feedList >>= showBatch feedStyle feedList-run Preview {..} = previewFeed feedURI-run Stream  {..} = getFeedList feedList >>= streamFeeds feedList feedInterval-run Version      = putStrLn $ "ureader version " ++ showVersion version+run Add     {..} = addFeed      feedList   feedURI+                                feedParent feedTopic+run Batch   {..} = getFeedList  feedList  feedGroup+               >>= showBatch    feedStyle feedList+run Index   {..} = getIndex     feedList  feedGroup+               >>= renderFeedList+run Preview {..} = previewFeed  feedURI+run Stream  {..} = getFeedList  feedList feedGroup+               >>= streamFeeds  feedList feedInterval+run Version      = putVersion  main :: IO () main = getOptions >>= run
src/UReader/Localization.hs view
@@ -1,3 +1,16 @@+-- |+--   Copyright   :  (c) Sam Truzjan 2013+--   License     :  BSD3+--   Maintainer  :  pxqr.sta@gmail.com+--   Stability   :  experimental+--   Portability :  portable+--+--   This module provides simple localization for feed items.+--   Currently an UTC time (pubdate) translated to the LocalTime which+--   user expect to see.+--+--   +0000(UTC) -> +0004(MSK)+-- {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE OverlappingInstances #-} module UReader.Localization
src/UReader/Options.hs view
@@ -1,7 +1,16 @@+-- |+--   Copyright   :  (c) Sam Truzjan 2013+--   License     :  BSD3+--   Maintainer  :  pxqr.sta@gmail.com+--   Stability   :  experimental+--   Portability :  portable+--+--   All stuff relate to command line options should be in this+--   module: parsers, help, reasonable defaults.+-- module UReader.Options        ( Order (..)        , Style (..)-        , Options (..)        , getOptions        ) where@@ -15,6 +24,7 @@ import System.FilePath  import UReader.Rendering+import UReader.Outline   styleParser :: Parser Style@@ -43,7 +53,7 @@       )  feedListParser :: Implicit_ FilePath => Parser FilePath-feedListParser = option+feedListParser = strOption    ( long    "feeds"   <> metavar "PATH"   <> value   param_ <> showDefault@@ -65,22 +75,49 @@   <> help    "Minimal interval between feed updates"    ) +feedGroupParser :: Parser Selector+feedGroupParser = optional $ argument Just+   ( metavar "GROUP"+  <> help    "Feed group used to specify some subset of feeds"+   )++feedParentParser :: Parser String+feedParentParser = argument Just+  ( metavar  "GROUP"+ <> help     "The group feed belongs to"+  )++feedTopicParser :: Parser String+feedTopicParser = argument Just+   ( metavar "TOPIC"+ <>  help    "The main feed topic used as feed name"+   )+ data Options    = Add     { feedList   :: FilePath+             , feedParent :: String+             , feedTopic  :: String              , feedURI    :: URI              }    | Batch   { feedList   :: FilePath              , feedStyle  :: Style+             , feedGroup  :: Selector              }    | Preview { feedURI    :: URI  }    | Stream  { feedList   :: FilePath              , feedInterval :: Int+             , feedGroup  :: Selector              }+   | Index   { feedList   :: FilePath+             , feedGroup  :: Selector+             }    | Version      deriving (Show, Eq)  addParser :: Implicit_ String => Parser Options-addParser = Add <$> feedListParser <*> feedLinkParser+addParser = Add <$> feedListParser+                <*> feedParentParser <*> feedTopicParser+                <*> feedLinkParser  addInfo :: Implicit_ String => ParserInfo Options addInfo = info (helper <*> addParser) modifier@@ -88,7 +125,7 @@     modifier = progDesc "Add a feed to the feed list"  streamParser :: Implicit_ String => Parser Options-streamParser = Stream <$> feedListParser <*> intervalTime+streamParser = Stream <$> feedListParser <*> intervalTime <*> feedGroupParser  streamInfo :: Implicit_ String => ParserInfo Options streamInfo = info (helper <*> streamParser) modifier@@ -96,7 +133,7 @@     modifier = progDesc "Show feed as never ending stream"  feedParser :: Implicit_ String => Parser Options-feedParser = Batch <$> feedListParser <*> styleParser+feedParser = Batch <$> feedListParser <*> styleParser <*> feedGroupParser  feedInfo :: Implicit_ String => ParserInfo Options feedInfo = info (helper <*> feedParser) modifier@@ -111,6 +148,14 @@   where     modifier = progDesc "Show feed specified by URI or file path" +indexParser :: Implicit_ FilePath => Parser Options+indexParser = Index <$> feedListParser <*> feedGroupParser++indexInfo :: Implicit_ FilePath => ParserInfo Options+indexInfo = info (helper <*> indexParser) modifier+  where+    modifier = progDesc "Show your feed list"+ versionParser :: Parser Options versionParser = flag' Version     ( long  "version"@@ -123,6 +168,7 @@ optionsParser = subparser $ mconcat   [ command "add"    addInfo   , command "feed"   feedInfo+  , command "index"  indexInfo   , command "stream" streamInfo   , command "view"   previewInfo   ]
src/UReader/RSS.hs view
@@ -1,3 +1,12 @@+-- |+--   Copyright   :  (c) Sam Truzjan 2013+--   License     :  BSD3+--   Maintainer  :  pxqr.sta@gmail.com+--   Stability   :  experimental+--   Portability :  portable+--+--   This module provides network related stuff.+-- module UReader.RSS        ( filterItems        , reverseItems
src/UReader/Rendering.hs view
@@ -1,8 +1,19 @@+-- |+--   Copyright   :  (c) Sam Truzjan 2013+--   License     :  BSD3+--   Maintainer  :  pxqr.sta@gmail.com+--   Stability   :  experimental+--   Portability :  portable+--+--   This module provides colored (ansi-terminal compatible) rendering+--   for OPML, RSS, (Atom not yet) and HTML.+-- {-# OPTIONS -fno-warn-orphans #-} module UReader.Rendering        ( Order (..)        , Style (..)        , renderRSS+       , renderFeedList        ) where  import Control.Applicative@@ -16,16 +27,59 @@ import Data.List.Split as L import Data.Set as S import Text.HTML.TagSoup+import Text.OPML.Syntax import Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>), width) import Text.RSS.Syntax import Text.XML.Light.Types+import Network.URI import System.IO import System.Console.Terminal.Size as Terminal  import UReader.RSS import UReader.Localization+import UReader.Outline +{-----------------------------------------------------------------------+  Feed list+-----------------------------------------------------------------------} +renderFeedList :: OPML -> IO ()+renderFeedList = print . pretty++instance Pretty Outline where+  pretty Outline  {..} =+    fill 28 (topicTy (pretty opmlText))+                      <+> ppURI opmlOutlineAttrs <>+      if L.null opmlOutlineChildren then mempty else linebreak <>+        indent 4 (vsep $ L.map pretty opmlOutlineChildren)+--    , "type" <+> pretty opmlType+--    , "categories" <+> pretty opmlCategories+--    , "comment"    <+> pretty opmlIsComment+--    , "breakpoint" <+> pretty opmlIsBreakpoint+--    , "other"      <+> pretty (show opmlOutlineOther)+    where+      topicTy+        | L.null opmlOutlineChildren = blue    . underline+        |         otherwise          = magenta . bold++      ppURI (lookupAttr uriQName -> Just uriStr)+        | Just uri <- parseURI uriStr = "<" <> text (show uri) <> ">"+        |         otherwise           = red "invalid URL"+      ppURI _ = mempty++instance Pretty OPMLHead where+  pretty OPMLHead {..} = pretty opmlTitle++instance Pretty OPML where+  pretty OPML {..}+    = --"version" <+> text opmlVersion </>+      --"head   " <+> pretty opmlHead  </>+      vsep (L.map pretty opmlBody)++{-----------------------------------------------------------------------+  Feed+-----------------------------------------------------------------------}+ data Order = NewFirst            | OldFirst              deriving (Show, Read, Eq, Ord, Bounded, Enum)@@ -138,8 +192,8 @@  instance Pretty RSSCategory where   pretty RSSCategory {..} =-    dullyellow (maybe mempty text rssCategoryDomain) <>-    dullred    (hsep $ L.map pretty rssCategoryAttrs)  <>+    dullyellow (maybe mempty text rssCategoryDomain)  <>+    dullred    (hsep $ L.map pretty rssCategoryAttrs) <>     dullblue   (text rssCategoryValue)  instance Pretty Attr where
ureader.cabal view
@@ -1,10 +1,10 @@ name:                ureader-version:             0.1.0.0+version:             0.2.0.0 license:             BSD3 license-file:        LICENSE-author:              Sam T.-maintainer:          Sam T. <pxqr.sta@gmail.com>-copyright:           (c) 2013, Sam T.+author:              Sam Truzjan+maintainer:          Sam Truzjan <pxqr.sta@gmail.com>+copyright:           (c) 2013, Sam Truzjan category:            RSS build-type:          Simple cabal-version:       >= 1.10@@ -18,11 +18,13 @@         and color support. Everything it does is fetch RSS documents,         merge them according to specified options, format and flush         resulting feed to stdout. So `ureader` could be used with-        pagers like `more(1)` or in linux terminal.+        pagers like more(1) or in linux terminal.         .         [/Release Notes/]         .           * /0.1.0.0:/ Initial version.+        .+          * /0.2.0.0:/ Use OPML for subscription list.   source-repository head@@ -49,6 +51,7 @@   build-depends:       base       == 4.*                      , implicit-params == 0.2.*                      , data-default+                     , deepseq                       , async                      , parallel-io == 0.3.*@@ -71,6 +74,7 @@                      , optparse-applicative == 0.5.*                      , terminal-size        == 0.2.* +                     , opml    == 0.4.*                      , xml     == 1.3.*                      , feed    == 0.3.*                      , tagsoup == 0.12.*