-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Execute arbitrary actions for each unread element of RSS/Atom feeds
--   
--   Cf README file
@package imm
@version 1.2.1.0

module Imm.Prelude

-- | Right-associative tuple type-constructor
type a ::: b = (a, b)

-- | Right-associative tuple data-constructor
(+:) :: a -> b -> (a, b)
infixr 0 +:
(*:) :: (Functor f, Functor g) => (a -> f a) -> (b -> g b) -> (a, b) -> Product f g (a, b)
infixr 0 *:
data HLeft
data HRight
data HId
data HNo
class Sub i sub sup
inj' :: Sub i sub sup => Tagged i (sub a -> sup a)

-- | A constraint <tt>f :&lt;: g</tt> expresses that <tt>f</tt> is subsumed
--   by <tt>g</tt>, i.e. <tt>f</tt> can be used to construct elements in
--   <tt>g</tt>.
class (Functor sub, Functor sup) => sub :<: sup
inj :: (:<:) sub sup => sub a -> sup a

-- | Functors <tt>f</tt> and <tt>g</tt> are paired when they can annihilate
--   each other
class (Monad m, Functor f, Functor g) => PairingM f g m | f -> g
pairM :: PairingM f g m => (a -> b -> m r) -> f a -> g b -> m r
interpret :: (PairingM f g m) => (a -> b -> m r) -> Cofree f a -> FreeT g m b -> m r
type LByteString = ByteString
type ByteString = ByteString
type LText = Text
type Text = Text

-- | Generic <a>show</a>
show :: (Show a, IsString b) => a -> b

-- | Shortcut to <a>liftIO</a>
io :: MonadIO m => IO a -> m a

-- | Infix operator for <a>line</a>
(<++>) :: Doc -> Doc -> Doc
instance GHC.Base.Monad m => Imm.Prelude.PairingM Data.Functor.Identity.Identity Data.Functor.Identity.Identity m
instance (Imm.Prelude.PairingM f f' m, Imm.Prelude.PairingM g g' m) => Imm.Prelude.PairingM (Data.Functor.Sum.Sum f g) (Data.Functor.Product.Product f' g') m
instance (Imm.Prelude.PairingM f f' m, Imm.Prelude.PairingM g g' m) => Imm.Prelude.PairingM (Data.Functor.Product.Product f g) (Data.Functor.Sum.Sum f' g') m
instance (GHC.Base.Functor f, GHC.Base.Functor g, Imm.Prelude.Sub (Imm.Prelude.Contains f g) f g) => f Imm.Prelude.:<: g
instance Imm.Prelude.Sub Imm.Prelude.HId a a
instance Imm.Prelude.Sub Imm.Prelude.HLeft a (Data.Functor.Sum.Sum a b)
instance Imm.Prelude.Sub x f g => Imm.Prelude.Sub (Imm.Prelude.HRight, x) f (Data.Functor.Sum.Sum h g)


-- | DSL/interpreter model for the logger
module Imm.Logger
data LogLevel
Debug :: LogLevel
Info :: LogLevel
Warning :: LogLevel
Error :: LogLevel

-- | Logger DSL
data LoggerF next
Log :: LogLevel -> Doc -> next -> LoggerF next
GetLevel :: (LogLevel -> next) -> LoggerF next
SetLevel :: LogLevel -> next -> LoggerF next
SetColorize :: Bool -> next -> LoggerF next
Flush :: next -> LoggerF next

