packages feed

HaskellNet 0.6.0.2 → 0.6.1.2

raw patch · 5 files changed

+95/−47 lines, 5 filesdep ~arraydep ~basedep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: array, base, bytestring, cryptohash-md5, mime-mail, mtl, old-time, pretty, text

API changes (from Hackage documentation)

+ Network.HaskellNet.Auth: XOAUTH2 :: AuthType
+ Network.HaskellNet.IMAP: MinusGmailLabels :: [GmailLabel] -> FlagsQuery
+ Network.HaskellNet.IMAP: PlusGmailLabels :: [GmailLabel] -> FlagsQuery
+ Network.HaskellNet.IMAP: ReplaceGmailLabels :: [GmailLabel] -> FlagsQuery
+ Network.HaskellNet.IMAP: XGMRAW :: String -> SearchQuery
+ Network.HaskellNet.IMAP: XOAUTH2 :: AuthType
+ Network.HaskellNet.IMAP: appendFull :: IMAPConnection -> MailboxName -> ByteString -> Maybe [Flag] -> Maybe CalendarTime -> IO ()
+ Network.HaskellNet.IMAP.Types: type GmailLabel = String
+ Network.HaskellNet.POP3: XOAUTH2 :: AuthType
+ Network.HaskellNet.SMTP: XOAUTH2 :: AuthType

Files

