module Main where import InputParser import ElementBlocker import UrlBlocker import Text.ParserCombinators.Parsec hiding (Line, many, optional) import Task import Control.Applicative hiding (many) import SourceInfo as Source import ProgramOptions as Options import System.Environment import Templates import Data.Time.Clock import Network.HTTP.Conduit import Network.URI import Data.Text.Lazy.Encoding import Data.Text.Lazy (unpack) import Network.Socket import System.Directory import System.IO getResponse :: String -> IO String getResponse url = do putStrLn $ "load " ++ url ++ "..." withSocketsDo $ unpack . decodeUtf8 <$> simpleHttp url getFileContent :: String -> IO String getFileContent url = do handle <- openFile url ReadMode hSetEncoding handle utf8 hGetContents handle processSources :: Options -> String -> [SourceInfo]-> IO () processSources options taskFile sources = do (parsed, sourceInfo) <- unzip <$> mapM parseSource sources let parsed' = concat parsed sourceInfoText = showInfo sourceInfo optionsText = logOptions options writeTask taskFile (sourceInfoText ++ optionsText) parsed' if null._cssDomain $ options then putStrLn "WARNING: CSS generation is not run because webserver domain is not specified" else elemBlock (_webDir options) sourceInfoText parsed' urlBlock (_privoxyDir options) sourceInfoText parsed' writeTemplateFiles (_privoxyDir options) (_cssDomain options) putStrLn $ "Run 'adblock2privoxy -t " ++ taskFile ++ "' every 1-2 days to process data updates." where parseSource sourceInfo = do let url = _url sourceInfo loader = if isURI url then getResponse else getFileContent putStrLn $ "process " ++ url text <- loader url now <- getCurrentTime case parse adblockFile url text of Right parsed -> let sourceInfo' = updateInfo now parsed sourceInfo url' = _url sourceInfo' in if url == url' then return (parsed, sourceInfo') else parseSource sourceInfo' Left msg -> return ([], sourceInfo) <$ putStrLn $ show msg main::IO() main = do now <- getCurrentTime args <- getArgs (options@(Options printVersion _ _ taskFile _ forced), urls) <- parseOptions args (options', task) <- do fileExists <- doesFileExist taskFile if fileExists then do task <- readTask taskFile return (fillFromLog options task, Just task) else return (options, Nothing) let action | printVersion = putStrLn versionText | not . null $ urls = processSources options' taskFile (makeInfo <$> urls) | otherwise = case task of Nothing -> writeError "no input specified" (Just task') -> do let sources = Source.readLogInfos task' if forced || or (infoExpired now <$> sources) then processSources options' taskFile sources else putStrLn "all sources are up to date" action now' <- getCurrentTime putStrLn $ concat ["Execution done in ", show $ diffUTCTime now' now, " seconds."]