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 "msg-authorizer.h" | ||
21 | #include "msg-error.h" | ||
22 | #include "msg-input-stream.h" | ||
23 | #include "msg-private.h" | ||
24 | #include "msg-service.h" | ||
25 | #include "drive/msg-drive.h" | ||
26 | #include "drive/msg-drive-item.h" | ||
27 | #include "drive/msg-drive-item-file.h" | ||
28 | #include "drive/msg-drive-service.h" | ||
29 | |||
30 | struct _MsgDriveService { | ||
31 | MsgService parent_instance; | ||
32 | }; | ||
33 | |||
34 |
6/7✓ Branch 0 taken 3 times.
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 66 times.
|
150 | G_DEFINE_TYPE (MsgDriveService, msg_drive_service, MSG_TYPE_SERVICE); |
35 | |||
36 | static void | ||
37 | 2 | msg_drive_service_init (__attribute__ ((unused)) MsgDriveService *self) | |
38 | { | ||
39 | 2 | } | |
40 | |||
41 | static void | ||
42 | 3 | msg_drive_service_class_init (__attribute__ ((unused)) MsgDriveServiceClass *class) | |
43 | { | ||
44 | 3 | } | |
45 | |||
46 | /** | ||
47 | * msg_drive_service_new: | ||
48 | * @authorizer: A authorizer | ||
49 | * | ||
50 | * Creates a new `MsgDriveService` using #MsgAuthorizer. | ||
51 | * | ||
52 | * Returns: the newly created `MsgDriveService` | ||
53 | */ | ||
54 | MsgDriveService * | ||
55 | 2 | msg_drive_service_new (MsgAuthorizer *authorizer) | |
56 | { | ||
57 | 2 | return g_object_new (MSG_TYPE_DRIVE_SERVICE, "authorizer", authorizer, NULL); | |
58 | } | ||
59 | |||
60 | /** | ||
61 | * msg_drive_service_get_drives: | ||
62 | * @self: a #MsgDriveService | ||
63 | * @cancellable: a #GCancellable | ||
64 | * @error: a #GError | ||
65 | * | ||
66 | * Queries the Microsoft Graph API for all the drives of the currently logged in user | ||
67 | * | ||
68 | * Returns: (element-type MsgDrive) (transfer full): all drives the user can access | ||
69 | */ | ||
70 | GList * | ||
71 | 10 | msg_drive_service_get_drives (MsgDriveService *self, | |
72 | GCancellable *cancellable, | ||
73 | GError **error) | ||
74 | { | ||
75 | 10 | g_autofree char *url = NULL; | |
76 | 10 | JsonObject *root_object = NULL; | |
77 | 10 | JsonArray *array = NULL; | |
78 | 10 | guint array_length = 0, index = 0; | |
79 | 10 | g_autolist (MsgDrive) list = NULL; | |
80 | 10 | g_autoptr (GBytes) response = NULL; | |
81 | 10 | g_autoptr (JsonParser) parser = NULL; | |
82 | |||
83 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
|
10 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
84 | ✗ | return NULL; | |
85 | |||
86 | 10 | url = g_strconcat (MSG_API_ENDPOINT, "/me/drives", NULL); | |
87 | |||
88 | do { | ||
89 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | g_autoptr (SoupMessage) message = NULL; |
90 | |||
91 | 10 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
92 | 10 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (!parser) |
94 | ✗ | return NULL; | |
95 | |||
96 | 10 | array = json_object_get_array_member (root_object, "value"); | |
97 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | g_assert (array != NULL); |
98 | |||
99 | 10 | array_length = json_array_get_length (array); | |
100 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
|
20 | for (index = 0; index < array_length; index++) { |
101 | 10 | MsgDrive *drive = NULL; | |
102 | 10 | JsonObject *drive_object = NULL; | |
103 | 10 | g_autoptr (GError) local_error = NULL; | |
104 | |||
105 | 10 | drive_object = json_array_get_object_element (array, index); | |
106 | 10 | drive = msg_drive_new_from_json (drive_object, &local_error); | |
107 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | if (drive) { |
108 | 10 | list = g_list_append (list, drive); | |
109 | } else { | ||
110 | ✗ | g_warning ("Could not parse drive object: %s", local_error->message); | |
111 | } | ||
112 | } | ||
113 | |||
114 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | g_clear_pointer (&url, g_free); |
115 | 10 | url = msg_service_get_next_link (root_object); | |
116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | } while (url != NULL); |
117 | |||
118 | 10 | return g_steal_pointer (&list); | |
119 | } | ||
120 | |||
121 | /** | ||
122 | * msg_drive_service_get_root: | ||
123 | * @self: a #MsgDriveService | ||
124 | * @drive: a #MsgDrive | ||
125 | * @cancellable: a #GCancellable | ||
126 | * @error: a #GError | ||
127 | * | ||
128 | * Get root item of selected drive | ||
129 | * | ||
130 | * Returns: (transfer full): root 'MsgDriveItem' | ||
131 | */ | ||
132 | MsgDriveItem * | ||
133 | 9 | msg_drive_service_get_root (MsgDriveService *self, | |
134 | MsgDrive *drive, | ||
135 | GCancellable *cancellable, | ||
136 | GError **error) | ||
137 | { | ||
138 | 9 | g_autofree char *url = NULL; | |
139 | 9 | g_autoptr (SoupMessage) message = NULL; | |
140 | 9 | JsonObject *root_object = NULL; | |
141 | 9 | g_autoptr (GBytes) response = NULL; | |
142 | 9 | g_autoptr (JsonParser) parser = NULL; | |
143 | |||
144 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
|
9 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
145 | ✗ | return NULL; | |
146 | |||
147 | 9 | url = g_strconcat (MSG_API_ENDPOINT, "/drives/", msg_drive_get_id (drive), "/root", NULL); | |
148 | 9 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
149 | 9 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (!parser) |
151 | ✗ | return NULL; | |
152 | |||
153 | 9 | return msg_drive_item_new_from_json (root_object, error); | |
154 | } | ||
155 | |||
156 | /** | ||
157 | * msg_drive_service_download_item: | ||
158 | * @self: a #MsgDriveService | ||
159 | * @item: a #MsgDriveItem | ||
160 | * @cancellable: a #GCancellable | ||
161 | * @error: a #GError | ||
162 | * | ||
163 | * Download item | ||
164 | * | ||
165 | * Returns: (transfer full): input stream of drive item | ||
166 | */ | ||
167 | GInputStream * | ||
168 | 2 | msg_drive_service_download_item (MsgDriveService *self, | |
169 | MsgDriveItem *item, | ||
170 | GCancellable *cancellable, | ||
171 | GError **error) | ||
172 | { | ||
173 | 2 | g_autofree char *url = NULL; | |
174 | |||
175 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!MSG_IS_DRIVE_ITEM_FILE (item)) { |
176 | ✗ | g_warning ("Download only allowed for files"); | |
177 | ✗ | return NULL; | |
178 | } | ||
179 | |||
180 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
181 | ✗ | return NULL; | |
182 | |||
183 | 2 | url = g_strconcat (MSG_API_ENDPOINT, | |
184 | "/drives/", | ||
185 | msg_drive_item_get_drive_id (item), | ||
186 | "/items/", | ||
187 | msg_drive_item_get_id (item), | ||
188 | "/content", | ||
189 | NULL); | ||
190 | |||
191 | 2 | return msg_input_stream_new (MSG_SERVICE (self), url); | |
192 | } | ||
193 | |||
194 | /** | ||
195 | * msg_drive_service_list_children: | ||
196 | * @self: a #MsgDriveService | ||
197 | * @item: a #MsgDriveItem | ||
198 | * @cancellable: a #GCancellable | ||
199 | * @error: a #GError | ||
200 | * | ||
201 | * Get a list of all files in folder item | ||
202 | * | ||
203 | * Returns: (element-type MsgDriveItem) (transfer full): all items in folder | ||
204 | */ | ||
205 | GList * | ||
206 | 1 | msg_drive_service_list_children (MsgDriveService *self, | |
207 | MsgDriveItem *item, | ||
208 | GCancellable *cancellable, | ||
209 | GError **error) | ||
210 | { | ||
211 | 1 | g_autoptr (MsgDriveItem) child_item = NULL; | |
212 | 1 | g_autofree char *url = NULL; | |
213 | 1 | JsonObject *root_object = NULL; | |
214 | 1 | JsonArray *array = NULL; | |
215 | 1 | guint array_length = 0, index = 0; | |
216 | 1 | JsonObject *item_object = NULL; | |
217 | 1 | g_autolist (MsgDriveItem) children = NULL; | |
218 | 1 | g_autoptr (GBytes) response = NULL; | |
219 | 1 | g_autoptr (JsonParser) parser = NULL; | |
220 | |||
221 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
222 | ✗ | return NULL; | |
223 | |||
224 | 1 | url = g_strconcat (MSG_API_ENDPOINT, | |
225 | "/drives/", | ||
226 | msg_drive_item_get_drive_id (item), | ||
227 | "/items/", | ||
228 | msg_drive_item_get_id (item), | ||
229 | "/children", | ||
230 | "?$expand=thumbnails", | ||
231 | NULL); | ||
232 | |||
233 | do { | ||
234 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | g_autoptr (SoupMessage) message = NULL; |
235 | |||
236 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL /*msg_drive_item_get_etag (item)*/, FALSE); | |
237 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
238 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
239 | ✗ | return NULL; | |
240 | |||
241 | 1 | array = json_object_get_array_member (root_object, "value"); | |
242 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert (array != NULL); |
243 | |||
244 | 1 | array_length = json_array_get_length (array); | |
245 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
|
7 | for (index = 0; index < array_length; index++) { |
246 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | g_autoptr (GError) local_error = NULL; |
247 | 6 | item_object = json_array_get_object_element (array, index); | |
248 | |||
249 | 6 | child_item = msg_drive_item_new_from_json (item_object, &local_error); | |
250 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (local_error) { |
251 | ✗ | g_warning ("Could not read child item: %s", local_error->message); | |
252 | ✗ | continue; | |
253 | } | ||
254 | |||
255 | 6 | children = g_list_prepend (children, g_steal_pointer (&child_item)); | |
256 | } | ||
257 | |||
258 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | g_clear_pointer (&url, g_free); |
259 | 1 | url = msg_service_get_next_link (root_object); | |
260 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } while (url != NULL); |
261 | |||
262 | 1 | return g_steal_pointer (&children); | |
263 | } | ||
264 | |||
265 | /** | ||
266 | * msg_drive_service_rename: | ||
267 | * @self: a #MsgDriveService | ||
268 | * @item: a #MsgDriveItem | ||
269 | * @new_name: new name of item | ||
270 | * @cancellable: a #GCancellable | ||
271 | * @error: a #GError | ||
272 | * | ||
273 | * Sets a new drive item name | ||
274 | * | ||
275 | * Returns: (transfer full): the renamed `MsgDriveItem` | ||
276 | */ | ||
277 | MsgDriveItem * | ||
278 | 1 | msg_drive_service_rename (MsgDriveService *self, | |
279 | MsgDriveItem *item, | ||
280 | const char *new_name, | ||
281 | GCancellable *cancellable, | ||
282 | GError **error) | ||
283 | { | ||
284 | 1 | g_autoptr (SoupMessage) message = NULL; | |
285 | 1 | g_autoptr (JsonBuilder) builder = NULL; | |
286 | 1 | g_autoptr (JsonNode) rename_node = NULL; | |
287 | 1 | g_autofree char *url = NULL; | |
288 | 1 | g_autofree char *json = NULL; | |
289 | 1 | JsonObject *root_object = NULL; | |
290 | 1 | g_autoptr (GBytes) response = NULL; | |
291 | 1 | GBytes *body = NULL; | |
292 | 1 | g_autoptr (JsonParser) parser = NULL; | |
293 | |||
294 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
295 | ✗ | return NULL; | |
296 | |||
297 | 1 | url = g_strconcat (MSG_API_ENDPOINT, | |
298 | "/drives/", | ||
299 | msg_drive_item_get_drive_id (item), | ||
300 | "/items/", | ||
301 | msg_drive_item_get_id (item), | ||
302 | NULL); | ||
303 | |||
304 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "PATCH", url, NULL, FALSE); | |
305 | |||
306 | 1 | builder = json_builder_new (); | |
307 | 1 | json_builder_begin_object (builder); | |
308 | 1 | json_builder_set_member_name (builder, "name"); | |
309 | 1 | json_builder_add_string_value (builder, new_name); | |
310 | 1 | json_builder_end_object (builder); | |
311 | 1 | rename_node = json_builder_get_root (builder); | |
312 | 1 | json = json_to_string (rename_node, TRUE); | |
313 | |||
314 | 1 | body = g_bytes_new (json, strlen (json)); | |
315 | 1 | soup_message_set_request_body_from_bytes (message, "application/json", body); | |
316 | |||
317 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
318 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
319 | ✗ | return NULL; | |
320 | |||
321 | 1 | return msg_drive_item_new_from_json (root_object, error); | |
322 | } | ||
323 | |||
324 | /** | ||
325 | * msg_drive_service_download_url: | ||
326 | * @self: a #MsgDriveService | ||
327 | * @url: url to download | ||
328 | * @cancellable: a #GCancellable | ||
329 | * @error: a #GError | ||
330 | * | ||
331 | * Download url | ||
332 | * | ||
333 | * Returns: (transfer full): a new `GInputStream` for url | ||
334 | */ | ||
335 | GInputStream * | ||
336 | 1 | msg_drive_service_download_url (MsgDriveService *self, | |
337 | const char *url, | ||
338 | GCancellable *cancellable, | ||
339 | GError **error) | ||
340 | { | ||
341 | 1 | SoupMessage *message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
342 | |||
343 | 1 | return msg_service_send (MSG_SERVICE (self), message, cancellable, error); | |
344 | } | ||
345 | |||
346 | /** | ||
347 | * msg_drive_service_create_folder: | ||
348 | * @self: a drive service | ||
349 | * @parent: parent drive item | ||
350 | * @name: name of new folder | ||
351 | * @cancellable: a cancellable | ||
352 | * @error: a error | ||
353 | * | ||
354 | * Creates a new folder called name under parent. | ||
355 | * | ||
356 | * Returns: (transfer full): a newly created `MsgDriveItem` | ||
357 | */ | ||
358 | MsgDriveItem * | ||
359 | 8 | msg_drive_service_create_folder (MsgDriveService *self, | |
360 | MsgDriveItem *parent, | ||
361 | const char *name, | ||
362 | GCancellable *cancellable, | ||
363 | GError **error) | ||
364 | { | ||
365 | 8 | g_autofree char *url = NULL; | |
366 | 8 | g_autoptr (SoupMessage) message = NULL; | |
367 | 8 | g_autofree char *json = NULL; | |
368 | 8 | g_autoptr (JsonBuilder) builder = NULL; | |
369 | 8 | g_autoptr (JsonNode) create_node = NULL; | |
370 | 8 | JsonObject *root_object = NULL; | |
371 | 8 | g_autoptr (GBytes) response = NULL; | |
372 | 8 | GBytes *body = NULL; | |
373 | 8 | g_autoptr (JsonParser) parser = NULL; | |
374 | |||
375 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
376 | ✗ | return NULL; | |
377 | |||
378 | 8 | url = g_strconcat (MSG_API_ENDPOINT, | |
379 | "/drives/", | ||
380 | msg_drive_item_get_drive_id (parent), | ||
381 | "/items/", | ||
382 | msg_drive_item_get_id (parent), | ||
383 | "/children", | ||
384 | NULL); | ||
385 | |||
386 | 8 | message = msg_service_build_message (MSG_SERVICE (self), "POST", url, NULL, FALSE); | |
387 | |||
388 | 8 | builder = json_builder_new (); | |
389 | 8 | json_builder_begin_object (builder); | |
390 | 8 | json_builder_set_member_name (builder, "name"); | |
391 | 8 | json_builder_add_string_value (builder, name); | |
392 | 8 | json_builder_set_member_name (builder, "@microsoft.graph.conflictBehavior"); | |
393 | 8 | json_builder_add_string_value (builder, "rename"); | |
394 | 8 | json_builder_set_member_name (builder, "folder"); | |
395 | 8 | json_builder_begin_object (builder); | |
396 | 8 | json_builder_end_object (builder); | |
397 | 8 | json_builder_end_object (builder); | |
398 | 8 | create_node = json_builder_get_root (builder); | |
399 | 8 | json = json_to_string (create_node, TRUE); | |
400 | |||
401 | 8 | body = g_bytes_new (json, strlen (json)); | |
402 | 8 | soup_message_set_request_body_from_bytes (message, "application/json", body); | |
403 | |||
404 | 8 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
405 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!parser) |
406 | ✗ | return NULL; | |
407 | |||
408 | 8 | return msg_drive_item_new_from_json (root_object, error); | |
409 | } | ||
410 | |||
411 | /** | ||
412 | * msg_drive_service_delete: | ||
413 | * @self: a drive service | ||
414 | * @item: a #MsgDriveItem | ||
415 | * @cancellable: a cancellable | ||
416 | * @error: a error | ||
417 | * | ||
418 | * Deletes item. | ||
419 | * | ||
420 | * Returns: %TRUE when item has been deleted, otherwise %FALSE | ||
421 | */ | ||
422 | gboolean | ||
423 | 11 | msg_drive_service_delete (MsgDriveService *self, | |
424 | MsgDriveItem *item, | ||
425 | GCancellable *cancellable, | ||
426 | GError **error) | ||
427 | { | ||
428 | 11 | g_autoptr (SoupMessage) message = NULL; | |
429 | 11 | g_autofree char *url = NULL; | |
430 | 11 | g_autoptr (GBytes) bytes = NULL; | |
431 | |||
432 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
11 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
433 | ✗ | return FALSE; | |
434 | |||
435 | 11 | url = g_strconcat (MSG_API_ENDPOINT, | |
436 | "/drives/", | ||
437 | msg_drive_item_get_drive_id (item), | ||
438 | "/items/", | ||
439 | msg_drive_item_get_id (item), | ||
440 | NULL); | ||
441 | |||
442 | 11 | message = msg_service_build_message (MSG_SERVICE (self), "DELETE", url, NULL, FALSE); | |
443 | |||
444 | 11 | bytes = msg_service_send_and_read (MSG_SERVICE (self), message, cancellable, error); | |
445 | 11 | return bytes != NULL; | |
446 | } | ||
447 | |||
448 | /** | ||
449 | * msg_drive_service_update: | ||
450 | * @self: a drive service | ||
451 | * @item: a drive item | ||
452 | * @cancellable: a cancellable | ||
453 | * @error: a error | ||
454 | * | ||
455 | * Creates an update stream for drive item in order to update it's content. | ||
456 | * | ||
457 | * Returns: (transfer full): an output stream | ||
458 | */ | ||
459 | GOutputStream * | ||
460 | 7 | msg_drive_service_update (MsgDriveService *self, | |
461 | MsgDriveItem *item, | ||
462 | GCancellable *cancellable, | ||
463 | GError **error) | ||
464 | { | ||
465 | 7 | GOutputStream *stream = NULL; | |
466 | 7 | g_autofree char *url = NULL; | |
467 | 7 | g_autoptr (JsonBuilder) builder = NULL; | |
468 | 7 | g_autoptr (JsonNode) create_node = NULL; | |
469 | 7 | g_autoptr (SoupMessage) message = NULL; | |
470 | 7 | JsonObject *root_object = NULL; | |
471 | 7 | g_autofree char *json = NULL; | |
472 | 7 | g_autoptr (GBytes) response = NULL; | |
473 | 7 | GBytes *body = NULL; | |
474 | const char *upload_url; | ||
475 | 7 | g_autoptr (JsonParser) parser = NULL; | |
476 | |||
477 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
7 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
478 | ✗ | return NULL; | |
479 | |||
480 | 7 | url = g_strconcat (MSG_API_ENDPOINT, | |
481 | "/drives/", | ||
482 | msg_drive_item_get_drive_id (item), | ||
483 | "/items/", | ||
484 | msg_drive_item_get_id (item), | ||
485 | "/createUploadSession", | ||
486 | NULL); | ||
487 | |||
488 | 7 | message = msg_service_build_message (MSG_SERVICE (self), "POST", url, NULL, FALSE); | |
489 | 7 | builder = json_builder_new (); | |
490 | 7 | json_builder_begin_object (builder); | |
491 | 7 | json_builder_set_member_name (builder, "@microsoft.graph.conflictBehavior"); | |
492 | 7 | json_builder_add_string_value (builder, "rename"); | |
493 | 7 | json_builder_end_object (builder); | |
494 | 7 | create_node = json_builder_get_root (builder); | |
495 | 7 | json = json_to_string (create_node, TRUE); | |
496 | |||
497 | 7 | body = g_bytes_new (json, strlen (json)); | |
498 | 7 | soup_message_set_request_body_from_bytes (message, "application/json", body); | |
499 | |||
500 | 7 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
501 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!parser) |
502 | ✗ | return NULL; | |
503 | |||
504 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
7 | if (!json_object_has_member (root_object, "uploadUrl")) { |
505 | ✗ | g_set_error (error, | |
506 | msg_error_quark (), | ||
507 | MSG_ERROR_FAILED, | ||
508 | "No uploadUrl found"); | ||
509 | ✗ | return NULL; | |
510 | } | ||
511 | |||
512 | 7 | upload_url = json_object_get_string_member (root_object, "uploadUrl"); | |
513 | |||
514 | 7 | stream = g_memory_output_stream_new (NULL, 0, g_try_realloc, g_free); | |
515 | 7 | g_object_set_data (G_OBJECT (stream), "ms-graph-upload-url", g_strdup (upload_url)); | |
516 | 7 | g_object_set_data (G_OBJECT (stream), "ms-graph-item", item); | |
517 | |||
518 | 7 | return stream; | |
519 | } | ||
520 | |||
521 | /** | ||
522 | * msg_drive_service_update_finish: | ||
523 | * @self: a #MsgDriveService | ||
524 | * @item: a #MsgDriveItem | ||
525 | * @stream: stream where data is store and needs to be transfered | ||
526 | * @cancellable: a #GCancellable | ||
527 | * @error: a #GError | ||
528 | * | ||
529 | * Finish a update session of given #item. | ||
530 | * | ||
531 | * Returns: (transfer full): a new #MsgDriveItem or %NULL on error. | ||
532 | */ | ||
533 | MsgDriveItem * | ||
534 | 7 | msg_drive_service_update_finish (MsgDriveService *self, | |
535 | MsgDriveItem *item, | ||
536 | GOutputStream *stream, | ||
537 | GCancellable *cancellable, | ||
538 | GError **error) | ||
539 | { | ||
540 | GBytes *bytes; | ||
541 | 7 | g_autofree char *url = NULL; | |
542 | 7 | SoupMessage *message = NULL; | |
543 | 7 | JsonObject *root_object = NULL; | |
544 | gconstpointer data; | ||
545 | gsize len; | ||
546 | 7 | g_autoptr (GBytes) response = NULL; | |
547 | 7 | GBytes *body = NULL; | |
548 | 7 | g_autoptr (JsonParser) parser = NULL; | |
549 | |||
550 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
7 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
551 | ✗ | return NULL; | |
552 | |||
553 | 7 | url = g_strconcat (MSG_API_ENDPOINT, | |
554 | "/drives/", | ||
555 | msg_drive_item_get_drive_id (item), | ||
556 | "/items/", | ||
557 | msg_drive_item_get_id (item), | ||
558 | "/content", | ||
559 | NULL); | ||
560 | |||
561 | 7 | g_output_stream_close (stream, NULL, NULL); | |
562 | 7 | bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (stream)); | |
563 | 7 | data = g_bytes_get_data (bytes, &len); | |
564 | |||
565 | 7 | message = msg_service_build_message (MSG_SERVICE (self), "PUT", url, NULL, FALSE); | |
566 | 7 | body = g_bytes_new (data, len); | |
567 | 7 | soup_message_set_request_body_from_bytes (message, "application/octet-stream", body); | |
568 | |||
569 | 7 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
570 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!parser) |
571 | ✗ | return NULL; | |
572 | |||
573 | 7 | return msg_drive_item_new_from_json (root_object, error); | |
574 | } | ||
575 | |||
576 | /** | ||
577 | * msg_drive_service_add_item_to_folder: | ||
578 | * @self: a msg drive service | ||
579 | * @parent: parent drive item | ||
580 | * @item: drive item to add | ||
581 | * @cancellable: a cancellable | ||
582 | * @error: a error | ||
583 | * | ||
584 | * Adds item to parent folder | ||
585 | * | ||
586 | * Returns: (transfer full): a new drive item | ||
587 | */ | ||
588 | MsgDriveItem * | ||
589 | 7 | msg_drive_service_add_item_to_folder (MsgDriveService *self, | |
590 | MsgDriveItem *parent, | ||
591 | MsgDriveItem *item, | ||
592 | GCancellable *cancellable, | ||
593 | GError **error) | ||
594 | { | ||
595 | 7 | g_autofree char *url = NULL; | |
596 | 7 | g_autoptr (SoupMessage) message = NULL; | |
597 | 7 | g_autofree char *escaped_name = NULL; | |
598 | 7 | JsonObject *root_object = NULL; | |
599 | 7 | g_autoptr (GBytes) response = NULL; | |
600 | 7 | GBytes *body = NULL; | |
601 | 7 | g_autoptr (JsonParser) parser = NULL; | |
602 | |||
603 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
7 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
604 | ✗ | return FALSE; | |
605 | |||
606 | 7 | escaped_name = g_uri_escape_string (msg_drive_item_get_name (item), NULL, TRUE); | |
607 | 7 | url = g_strconcat (MSG_API_ENDPOINT, | |
608 | "/drives/", | ||
609 | msg_drive_item_get_drive_id (parent), | ||
610 | "/items/", | ||
611 | msg_drive_item_get_id (parent), | ||
612 | ":/", | ||
613 | escaped_name, | ||
614 | ":/content", | ||
615 | NULL); | ||
616 | |||
617 | 7 | message = msg_service_build_message (MSG_SERVICE (self), "PUT", url, NULL, FALSE); | |
618 | 7 | body = g_bytes_new ("", 0); | |
619 | 7 | soup_message_set_request_body_from_bytes (message, "text/plain", body); | |
620 | |||
621 | 7 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
622 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!parser) |
623 | ✗ | return FALSE; | |
624 | |||
625 | 7 | return msg_drive_item_new_from_json (root_object, error); | |
626 | } | ||
627 | |||
628 | /** | ||
629 | * msg_drive_service_get_shared_with_me: | ||
630 | * @self: a #MsgDriveService | ||
631 | * @cancellable: a #GCancellable | ||
632 | * @error: a #GError | ||
633 | * | ||
634 | * Requests all shared with me items | ||
635 | * | ||
636 | * Returns: (element-type MsgDriveItem) (transfer full): shared with me list | ||
637 | */ | ||
638 | GList * | ||
639 | 1 | msg_drive_service_get_shared_with_me (MsgDriveService *self, | |
640 | GCancellable *cancellable, | ||
641 | GError **error) | ||
642 | { | ||
643 | 1 | g_autoptr (MsgDriveItem) child_item = NULL; | |
644 | 1 | g_autofree char *url = NULL; | |
645 | 1 | JsonObject *root_object = NULL; | |
646 | 1 | JsonArray *array = NULL; | |
647 | 1 | guint array_length = 0, index = 0; | |
648 | 1 | JsonObject *item_object = NULL; | |
649 | 1 | g_autolist (MsgDriveItem) children = NULL; | |
650 | 1 | g_autoptr (GBytes) response = NULL; | |
651 | 1 | g_autoptr (JsonParser) parser = NULL; | |
652 | |||
653 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error)) |
654 | ✗ | return NULL; | |
655 | |||
656 | 1 | url = g_strconcat (MSG_API_ENDPOINT, | |
657 | "/me/drive/sharedWithMe", | ||
658 | NULL); | ||
659 | do { | ||
660 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | g_autoptr (SoupMessage) message = NULL; |
661 | |||
662 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE); | |
663 | 1 | parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error); | |
664 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!parser) |
665 | ✗ | return NULL; | |
666 | |||
667 | 1 | array = json_object_get_array_member (root_object, "value"); | |
668 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert (array != NULL); |
669 | |||
670 | 1 | array_length = json_array_get_length (array); | |
671 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
|
5 | for (index = 0; index < array_length; index++) { |
672 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | g_autoptr (GError) local_error = NULL; |
673 | 4 | item_object = json_array_get_object_element (array, index); | |
674 | |||
675 | 4 | child_item = msg_drive_item_new_from_json (item_object, &local_error); | |
676 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (local_error) { |
677 | ✗ | g_warning ("Could not load shared with me item: %s", local_error->message); | |
678 | ✗ | continue; | |
679 | } | ||
680 | |||
681 | 4 | children = g_list_prepend (children, g_steal_pointer (&child_item)); | |
682 | } | ||
683 | |||
684 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | g_clear_pointer (&url, g_free); |
685 | 1 | url = msg_service_get_next_link (root_object); | |
686 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } while (url != NULL); |
687 | |||
688 | 1 | return g_steal_pointer (&children); | |
689 | } | ||
690 | |||
691 | /** | ||
692 | * msg_drive_service_copy_file: | ||
693 | * @self: #MsgDriveService | ||
694 | * @file: source #MsgDriveItem | ||
695 | * @destination: destination directory #MsgDriveItem | ||
696 | * @cancellable: a #GCancellable | ||
697 | * @error: a #GError | ||
698 | * | ||
699 | * Copy a file async on remote server to a new directory. | ||
700 | * | ||
701 | * Returns: %TRUE if accepted, %FALSE on error | ||
702 | */ | ||
703 | gboolean | ||
704 | 1 | msg_drive_service_copy_file (MsgDriveService *self, | |
705 | MsgDriveItem *file, | ||
706 | MsgDriveItem *destination, | ||
707 | GCancellable *cancellable, | ||
708 | GError **error) | ||
709 | { | ||
710 | 1 | g_autofree char *url = NULL; | |
711 | 1 | g_autoptr (SoupMessage) message = NULL; | |
712 | 1 | g_autofree char *json = NULL; | |
713 | 1 | g_autoptr (JsonBuilder) builder = NULL; | |
714 | 1 | g_autoptr (JsonNode) create_node = NULL; | |
715 | 1 | GError *local_error = NULL; | |
716 | 1 | g_autoptr (GBytes) response = NULL; | |
717 | 1 | GBytes *body = NULL; | |
718 | 1 | g_autoptr (JsonParser) parser = NULL; | |
719 | |||
720 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, &local_error)) { |
721 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
722 | ✗ | return FALSE; | |
723 | } | ||
724 | |||
725 | 1 | url = g_strconcat (MSG_API_ENDPOINT, | |
726 | "/drives/", | ||
727 | msg_drive_item_get_drive_id (file), | ||
728 | "/items/", | ||
729 | msg_drive_item_get_id (file), | ||
730 | "/copy", | ||
731 | NULL); | ||
732 | |||
733 | 1 | message = msg_service_build_message (MSG_SERVICE (self), "POST", url, NULL, FALSE); | |
734 | |||
735 | 1 | builder = json_builder_new (); | |
736 | 1 | json_builder_begin_object (builder); | |
737 | |||
738 | 1 | json_builder_set_member_name (builder, "parentReference"); | |
739 | 1 | json_builder_begin_object (builder); | |
740 | 1 | json_builder_set_member_name (builder, "driveId"); | |
741 | 1 | json_builder_add_string_value (builder, msg_drive_item_get_drive_id (destination)); | |
742 | 1 | json_builder_set_member_name (builder, "id"); | |
743 | 1 | json_builder_add_string_value (builder, msg_drive_item_get_id (destination)); | |
744 | 1 | json_builder_end_object (builder); | |
745 | |||
746 | 1 | json_builder_end_object (builder); | |
747 | 1 | create_node = json_builder_get_root (builder); | |
748 | 1 | json = json_to_string (create_node, TRUE); | |
749 | |||
750 | 1 | body = g_bytes_new (json, strlen (json)); | |
751 | 1 | soup_message_set_request_body_from_bytes (message, "application/json", body); | |
752 | |||
753 | 1 | response = msg_service_send_and_read (MSG_SERVICE (self), message, cancellable, &local_error); | |
754 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (local_error) { |
755 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
756 | ✗ | return FALSE; | |
757 | } | ||
758 | |||
759 | 1 | return TRUE; | |
760 | } | ||
761 | |||
762 | /** | ||
763 | * msg_drive_service_move_file: | ||
764 | * @self: #MsgDriveService | ||
765 | * @file: source #MsgDriveItem | ||
766 | * @destination: destination directory #MsgDriveItem | ||
767 | * @cancellable: a #GCancellable | ||
768 | * @error: a #GError | ||
769 | * | ||
770 | * Move a file async on remote server to a new directory. | ||
771 | * | ||
772 | * Returns: (transfer full): moved #MsgDriveItem | ||
773 | */ | ||
774 | MsgDriveItem * | ||
775 | ✗ | msg_drive_service_move_file (MsgDriveService *self, | |
776 | MsgDriveItem *file, | ||
777 | MsgDriveItem *destination, | ||
778 | GCancellable *cancellable, | ||
779 | GError **error) | ||
780 | { | ||
781 | ✗ | g_autofree char *url = NULL; | |
782 | ✗ | g_autoptr (SoupMessage) message = NULL; | |
783 | ✗ | g_autofree char *json = NULL; | |
784 | ✗ | g_autoptr (JsonBuilder) builder = NULL; | |
785 | ✗ | g_autoptr (JsonNode) create_node = NULL; | |
786 | ✗ | GError *local_error = NULL; | |
787 | ✗ | g_autoptr (GBytes) response = NULL; | |
788 | ✗ | GBytes *body = NULL; | |
789 | ✗ | g_autoptr (JsonParser) parser = NULL; | |
790 | ✗ | MsgDriveItem *item = NULL; | |
791 | ✗ | JsonObject *root_object = NULL; | |
792 | |||
793 | ✗ | if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, &local_error)) { | |
794 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
795 | ✗ | return NULL; | |
796 | } | ||
797 | |||
798 | ✗ | url = g_strconcat (MSG_API_ENDPOINT, | |
799 | "/drives/", | ||
800 | msg_drive_item_get_drive_id (file), | ||
801 | "/items/", | ||
802 | msg_drive_item_get_id (file), | ||
803 | NULL); | ||
804 | |||
805 | ✗ | message = msg_service_build_message (MSG_SERVICE (self), "PATCH", url, NULL, FALSE); | |
806 | |||
807 | ✗ | builder = json_builder_new (); | |
808 | ✗ | json_builder_begin_object (builder); | |
809 | |||
810 | ✗ | json_builder_set_member_name (builder, "parentReference"); | |
811 | ✗ | json_builder_begin_object (builder); | |
812 | ✗ | json_builder_set_member_name (builder, "id"); | |
813 | ✗ | json_builder_add_string_value (builder, msg_drive_item_get_id (destination)); | |
814 | ✗ | json_builder_end_object (builder); | |
815 | |||
816 | ✗ | json_builder_end_object (builder); | |
817 | ✗ | create_node = json_builder_get_root (builder); | |
818 | ✗ | json = json_to_string (create_node, TRUE); | |
819 | |||
820 | ✗ | body = g_bytes_new (json, strlen (json)); | |
821 | ✗ | soup_message_set_request_body_from_bytes (message, "application/json", body); | |
822 | |||
823 | ✗ | response = msg_service_send_and_read (MSG_SERVICE (self), message, cancellable, &local_error); | |
824 | ✗ | if (local_error) { | |
825 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
826 | ✗ | return NULL; | |
827 | } | ||
828 | |||
829 | ✗ | parser = msg_service_parse_response (response, &root_object, &local_error); | |
830 | ✗ | if (local_error != NULL) { | |
831 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
832 | ✗ | return NULL; | |
833 | } | ||
834 | |||
835 | ✗ | item = msg_drive_item_new_from_json (root_object, &local_error); | |
836 | ✗ | if (local_error) { | |
837 | ✗ | g_propagate_error (error, g_steal_pointer (&local_error)); | |
838 | ✗ | return FALSE; | |
839 | } | ||
840 | |||
841 | ✗ | return item; | |
842 | } | ||
843 |