packages feed

boomange-0.1.0.0: Main.hs

{-
	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 <http://www.gnu.org/licenses/>
-}

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