{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Xmobar.Plugins.NotmuchMail
(
MailItem(..)
, NotmuchMail(..)
) where
import Xmobar.Run.Exec (Exec(alias, rate, run))
import Control.Concurrent.Async (mapConcurrently)
import Data.Maybe (catMaybes)
import System.Exit (ExitCode(ExitSuccess))
import System.Process (readProcessWithExitCode)
data MailItem = MailItem
{ MailItem -> String
name :: String
, MailItem -> String
address :: String
, MailItem -> String
query :: String
}
deriving (ReadPrec [MailItem]
ReadPrec MailItem
Int -> ReadS MailItem
ReadS [MailItem]
(Int -> ReadS MailItem)
-> ReadS [MailItem]
-> ReadPrec MailItem
-> ReadPrec [MailItem]
-> Read MailItem
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MailItem]
$creadListPrec :: ReadPrec [MailItem]
readPrec :: ReadPrec MailItem
$creadPrec :: ReadPrec MailItem
readList :: ReadS [MailItem]
$creadList :: ReadS [MailItem]
readsPrec :: Int -> ReadS MailItem
$creadsPrec :: Int -> ReadS MailItem
Read, Int -> MailItem -> ShowS
[MailItem] -> ShowS
MailItem -> String
(Int -> MailItem -> ShowS)
-> (MailItem -> String) -> ([MailItem] -> ShowS) -> Show MailItem
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MailItem] -> ShowS
$cshowList :: [MailItem] -> ShowS
show :: MailItem -> String
$cshow :: MailItem -> String
showsPrec :: Int -> MailItem -> ShowS
$cshowsPrec :: Int -> MailItem -> ShowS
Show)
data NotmuchMail = NotmuchMail
{ NotmuchMail -> String
nmAlias :: String
, NotmuchMail -> [MailItem]
mailItems :: [MailItem]
, NotmuchMail -> Int
nmRate :: Int
}
deriving (ReadPrec [NotmuchMail]
ReadPrec NotmuchMail
Int -> ReadS NotmuchMail
ReadS [NotmuchMail]
(Int -> ReadS NotmuchMail)
-> ReadS [NotmuchMail]
-> ReadPrec NotmuchMail
-> ReadPrec [NotmuchMail]
-> Read NotmuchMail
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [NotmuchMail]
$creadListPrec :: ReadPrec [NotmuchMail]
readPrec :: ReadPrec NotmuchMail
$creadPrec :: ReadPrec NotmuchMail
readList :: ReadS [NotmuchMail]
$creadList :: ReadS [NotmuchMail]
readsPrec :: Int -> ReadS NotmuchMail
$creadsPrec :: Int -> ReadS NotmuchMail
Read, Int -> NotmuchMail -> ShowS
[NotmuchMail] -> ShowS
NotmuchMail -> String
(Int -> NotmuchMail -> ShowS)
-> (NotmuchMail -> String)
-> ([NotmuchMail] -> ShowS)
-> Show NotmuchMail
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NotmuchMail] -> ShowS
$cshowList :: [NotmuchMail] -> ShowS
show :: NotmuchMail -> String
$cshow :: NotmuchMail -> String
showsPrec :: Int -> NotmuchMail -> ShowS
$cshowsPrec :: Int -> NotmuchMail -> ShowS
Show)
instance Exec NotmuchMail where
rate :: NotmuchMail -> Int
rate :: NotmuchMail -> Int
rate NotmuchMail{ Int
nmRate :: Int
nmRate :: NotmuchMail -> Int
nmRate } = Int
nmRate
alias :: NotmuchMail -> String
alias :: NotmuchMail -> String
alias NotmuchMail{ String
nmAlias :: String
nmAlias :: NotmuchMail -> String
nmAlias } = String
nmAlias
run :: NotmuchMail -> IO String
run :: NotmuchMail -> IO String
run NotmuchMail{ [MailItem]
mailItems :: [MailItem]
mailItems :: NotmuchMail -> [MailItem]
mailItems } =
[String] -> String
unwords ([String] -> String)
-> ([Maybe String] -> [String]) -> [Maybe String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe String] -> [String]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe String] -> String) -> IO [Maybe String] -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MailItem -> IO (Maybe String)) -> [MailItem] -> IO [Maybe String]
forall (t :: * -> *) a b.
Traversable t =>
(a -> IO b) -> t a -> IO (t b)
mapConcurrently MailItem -> IO (Maybe String)
notmuchSpawn [MailItem]
mailItems
where
MailItem -> IO (Maybe String)
notmuchSpawn :: MailItem -> IO (Maybe String)
= \MailItem{ String
address :: String
address :: MailItem -> String
address, String
name :: String
name :: MailItem -> String
name, String
query :: String
query :: MailItem -> String
query } -> do
let args :: [String]
args = [ String
"search"
, String -> ShowS
tryAdd String
"to:" String
address
, String
"tag:unread", String -> ShowS
tryAdd String
"and " String
query
]
(ExitCode
exitCode, String
out, String
_) <- String -> [String] -> String -> IO (ExitCode, String, String)
readProcessWithExitCode String
"notmuch" [String]
args []
let numThreads :: Int
numThreads = [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> [String]
lines String
out)
Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$!
(String
name String -> ShowS
forall a. Semigroup a => a -> a -> a
<>) ShowS -> (Int -> String) -> Int -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Maybe Int -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> if ExitCode
exitCode ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ExitCode
ExitSuccess Bool -> Bool -> Bool
|| Int
numThreads Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1
then Maybe Int
forall a. Maybe a
Nothing
else Int -> Maybe Int
forall a. a -> Maybe a
Just Int
numThreads
String -> ShowS
tryAdd :: String -> String -> String
= \String
prefix String
str -> if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str then String
"" else String
prefix String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
str