{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE PatternSynonyms, ViewPatterns #-} module Input(fetchDocument, readStrict) where import Data.Text.Lazy (fromStrict) import qualified Data.Text as Txt import qualified Data.Text.IO as Txt import Data.Text.Encoding import qualified Data.Text.Lazy as LTxt import qualified Data.ByteString.Lazy as B import qualified Text.XML as XML import Network.URI import Network.URI.Fetch import Network.URI.Fetch.XML (fetchDocument) import Network.URI.Charset import qualified Data.Map as M import qualified Data.Set as Set import Data.List (intercalate) import Data.Time.Clock -- For alternative styles import qualified Data.CSS.Syntax.Tokens as CSSTok import Data.CSS.Syntax.StyleSheet import Data.CSS.Preprocessor.Conditions (conditionalStyles) import System.IO import System.IO.Temp import System.Directory import System.FilePath (()) import Data.FileEmbed -- For C API import Types import Data.Maybe (fromMaybe) import Foreign.StablePtr import Foreign.C.String -------- ---- C API -------- foreign export ccall c_newSession :: IO (StablePtr Session) foreign export ccall c_freeSession :: StablePtr Session -> IO () c_newSession = do sess <- newSession newStablePtr $ sess {aboutPages = map lazify $(embedDir $ buildDirFile "about")} where lazify (a, b) = (a, B.fromStrict b) c_freeSession = freeStablePtr foreign export ccall c_fetchURL :: StablePtr Session -> CString -> StablePtr (Page RhapsodeCSS) -> CString -> IO (StablePtr (Page RhapsodeCSS)) c_fetchURL c_session c_mimes c_referer c_uri = do session <- deRefStablePtr c_session mimes <- peekCString c_mimes referer <- deRefStablePtr c_referer uri <- peekCString c_uri let uri' = nullURI `fromMaybe` parseURIReference uri `relativeTo` pageURL referer doc <- fetchDocument session referer uri' newStablePtr doc foreign export ccall c_enableLogging :: StablePtr Session -> IO (StablePtr Session) c_enableLogging c_session = do ret <- deRefStablePtr c_session >>= enableLogging freeStablePtr c_session newStablePtr ret foreign export ccall c_writeLog :: CString -> StablePtr Session -> IO () c_writeLog c_path c_session = do path <- peekCString c_path withFile path AppendMode (\logfile -> deRefStablePtr c_session >>= writeLog logfile) foreign export ccall c_lastVisited :: CString -> IO CString c_lastVisited def = do path <- ( "history.gmni") <$> getXdgDirectory XdgData "rhapsode" exists <- doesFileExist path if not exists then return def else do file <- readFile path case map words $ lines file of (_:url:_):_ -> newCString url _ -> return def