packages feed

archiver-0.1: archiver.hs

import Control.Concurrent (threadDelay)
import Control.Monad (forever, when)
import qualified Data.ByteString.Char8 as B (break, drop, length, readFile, unpack, writeFile)
import Data.Maybe (fromMaybe)
import System.Environment (getArgs)

import System.INotify (addWatch, initINotify, EventVariety(AllEvents))

import Network.URL.Archiver (checkArchive)

main :: IO ()
main = do args <- getArgs
          case args of
           (f:[]) ->   watch Nothing f
           (f:e:[]) -> watch (Just e) f
           _ -> error "must supply a filename or a filename and an email address"

watch :: Maybe String -> FilePath -> IO ()
watch user file = do i <- initINotify
                     archivePage user file -- empty out existing file, then we add a watch & sleep
                     _ <- addWatch i [AllEvents] file (\_ -> archivePage user file)
                     forever $ threadDelay maxBound -- sleep... forever

archivePage :: Maybe String -> FilePath -> IO ()
archivePage user file = do contents <- B.readFile file
                           let (url,rest) = B.break (=='\n') contents
                           checkArchive email (B.unpack url)
                           print url
                           -- banned >=100 requests/hour; choke to ~1/minute
                           threadDelay 40000000 -- ~40 seconds
                           when (B.length rest /= 0) (B.writeFile file (B.drop 1 rest) >> archivePage user file) -- drop to get rid of leading \n
                           return ()
                           where
                               email = fromMaybe "nobody@mailinator.com" user