Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-ebook-adapter"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <libedataserver/libedataserver.h>
10 : : #include <libtracker-sparql/tracker-sparql.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-ebook-adapter.h"
14 : : #include "valent-ebook-store.h"
15 : :
16 : :
17 : : struct _ValentEBookAdapter
18 : : {
19 : : ValentContactsAdapter parent_instance;
20 : :
21 : : ESourceRegistry *registry;
22 : : GHashTable *stores;
23 : : };
24 : :
25 : : static void g_async_initable_iface_init (GAsyncInitableIface *iface);
26 : :
27 : 0 : G_DEFINE_FINAL_TYPE_WITH_CODE (ValentEBookAdapter, valent_ebook_adapter, VALENT_TYPE_CONTACTS_ADAPTER,
28 : : G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, g_async_initable_iface_init))
29 : :
30 : : static void
31 : 0 : g_async_initable_new_async_cb (GAsyncInitable *initable,
32 : : GAsyncResult *result,
33 : : ValentEBookAdapter *self)
34 : : {
35 : 0 : g_autoptr (ESource) source = NULL;
36 : 0 : g_autoptr (GObject) object = NULL;
37 : 0 : g_autoptr (GError) error = NULL;
38 : :
39 : 0 : object = g_async_initable_new_finish (initable, result, &error);
40 : 0 : if (object == NULL)
41 : : {
42 : 0 : if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
43 : 0 : g_warning ("%s(): %s", G_STRFUNC, error->message);
44 : :
45 : 0 : return;
46 : : }
47 : :
48 : 0 : g_object_get (object, "source", &source, NULL);
49 : 0 : g_hash_table_replace (self->stores,
50 : : g_steal_pointer (&source),
51 : : g_steal_pointer (&object));
52 : : }
53 : :
54 : : static void
55 : 0 : on_source_added (ESourceRegistry *registry,
56 : : ESource *source,
57 : : ValentEBookAdapter *self)
58 : : {
59 : 0 : g_autoptr (TrackerSparqlConnection) connection = NULL;
60 : 0 : g_autoptr (GCancellable) destroy = NULL;
61 : :
62 : 0 : g_assert (E_IS_SOURCE_REGISTRY (registry));
63 : 0 : g_assert (E_IS_SOURCE (source));
64 : 0 : g_assert (VALENT_IS_EBOOK_ADAPTER (self));
65 : :
66 : 0 : if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
67 : 0 : return;
68 : :
69 : 0 : g_object_get (self,
70 : : "cancellable", &destroy,
71 : : "connection", &connection,
72 : : NULL);
73 : 0 : g_async_initable_new_async (VALENT_TYPE_EBOOK_STORE,
74 : : G_PRIORITY_DEFAULT,
75 : : destroy,
76 : : (GAsyncReadyCallback)g_async_initable_new_async_cb,
77 : : self,
78 : : "connection", connection,
79 : : "parent", self,
80 : : "source", source,
81 : : NULL);
82 : : }
83 : :
84 : : static void
85 : 0 : on_source_removed (ESourceRegistry *registry,
86 : : ESource *source,
87 : : ValentEBookAdapter *self)
88 : : {
89 : 0 : g_assert (E_IS_SOURCE_REGISTRY (registry));
90 : 0 : g_assert (E_IS_SOURCE (source));
91 : 0 : g_assert (VALENT_IS_EBOOK_ADAPTER (self));
92 : :
93 : 0 : if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
94 : : return;
95 : :
96 : 0 : if (!g_hash_table_remove (self->stores, source))
97 : : {
98 : 0 : g_warning ("Source \"%s\" not found in \"%s\"",
99 : : e_source_get_display_name (source),
100 : : G_OBJECT_TYPE_NAME (self));
101 : : }
102 : : }
103 : :
104 : : /*
105 : : * GAsyncInitable
106 : : */
107 : : static void
108 : 0 : e_source_registry_new_cb (GObject *object,
109 : : GAsyncResult *result,
110 : : gpointer user_data)
111 : : {
112 : 0 : g_autoptr (GTask) task = G_TASK (g_steal_pointer (&user_data));
113 : 0 : ValentEBookAdapter *self = g_task_get_source_object (task);
114 : 0 : g_autolist (ESource) sources = NULL;
115 : 0 : g_autoptr (GError) error = NULL;
116 : :
117 : 0 : g_assert (VALENT_IS_EBOOK_ADAPTER (self));
118 : :
119 : 0 : self->registry = e_source_registry_new_finish (result, &error);
120 : 0 : if (self->registry == NULL)
121 : : {
122 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
123 : : VALENT_PLUGIN_STATE_ERROR,
124 : : error);
125 : 0 : g_task_return_error (task, g_steal_pointer (&error));
126 : 0 : return;
127 : : }
128 : :
129 : : /* Load existing address books */
130 : 0 : sources = e_source_registry_list_sources (self->registry,
131 : : E_SOURCE_EXTENSION_ADDRESS_BOOK);
132 : :
133 : 0 : for (const GList *iter = sources; iter; iter = iter->next)
134 : 0 : on_source_added (self->registry, E_SOURCE (iter->data), self);
135 : :
136 : 0 : g_signal_connect_object (self->registry,
137 : : "source-added",
138 : : G_CALLBACK (on_source_added),
139 : : self,
140 : : G_CONNECT_DEFAULT);
141 : 0 : g_signal_connect_object (self->registry,
142 : : "source-removed",
143 : : G_CALLBACK (on_source_removed),
144 : : self,
145 : : G_CONNECT_DEFAULT);
146 : :
147 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
148 : : VALENT_PLUGIN_STATE_ACTIVE,
149 : : NULL);
150 : 0 : g_task_return_boolean (task, TRUE);
151 : : }
152 : :
153 : : static void
154 : 0 : valent_ebook_adapter_init_async (GAsyncInitable *initable,
155 : : int io_priority,
156 : : GCancellable *cancellable,
157 : : GAsyncReadyCallback callback,
158 : : gpointer user_data)
159 : : {
160 : 0 : g_autoptr (GTask) task = NULL;
161 : :
162 : 0 : g_assert (VALENT_IS_EBOOK_ADAPTER (initable));
163 : 0 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
164 : :
165 : 0 : task = g_task_new (initable, cancellable, callback, user_data);
166 : 0 : g_task_set_priority (task, io_priority);
167 : 0 : g_task_set_source_tag (task, valent_ebook_adapter_init_async);
168 : :
169 : 0 : e_source_registry_new (cancellable,
170 : : e_source_registry_new_cb,
171 : : g_steal_pointer (&task));
172 : 0 : }
173 : :
174 : : static void
175 : 0 : g_async_initable_iface_init (GAsyncInitableIface *iface)
176 : : {
177 : 0 : iface->init_async = valent_ebook_adapter_init_async;
178 : 0 : }
179 : :
180 : : /*
181 : : * ValentObject
182 : : */
183 : : static void
184 : 0 : valent_ebook_adapter_destroy (ValentObject *object)
185 : : {
186 : 0 : ValentEBookAdapter *self = VALENT_EBOOK_ADAPTER (object);
187 : :
188 : 0 : g_clear_object (&self->registry);
189 : 0 : g_hash_table_remove_all (self->stores);
190 : :
191 : 0 : VALENT_OBJECT_CLASS (valent_ebook_adapter_parent_class)->destroy (object);
192 : 0 : }
193 : :
194 : : /*
195 : : * GObject
196 : : */
197 : : static void
198 : 0 : valent_ebook_adapter_finalize (GObject *object)
199 : : {
200 : 0 : ValentEBookAdapter *self = VALENT_EBOOK_ADAPTER (object);
201 : :
202 : 0 : g_clear_pointer (&self->stores, g_hash_table_unref);
203 : :
204 : 0 : G_OBJECT_CLASS (valent_ebook_adapter_parent_class)->finalize (object);
205 : 0 : }
206 : :
207 : : static void
208 : 0 : valent_ebook_adapter_class_init (ValentEBookAdapterClass *klass)
209 : : {
210 : 0 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
211 : 0 : ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
212 : :
213 : 0 : object_class->finalize = valent_ebook_adapter_finalize;
214 : :
215 : 0 : vobject_class->destroy = valent_ebook_adapter_destroy;
216 : : }
217 : :
218 : : static void
219 : 0 : valent_ebook_adapter_init (ValentEBookAdapter *self)
220 : : {
221 : 0 : self->stores = g_hash_table_new_full ((GHashFunc)e_source_hash,
222 : : (GEqualFunc)e_source_equal,
223 : : g_object_unref,
224 : : g_object_unref);
225 : 0 : }
226 : :
|