~alcinnz/hurl

ref: 0836606622d85d93c5aa9177efbe01b09eba4f4f hurl/src/Network/URI/PlugIns/Rewriters.hs -rw-r--r-- 1.9 KiB
08366066 — Adrian Cochrane Switch cryptography library & implement HSTS. 2 years ago
                                                                                
4371e0f3 Adrian Cochrane
9794e7d5 Adrian Cochrane
4371e0f3 Adrian Cochrane
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{-# 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 "")