CHANGELOG view
@@ -1,3 +1,9 @@+0.6.1.0 (2023-06-27)+  - fixed bug with wrong IMAP header decoding ([Issue 89](https://github.com/qnikst/HaskellNet/issues/89))+    Thanks to William Arteroi (@wwmoraes) and Nathan Collins (@ntc2)+  - added support for OAuth2 authorization+    Thanks to @paumr.+ 0.6.0.1 (2022-05-17)   - GHC 9.0+ support 
HaskellNet.cabal view
@@ -6,7 +6,7 @@                 Full examples can be found in the <https://github.com/qnikst/HaskellNet/tree/master/example repository>.                 Additional documentation on the major updates can be found in the                 <https://github.com/qnikst/HaskellNet/blob/master/Updating.md Updating.md> file-Version:        0.6.0.2+Version:        0.6.1.2 Copyright:      (c) 2006 Jun Mukai Author:         Jun Mukai Maintainer:     Alexander Vershilov <alexander.vershilov@sirius.online>,@@ -19,12 +19,11 @@ Cabal-version:  1.22 Build-type:     Simple Tested-with:-  GHC ==8.4.4-   || ==8.6.5-   || ==8.8.4+  GHC ==8.8.4    || ==8.10.7    || ==9.0.2-   || ==9.2.2+   || ==9.2.5+   || ==9.4.4  Extra-Source-Files:   CHANGELOG@@ -70,15 +69,15 @@   Build-Depends:     base >= 4.3 && < 4.18,     network >= 2.6.3.1 && < 3.2,-    mtl,-    bytestring >=0.10.2,-    pretty,-    array,-    cryptohash-md5,+    mtl >= 2.2.2 && < 2.3,+    bytestring >=0.10.2 && < 0.12,+    pretty >= 1.1.3 && < 1.2,+    array >= 0.5 && < 0.6,+    cryptohash-md5  >= 0.11 && < 0.12,     base64 < 0.5,-    old-time,-    mime-mail >= 0.4.7 && < 0.6,-    text+    old-time  >= 1.0 && < 1.2,+    mime-mail >= 0.4 && < 0.6,+    text  >= 1.0 && < 3    if !impl(ghc >= 8.0)     Build-depends: fail >= 4.9.0.0 && <4.10
src/Network/HaskellNet/Auth.hs view
@@ -24,6 +24,7 @@ data AuthType = PLAIN               | LOGIN               | CRAM_MD5+              | XOAUTH2                 deriving Eq  instance Show AuthType where@@ -32,6 +33,7 @@               showMain PLAIN    = "PLAIN"               showMain LOGIN    = "LOGIN"               showMain CRAM_MD5 = "CRAM-MD5"+              showMain XOAUTH2  = "XOAUTH2"  b64Encode :: String -> String b64Encode = T.unpack . encode . T.pack@@ -86,3 +88,4 @@ auth PLAIN    _ u p = plain u p auth LOGIN    _ u p = let (u', p') = login u p in unwords [u', p'] auth CRAM_MD5 c u p = cramMD5 c u p+auth XOAUTH2  _ u p = b64Encode $ "user=" ++ u ++ "\001auth=" ++ p ++ "\001\001"
src/Network/HaskellNet/IMAP.hs view
@@ -8,7 +8,7 @@       -- ** autenticated state commands     , select, examine, create, delete, rename     , subscribe, unsubscribe-    , list, lsub, status, append+    , list, lsub, status, append, appendFull       -- ** selected state commands     , check, close, expunge     , search, store, copy@@ -70,6 +70,7 @@                  | SUBJECTs String                  | TEXTs String                  | TOs String+                 | XGMRAW String                  | UIDs [UID]  @@ -99,6 +100,7 @@               showQuery (SUBJECTs s)    = "SUBJECT " ++ s               showQuery (TEXTs s)       = "TEXT " ++ s               showQuery (TOs addr)      = "TO " ++ addr+              showQuery (XGMRAW s)      = "X-GM-RAW " ++ s               showQuery (UIDs uids)     = concat $ intersperse "," $                                           map show uids               showFlag Seen        = "SEEN"@@ -112,6 +114,9 @@ data FlagsQuery = ReplaceFlags [Flag]                 | PlusFlags [Flag]                 | MinusFlags [Flag]+                | ReplaceGmailLabels [GmailLabel]+                | PlusGmailLabels [GmailLabel]+                | MinusGmailLabels [GmailLabel]  ---------------------------------------------------------------------- -- establish connection@@ -213,10 +218,10 @@                     return buf'         let (resp, mboxUp, value) = eval pNone (show6 num) buf         case resp of-         OK _ _        -> do mboxUpdate conn mboxUp-                             return value-         NO _ msg      -> fail ("NO: " ++ msg)-         BAD _ msg     -> fail ("BAD: " ++ msg)+         OK _ _ -> do mboxUpdate conn mboxUp+                      return value+         NO _ msg -> fail ("NO: " ++ msg)+         BAD _ msg -> fail ("BAD: " ++ msg)          PREAUTH _ msg -> fail ("preauth: " ++ msg)  noop :: IMAPConnection -> IO ()@@ -332,13 +337,13 @@        buf2 <- getResponse $ stream conn        let (resp, mboxUp, ()) = eval pNone (show6 num) buf2        case resp of-         OK _ _ -> mboxUpdate conn mboxUp-         NO _ msg -> fail ("NO: "++msg)-         BAD _ msg -> fail ("BAD: "++msg)+         OK _ _        -> mboxUpdate conn mboxUp+         NO _ msg      -> fail ("NO: "++msg)+         BAD _ msg     -> fail ("BAD: "++msg)          PREAUTH _ msg -> fail ("PREAUTH: "++msg)     where mailLines = BS.lines mailData           len       = sum $ map ((2+) . BS.length) mailLines-          tstr      = maybe "" ((" "++) . show) time+          tstr      = maybe "" ((" "++) . datetimeToStringIMAP) time           fstr      = maybe "" ((" ("++) . (++")") . unwords . map show) flags'  check :: IMAPConnection -> IO ()@@ -377,26 +382,26 @@ fetchSize :: IMAPConnection -> UID -> IO Int fetchSize conn uid =     do lst <- fetchByString conn uid "RFC822.SIZE"-       return $ maybe 0 read $ lookup' "RFC822.SIZE" lst+       return $ maybe 0 read $ lookup "RFC822.SIZE" lst  fetchHeaderFields :: IMAPConnection                   -> UID -> [String] -> IO ByteString fetchHeaderFields conn uid hs =-    do lst <- fetchByString conn uid ("BODY[HEADER.FIELDS "++unwords hs++"]")-       return $ maybe BS.empty BS.pack $-              lookup' ("BODY[HEADER.FIELDS "++unwords hs++"]") lst+    do let fetchCmd = "BODY[HEADER.FIELDS ("++unwords hs++")]"+       lst <- fetchByString conn uid fetchCmd+       return $ maybe BS.empty BS.pack $ lookup' fetchCmd lst  fetchHeaderFieldsNot :: IMAPConnection                      -> UID -> [String] -> IO ByteString fetchHeaderFieldsNot conn uid hs =-    do let fetchCmd = "BODY[HEADER.FIELDS.NOT "++unwords hs++"]"+    do let fetchCmd = "BODY[HEADER.FIELDS.NOT ("++unwords hs++")]"        lst <- fetchByString conn uid fetchCmd        return $ maybe BS.empty BS.pack $ lookup' fetchCmd lst  fetchFlags :: IMAPConnection -> UID -> IO [Flag] fetchFlags conn uid =     do lst <- fetchByString conn uid "FLAGS"-       return $ getFlags $ lookup' "FLAGS" lst+       return $ getFlags $ lookup "FLAGS" lst     where getFlags Nothing  = []           getFlags (Just s) = eval' dvFlags "" s @@ -431,9 +436,12 @@     where fstrs fs = "(" ++ (concat $ intersperse " " $ map show fs) ++ ")"           toFStr s fstrs' =               s ++ (if isSilent then ".SILENT" else "") ++ " " ++ fstrs'-          flgs (ReplaceFlags fs) = toFStr "FLAGS" $ fstrs fs-          flgs (PlusFlags fs)    = toFStr "+FLAGS" $ fstrs fs-          flgs (MinusFlags fs)   = toFStr "-FLAGS" $ fstrs fs+          flgs (ReplaceGmailLabels ls) = toFStr "X-GM-LABELS" $ fstrs ls+          flgs (PlusGmailLabels ls)    = toFStr "+X-GM-LABELS" $ fstrs ls+          flgs (MinusGmailLabels ls)   = toFStr "-X-GM-LABELS" $ fstrs ls+          flgs (ReplaceFlags fs)       = toFStr "FLAGS" $ fstrs fs+          flgs (PlusFlags fs)          = toFStr "+FLAGS" $ fstrs fs+          flgs (MinusFlags fs)         = toFStr "-FLAGS" $ fstrs fs           procStore (n, ps) = (maybe (toEnum (fromIntegral n)) read                                          (lookup' "UID" ps)                               ,maybe [] (eval' dvFlags "") (lookup' "FLAG" ps))@@ -452,25 +460,55 @@ ---------------------------------------------------------------------- -- auxialiary functions +showMonth :: Month -> String+showMonth January   = "Jan"+showMonth February  = "Feb"+showMonth March     = "Mar"+showMonth April     = "Apr"+showMonth May       = "May"+showMonth June      = "Jun"+showMonth July      = "Jul"+showMonth August    = "Aug"+showMonth September = "Sep"+showMonth October   = "Oct"+showMonth November  = "Nov"+showMonth December  = "Dec"++show2 :: Int -> String+show2 n | n < 10    = '0' : show n+        | otherwise = show n+++show4 :: (Ord a, Num a, Show a) => a -> String+show4 n | n > 1000 = show n+        | n > 100  = '0' : show n+        | n > 10   = "00" ++ show n+        | otherwise  = "000" ++ show n+ dateToStringIMAP :: CalendarTime -> String dateToStringIMAP date = concat $ intersperse "-" [show2 $ ctDay date                                                  , showMonth $ ctMonth date                                                  , show $ ctYear date]-    where show2 n | n < 10    = '0' : show n-                  | otherwise = show n-          showMonth January   = "Jan"-          showMonth February  = "Feb"-          showMonth March     = "Mar"-          showMonth April     = "Apr"-          showMonth May       = "May"-          showMonth June      = "Jun"-          showMonth July      = "Jul"-          showMonth August    = "Aug"-          showMonth September = "Sep"-          showMonth October   = "Oct"-          showMonth November  = "Nov"-          showMonth December  = "Dec"+timeToStringIMAP :: CalendarTime -> String+timeToStringIMAP c = concat+                     $ intersperse ":"+                     $ fmap show2 [ctHour c, ctMin c, ctSec c] +-- Convert CalenarTime to "date-time" string per RFC3501+datetimeToStringIMAP :: CalendarTime -> String+datetimeToStringIMAP c =+  "\""+  ++ dateToStringIMAP c+  ++ " "+  ++ timeToStringIMAP c+  ++ " "+  ++ zone (ctTZ c)+  ++ "\""+  where+    zone s =+      (if s>=0 then "+" else "-") +++      show4 (s `div` 3600)+ strip :: ByteString -> ByteString strip = fst . BS.spanEnd isSpace . BS.dropWhile isSpace @@ -482,10 +520,10 @@  lookup' :: String -> [(String, b)] -> Maybe b lookup' _ [] = Nothing-lookup' q ((k,v):xs) | q == lastWord k  = return v+lookup' q ((k,v):xs) | q == query k  = return v                      | otherwise        = lookup' q xs     where-        lastWord = last . words+        query = unwords . drop 2 . words  -- TODO: This is just a first trial solution for this stack overflow question: --       http://stackoverflow.com/questions/26183675/error-when-fetching-subject-from-email-using-haskellnets-imap
src/Network/HaskellNet/IMAP/Types.hs view
@@ -1,5 +1,6 @@ module Network.HaskellNet.IMAP.Types     ( MailboxName+    , GmailLabel     , UID     , Charset     , MailboxInfo(..)@@ -28,6 +29,7 @@ type MailboxName = String type UID = Word64 type Charset = String+type GmailLabel = String  data MailboxInfo = MboxInfo { _mailbox :: MailboxName                             , _exists :: Integer