module Main where
import InputParser
import ElementBlocker
import UrlBlocker
import Text.ParserCombinators.Parsec hiding (Line, many, optional)
import Task
import SourceInfo as Source
import ProgramOptions as Options
import System.Environment
import Templates
import Control.Monad
import Data.Time.Clock
import Network.HTTP.Conduit
import Network.URI
import System.Directory
import System.IO
import Network
import GHC.IO.Encoding
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
manager <- newManager tlsManagerSettings
(parsed, sourceInfo) <- mapAndUnzipM (parseSource manager) sources
let parsed' = concat parsed
sourceInfoText = showInfo sourceInfo
optionsText = logOptions options
createDirectoryIfMissing True $ _privoxyDir 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 (_debugLevel options) parsed'
urlBlock (_privoxyDir options) sourceInfoText parsed'
writeTemplateFiles (_privoxyDir options) (_cssDomain options) (_useHTTP options)
putStrLn $ "Run 'adblock2privoxy -t " ++ taskFile ++ "' every 1-2 days to process data updates."
where
parseSource manager sourceInfo = do
let
url = _url sourceInfo
loader = if isURI url then downloadHttp manager 5 else getFileContent
putStrLn $ "process " ++ url
text <- loader url
now <- getCurrentTime
let strictParse = text `seq` parse adblockFile url text
case strictParse of
Right parsed ->
let sourceInfo' = updateInfo now parsed sourceInfo
url' = _url sourceInfo'
in if url == url'
then return (parsed, sourceInfo')
else parseSource manager sourceInfo'
Left msg -> return ([], sourceInfo) <$ putStrLn $ show msg
main::IO()
main = do
setLocaleEncoding utf8
setFileSystemEncoding utf8
setForeignEncoding utf8
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 || any (infoExpired now) sources
then processSources options' taskFile sources
else putStrLn "all sources are up to date"
debug = _debugLevel options
when (debug > DebugLevel 0) $
putStrLn $ concat ["Debug level '", show debug, "'."]
action
now' <- getCurrentTime
putStrLn $ concat ["Execution done in ", show $ diffUTCTime now' now, " seconds."]