{-# LANGUAGE FlexibleContexts #-}
module Network.URI.PlugIns.Rewriters(parseRewriter, parseRewriters, Rewriter, applyRewriter) where
import Text.RE.Tools.Edit
import Text.RE.TDFA.String
import Network.URI (URI, uriToString, parseAbsoluteURI)
import Data.Maybe (catMaybes, fromMaybe)
import System.Directory as Dir
import System.FilePath ((</>))
import Control.Concurrent.Async (forConcurrently)
type Rewriter = Edits Maybe RE String
parseRewriter :: FilePath -> IO Rewriter
parseRewriter filepath = do
source <- readFile filepath
let parseLine line | [pattern, template] <- words line = compileSearchReplace pattern template
| [pattern] <- words line = compileSearchReplace pattern "about:blank"
| otherwise = Nothing
let edits = catMaybes $ map parseLine $ lines source
return $ Select $ map Template edits
parseRewriters :: String -> IO Rewriter
parseRewriters app = do
dir <- Dir.getXdgDirectory Dir.XdgConfig "nz.geek.adrian.hurl"
exists <- Dir.doesDirectoryExist dir
if exists then do
rewriters <- loadRewriters dir
let inner = dir </> app
innerExists <- Dir.doesDirectoryExist dir
if innerExists then do
appRewriters <- loadRewriters inner
return $ Select (appRewriters ++ rewriters)
else return $ Select rewriters
else return $ Select []
where
loadRewriters dir = do
files <- Dir.listDirectory dir
raw <- forConcurrently files $ \file -> do
exists <- doesFileExist file
if exists then do
rewriter <- parseRewriter file
return $ case rewriter of
Select x -> x
Pipe x -> x
else return []
return $ concat raw
applyRewriter :: Rewriter -> URI -> Maybe URI
applyRewriter rewriter uri = parseAbsoluteURI =<<
applyEdits firstLine rewriter (uriToString id uri "")