comparison pui-get-updates.c @ 0:6884bb8130ca

Initial revision
author Guido Berhoerster <guido+pui@berhoerster.name>
date Sun, 20 May 2018 11:32:57 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:6884bb8130ca
1 /*
2 * Copyright (C) 2018 Guido Berhoerster <guido+pui@berhoerster.name>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "pui-get-updates.h"
25
26 typedef struct {
27 PkControl *pk_control;
28 PkTask *pk_task;
29 guint refresh_interval;
30 } PuiGetUpdates;
31
32 GQuark
33 pui_get_updates_error_quark(void)
34 {
35 return (g_quark_from_static_string("pui-get-updates-error-quark"));
36 }
37
38 static void
39 on_get_updates_finished(GObject *source_object, GAsyncResult *async_result,
40 gpointer user_data)
41 {
42 GTask *task = user_data;
43 PuiGetUpdates *get_updates;
44 PkResults *results = NULL;
45 PkError *pk_error = NULL;
46 GError *error = NULL;
47 gint error_code;
48 GPtrArray *package_list;
49
50 get_updates = g_task_get_task_data(task);
51
52 g_debug("get updates transaction finished");
53 results = pk_client_generic_finish(PK_CLIENT(get_updates->pk_task),
54 async_result, &error);
55 if (results == NULL) {
56 /* pass the error on */
57 g_task_return_error(task, error);
58 goto out;
59 }
60
61 pk_error = pk_results_get_error_code(results);
62 if (pk_error != NULL) {
63 /* transaction failed, return error */
64 g_debug("failed to refresh the cache: %s",
65 pk_error_get_details(pk_error));
66 if (pk_error_get_code(pk_error) ==
67 PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
68 error_code = PUI_GET_UPDATES_ERROR_CANCELLED;
69 } else {
70 error_code =
71 PUI_GET_UPDATES_ERROR_GET_UPDATES_FAILED;
72 }
73 error = g_error_new(PUI_GET_UPDATES_ERROR, error_code,
74 "Failed to get package updates: %s",
75 pk_error_get_details(pk_error));
76 g_task_return_error(task, error);
77 g_object_unref(pk_error);
78 goto out;
79 }
80
81 /* return results */
82 package_list = pk_results_get_package_array(results);
83 g_assert(package_list != NULL);
84 g_task_return_pointer(task, package_list,
85 (GDestroyNotify)g_ptr_array_unref);
86
87 out:
88 if (results != NULL) {
89 g_object_unref(results);
90 }
91 g_object_unref(task);
92 }
93
94 static void
95 on_refresh_cache_finished(GObject *source_object, GAsyncResult *async_result,
96 gpointer user_data)
97 {
98 GTask *task = user_data;
99 PuiGetUpdates *get_updates;
100 PkResults *results = NULL;
101 PkClient *pk_client;
102 GError *error = NULL;
103 PkError *pk_error = NULL;
104 gint error_code;
105
106 get_updates = g_task_get_task_data(task);
107 pk_client = PK_CLIENT(get_updates->pk_task);
108
109 g_debug("refresh cache transaction finished");
110 results = pk_client_generic_finish(pk_client, async_result, &error);
111 if (results == NULL) {
112 g_task_return_error(task, error);
113 goto out;
114 }
115
116 pk_error = pk_results_get_error_code(results);
117 if (pk_error != NULL) {
118 /* transaction failed, return error */
119 g_debug("failed to refresh the cache: %s",
120 pk_error_get_details(pk_error));
121 if (pk_error_get_code(pk_error) ==
122 PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
123 error_code = PUI_GET_UPDATES_ERROR_CANCELLED;
124 } else {
125 error_code = PUI_GET_UPDATES_ERROR_REFRESH_FAILED;
126 }
127 error = g_error_new(PUI_GET_UPDATES_ERROR, error_code,
128 "Failed to refresh the cache: %s",
129 pk_error_get_details(pk_error));
130 g_task_return_error(task, error);
131 g_object_unref(pk_error);
132 goto out;
133 }
134
135 /* cache is up to date, get updates */
136 pk_client_get_updates_async(pk_client,
137 pk_bitfield_value(PK_FILTER_ENUM_NONE),
138 g_task_get_cancellable(task), NULL, NULL, on_get_updates_finished,
139 task);
140
141 out:
142 if (results != NULL) {
143 g_object_unref(results);
144 }
145 }
146
147 static void
148 on_get_time_since_refresh_finished(GObject *source_object,
149 GAsyncResult *async_result, gpointer user_data)
150 {
151 GTask *task = user_data;
152 PuiGetUpdates *get_updates;
153 guint last_refresh;
154 GError *error = NULL;
155 PkClient *pk_client;
156
157 get_updates = g_task_get_task_data(task);
158 pk_client = PK_CLIENT(get_updates->pk_task);
159
160 last_refresh =
161 pk_control_get_time_since_action_finish(get_updates->pk_control,
162 async_result, &error);
163 if (last_refresh == 0) {
164 g_task_return_error(task, error);
165 g_object_unref(task);
166 return;
167 }
168 g_debug("time since last cache refresh: %us", last_refresh);
169
170 if (last_refresh > get_updates->refresh_interval) {
171 /* cache is out of date, refresh first */
172 g_debug("refreshing the cache");
173 pk_client_refresh_cache_async(pk_client, FALSE,
174 g_task_get_cancellable(task), NULL, NULL,
175 on_refresh_cache_finished, task);
176 } else {
177 /* cache is up to date, get updates */
178 g_debug("getting updates");
179 pk_client_get_updates_async(pk_client,
180 pk_bitfield_value(PK_FILTER_ENUM_NONE),
181 g_task_get_cancellable(task), NULL, NULL,
182 on_get_updates_finished, task);
183 }
184 }
185
186 static void
187 pui_get_updates_free(gpointer data)
188 {
189 PuiGetUpdates *get_updates = data;
190
191 g_object_unref(get_updates->pk_control);
192 g_object_unref(get_updates->pk_task);
193 g_slice_free(PuiGetUpdates, data);
194 }
195
196 void
197 pui_get_updates_async(PkControl *pk_control, guint refresh_interval,
198 GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
199 {
200 PuiGetUpdates *get_updates;
201 GTask *task;
202 PkClient *pk_client;
203
204 get_updates = g_slice_new0(PuiGetUpdates);
205 get_updates->pk_control = g_object_ref(pk_control);
206 get_updates->pk_task = pk_task_new();
207 get_updates->refresh_interval = refresh_interval;
208
209 pk_client = PK_CLIENT(get_updates->pk_task);
210 pk_client_set_cache_age(pk_client, refresh_interval);
211 pk_client_set_background(pk_client, TRUE);
212
213 task = g_task_new(NULL, cancellable, callback, user_data);
214 g_task_set_task_data(task, get_updates, pui_get_updates_free);
215
216 /* check whether to refresh the cache before checking for updates */
217 g_debug("getting the time since the cache was last refreshed");
218 pk_control_get_time_since_action_async(pk_control,
219 PK_ROLE_ENUM_REFRESH_CACHE, cancellable,
220 on_get_time_since_refresh_finished, task);
221 }
222
223 GPtrArray *
224 pui_get_updates_finish(GAsyncResult *result, GError **errorp)
225 {
226 return (g_task_propagate_pointer(G_TASK(result), errorp));
227 }