-- | Logger interpreter
data CoLoggerF m a
CoLoggerF :: (LogLevel -> Doc -> m a) -> m (LogLevel, a) -> (LogLevel -> m a) -> (Bool -> m a) -> m a -> CoLoggerF m a
[logH] :: CoLoggerF m a -> LogLevel -> Doc -> m a
[getLevelH] :: CoLoggerF m a -> m (LogLevel, a)
[setLevelH] :: CoLoggerF m a -> LogLevel -> m a
[setColorizeH] :: CoLoggerF m a -> Bool -> m a
[flushH] :: CoLoggerF m a -> m a
log :: (MonadFree f m, LoggerF :<: f) => LogLevel -> Doc -> m ()
getLogLevel :: (MonadFree f m, LoggerF :<: f) => m LogLevel
setLogLevel :: (MonadFree f m, LoggerF :<: f) => LogLevel -> m ()
setColorizeLogs :: (MonadFree f m, LoggerF :<: f) => Bool -> m ()
flushLogs :: (MonadFree f m, LoggerF :<: f) => m ()
logDebug :: (MonadFree f m, LoggerF :<: f) => Doc -> m ()
logInfo :: (MonadFree f m, LoggerF :<: f) => Doc -> m ()
logWarning :: (MonadFree f m, LoggerF :<: f) => Doc -> m ()
logError :: (MonadFree f m, LoggerF :<: f) => Doc -> m ()
instance GHC.Base.Functor m => GHC.Base.Functor (Imm.Logger.CoLoggerF m)
instance GHC.Base.Functor Imm.Logger.LoggerF
instance GHC.Show.Show Imm.Logger.LogLevel
instance GHC.Read.Read Imm.Logger.LogLevel
instance GHC.Classes.Ord Imm.Logger.LogLevel
instance GHC.Classes.Eq Imm.Logger.LogLevel
instance GHC.Base.Monad m => Imm.Prelude.PairingM (Imm.Logger.CoLoggerF m) Imm.Logger.LoggerF m
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Logger.LogLevel


-- | DSL/interpreter model for a generic key-value database
module Imm.Database

-- | Generic database table
class (Ord (Key t), Show (Key t), Show (Entry t), Typeable t, Show t, Pretty t, Pretty (Key t), Pretty (Entry t)) => Table t where {
    type family Key t :: *;
    type family Entry t :: *;
}

-- | Database DSL
data DatabaseF t next
Describe :: t -> (Doc -> next) -> DatabaseF t next
FetchList :: t -> [Key t] -> (Either SomeException (Map (Key t) (Entry t)) -> next) -> DatabaseF t next
FetchAll :: t -> (Either SomeException (Map (Key t) (Entry t)) -> next) -> DatabaseF t next
Update :: t -> (Key t) -> (Entry t -> Entry t) -> (Either SomeException () -> next) -> DatabaseF t next
InsertList :: t -> [(Key t, Entry t)] -> (Either SomeException () -> next) -> DatabaseF t next
DeleteList :: t -> [Key t] -> (Either SomeException () -> next) -> DatabaseF t next
Purge :: t -> (Either SomeException () -> next) -> DatabaseF t next
Commit :: t -> (Either SomeException () -> next) -> DatabaseF t next

