hbro-0.6.7: Hbro/Extra/Bookmarks.hs
module Hbro.Extra.Bookmarks (
addWithTags,
addAllWithTags,
load,
loadWithTag,
deleteWithTag,
add,
) where
-- {{{ Imports
import Hbro.Core
import Hbro.Gui
import Hbro.Types
import Hbro.Util
import qualified Data.ByteString.Char8 as B
import Data.List
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Graphics.UI.Gtk.Entry.Entry
import Graphics.UI.Gtk.WebKit.WebView
import System.Environment
import qualified System.Info as Sys
import System.IO
import System.Posix.Process
import System.Process
import System.ZMQ
-- }}}
-- | Add current URI to bookmarks.
-- Prompt for a tags list to apply.
addWithTags :: Browser -> IO ()
addWithTags browser = do
uri <- webViewGetUri (mWebView $ mGUI browser)
case uri of
Just u -> prompt "Bookmark with tags:" "" False browser (\b -> do
tags <- entryGetText (mPromptEntry $ mGUI b)
add u (words tags))
_ -> return ()
-- | Add current URIs from all opened windows to bookmarks.
addAllWithTags :: Browser -> IO ()
addAllWithTags browser =
prompt "Bookmark all instances with tag:" "" False browser (\b -> do
tags <- entryGetText (mPromptEntry $ mGUI b)
uri <- webViewGetUri (mWebView $ mGUI browser)
case uri of
Just u -> add u $ words tags
_ -> return ()
(_, pids, _) <- readProcessWithExitCode "pidof" ["hbro"] []
(_, pids', _) <- readProcessWithExitCode "pidof" ["hbro-" ++ Sys.os ++ "-" ++ Sys.arch] []
myPid <- getProcessID
let pidsList = delete (show myPid) . nub . words $ pids ++ " " ++ pids'
let bookmarkPID = (\pid -> withContext 1 $ \context -> do
withSocket context Req $ \reqSocket ->
let
socketURI = "ipc://" ++ (mSocketDir $ mConfiguration browser) ++ "/hbro." ++ pid
in do
connect reqSocket socketURI
send reqSocket (B.pack "getUri") []
uri <- receive reqSocket []
add (B.unpack uri) (words tags)
)
_ <- mapM bookmarkPID pidsList
return ())
-- |
load :: Browser -> IO ()
load browser = do
-- Load bookmarks file
configHome <- getEnv "XDG_CONFIG_HOME"
file <- T.readFile $ configHome ++ "/hbro/bookmarks"
-- Reformat lines
let file' = T.unlines . sort . nub $ map reformat (T.lines file)
-- Let user select a URI
(Just input, Just output, _, _) <- createProcess (proc "dmenu" ["-l", "10"]) {
std_in = CreatePipe,
std_out = CreatePipe }
_ <- T.hPutStr input file'
entry <- catch (hGetLine output) (\e -> return "ERROR" )
case reverse . words $ entry of
["ERROR"] -> return ()
uri:_ -> loadURI uri browser
_ -> return ()
reformat :: T.Text -> T.Text
reformat line =
T.unwords $ tags' ++ [uri]
where
uri:tags = T.words line
tags' = sort $ map (\tag -> T.snoc (T.cons '[' tag) ']') tags
-- |
loadWithTag :: Browser -> IO ()
loadWithTag browser = do
-- Read bookmarks file
configHome <- getEnv "XDG_CONFIG_HOME"
file <- T.readFile $ configHome ++ "/hbro/bookmarks"
-- Filter tags list
let list = T.unlines . sort . nub . T.words . T.unwords $ map getTags (T.lines file)
-- Let user select a tag
(Just input, Just output, _, _) <- createProcess (proc "dmenu" ["-l", "10"]) {
std_in = CreatePipe,
std_out = CreatePipe }
_ <- T.hPutStr input list
tag <- catch (hGetLine output) (\e -> return "ERROR" )
case tag of
"ERROR" -> return ()
"" -> return ()
t -> do
_ <- mapM (\uri -> runExternalCommand ("hbro -u \"" ++ (T.unpack uri) ++ "\"")) uris
return ()
where
file' = filter (tagFilter $ T.pack t) (T.lines file)
uris = map getUri file'
--
tagFilter :: T.Text -> T.Text -> Bool
tagFilter tag line = let uri:tags = T.words line in case (intersect [tag] tags) of
[t] -> True
_ -> False
-- |
deleteWithTag :: Browser -> IO ()
deleteWithTag browser = do
configHome <- getEnv "XDG_CONFIG_HOME"
file <- T.readFile $ configHome ++ "/hbro/bookmarks"
let tagsList = T.unlines . sort . nub . T.words . T.unwords $ map getTags (T.lines file)
(Just input, Just output, _, _) <- createProcess (proc "dmenu" []) {
std_in = CreatePipe,
std_out = CreatePipe }
_ <- T.hPutStr input tagsList
tag <- catch (hGetLine output) (\e -> return "ERROR" )
case tag of
"ERROR" -> return ()
"" -> return ()
t -> do
T.writeFile (configHome ++ "/hbro/bookmarks.old") file
T.writeFile (configHome ++ "/hbro/bookmarks") file'
return ()
where
file' = T.unlines $ filter (not . (tagFilter $ T.pack tag)) (T.lines file)
-- | The elementary bookmark action
add :: String -> [String] -> IO ()
add uri tags = do
configHome <- getEnv "XDG_CONFIG_HOME"
appendFile (configHome ++ "/hbro/bookmarks") $ uri ++ " " ++ (unwords tags) ++ "\n"
-- |
getTags :: T.Text -> T.Text
getTags line = let _:tags = T.words line in T.unwords tags
-- |
getUri :: T.Text -> T.Text
getUri line = let uri:_ = T.words line in uri