a152df37c2687d065d70f6b81da6c40038ab92e7
[modest] / src / modest-search.c
1 #define _GNU_SOURCE
2
3 #include <string.h>
4
5 #include <tny-shared.h>
6 #include <tny-folder.h>
7 #include <tny-list.h>
8 #include <tny-iterator.h>
9 #include <tny-simple-list.h>
10
11 #include "modest-search.h"
12 #include "modest-mime-part-search-stream.h"
13
14 static GList*
15 add_header (GList *list, TnyHeader *header, TnyFolder *folder)
16 {
17         gchar *furl = tny_folder_get_url_string (folder);
18         const gchar *uid = tny_header_get_uid (header);
19         gchar *str  = g_strdup_printf ("%s/%s", furl, uid);
20         g_free (furl);
21         return g_list_prepend (list, str);
22 }
23
24
25
26 /**
27  * modest_search:
28  * @folder: a #TnyFolder instance
29  * @search: a #ModestSearch query
30  *
31  * This operation will search @folder for headers that match the query @search.
32  * It will return a doubly linked list with URIs that point to the message.
33  **/
34 GList *
35 modest_search (TnyFolder *folder, ModestSearch *search)
36 {
37         GList *retval = NULL;
38         TnyIterator *iter;
39         TnyList *list = tny_simple_list_new ();
40         tny_folder_get_headers (folder, list, FALSE, NULL);
41
42         iter = tny_list_create_iterator (list);
43         while (!tny_iterator_is_done (iter))
44         {
45                 TnyHeader *cur = (TnyHeader *) tny_iterator_get_current (iter);
46                 time_t t = tny_header_get_date_sent (cur);
47
48                 if (search->flags & MODEST_SEARCH_BEFORE)
49                         if (!(t <= search->before))
50                                 goto go_next;
51
52                 if (search->flags & MODEST_SEARCH_AFTER)
53                         if (!(t >= search->after))
54                                 goto go_next;
55
56
57                 if (search->flags & MODEST_SEARCH_SIZE)
58                         if (tny_header_get_message_size  (cur) < search->minsize)
59                                 goto go_next;
60                 
61                 if (search->flags & MODEST_SEARCH_SUBJECT) {
62                         if (strcasestr (tny_header_get_subject (cur), search->subject))
63                                 retval = add_header (retval, cur, folder);
64                 } else if (search->flags & MODEST_SEARCH_SENDER) {
65                         if (strcasestr (tny_header_get_from (cur), search->subject))
66                                 retval = add_header (retval, cur, folder);
67                 } else if (search->flags & MODEST_SEARCH_RECIPIENT) {
68                         if (strcasestr (tny_header_get_to (cur), search->subject))
69                                 retval = add_header (retval, cur, folder);
70                 } else if (search->flags & MODEST_SEARCH_BODY) 
71                 {
72                         TnyHeaderFlags flags = tny_header_get_flags (cur);
73                         
74                         if (flags & TNY_HEADER_FLAG_CACHED)
75                         {
76                                 GError *err = NULL;
77                                 TnyMsg *msg = tny_folder_get_msg (folder, cur, &err);
78                                 
79                                 if (err == NULL)
80                                 {
81                                         TnyIterator *piter;
82                                         TnyList *parts = tny_simple_list_new ();
83                                         tny_mime_part_get_parts  (TNY_MIME_PART (msg), parts);
84                                         piter = tny_list_create_iterator (parts);
85
86                                         while (!tny_iterator_is_done (piter))
87                                         {
88                                                 TnyStream *stream;
89                                                 TnyMimePart *pcur = (TnyMimePart *) tny_iterator_get_current (piter);
90
91                                                 stream = modest_mime_part_search_stream_new (search->body);
92
93                                                 tny_mime_part_decode_to_stream (pcur, stream);
94
95                                                 if (((ModestMimePartSearchStream *) stream)->found)
96                                                         retval = add_header (retval, cur, folder);                              
97
98                                                 g_object_unref (stream);
99                                                 g_object_unref (pcur);
100                                                 tny_iterator_next (piter);
101                                         }
102                                         g_object_unref (piter);
103                                         g_object_unref (parts);
104                                 } else
105                                         g_error_free (err);
106                                 
107                                 if (msg)
108                                         g_object_unref (msg);
109                         }
110                 }
111
112                         
113
114 go_next:
115                 g_object_unref (cur);
116                 tny_iterator_next (iter);
117         }
118         g_object_unref (iter);
119         g_object_unref (list);
120         
121         return retval;
122 }
123