Compare commits

...

2 Commits

4 changed files with 60 additions and 22 deletions

View File

@ -10,6 +10,9 @@ import Data.Environment
import UnliftIO.Directory
(XdgDirectory(XdgData), getXdgDirectory)
import System.Environment
(lookupEnv)
import qualified Operations
commands :: Parser (BuukaM ())
@ -24,5 +27,8 @@ commands = subparser
main :: IO ()
main = do
env <- Environment <$> getXdgDirectory XdgData "buuka"
execParser (info (commands <**> helper) fullDesc) >>= runBuukaM env
env <- Environment <$> (lookupEnv "BUUKA_HOME" >>= maybe defaultHome pure)
execParser (info (commands <**> helper) (fullDesc <> progDesc description)) >>= runBuukaM env
where
defaultHome = getXdgDirectory XdgData "buuka"
description = "Bookmarks manager. Stores the bookmarks in a yaml file under your xdg directory or in a folder specified by the BUUKA_HOME environment variable"

View File

@ -38,6 +38,7 @@ library
, Control.Monad.Buuka
, Operations.Insert
, Operations.List
, Operations.Format
, Operations
, Data.Environment
, Data.Buuka

48
src/Operations/Format.hs Normal file
View File

@ -0,0 +1,48 @@
{-# LANGUAGE LambdaCase #-}
{-|
Module : Operations.Format
Description : Format the list of bookmarks
Copyright : (c) Mats Rauhala, 2020
License : BSD-3-Clause
Maintainer : mats.rauhala@iki.fi
Stability : experimental
Portability : POSIX
Format the list of bookmarks. It uses the "hashids" module to create a unique
hash for each entry. Some extra (user) security is given by using the hash of
the full entries as the initial context for hashids. If the state has been
modified between operations, the ids change.
-}
module Operations.Format where
import Data.Buuka
(Buuka, BuukaEntry(..), URL(..))
import qualified Data.Buuka as B
import Data.Semigroup
(Max(..))
import Web.Hashids
import Control.Lens
import Data.Text.Strict.Lens
(unpacked, utf8)
-- | Format the entries
formatEntries
:: Buuka -- ^ The full set of entries, for the context
-> [BuukaEntry] -- ^ The list of entries to be formatted
-> [String]
formatEntries buuka xs =
let formatted = zipWith formatEntry [1..] xs
indexWidth = getMax . foldMap (Max . length . fst) $ formatted
in fmap (\(idx,x) -> idx <> replicate (indexWidth - length idx) ' ' <> ". " <> x) formatted
where
ctx = mkContext buuka
mkContext :: Buuka -> HashidsContext
mkContext = hashidsSimple . B.fingerprint
formatEntry :: Int -> BuukaEntry -> (String, String)
formatEntry n = \case
BuukaEntry{title=Just t} -> (encode ctx n ^. utf8 . unpacked, t)
BuukaEntry{url=URL u} -> (encode ctx n ^. utf8 . unpacked, u)

View File

@ -8,33 +8,16 @@ import Control.Monad.Reader
import Data.Foldable
(traverse_)
import Data.Semigroup
(Max(..))
import Data.Buuka
(Buuka, BuukaEntry(..), URL(..))
(Buuka)
import qualified Data.Buuka as B
import Web.Hashids
import Operations.Format
import Control.Lens
import Data.Text.Strict.Lens
(unpacked, utf8)
list :: BuukaM ()
list =
buukaQ (asks go) >>= traverse_ (liftIO . putStrLn)
where
go :: Buuka -> [String]
go b =
let ctx = hashidsSimple (B.fingerprint b)
in format ctx (B.elements b)
format :: HashidsContext -> [BuukaEntry] -> [String]
format ctx xs =
let formatted = zipWith (formatEntry ctx) [1..] xs
indexWidth = getMax . foldMap (Max . length . fst) $ formatted
in fmap (\(idx,x) -> idx <> replicate (indexWidth - length idx) ' ' <> ". " <> x) formatted
formatEntry :: HashidsContext -> Int -> BuukaEntry -> (String, String)
formatEntry ctx n = \case
BuukaEntry{title=Just t} -> (encode ctx n ^. utf8 . unpacked, t)
BuukaEntry{url=URL u} -> (encode ctx n ^. utf8 . unpacked, u)
go b = formatEntries b (B.elements b)