packages feed

boomange-0.1.0.1: 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 for SimtreeLo\n" ++
  "# The first line indicates the comment pattern" ++
  "# Leaves represent the URI of their direct parents"	

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  
      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"
      bookFile = cDir ++ [pathSeparator] ++ "bookmarks"      
      outFile = cDir ++ [pathSeparator] ++ "bookmarks.html"
      config =
        Description
        {
          name = "config"
	, values = [
            ("output",outFile)
          , ("header",htmlDir ++ [pathSeparator] ++ "header.html")
          , ("footer", htmlDir ++ [pathSeparator] ++ "footer.html")
          ]
	}
	
      watch =
        Description
                   {
                     name = "watch"
                   , values = [
                     ("default",bookFile)
                     ]
                   }	
      sampleBookmarks =
        "Boomange\n\tDocumentation\n" ++
        "\t\tDescriLo\n\t\t\thttp://hackage.haskell.org/package/descrilo-0.1.0.0/docs/Data-DescriLo.html\n" ++
        "\t\tSimtreeLo\n\t\t\thttp://hackage.haskell.org/package/simtreelo-0.1.0.0/docs/Data-Simtreelo.html\n"
        
      cFile = cDir ++ [pathSeparator] ++ "config"
  in
   do
     -- creates the base config file
     hcFile <- openFile cFile WriteMode
     hPutStr hcFile configHeader
     hPutStr hcFile $ show config
     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 $ sampleBookmarks
     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