module Imm.Core (
FeedConfig,
FeedList,
dispatch,
importOPML,
check,
showStatus,
markAsRead,
markAsUnread,
update,
) where
import Imm.Config
import Imm.Database
import Imm.Error
import Imm.Feed (FeedParser(..))
import qualified Imm.Feed as Feed
import Imm.Maildir (MaildirWriter(..))
import qualified Imm.Maildir as Maildir
import Imm.Mail (MailFormatter(..))
import qualified Imm.Mail as Mail
import Imm.OPML as OPML
import Imm.Util
import Control.Concurrent.Async
import Control.Monad hiding(forM_, mapM_)
import Control.Monad.Error hiding(forM_, mapM_)
import Data.Foldable hiding(foldr)
import Data.Time as T
import Prelude hiding(log, mapM_, sum)
import System.Log.Logger
import Text.Feed.Query as F
import Text.Feed.Types as F
type FeedConfig = (Config -> Config, FeedID)
type FeedList = [FeedConfig]
dispatch :: (Config -> Config) -> Feed.Action -> FeedList -> IO ()
dispatch baseConfig Feed.Check feeds = void $ mapConcurrently (check baseConfig) feeds
dispatch baseConfig Feed.ShowStatus feeds = mapM_ (showStatus baseConfig) feeds
dispatch baseConfig Feed.MarkAsRead feeds = mapM_ (markAsRead baseConfig) feeds
dispatch baseConfig Feed.MarkAsUnread feeds = mapM_ (markAsUnread baseConfig) feeds
dispatch baseConfig Feed.Update feeds = void $ mapConcurrently (update baseConfig) feeds
importOPML :: (MonadBase IO m, MonadPlus m) => String -> m ()
importOPML = mapM_ addFeeds . OPML.read
check :: (Config -> Config) -> FeedConfig -> IO ()
check baseConfig (f, feedID) = withError "imm.core". withConfig (f . baseConfig) $ Feed.download feedID >>= Feed.check
showStatus :: (Config -> Config) -> FeedConfig -> IO ()
showStatus baseConfig (f, feedID) = withConfig (f . baseConfig) (io . noticeM "imm.core" =<< Feed.showStatus feedID)
markAsRead :: (Config -> Config) -> FeedConfig -> IO ()
markAsRead baseConfig (f, feedID) = withError "imm.core" . withConfig (f . baseConfig) $ Feed.markAsRead feedID
markAsUnread :: (Config -> Config) -> FeedConfig -> IO ()
markAsUnread baseConfig (f, feedID) = withError "imm.core" . withConfig (f . baseConfig) $ Feed.markAsUnread feedID
update :: (Config -> Config) -> FeedConfig -> IO ()
update baseConfig (f, feedID) = withError "imm.core" . withConfig (f . baseConfig) $ do
(uri, feed) <- Feed.download feedID
Maildir.init
io . debugM "imm.core" $ Feed.describe feed
lastCheck <- getLastCheck uri
(results :: [Integer]) <- forM (feedItems feed) $ \item -> do
date <- Feed.getDate item
(date > lastCheck) ? (updateItem (item, feed) >> return 1) ?? return 0
io . noticeM "imm.core" $ "==> " ++ show (sum results) ++ " new item(s) for <" ++ show feedID ++ ">"
Feed.markAsRead uri
updateItem :: (Applicative m, FeedParser m, MaildirWriter m, MailFormatter m, MonadBase IO m, MonadError ImmError m) => (Item, Feed) -> m ()
updateItem (item, feed) = do
timeZone <- io getCurrentTimeZone
Maildir.write =<< Mail.build timeZone (item, feed)