{- Copyright 2013,2014 Marcelo Millani This file is part of boomange. boomange is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. boomange is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with boomange. If not, see -} import Control.Exception import Control.Monad import System.IO import System.Directory import System.Environment import System.FilePath import Data.List import Paths_boomange -- automatically generated import Data.DescriLo import Data.Builder import Data.Entities hiding (name) import Data.Loader appName = "boomange" -- header to be used on the sample config file configHeader = "# This is the configuration file for " ++ appName ++ "\n" ++ "# For a full description of its syntax, see the haddock documentation of DescriLo\n" ++ "# In the config description:\n" ++ "# output - where should the resulting html file be placed\n" ++ "# header - file to be prepended to output\n" ++ "# footer - file to be appended to output\n" ++ "# there are no other values for config\n\n" ++ "# In the watch description, there may be an unlimited amount of values and the left part is always ignored by the program and may be used for organization.\n" ++ "# The right part indicates which file will be read to create the output. It will behave as if all of the files were concatenated.\n\n" -- header to be used on the sample bookmarks file bookmarksHeader = "# This is a sample bookmarks file for " ++ appName ++ "\n" ++ "# For a full description of its syntax, see the haddock documentation of DescriLo\n" ++ "# Every description has at least two values:\n" ++ "# type - may be either 'folder' or 'url'\n" ++ "# father - creates an hierarchy. May be the name of any folder description or 'root'\n" ++ "# Additionally, descriptions where type=url have the following value:\n" ++ "# url - where it links to\n" ++ "# there are no other possible values\n\n" generateBookmarks config = do header <- readFile $ headerFile config footer <- readFile $ footerFile config final <- openFile (outputFile config) WriteMode bookmarks <- loadBookmarks $ watch config let body = htmlBookmarks bookmarks hPutStr final header hPutStr final body hPutStr final footer hClose final -- | gets the directory where configuration files should be placed -- -- First, checks if XDG_CONFIG_HOME exists, producing $XDG_CONFIG_HOME/appName if it does -- if it does not, the checks if HOME does, producing $HOME/.config/appName if it does -- if it still fails, returns getAppUserDataDirectory appName getConfigDirectory appName = let failXDG e = do dir <- getEnv "HOME" return $ dir ++ [pathSeparator] ++ ".config" ++ [pathSeparator] ++ appName in let failHOME e = getAppUserDataDirectory appName in do handle (failHOME::SomeException -> IO FilePath) $ handle (failXDG::SomeException -> IO FilePath) $ do dir <- getEnv "XDG_CONFIG_HOME" return $ dir ++ [pathSeparator] ++ appName -- | installs a basic configuration installConfig cDir = let htmlDir = cDir ++ [pathSeparator] ++ "html" in let bookFile = cDir ++ [pathSeparator] ++ "bookmarks" in let outFile = cDir ++ [pathSeparator] ++ "bookmarks.html" in let config = Description { name = "config" , values = [ ("output",outFile) ,("header",htmlDir ++ [pathSeparator] ++ "header.html") ,("footer", htmlDir ++ [pathSeparator] ++ "footer.html") ] } in let watch = Description { name = "watch" , values = [ ("default",bookFile) ] } in let sampleFolder = Description { name = "Sample Folder" , values = [ ("type","folder") ,("father","root") ] } in let sampleUrl = Description { name = "Sample Url" , values = [ ("type","url") ,("father","Sample Folder") ,("url","file://" ++ outFile) ] } in let cFile = cDir ++ [pathSeparator] ++ "config" in do -- creates the base config file hcFile <- openFile cFile WriteMode hPutStr hcFile configHeader hPutStr hcFile $ show config -- hPutStr hcFile $ "\n\n" hPutStr hcFile $ show watch hClose hcFile -- copies the default html files headerFile <- getDataFileName "html/header.html" footerFile <- getDataFileName "html/footer.html" cssFile <- getDataFileName "style.css" -- creates the html folder createDirectoryIfMissing True htmlDir -- copies html files copyFile headerFile $ htmlDir ++ [pathSeparator] ++ "header.html" copyFile footerFile $ htmlDir ++ [pathSeparator] ++ "footer.html" -- copies css file copyFile cssFile $ cDir ++ [pathSeparator] ++ "style.css" -- creates a sample bookmarks file hBookmarks <- openFile bookFile WriteMode hPutStr hBookmarks bookmarksHeader hPutStr hBookmarks $ show sampleFolder hPutStr hBookmarks $ show sampleUrl hClose hBookmarks main = do cDir <- getConfigDirectory appName -- if the configuration directory does not exists, sets it up confExists <- doesDirectoryExist cDir when (not confExists) $ do createDirectoryIfMissing True cDir installConfig cDir let cFile = cDir ++ "/config" config <- loadConfig cFile generateBookmarks config