{-# LANGUAGE TemplateHaskell, DeriveGeneric #-} {-# OPTIONS_HADDOCK not-home #-} module Network.ScrapeChanges.Domain where import Control.Lens import Data.Validation import Data.List.NonEmpty import Data.Hashable (Hashable, hashWithSalt) import Data.ByteString.Lazy (ByteString) import qualified Data.Text.Lazy as TextLazy import GHC.Generics (Generic) -- |String encoded in the standard cron format type CronScheduleString = String -- |Url to scrape type Url = String -- |Body of the HTTP request type HttpBody = ByteString -- |Function extracting 'Text' of 'HttpBody' type Scraper = HttpBody -> Text -- |Codomain of 'Scraper' type Text = TextLazy.Text -- |Mail address for provided 'MailConfig' data MailAddr = MailAddr { -- |Optional name for the given '_mailAddr' _mailAddrName :: Maybe Text -- |Mail address , _mailAddr :: String } deriving (Show, Eq, Generic) makeLenses ''MailAddr instance Hashable MailAddr data Mail = Mail { _mailFrom :: MailAddr , _mailTo :: NonEmpty MailAddr , _mailSubject :: Text , _mailBody :: Text } deriving (Show, Eq, Generic) makeLenses ''Mail instance Hashable Mail data CallbackConfig -- |Send a mail when there's changed data at your scrape target. -- This needs sendmail to be configured correctly on the host your -- program runs. = MailConfig Mail -- |Just execute the provided function when there's changed data at -- your scrape target. | OtherConfig (Text -> IO ()) makePrisms ''CallbackConfig instance Eq CallbackConfig where (MailConfig _) == (OtherConfig _) = False (OtherConfig _) == (MailConfig _) = False (OtherConfig _) == (OtherConfig _) = False (MailConfig m1) == (MailConfig m2) = m1 == m2 data ScrapeConfig = ScrapeConfig { -- |The url to be called using GET _scrapeInfoUrl :: String -- |The callback config to be executed when something in '_scrapeInfoUrl' -- has changed , _scrapeInfoCallbackConfig :: CallbackConfig } deriving (Eq) makeLenses ''ScrapeConfig instance Hashable ScrapeConfig where hashWithSalt i c = let scrapeInfoUrlHash = hashWithSalt i (c ^. scrapeInfoUrl) mailConfigHash = hashWithSalt i (c ^? scrapeInfoCallbackConfig . _MailConfig) in scrapeInfoUrlHash + mailConfigHash data ScrapeResult = -- |Signals that the last execution of the provided 'ScrapeConfig' led to execution of 'CallbackConfig' CallbackCalled -- |Signals that the last execution of the provided 'ScrapeConfig' didn't lead to execution of 'CallbackConfig' | CallbackNotCalled deriving Show data ScrapeSchedule = ScrapeSchedule { _scrapeScheduleCron :: CronScheduleString , _scrapeScheduleConfig :: ScrapeConfig , _scrapeScheduleScraper :: Scraper } makeLenses ''ScrapeSchedule data ValidationError = UrlNotAbsolute | UrlProtocolInvalid | MailConfigInvalidMailFromAddr String | MailConfigInvalidMailToAddr String | CronScheduleInvalid String deriving (Show, Eq) type ScrapeValidation t = AccValidation [ValidationError] t