blob: fc63a8955f8e9a8ccbb32faa563889c1639ea5a8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
{- Email accessors.
-
- Copyright 2013 Raúl Benencia <rul@kalgan.cc>
-
- Licensed under the GNU GPL version 3 or higher
-
-}
module Lazymail.Email where
import Codec.MIME.Type(MIMEValue(..), MIMEContent(..), showMIMEType, Type(..), MIMEType(..))
import Data.Char(toLower)
import Data.List(find)
getBody :: MIMEValue -> String
getBody msg =
case mime_val_content msg of
Single c -> c
Multi mvs -> case firstTextPart mvs of
Just mv -> unwrapContent . mime_val_content $ mv
Nothing -> "This email has no displayable content."
where
unwrapContent (Single c) = c
-- hackish function for showing the email. In he future the logic of this
-- function should be improved.
firstTextPart [] = Nothing
firstTextPart (mv:mvs) = case mime_val_content mv of
Single c -> if isText mv then Just mv else firstTextPart mvs
Multi mvs' -> firstTextPart mvs'
where
isText = \mv -> case (mimeType $ mime_val_type mv) of
Text text -> True
_ -> False
getHeaders :: MIMEValue -> [(String,String)]
getHeaders = mime_val_headers
-- | Convert a String to multiple Strings, cropped by the maximum column
-- size if necessary.
formatBody :: String -> Int -> [String]
formatBody body maxColumns = format [] [] body where
format parsed acc [] = parsed ++ [acc]
format parsed acc ('\r':'\n':xs) = format (parsed ++ [acc]) [] xs
format parsed acc rest@(x:xs) | length acc < maxColumns = format parsed (acc ++ [x]) xs
| otherwise = format (parsed ++ [acc]) "+" rest
-- The following function is a verbatim copy of the unexported function in
-- Codec.MIME.Parse.
-- case in-sensitive lookup of field names or attributes\/parameters.
lookupField' :: String -> [(String,a)] -> Maybe a
lookupField' n ns =
-- assume that inputs have been mostly normalized already
-- (i.e., lower-cased), but should the lookup fail fall back
-- to a second try where we do normalize before giving up.
case lookup n ns of
x@Just{} -> x
Nothing ->
let nl = map toLower n in
case find (\ (y,_) -> nl == map toLower y) ns of
Nothing -> Nothing
Just (_,x) -> Just x
unwrapField = maybe "" id
lookupField n ns = unwrapField $ lookupField' n ns
{-import Text.Parsec.Error(ParseError)
import Text.ParserCombinators.Parsec (parse)
import Text.ParserCombinators.Parsec.Rfc2822
parseEmail :: String -> Message
parseEmail msg = unwrapEmail $ parse message "<stdin>" $ fixEol msg
unwrapEmail (Right email) = email
getFields (Message fs _) = fs
-- There is obviously a pattern here. Find a way to narrow it down.
getReturnPath fs = do { ReturnPath f <- fs; f }
getFrom fs = do { From f <- fs; f }
getTo fs = do { To f <- fs; f }
getCc fs = do { Cc f <- fs; f }
getBcc fs = do { Bcc f <- fs; f }
getReplyTo fs = do { ReplyTo f <- fs; f }
getSubject fs = do { Subject f <- fs; f }
getMessageID fs = do { MessageID f <- fs; f }
getInReplyTo fs = do { InReplyTo f <- fs; f }
getReferences fs = do { References f <- fs; f }
getComments fs = do { Comments f <- fs; f }
getKeywords fs = do { Keywords f <- fs; f }
--getDate fs = do { Date f <- fs; f }
--getResentDate fs = do { ResentDate f <- fs; f }
getResentFrom fs = do { ResentFrom f <- fs; f }
--getResentSender fs = do { ResentSender f <- fs; f }
getResentTo fs = do { ResentTo f <- fs; f }
getResentCc fs = do { ResentCc f <- fs; f }
getResentBcc fs = do { ResentBcc f <- fs; f }
getResentMessageID fs = do { ResentMessageID f <- fs; f }
--getReceived fs = do { Received f <- fs; f }
getBody (Message _ []) = "Empty body"
getBody (Message _ body) = body
-- Make sure all lines are terminated by CRLF.
fixEol :: String -> String
fixEol ('\r':'\n':xs) = '\r' : '\n' : fixEol xs
fixEol ('\n':xs) = '\r' : '\n' : fixEol xs
fixEol (x:xs) = x : fixEol xs
fixEol [] = []-}
|