Line | Branch | Exec | Source |
---|---|---|---|
1 | /* Copyright 2023-2024 Jan-Michael Brummer | ||
2 | * | ||
3 | * This program is free software: you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU Lesser General Public License as published by | ||
5 | * the Free Software Foundation, either version 3 of the License, or | ||
6 | * (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU Lesser General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU Lesser General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <libsoup/soup.h> | ||
18 | #include <json-glib/json-glib.h> | ||
19 | |||
20 | #include <stdio.h> | ||
21 | |||
22 | #include "msg-authorizer.h" | ||
23 | #include "msg-error.h" | ||
24 | #include "msg-private.h" | ||
25 | #include "msg-service.h" | ||
26 | #include "msg-message.h" | ||
27 | #include "msg-mail-folder.h" | ||
28 | #include "msg-message-service.h" | ||
29 | |||
30 | struct _MsgMessageService { | ||
31 | MsgService parent_instance; | ||
32 | }; | ||
33 | |||
34 |
6/7✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 11 times.
|
34 | G_DEFINE_TYPE (MsgMessageService, msg_message_service, MSG_TYPE_SERVICE); |
35 | |||
36 | static void | ||
37 | 1 | msg_message_service_init (__attribute__ ((unused)) MsgMessageService *self) | |
38 | { | ||
39 | 1 | } | |
40 | |||
41 | static void | ||
42 | 2 | msg_message_service_class_init (__attribute__ ((unused)) MsgMessageServiceClass *class) | |
43 | { | ||
44 | 2 | } | |
45 | |||
46 | MsgMessageService * | ||
47 | 1 | msg_message_service_new (MsgAuthorizer *authorizer) | |
48 | { | ||
49 | 1 | return g_object_new (MSG_TYPE_MESSAGE_SERVICE, "authorizer", authorizer, NULL); | |
50 | } | ||
51 | |||
52 | /** | ||
53 | * msg_message_service_get_messages | ||
54 | * @self: a #MsgMessageService | ||
55 | * @cancellable: a #GCancellable | ||
56 | * @error: a #GError | ||
57 | * | ||
58 | * Get all messages for given service | ||
59 | * | ||
60 | * Returns: (element-type MsgMessage) (transfer full): all messages the user can access | ||
61 | */ | ||
62 | GList * | ||
63 | 1 | msg_message_service_get_messages (MsgMessageService *self, | |
64 | GCancellable *cancellable, | ||
65 | GError **error) | ||
66 | { | ||
67 | 1 | JsonObject *root_object = NULL; | |
68 | 1 | g_autofree char *url = NULL; | |
69 | 1 | g_autolist (MsgMessage) list = NULL; | |
70 | 1 | JsonArray *array = NULL; | |
71 | 1 | guint array_length = 0, index = 0; | |
72 | 1 | g_autoptr (GBytes) response = NULL; | |
73 | 1 | g_autoptr (JsonParser) parser = NULL; | |
74 | |||
75 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
76 | ✗ | return NULL; | |
77 | |||
78 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/messages", NULL); | |
79 | |||
80 | do { | ||
81 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | g_autoptr (SoupMessage) message = NULL; |
82 | |||
83 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
84 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
85 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
86 | ✗ | return NULL; | |
87 | |||
88 | 1 | array = json_object_get_array_member (root_object, "value"); | |
89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert (array != NULL); |
90 | |||
91 | 1 | array_length = json_array_get_length (array); | |
92 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | for (index = 0; index < array_length; index++) { |
93 | 1 | g_autoptr (GError) local_error = NULL; | |
94 | 1 | MsgMessage *msg = NULL; | |
95 | 1 | JsonObject *message_object = NULL; | |
96 | |||
97 | 1 | message_object = json_array_get_object_element (array, index); | |
98 | |||
99 | 1 | msg = msg_message_new_from_json (message_object, &local_error); | |
100 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (msg) { |
101 | 1 | list = g_list_append (list, msg); | |
102 | } else { | ||
103 | ✗ | g_warning ("Could not parse message object: %s", local_error->message); | |
104 | ✗ | g_clear_error (&local_error); | |
105 | } | ||
106 | } | ||
107 | |||
108 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | g_clear_pointer (&url, g_free); |
109 | 1 | url = msg_service_get_next_link (root_object); | |
110 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } while (url != NULL); |
111 | |||
112 | 1 | return g_steal_pointer (&list); | |
113 | } | ||
114 | |||
115 | /** | ||
116 | * msg_message_service_get_mail_folders | ||
117 | * @self: a #MsgMessageService | ||
118 | * @cancellable: a #GCancellable | ||
119 | * @error: a #GError | ||
120 | * | ||
121 | * Get all folders for given service | ||
122 | * | ||
123 | * Returns: (element-type MsgMailFolder) (transfer full): all mail folders the user can access | ||
124 | */ | ||
125 | GList * | ||
126 | 1 | msg_message_service_get_mail_folders (MsgMessageService *self, | |
127 | GCancellable *cancellable, | ||
128 | GError **error) | ||
129 | { | ||
130 | 1 | JsonObject *root_object = NULL; | |
131 | 1 | g_autofree char *url = NULL; | |
132 | 1 | g_autolist (MsgMailFolder) list = NULL; | |
133 | 1 | JsonArray *array = NULL; | |
134 | 1 | guint array_length = 0, index = 0; | |
135 | 1 | g_autoptr (GBytes) response = NULL; | |
136 | 1 | g_autoptr (JsonParser) parser = NULL; | |
137 | |||
138 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
139 | ✗ | return NULL; | |
140 | |||
141 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders", NULL); | |
142 | |||
143 | do { | ||
144 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | g_autoptr (SoupMessage) message = NULL; |
145 | |||
146 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
147 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
148 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
149 | ✗ | return NULL; | |
150 | |||
151 | 1 | array = json_object_get_array_member (root_object, "value"); | |
152 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert (array != NULL); |
153 | |||
154 | 1 | array_length = json_array_get_length (array); | |
155 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | for (index = 0; index < array_length; index++) { |
156 | 8 | g_autoptr (GError) local_error = NULL; | |
157 | 8 | MsgMailFolder *folder = NULL; | |
158 | 8 | JsonObject *object = NULL; | |
159 | |||
160 | 8 | object = json_array_get_object_element (array, index); | |
161 | |||
162 | 8 | folder = msg_mail_folder_new_from_json (object, &local_error); | |
163 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (folder) { |
164 | 8 | list = g_list_append (list, folder); | |
165 | } else { | ||
166 | ✗ | g_warning ("Could not parse mail folder object: %s", local_error->message); | |
167 | ✗ | g_clear_error (&local_error); | |
168 | } | ||
169 | } | ||
170 | |||
171 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | g_clear_pointer (&url, g_free); |
172 | 1 | url = msg_service_get_next_link (root_object); | |
173 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } while (url != NULL); |
174 | |||
175 | 1 | return g_steal_pointer (&list); | |
176 | } | ||
177 | |||
178 | /** | ||
179 | * msg_message_service_get_mail_folder | ||
180 | * @self: a #MsgMessageService | ||
181 | * @type: a #MsgMessageMailFolderType | ||
182 | * @cancellable: a #GCancellable | ||
183 | * @error: a #GError | ||
184 | * | ||
185 | * Get a specific mail folder for given service | ||
186 | * | ||
187 | * Returns: (transfer full): a #MsgMailFolder | ||
188 | */ | ||
189 | MsgMailFolder * | ||
190 | 7 | msg_message_service_get_mail_folder (MsgMessageService *self, | |
191 | MsgMessageMailFolderType type, | ||
192 | GCancellable *cancellable, | ||
193 | GError **error) | ||
194 | { | ||
195 | 7 | g_autoptr (SoupMessage) message = NULL; | |
196 | 7 | g_autofree char *url = NULL; | |
197 | 7 | g_autoptr (GBytes) response = NULL; | |
198 | 7 | JsonObject *root_object = NULL; | |
199 | 7 | g_autoptr (JsonParser) parser = NULL; | |
200 | |||
201 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
7 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
202 | ✗ | return NULL; | |
203 | |||
204 |
7/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
7 | switch (type) { |
205 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_INBOX: | |
206 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/inbox", NULL); | |
207 | 1 | break; | |
208 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_DRAFTS: | |
209 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/drafts", NULL); | |
210 | 1 | break; | |
211 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_SENT_ITEMS: | |
212 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/sentitems", NULL); | |
213 | 1 | break; | |
214 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_JUNK_EMAIL: | |
215 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/junkemail", NULL); | |
216 | 1 | break; | |
217 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_DELETED_ITEMS: | |
218 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/deleteditems", NULL); | |
219 | 1 | break; | |
220 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_OUTBOX: | |
221 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/outbox", NULL); | |
222 | 1 | break; | |
223 | 1 | case MSG_MESSAGE_MAIL_FOLDER_TYPE_ARCHIVE: | |
224 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/archive", NULL); | |
225 | 1 | break; | |
226 | } | ||
227 | |||
228 | 7 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
229 | 7 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
230 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!parser) |
231 | ✗ | return NULL; | |
232 | |||
233 | 7 | return msg_mail_folder_new_from_json (root_object, error); | |
234 | } | ||
235 | |||
236 | /** | ||
237 | * msg_message_service_delete: | ||
238 | * @self: a #MsgMessageService | ||
239 | * @message: a #MsgMessage | ||
240 | * @cancellable: a #GCancellable | ||
241 | * @error: a #GError | ||
242 | * | ||
243 | * Delets #message. | ||
244 | * | ||
245 | * Returns: %TRUE for succes, else &FALSE | ||
246 | */ | ||
247 | gboolean | ||
248 | 1 | msg_message_service_delete (MsgMessageService *self, | |
249 | MsgMessage *message, | ||
250 | GCancellable *cancellable, | ||
251 | GError **error) | ||
252 | { | ||
253 | 1 | g_autoptr (SoupMessage) soup_message = NULL; | |
254 | 1 | g_autofree char *url = NULL; | |
255 | 1 | g_autoptr (GBytes) response = NULL; | |
256 | 1 | g_autoptr (JsonParser) parser = NULL; | |
257 | |||
258 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
259 | ✗ | return FALSE; | |
260 | |||
261 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/messages/", msg_message_get_id (message), NULL); | |
262 | 1 | soup_message = msg_service_build_message (MSG_SERVICE (self), "DELETE", url, NULL, FALSE); | |
263 | 1 | response = msg_service_send_and_read (MSG_SERVICE (self), soup_message, cancellable, error); | |
264 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!response) |
265 | ✗ | return FALSE; | |
266 | |||
267 | 1 | return TRUE; | |
268 | } | ||
269 | |||
270 | /** | ||
271 | * msg_message_service_create_draft: | ||
272 | * @self: a #MsgContextService | ||
273 | * @message: a #MsgMessage | ||
274 | * @cancellable: a #GCancellable | ||
275 | * @error: a #GError | ||
276 | * | ||
277 | * Create new draft message #message and return new message object. | ||
278 | * | ||
279 | * Returns: (transfer full): a new #MsgMessage | ||
280 | */ | ||
281 | MsgMessage * | ||
282 | 1 | msg_message_service_create_draft (MsgMessageService *self, | |
283 | MsgMessage *message, | ||
284 | GCancellable *cancellable, | ||
285 | GError **error) | ||
286 | { | ||
287 | 1 | g_autoptr (SoupMessage) soup_message = NULL; | |
288 | 1 | JsonObject *root_object = NULL; | |
289 | 1 | g_autofree char *url = NULL; | |
290 | 1 | g_autoptr (JsonParser) parser = NULL; | |
291 | 1 | g_autoptr (JsonBuilder) builder = NULL; | |
292 | 1 | g_autoptr (JsonNode) node = NULL; | |
293 | 1 | g_autofree char *json = NULL; | |
294 | 1 | GBytes *body = NULL; | |
295 | |||
296 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
297 | ✗ | return NULL; | |
298 | |||
299 | 1 | url = g_strconcat (MSG_API_ENDPOINT, "/me/messages", NULL); | |
300 | 1 | soup_message = msg_service_build_message (MSG_SERVICE (self), "POST", url, NULL, FALSE); | |
301 | |||
302 | 1 | builder = json_builder_new (); | |
303 | 1 | json_builder_begin_object (builder); | |
304 | 1 | json_builder_set_member_name (builder, "subject"); | |
305 | 1 | json_builder_add_string_value (builder, msg_message_get_subject (message)); | |
306 | |||
307 | 1 | json_builder_set_member_name (builder, "body"); | |
308 | 1 | json_builder_begin_object (builder); | |
309 | 1 | json_builder_set_member_name (builder, "content"); | |
310 | 1 | json_builder_add_string_value (builder, msg_message_get_body_preview (message)); | |
311 | 1 | json_builder_end_object (builder); | |
312 | 1 | json_builder_end_object (builder); | |
313 | 1 | node = json_builder_get_root (builder); | |
314 | 1 | json = json_to_string (node, TRUE); | |
315 | |||
316 | 1 | body = g_bytes_new (json, strlen (json)); | |
317 | 1 | soup_message_set_request_body_from_bytes (soup_message, "application/json", body); | |
318 | |||
319 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), soup_message, &root_object, cancellable, error); | |
320 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
321 | ✗ | return NULL; | |
322 | |||
323 | 1 | return msg_message_new_from_json (root_object, error); | |
324 | } | ||
325 |