aboutsummaryrefslogtreecommitdiff
path: root/Maildir.hs
diff options
context:
space:
mode:
authorRaúl Benencia <rul@kalgan.cc>2013-08-20 20:37:34 -0300
committerRaúl Benencia <rul@kalgan.cc>2013-08-20 20:37:34 -0300
commitce68d07f31019bf318a75e0ef9c438f0d25ae846 (patch)
treec57d8f0c92bfa5fe6722d2685e1361205580ef1a /Maildir.hs
first commit
Diffstat (limited to 'Maildir.hs')
-rw-r--r--Maildir.hs125
1 files changed, 125 insertions, 0 deletions
diff --git a/Maildir.hs b/Maildir.hs
new file mode 100644
index 0000000..633db23
--- /dev/null
+++ b/Maildir.hs
@@ -0,0 +1,125 @@
+-- This module is part of Lazymail, a Haskell email client.
+--
+-- Copyright (C) 2013 Raúl Benencia <rul@kalgan.cc>
+--
+-- This program 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.
+--
+-- 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, see <http://www.gnu.org/licenses/>.
+
+module Maildir where
+
+import Control.Monad.Loops(allM)
+import Control.Monad (forM, filterM)
+import Data.List(isPrefixOf)
+import System.Directory (doesDirectoryExist, getDirectoryContents)
+import System.FilePath ((</>))
+import System.IO(IOMode(..), hGetContents, openFile)
+import Network.Email.Mailbox(Flag(..), Flags)
+
+type Maildir = FilePath
+
+isMaildir :: FilePath -> IO Bool
+isMaildir fp = allM doesDirectoryExist [ fp
+ , fp </> "cur"
+ , fp </> "new"
+ , fp </> "tmp"]
+
+listIDs :: Maildir -> IO [FilePath]
+listIDs md = getNewIDs md `appendM` getReadIDs md
+ where mxs `appendM` mxs' = do
+ xs <- mxs
+ xs' <- mxs'
+ return (xs ++ xs')
+
+getNewIDs :: Maildir -> IO [FilePath]
+getNewIDs md = getIDs (md </> "new")
+
+getReadIDs :: Maildir -> IO [FilePath]
+getReadIDs md = getIDs (md </> "cur")
+
+getIDs :: FilePath -> IO [FilePath]
+getIDs fp = do
+ names <-getDirectoryContents fp
+ let properNames = filter (`notElem` [".", ".."]) names
+ return $ map (fp </>) properNames
+
+listMessageFlags :: Maildir -> IO [(FilePath, Flags)]
+listMessageFlags fp = do
+ ids <- (listIDs fp)
+ let flags = map getFlags ids
+ return (zip ids flags)
+
+getFlags :: FilePath -> Flags
+getFlags fp = map toFlag $ strip fp
+ where strip x
+ | null x = []
+ | ":2," `isPrefixOf` x = drop 3 x
+ | otherwise = let (discard, analyze) = span (/= ':') fp
+ in strip analyze
+
+toFlag :: Char -> Flag
+toFlag c | c == 'S' = SEEN
+ | c == 'A' = ANSWERED
+ | c == 'F' = FLAGGED
+ | c == 'D' = DRAFT
+ | c == 'P' = FORWARDED
+ | c == 'T' = DELETED
+ | otherwise = OTHERFLAG [c]
+
+getAll :: Maildir -> IO [(FilePath, Flags, String)]
+getAll fp = do
+ ids <- listIDs fp
+ msgs <- mapM (\x -> hGetContents =<< openFile x ReadMode) ids
+ let flags = map getFlags ids
+ return $ zip3 ids flags msgs
+
+{- | Returns information about specific messages. -}
+getMessages :: Maildir -> [FilePath] -> IO [(FilePath, Flags, String)]
+getMessages mb list = do
+ messages <- getAll mb
+ return $ filter (\(id, f, m) -> id `elem` list) messages
+
+--
+-- | Based on getRecursiveContents from Real World Haskell
+--
+getMaildirsRecursively :: FilePath -> IO [Maildir]
+getMaildirsRecursively topdir = do
+ result <- search topdir
+ includeTopDir <- isMaildir topdir
+ if includeTopDir
+ then return (topdir:result)
+ else return result
+
+ where
+ search topdir = do
+ names <- getDirectoryContents topdir
+ let properNames = filter (`notElem` [".", ".."]) names
+ paths <- forM properNames $ \name -> do
+ let path = topdir </> name
+ isDirectory <- doesDirectoryExist path
+ if isDirectory
+ then do
+ result <- search path
+ return ([path] ++ result)
+ else return []
+
+ filterM isMaildir (concat paths)
+
+
+-- Temporal code for testing purposes
+defaultPath = "/home/rul/mail/linti/INBOX.academic.c.questions"
+getFirstEmail = do
+ lst <- getAll defaultPath
+ let (_, _, msg) = head lst
+ return msg
+
+ \ No newline at end of file
nihil fit ex nihilo