src/mn-message-mime.c (6959B) - raw
1 /*
2 * Mail Notification
3 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <string.h>
21 #include <glib/gi18n.h>
22 #include <libgnomevfs/gnome-vfs.h>
23 #include "mn-message-mime.h"
24 #include "mn-gmime-stream-vfs.h"
25 #include "mn-util.h"
26 #include "mn-vfs.h"
27
28 static gboolean
29 is_spam (GMimeMessage *mime_message)
30 {
31 const char *spam;
32
33 g_return_val_if_fail(GMIME_IS_MESSAGE(mime_message), FALSE);
34
35 /* SpamAssassin */
36 spam = g_mime_message_get_header(mime_message, "X-Spam-Status");
37 if (spam && mn_ascii_str_case_has_prefix(spam, "yes"))
38 return TRUE;
39
40 /* bogofilter */
41 spam = g_mime_message_get_header(mime_message, "X-Bogosity");
42 if (spam && mn_ascii_str_case_has_prefix(spam, "yes"))
43 return TRUE;
44
45 return FALSE;
46 }
47
48 MNMessage *
49 mn_message_new_from_mime_message (MNMailbox *mailbox,
50 GMimeMessage *mime_message,
51 const char *uri,
52 MNMessageFlags flags,
53 gboolean handle_status)
54 {
55 return mn_message_new_from_mime_message_full(MN_TYPE_MESSAGE,
56 mailbox,
57 mime_message,
58 NULL,
59 uri,
60 flags,
61 handle_status);
62 }
63
64 MNMessage *
65 mn_message_new_from_mime_message_full (GType type,
66 MNMailbox *mailbox,
67 GMimeMessage *mime_message,
68 const char *mid,
69 const char *uri,
70 MNMessageFlags flags,
71 gboolean handle_status)
72 {
73 MNMessage *message;
74 const char *id;
75 time_t sent_time;
76 const char *from;
77 const char *subject;
78 char *decoded_from;
79 char *decoded_subject;
80
81 g_return_val_if_fail(type != 0, NULL);
82 g_return_val_if_fail(MN_IS_MAILBOX(mailbox), NULL);
83 g_return_val_if_fail(GMIME_IS_MESSAGE(mime_message), NULL);
84
85 if (is_spam(mime_message))
86 return NULL;
87
88 if (handle_status)
89 {
90 const char *status;
91
92 status = g_mime_message_get_header(mime_message, "Status");
93 if (status && strchr(status, 'R'))
94 return NULL; /* the message was read */
95 else if (status && strchr(status, 'O'))
96 flags &= ~MN_MESSAGE_NEW;
97 else
98 flags |= MN_MESSAGE_NEW;
99 }
100
101 id = g_mime_message_get_message_id(mime_message);
102 g_mime_message_get_date(mime_message, &sent_time, NULL);
103 from = g_mime_message_get_sender(mime_message);
104 subject = g_mime_message_get_subject(mime_message);
105
106 decoded_from = from ? g_mime_utils_header_decode_text(from) : NULL;
107 decoded_subject = subject ? g_mime_utils_header_decode_text(subject) : NULL;
108
109 message = g_object_new(type,
110 MN_MESSAGE_PROP_MAILBOX(mailbox),
111 MN_MESSAGE_PROP_SENT_TIME(sent_time),
112 MN_MESSAGE_PROP_ID((char *) id),
113 MN_MESSAGE_PROP_MID((char *) mid),
114 MN_MESSAGE_PROP_FROM(decoded_from),
115 MN_MESSAGE_PROP_SUBJECT(decoded_subject),
116 MN_MESSAGE_PROP_URI((char *) uri),
117 MN_MESSAGE_PROP_FLAGS(flags),
118 NULL);
119
120 g_free(decoded_from);
121 g_free(decoded_subject);
122
123 return message;
124 }
125
126 MNMessage *
127 mn_message_new_from_mime_stream (MNMailbox *mailbox,
128 GMimeStream *mime_stream,
129 const char *mid,
130 const char *uri,
131 MNMessageFlags flags,
132 gboolean handle_status,
133 GError **err)
134 {
135 return mn_message_new_from_mime_stream_full(MN_TYPE_MESSAGE,
136 mailbox,
137 mime_stream,
138 mid,
139 uri,
140 flags,
141 handle_status,
142 err);
143 }
144
145 MNMessage *
146 mn_message_new_from_mime_stream_full (GType type,
147 MNMailbox *mailbox,
148 GMimeStream *mime_stream,
149 const char *mid,
150 const char *uri,
151 MNMessageFlags flags,
152 gboolean handle_status,
153 GError **err)
154 {
155 GMimeParser *parser;
156 GMimeMessage *mime_message;
157 MNMessage *message = NULL;
158
159 g_return_val_if_fail(type != 0, NULL);
160 g_return_val_if_fail(MN_IS_MAILBOX(mailbox), NULL);
161 g_return_val_if_fail(GMIME_IS_STREAM(mime_stream), NULL);
162
163 parser = g_mime_parser_new_with_stream(mime_stream);
164 mime_message = g_mime_parser_construct_message(parser);
165 g_object_unref(parser);
166
167 if (mime_message)
168 {
169 message = mn_message_new_from_mime_message_full(type, mailbox, mime_message, mid, uri, flags, handle_status);
170 g_object_unref(mime_message);
171 }
172 else
173 g_set_error(err, 0, 0, _("unable to parse MIME message"));
174
175 return message;
176 }
177
178 MNMessage *
179 mn_message_new_from_uri (MNMailbox *mailbox,
180 GnomeVFSURI *uri,
181 MNMessageFlags flags,
182 gboolean handle_status,
183 GError **err)
184 {
185 return mn_message_new_from_uri_full(MN_TYPE_MESSAGE,
186 mailbox,
187 NULL,
188 uri,
189 flags,
190 handle_status,
191 err);
192 }
193
194 MNMessage *
195 mn_message_new_from_uri_full (GType type,
196 MNMailbox *mailbox,
197 const char *mid,
198 GnomeVFSURI *uri,
199 MNMessageFlags flags,
200 gboolean handle_status,
201 GError **err)
202 {
203 GnomeVFSResult result;
204 GnomeVFSHandle *handle;
205
206 g_return_val_if_fail(type != 0, NULL);
207 g_return_val_if_fail(MN_IS_MAILBOX(mailbox), NULL);
208 g_return_val_if_fail(uri != NULL, NULL);
209
210 result = gnome_vfs_open_uri(&handle, uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM);
211 if (result == GNOME_VFS_OK)
212 {
213 GMimeStream *stream;
214
215 stream = mn_gmime_stream_vfs_new(handle, uri, &result);
216 if (stream)
217 {
218 MNMessage *message;
219 char *text_uri;
220
221 text_uri = gnome_vfs_uri_to_string(uri, GNOME_VFS_URI_HIDE_NONE);
222
223 message = mn_message_new_from_mime_stream_full(type,
224 mailbox,
225 stream,
226 mid,
227 text_uri,
228 flags,
229 handle_status,
230 err);
231
232 g_free(text_uri);
233 g_object_unref(stream);
234
235 return message;
236 }
237 }
238
239 mn_vfs_result_to_g_error(result, err);
240 return NULL;
241 }
242
243 MNMessage *
244 mn_message_new_from_buffer (MNMailbox *mailbox,
245 const char *buffer,
246 unsigned int len,
247 const char *mid,
248 MNMessageFlags flags,
249 gboolean handle_status,
250 GError **err)
251 {
252 GMimeStream *stream;
253 MNMessage *message;
254
255 g_return_val_if_fail(MN_IS_MAILBOX(mailbox), NULL);
256 g_return_val_if_fail(buffer != NULL, NULL);
257
258 stream = g_mime_stream_mem_new_with_buffer(buffer, len);
259 message = mn_message_new_from_mime_stream(mailbox,
260 stream,
261 mid,
262 NULL,
263 flags,
264 handle_status,
265 err);
266 g_object_unref(stream);
267
268 return message;
269 }