-- | Database interpreter
data CoDatabaseF t m a
CoDatabaseF :: m (Doc, a) -> ([Key t] -> m (Either SomeException (Map (Key t) (Entry t)), a)) -> m (Either SomeException (Map (Key t) (Entry t)), a) -> (Key t -> (Entry t -> Entry t) -> m (Either SomeException (), a)) -> ([(Key t, Entry t)] -> m (Either SomeException (), a)) -> ([Key t] -> m (Either SomeException (), a)) -> m (Either SomeException (), a) -> m (Either SomeException (), a) -> CoDatabaseF t m a
[describeH] :: CoDatabaseF t m a -> m (Doc, a)
[fetchListH] :: CoDatabaseF t m a -> [Key t] -> m (Either SomeException (Map (Key t) (Entry t)), a)
[fetchAllH] :: CoDatabaseF t m a -> m (Either SomeException (Map (Key t) (Entry t)), a)
[updateH] :: CoDatabaseF t m a -> Key t -> (Entry t -> Entry t) -> m (Either SomeException (), a)
[insertListH] :: CoDatabaseF t m a -> [(Key t, Entry t)] -> m (Either SomeException (), a)
[deleteListH] :: CoDatabaseF t m a -> [Key t] -> m (Either SomeException (), a)
[purgeH] :: CoDatabaseF t m a -> m (Either SomeException (), a)
[commitH] :: CoDatabaseF t m a -> m (Either SomeException (), a)
data DatabaseException t
NotCommitted :: t -> DatabaseException t
NotDeleted :: t -> [Key t] -> DatabaseException t
NotFound :: t -> [Key t] -> DatabaseException t
NotInserted :: t -> [(Key t, Entry t)] -> DatabaseException t
NotPurged :: t -> DatabaseException t
NotUpdated :: t -> (Key t) -> DatabaseException t
UnableFetchAll :: t -> DatabaseException t
describeDatabase :: (MonadFree f m, DatabaseF t :<: f) => t -> m Doc
fetch :: (MonadFree f m, DatabaseF t :<: f, Table t, MonadThrow m) => t -> Key t -> m (Entry t)
fetchList :: (MonadFree f m, DatabaseF t :<: f, MonadThrow m) => t -> [Key t] -> m (Map (Key t) (Entry t))
fetchAll :: (MonadThrow m, MonadFree f m, DatabaseF t :<: f) => t -> m (Map (Key t) (Entry t))
update :: (MonadFree f m, DatabaseF t :<: f, MonadThrow m) => t -> Key t -> (Entry t -> Entry t) -> m ()
insert :: (MonadThrow m, MonadFree f m, LoggerF :<: f, DatabaseF t :<: f) => t -> Key t -> Entry t -> m ()
insertList :: (MonadThrow m, MonadFree f m, LoggerF :<: f, DatabaseF t :<: f) => t -> [(Key t, Entry t)] -> m ()
delete :: (MonadThrow m, MonadFree f m, LoggerF :<: f, DatabaseF t :<: f) => t -> Key t -> m ()
deleteList :: (MonadThrow m, MonadFree f m, LoggerF :<: f, DatabaseF t :<: f) => t -> [Key t] -> m ()
purge :: (MonadThrow m, MonadFree f m, DatabaseF t :<: f, LoggerF :<: f) => t -> m ()
commit :: (MonadThrow m, MonadFree f m, DatabaseF t :<: f, LoggerF :<: f) => t -> m ()
instance GHC.Base.Functor m => GHC.Base.Functor (Imm.Database.CoDatabaseF t m)
instance GHC.Base.Functor (Imm.Database.DatabaseF t)
instance (GHC.Classes.Eq t, GHC.Classes.Eq (Imm.Database.Key t), GHC.Classes.Eq (Imm.Database.Entry t)) => GHC.Classes.Eq (Imm.Database.DatabaseException t)
instance (GHC.Show.Show t, GHC.Show.Show (Imm.Database.Key t), GHC.Show.Show (Imm.Database.Entry t)) => GHC.Show.Show (Imm.Database.DatabaseException t)
instance (Imm.Database.Table t, GHC.Show.Show (Imm.Database.Key t), GHC.Show.Show (Imm.Database.Entry t), Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Imm.Database.Key t), Data.Typeable.Internal.Typeable t) => GHC.Exception.Exception (Imm.Database.DatabaseException t)
instance (Text.PrettyPrint.ANSI.Leijen.Internal.Pretty t, Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Imm.Database.Key t)) => Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Imm.Database.DatabaseException t)
instance GHC.Base.Monad m => Imm.Prelude.PairingM (Imm.Database.CoDatabaseF t m) (Imm.Database.DatabaseF t) m


-- | Simple logger interpreter. For further information, please consult
--   <a>System.Log.FastLogger</a>.
module Imm.Logger.Simple
data LoggerSettings
LoggerSettings :: LoggerSet -> LoggerSet -> LogLevel -> Bool -> LoggerSettings

-- | <a>LoggerSet</a> used for <a>Debug</a>, <a>Info</a> and <a>Warning</a>
--   logs
[loggerSet] :: LoggerSettings -> LoggerSet

-- | <a>LoggerSet</a> used for <a>Error</a> logs
[errorLoggerSet] :: LoggerSettings -> LoggerSet

-- | Discard logs that are strictly less serious than this level
[logLevel] :: LoggerSettings -> LogLevel

-- | Enable log colorisation
[colorizeLogs] :: LoggerSettings -> Bool

-- | Default logger forwards error messages to stderr, and other messages
--   to stdout.
defaultLogger :: MonadIO m => m LoggerSettings

-- | Interpreter for <a>LoggerF</a>
mkCoLogger :: (MonadIO m) => LoggerSettings -> CoLoggerF m LoggerSettings


-- | DSL/interpreter model for the HTTP client
module Imm.HTTP

-- | HTTP client DSL
data HttpClientF next
Get :: URI -> (Either SomeException LByteString -> next) -> HttpClientF next

