140 lines
3.6 KiB
Haskell
140 lines
3.6 KiB
Haskell
{--
|
|
HSFM, a filemanager written in Haskell.
|
|
Copyright (C) 2016 Julian Ospald
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
version 2 as published by the Free Software Foundation.
|
|
|
|
This program 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 this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
--}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# OPTIONS_HADDOCK ignore-exports #-}
|
|
|
|
module HSFM.Settings.Bookmarks where
|
|
|
|
|
|
import Control.Monad
|
|
(
|
|
void
|
|
)
|
|
import Data.Attoparsec.ByteString
|
|
import qualified Data.ByteString as BS
|
|
import Data.ByteString
|
|
(
|
|
ByteString
|
|
)
|
|
import Data.Maybe
|
|
(
|
|
catMaybes
|
|
, fromJust
|
|
)
|
|
import Data.Word8
|
|
(
|
|
_nul
|
|
)
|
|
import qualified HPath as P
|
|
import HPath
|
|
(
|
|
Abs
|
|
, Fn
|
|
, Path
|
|
)
|
|
import HSFM.FileSystem.FileOperations
|
|
import HSFM.FileSystem.FileType
|
|
import Prelude hiding (readFile, writeFile)
|
|
import System.Posix.Env.ByteString
|
|
(
|
|
getEnv
|
|
)
|
|
|
|
|
|
|
|
-- |A bookmark. `bkName` is principally a description of the bookmark
|
|
-- but must satisfy the constraints of a filename.
|
|
data Bookmark = MkBookmark {
|
|
bkName :: Path Fn
|
|
, bkPath :: Path Abs
|
|
} deriving (Show)
|
|
|
|
|
|
-- |Parses bookmarks from a ByteString that has pairs of
|
|
-- name and path. Name and path are separated by one null character
|
|
-- and the pairs itself are separated by two null characters from
|
|
-- each other.
|
|
bkParser :: Parser [Bookmark]
|
|
bkParser =
|
|
fmap catMaybes $ many' (fmap toBm $ bookmark <* word8 _nul <* word8 _nul)
|
|
where
|
|
toBm :: (ByteString, ByteString) -> Maybe Bookmark
|
|
toBm (name, path) = MkBookmark <$> P.parseFn name
|
|
<*> P.parseAbs path
|
|
bookmark :: Parser (ByteString, ByteString)
|
|
bookmark =
|
|
(\x y -> (BS.pack x, BS.pack y))
|
|
<$> many1' char
|
|
<* (word8 _nul)
|
|
<*> many1' char
|
|
char = satisfy (`notElem` [_nul])
|
|
|
|
|
|
-- |Writes bookmarks to a given file.
|
|
writeBookmarks :: [Bookmark] -> IO ()
|
|
writeBookmarks [] = return ()
|
|
writeBookmarks bs = do
|
|
bf <- bookmarksFile
|
|
bfd <- bookmarksDir
|
|
mkdirP bfd
|
|
readFile getFileInfo bfd >>= (\x -> createFile x bookmarksFileName)
|
|
let str = foldr1 (\x y -> x `BS.append` BS.pack [_nul, _nul]
|
|
`BS.append`
|
|
y `BS.append` BS.pack [_nul, _nul])
|
|
(fmap toByteString bs)
|
|
file <- readFile getFileInfo bf
|
|
void $ writeFile file str
|
|
where
|
|
toByteString :: Bookmark -> ByteString
|
|
toByteString b = (P.fromRel $ bkName b)
|
|
`BS.append` BS.singleton _nul
|
|
`BS.append` (P.fromAbs $ bkPath b)
|
|
|
|
|
|
-- |Reads bookmarks from a given file.
|
|
readBookmarks :: IO [Bookmark]
|
|
readBookmarks = do
|
|
p <- bookmarksFile
|
|
file <- readFile getFileInfo p
|
|
c <- readFileContents file
|
|
case parseOnly bkParser c of
|
|
Left _ -> return []
|
|
Right x -> return x
|
|
|
|
|
|
bookmarksDir :: IO (Path Abs)
|
|
bookmarksDir = do
|
|
mhomedir <- getEnv "HOME"
|
|
case mhomedir of
|
|
Nothing -> ioError (userError "No valid homedir?!")
|
|
Just home -> do
|
|
phome <- P.parseAbs home
|
|
reldir <- P.parseRel ".config/hsfm"
|
|
return $ phome P.</> reldir
|
|
|
|
|
|
bookmarksFile :: IO (Path Abs)
|
|
bookmarksFile = do
|
|
path <- bookmarksDir
|
|
return $ path P.</> bookmarksFileName
|
|
|
|
|
|
bookmarksFileName :: Path Fn
|
|
bookmarksFileName = fromJust $ P.parseFn "bookmarks"
|