-- | HTTP client interpreter
newtype CoHttpClientF m a
CoHttpClientF :: (URI -> m (Either SomeException LByteString, a)) -> CoHttpClientF m a
[getH] :: CoHttpClientF m a -> URI -> m (Either SomeException LByteString, a)

-- | Perform an HTTP GET request
get :: (MonadFree f m, HttpClientF :<: f, LoggerF :<: f, MonadThrow m) => URI -> m LByteString
instance GHC.Base.Functor m => GHC.Base.Functor (Imm.HTTP.CoHttpClientF m)
instance GHC.Base.Functor Imm.HTTP.HttpClientF
instance GHC.Base.Monad m => Imm.Prelude.PairingM (Imm.HTTP.CoHttpClientF m) Imm.HTTP.HttpClientF m


-- | Simple HTTP client interpreter. For more information, please consult
--   <a>Network.HTTP.Client</a>.
module Imm.HTTP.Simple

-- | Default manager uses TLS and no proxy
defaultManager :: IO Manager

-- | Interpreter for <a>HttpClientF</a>
mkCoHttpClient :: (MonadIO m, MonadCatch m) => Manager -> CoHttpClientF m Manager


-- | Helpers to manipulate feeds
module Imm.Feed

-- | Feed reference: either its URI, or its UID from database
data FeedRef
ByUID :: Int -> FeedRef
ByURI :: URI -> FeedRef
data Feed
Rss :: (RssDocument '[ContentModule, DublinCoreModule]) -> Feed
Atom :: AtomFeed -> Feed
data FeedElement
RssElement :: (RssItem '[ContentModule, DublinCoreModule]) -> FeedElement
AtomElement :: AtomEntry -> FeedElement
getFeedTitle :: Feed -> Text
getElements :: Feed -> [FeedElement]
getDate :: FeedElement -> Maybe UTCTime
getTitle :: FeedElement -> Text
getContent :: FeedElement -> Text
getHashes :: FeedElement -> [Int]
prettyElement :: FeedElement -> Doc
instance GHC.Show.Show Imm.Feed.FeedElement
instance GHC.Classes.Eq Imm.Feed.FeedElement
instance GHC.Show.Show Imm.Feed.Feed
instance GHC.Classes.Eq Imm.Feed.Feed
instance GHC.Show.Show Imm.Feed.FeedRef
instance GHC.Classes.Eq Imm.Feed.FeedRef
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Feed.FeedRef


-- | DSL/interpreter model for hooks, ie various events that can trigger
--   arbitrary actions
module Imm.Hooks

-- | Hooks DSL
data HooksF next
OnNewElement :: Feed -> FeedElement -> next -> HooksF next

-- | Hooks interpreter
data CoHooksF m a
CoHooksF :: (Feed -> FeedElement -> m a) -> CoHooksF m a

-- | Triggered for each unread feed element
[onNewElementH] :: CoHooksF m a -> Feed -> FeedElement -> m a
onNewElement :: (MonadFree f m, LoggerF :<: f, HooksF :<: f) => Feed -> FeedElement -> m ()
instance GHC.Base.Functor m => GHC.Base.Functor (Imm.Hooks.CoHooksF m)
instance GHC.Base.Functor Imm.Hooks.HooksF
instance GHC.Base.Monad m => Imm.Prelude.PairingM (Imm.Hooks.CoHooksF m) Imm.Hooks.HooksF m


-- | Hooks interpreter that writes a file for each element.
module Imm.Hooks.WriteFile

-- | Where and what to write in a file
data FileInfo
FileInfo :: FilePath -> ByteString -> FileInfo
data WriteFileSettings
WriteFileSettings :: (Feed -> FeedElement -> FileInfo) -> WriteFileSettings

-- | Interpreter for <a>HooksF</a>
mkCoHooks :: MonadIO m => WriteFileSettings -> CoHooksF m WriteFileSettings

-- | Wrapper around <a>defaultFilePath</a> and <a>defaultFileContent</a>
defaultSettings :: FilePath -> WriteFileSettings

-- | Generate a path
--   <tt><a>root</a><i><a>title</a></i><a>date</a>-<a>title</a>.html</tt>,
--   where <tt><a>root</a></tt> is the first argument
defaultFilePath :: FilePath -> Feed -> FeedElement -> FilePath

-- | Generate an HTML page, with a title, a header and an article that
--   contains the feed element
defaultFileContent :: Feed -> FeedElement -> ByteString
defaultArticleTitle :: Feed -> FeedElement -> Html
defaultArticleAuthor :: Feed -> FeedElement -> Html
defaultArticleDate :: Feed -> FeedElement -> Html

-- | Generate the HTML content for a given feed element
defaultBody :: Feed -> FeedElement -> Html
convertAtomURI :: (IsString t) => AtomURI -> t
convertURI :: (IsString t) => URIRef a -> t
convertText :: (IsString t) => Text -> t
convertDoc :: (IsString t) => Doc -> t


-- | Hooks interpreter that sends a mail via a SMTP server for each
--   element. You may want to consult <a>Network.HaskellNet.SMTP</a>,
--   <a>Network.HaskellNet.SMTP.SSL</a> and <a>Network.Mail.Mime</a>
--   modules for additional information.
--   
--   Here is an example configuration:
--   
--   <pre>
--   sendmail :: SendMailSettings
--   sendmail = SendMailSettings smtpServer formatMail
--   
--   formatMail :: FormatMail
--   formatMail = FormatMail
--     (\a b -&gt; (defaultFormatFrom a b) { addressEmail = "user@host" } )
--     defaultFormatSubject
--     defaultFormatBody
--     (\_ _ -&gt; [Address Nothing "user@host"])
--   
--   smtpServer :: Feed -&gt; FeedElement -&gt; SMTPServer
--   smtpServer _ _ = SMTPServer
--     (Just $ Authentication PLAIN "user" "password")
--     (StartTls "smtp.server" defaultSettingsSMTPSTARTTLS)
--   </pre>
module Imm.Hooks.SendMail
type Username = String
type Password = String
type ServerName = String

-- | How to connect to the SMTP server
data ConnectionSettings
Plain :: ServerName -> PortNumber -> ConnectionSettings
Ssl :: ServerName -> Settings -> ConnectionSettings
StartTls :: ServerName -> Settings -> ConnectionSettings

-- | How to authenticate to the SMTP server
data Authentication
Authentication :: AuthType -> Username -> Password -> Authentication
data SMTPServer
SMTPServer :: (Maybe Authentication) -> ConnectionSettings -> SMTPServer

-- | How to format outgoing mails from feed elements
data FormatMail
FormatMail :: (Feed -> FeedElement -> Address) -> (Feed -> FeedElement -> Text) -> (Feed -> FeedElement -> Text) -> (Feed -> FeedElement -> [Address]) -> FormatMail

-- | How to write the From: header of feed mails
[formatFrom] :: FormatMail -> Feed -> FeedElement -> Address

-- | How to write the Subject: header of feed mails
[formatSubject] :: FormatMail -> Feed -> FeedElement -> Text

-- | How to write the body of feed mails (sic!)
[formatBody] :: FormatMail -> Feed -> FeedElement -> Text

-- | How to write the To: header of feed mails
[formatTo] :: FormatMail -> Feed -> FeedElement -> [Address]
data SendMailSettings
SendMailSettings :: (Feed -> FeedElement -> SMTPServer) -> FormatMail -> SendMailSettings

-- | Interpreter for <a>HooksF</a>
mkCoHooks :: (MonadIO m) => SendMailSettings -> CoHooksF m SendMailSettings

-- | Fill <a>addressName</a> with the feed title and, if available, the
--   authors' names.
--   
--   This function leaves <a>addressEmail</a> empty. You are expected to
--   fill it adequately, because many SMTP servers enforce constraints on
--   the From: email.
defaultFormatFrom :: Feed -> FeedElement -> Address

-- | Fill mail subject with the element title
defaultFormatSubject :: Feed -> FeedElement -> Text

-- | Fill mail body with:
--   
--   <ul>
--   <li>a list of links associated to the element</li>
--   <li>the element's content or description/summary</li>
--   </ul>
defaultFormatBody :: Feed -> FeedElement -> Text
authenticate_ :: SMTPConnection -> Authentication -> IO Bool
withSMTPConnection :: SMTPServer -> (SMTPConnection -> IO a) -> IO a

-- | Build mail from a given feed
buildMail :: FormatMail -> UTCTime -> TimeZone -> Feed -> FeedElement -> Mail
instance GHC.Show.Show Imm.Hooks.SendMail.SMTPServer
instance GHC.Classes.Eq Imm.Hooks.SendMail.SMTPServer
instance GHC.Show.Show Imm.Hooks.SendMail.Authentication
instance GHC.Classes.Eq Imm.Hooks.SendMail.Authentication
instance GHC.Show.Show Imm.Hooks.SendMail.ConnectionSettings
instance GHC.Classes.Eq Imm.Hooks.SendMail.ConnectionSettings


-- | Feed table definitions. This is a specialization of
--   <a>Imm.Database</a>.
module Imm.Database.FeedTable

-- | Unique key in feeds table
newtype FeedID
FeedID :: URI -> FeedID
data DatabaseEntry
DatabaseEntry :: URI -> Text -> Set Int -> Maybe UTCTime -> DatabaseEntry
[entryURI] :: DatabaseEntry -> URI
[entryCategory] :: DatabaseEntry -> Text
[entryReadHashes] :: DatabaseEntry -> Set Int
[entryLastCheck] :: DatabaseEntry -> Maybe UTCTime
newDatabaseEntry :: FeedID -> Text -> DatabaseEntry

-- | Singleton type to represent feeds table
data FeedTable
FeedTable :: FeedTable
data FeedStatus
Unknown :: FeedStatus
New :: FeedStatus
LastUpdate :: UTCTime -> FeedStatus
data Database
Database :: [DatabaseEntry] -> Database
type DatabaseF' = DatabaseF FeedTable
type CoDatabaseF' = CoDatabaseF FeedTable
register :: (MonadThrow m, LoggerF :<: f, DatabaseF' :<: f, MonadFree f m) => FeedID -> Text -> m ()
getStatus :: (DatabaseF' :<: f, MonadFree f m, MonadCatch m) => FeedID -> m FeedStatus
addReadHash :: (DatabaseF' :<: f, MonadFree f m, MonadThrow m, LoggerF :<: f) => FeedID -> Int -> m ()

-- | Set the last check time to now
markAsRead :: (MonadIO m, DatabaseF' :<: f, MonadFree f m, MonadThrow m, LoggerF :<: f) => FeedID -> m ()

-- | Unset feed's last update and remove all read hashes
markAsUnread :: (DatabaseF' :<: f, MonadFree f m, MonadThrow m, LoggerF :<: f) => FeedID -> m ()
instance GHC.Show.Show Imm.Database.FeedTable.Database
instance GHC.Classes.Eq Imm.Database.FeedTable.Database
instance GHC.Show.Show Imm.Database.FeedTable.FeedTable
instance GHC.Show.Show Imm.Database.FeedTable.DatabaseEntry
instance GHC.Classes.Eq Imm.Database.FeedTable.DatabaseEntry
instance GHC.Show.Show Imm.Database.FeedTable.FeedID
instance GHC.Classes.Ord Imm.Database.FeedTable.FeedID
instance GHC.Classes.Eq Imm.Database.FeedTable.FeedID
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Database.FeedTable.FeedStatus
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Database.FeedTable.FeedTable
instance Imm.Database.Table Imm.Database.FeedTable.FeedTable
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Database.FeedTable.DatabaseEntry
instance Data.Aeson.Types.FromJSON.FromJSON Imm.Database.FeedTable.DatabaseEntry
instance Data.Aeson.Types.ToJSON.ToJSON Imm.Database.FeedTable.DatabaseEntry
instance Data.Aeson.Types.FromJSON.FromJSON Imm.Database.FeedTable.FeedID
instance Data.Aeson.Types.ToJSON.ToJSON Imm.Database.FeedTable.FeedID
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Imm.Database.FeedTable.FeedID


-- | Database interpreter based on a JSON file
module Imm.Database.JsonFile
data CacheStatus
Empty :: CacheStatus
Clean :: CacheStatus
Dirty :: CacheStatus
data JsonFileDatabase t
JsonFileDatabase :: FilePath -> (Map (Key t) (Entry t)) -> CacheStatus -> JsonFileDatabase t
mkJsonFileDatabase :: (Table t) => FilePath -> JsonFileDatabase t

-- | Default database is stored in <tt>$XDG_CONFIG_HOME/imm/feeds.json</tt>
defaultDatabase :: Table t => IO (JsonFileDatabase t)
data JsonException
UnableDecode :: JsonException

-- | Interpreter for <a>DatabaseF</a>
mkCoDatabase :: (Table t, FromJSON (Key t), FromJSON (Entry t), ToJSON (Key t), ToJSON (Entry t), MonadIO m, MonadCatch m) => JsonFileDatabase t -> CoDatabaseF t m (JsonFileDatabase t)
loadInCache :: (Table t, MonadIO m, MonadCatch m, FromJSON (Key t), FromJSON (Entry t)) => JsonFileDatabase t -> m (JsonFileDatabase t)
insert :: (Table t, MonadIO m, MonadCatch m, FromJSON (Key t), FromJSON (Entry t)) => JsonFileDatabase t -> [(Key t, Entry t)] -> m (JsonFileDatabase t)
insertInCache :: Table t => [(Key t, Entry t)] -> JsonFileDatabase t -> JsonFileDatabase t
update :: (Table t, MonadIO m, MonadCatch m, FromJSON (Key t), FromJSON (Entry t)) => JsonFileDatabase t -> Key t -> (Entry t -> Entry t) -> m (JsonFileDatabase t)
updateInCache :: Table t => Key t -> (Entry t -> Entry t) -> JsonFileDatabase t -> JsonFileDatabase t
delete :: (Table t, MonadIO m, MonadCatch m, FromJSON (Key t), FromJSON (Entry t)) => JsonFileDatabase t -> [Key t] -> m (JsonFileDatabase t)
deleteInCache :: Table t => [Key t] -> JsonFileDatabase t -> JsonFileDatabase t
purge :: (Table t, MonadIO m, MonadCatch m, FromJSON (Key t), FromJSON (Entry t)) => JsonFileDatabase t -> m (JsonFileDatabase t)
purgeInCache :: Table t => JsonFileDatabase t -> JsonFileDatabase t
commit :: (MonadIO m, ToJSON (Key t), ToJSON (Entry t)) => JsonFileDatabase t -> m (JsonFileDatabase t)
instance GHC.Show.Show Imm.Database.JsonFile.JsonException
instance GHC.Classes.Eq Imm.Database.JsonFile.JsonException
instance GHC.Show.Show Imm.Database.JsonFile.CacheStatus
instance GHC.Classes.Eq Imm.Database.JsonFile.CacheStatus
instance GHC.Exception.Exception Imm.Database.JsonFile.JsonException
instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Imm.Database.JsonFile.JsonFileDatabase t)


-- | DSL/interpreter model for parsing XML into a <a>Feed</a>
module Imm.XML

-- | XML parsing DSL
data XmlParserF next
ParseXml :: URI -> LByteString -> (Either SomeException Feed -> next) -> XmlParserF next

-- | XML parsing interpreter
newtype CoXmlParserF m a
CoXmlParserF :: (URI -> LByteString -> m (Either SomeException Feed, a)) -> CoXmlParserF m a
[parseXmlH] :: CoXmlParserF m a -> URI -> LByteString -> m (Either SomeException Feed, a)

-- | Parse XML into a <a>Feed</a>
parseXml :: (MonadFree f m, XmlParserF :<: f, MonadThrow m) => URI -> LByteString -> m Feed
instance GHC.Base.Functor m => GHC.Base.Functor (Imm.XML.CoXmlParserF m)
instance GHC.Base.Functor Imm.XML.XmlParserF
instance GHC.Base.Monad m => Imm.Prelude.PairingM (Imm.XML.CoXmlParserF m) Imm.XML.XmlParserF m


-- | Simple interpreter to parse XML into <a>Feed</a>, based on
--   <a>Conduit</a>.
module Imm.XML.Simple

-- | A <a>Conduit</a> to alter the raw XML before feeding it to the parser,
--   depending on the feed <a>URI</a>
type PreProcess m = URI -> Conduit Event m Event

-- | Interpreter for <a>XmlParserF</a>
mkCoXmlParser :: (MonadIO m, MonadCatch m) => PreProcess m -> CoXmlParserF m (PreProcess m)

-- | Default pre-process always forwards all <a>Event</a>s
defaultPreProcess :: Monad m => PreProcess m

module Imm.Core

-- | Feed reference: either its URI, or its UID from database
data FeedRef
printVersions :: (MonadIO m) => m ()

-- | Register the given feed URI in database
subscribe :: (LoggerF :<: f, MonadFree f m, DatabaseF' :<: f, MonadCatch m) => URI -> Maybe Text -> m ()

-- | Print database status for given feed(s)
showFeed :: (MonadIO m, LoggerF :<: f, MonadThrow m, MonadFree f m, DatabaseF' :<: f) => [FeedID] -> m ()

-- | Check for unread elements without processing them
check :: (MonadIO m, MonadCatch m, LoggerF :<: f, MonadFree f m, DatabaseF' :<: f, HttpClientF :<: f, XmlParserF :<: f) => [FeedID] -> m ()
run :: (MonadIO m, MonadCatch m, HooksF :<: f, LoggerF :<: f, MonadFree f m, DatabaseF' :<: f, HttpClientF :<: f, XmlParserF :<: f) => [FeedID] -> m ()

-- | <a>subscribe</a> to all feeds described by the OPML document provided
--   in input (stdin)
importOPML :: (MonadIO m, LoggerF :<: f, MonadFree f m, DatabaseF' :<: f, MonadCatch m) => m ()


-- | <h1>Getting started</h1>
--   
--   <h2>Dynamic reconfiguration</h2>
--   
--   This program is dynamically configured using the <a>dyre</a> library.
--   
--   You may want to check out <a>this documentation</a> to know how to get
--   started.
--   
--   Your personal configuration is located at
--   <tt>$XDG_CONFIG_HOME/imm/imm.hs</tt>.
--   
--   <h2>Interpreter pattern</h2>
--   
--   The behavior of this program can be customized through the interpreter
--   pattern, implemented using free monads (for the DSL part) and cofree
--   comonads (for the interpreter part).
--   
--   The design is inspired from <a>Cofun with cofree monads</a>.
module Imm.Boot

-- | Main function, meant to be used in your personal configuration file.
--   Each argument is an interpreter functor along with an initial state.
--   
--   Here is an example:
--   
--   <pre>
--   import           Imm.Boot
--   import           Imm.Database.JsonFile
--   import           Imm.Feed
--   import           Imm.Hooks.SendMail
--   import           Imm.HTTP.Simple
--   import           Imm.Logger.Simple
--   import           Imm.XML.Simple
--   
--   main :: IO ()
--   main = do
--     logger   &lt;- defaultLogger
--     manager  &lt;- defaultManager
--     database &lt;- defaultDatabase
--   
--     imm (mkCoHttpClient, manager) (mkCoDatabase, database) (mkCoLogger, logger) (mkCoHooks, sendmail) (mkCoXmlParser, defaultPreProcess)
--   
--   sendmail :: SendMailSettings
--   sendmail = SendMailSettings smtpServer formatMail
--   
--   formatMail :: FormatMail
--   formatMail = FormatMail
--     (\a b -&gt; (defaultFormatFrom a b) { addressEmail = "user@host" } )
--     defaultFormatSubject
--     defaultFormatBody
--     (\_ _ -&gt; [Address Nothing "user@host"])
--   
--   smtpServer :: Feed -&gt; FeedElement -&gt; SMTPServer
--   smtpServer _ _ = SMTPServer
--     (Just $ Authentication PLAIN "user" "password")
--     (StartTls "smtp.host" defaultSettingsSMTPSTARTTLS)
--   </pre>
imm :: (a -> CoHttpClientF IO a, a) -> (b -> CoDatabaseF' IO b, b) -> (c -> CoLoggerF IO c, c) -> (d -> CoHooksF IO d, d) -> (e -> CoXmlParserF IO e, e) -> IO ()
instance GHC.Show.Show Imm.Boot.InterruptedException
instance GHC.Read.Read Imm.Boot.InterruptedException
instance GHC.Classes.Eq Imm.Boot.InterruptedException
instance GHC.Show.Show Imm.Boot.SafeGuard
instance GHC.Read.Read Imm.Boot.SafeGuard
instance GHC.Classes.Eq Imm.Boot.SafeGuard
instance GHC.Exception.Exception Imm.Boot.InterruptedException


-- | Meta-module that reexports many Imm sub-modules.
--   
--   To get started, please consult <a>Imm.Boot</a>.
module Imm
