~ubuntu-branches/ubuntu/raring/almanah/raring-proposed

« back to all changes in this revision

Viewing changes to src/event-factories/f-spot.c

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2010-01-18 13:21:48 UTC
  • mfrom: (1.2.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100118132148-0miy3p9gvkuwnq2g
* New upstream release
* Remove gpgme_1.2_compat patch, included in upstream
* debian/watch: Update upstream tarballs url
* debian/control: 
  - Update homepage
  - Add libdbus-glib-1-dev to Build-Depends
* debian/copyright: 
  - Update source url
  - Update copyright years

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
/*
 
3
 * Almanah
 
4
 * Copyright (C) Philip Withnall 2009 <philip@tecnocode.co.uk>
 
5
 * 
 
6
 * Almanah is free software: you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation, either version 3 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * Almanah is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with Almanah.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <dbus/dbus-glib.h>
 
22
#include <stdlib.h>
 
23
 
 
24
#include "../main.h"
 
25
#include "../event.h"
 
26
#include "f-spot.h"
 
27
#include "../event-factory.h"
 
28
#include "../events/f-spot-photo.h"
 
29
 
 
30
static void almanah_f_spot_event_factory_dispose (GObject *object);
 
31
static void almanah_f_spot_event_factory_finalize (GObject *object);
 
32
static void query_events (AlmanahEventFactory *event_factory, GDate *date);
 
33
static GSList *get_events (AlmanahEventFactory *event_factory, GDate *date);
 
34
static void cancel_query (DBusGProxyCall *call, AlmanahFSpotEventFactory *self);
 
35
 
 
36
struct _AlmanahFSpotEventFactoryPrivate {
 
37
        DBusGConnection *connection;
 
38
        DBusGProxy *proxy;
 
39
        GSList *photos;
 
40
        GSList *current_queries;
 
41
};
 
42
 
 
43
G_DEFINE_TYPE (AlmanahFSpotEventFactory, almanah_f_spot_event_factory, ALMANAH_TYPE_EVENT_FACTORY)
 
44
#define ALMANAH_F_SPOT_EVENT_FACTORY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_F_SPOT_EVENT_FACTORY, AlmanahFSpotEventFactoryPrivate))
 
45
 
 
46
static void
 
47
almanah_f_spot_event_factory_class_init (AlmanahFSpotEventFactoryClass *klass)
 
48
{
 
49
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
50
        AlmanahEventFactoryClass *event_factory_class = ALMANAH_EVENT_FACTORY_CLASS (klass);
 
51
 
 
52
        g_type_class_add_private (klass, sizeof (AlmanahFSpotEventFactoryPrivate));
 
53
 
 
54
        gobject_class->dispose = almanah_f_spot_event_factory_dispose;
 
55
        gobject_class->finalize = almanah_f_spot_event_factory_finalize;
 
56
 
 
57
        event_factory_class->type_id = ALMANAH_EVENT_FACTORY_F_SPOT;
 
58
        event_factory_class->query_events = query_events;
 
59
        event_factory_class->get_events = get_events;
 
60
}
 
61
 
 
62
static void
 
63
almanah_f_spot_event_factory_init (AlmanahFSpotEventFactory *self)
 
64
{
 
65
        GError *error = NULL;
 
66
 
 
67
        self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_F_SPOT_EVENT_FACTORY, AlmanahFSpotEventFactoryPrivate);
 
68
 
 
69
        self->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 
70
        if (self->priv->connection == NULL) {
 
71
                /* TODO: something neater than this */
 
72
                g_error ("Error connecting to D-Bus for F-Spot event factory: %s", error->message);
 
73
                g_error_free (error);
 
74
                exit (1);
 
75
        }
 
76
 
 
77
        /* Connect to the F-Spot D-Bus service */
 
78
        self->priv->proxy = dbus_g_proxy_new_for_name (self->priv->connection,
 
79
                                               "org.gnome.FSpot",
 
80
                                               "/org/gnome/FSpot/PhotoRemoteControl",
 
81
                                               "org.gnome.FSpot.PhotoRemoteControl");
 
82
}
 
83
 
 
84
static void
 
85
almanah_f_spot_event_factory_dispose (GObject *object)
 
86
{
 
87
        AlmanahFSpotEventFactoryPrivate *priv = ALMANAH_F_SPOT_EVENT_FACTORY_GET_PRIVATE (object);
 
88
 
 
89
        if (priv->proxy != NULL)
 
90
                g_object_unref (priv->proxy);
 
91
        priv->proxy = NULL;
 
92
 
 
93
        if (priv->connection != NULL)
 
94
                dbus_g_connection_unref (priv->connection);
 
95
        priv->connection = NULL;
 
96
 
 
97
        /* Chain up to the parent class */
 
98
        G_OBJECT_CLASS (almanah_f_spot_event_factory_parent_class)->dispose (object);
 
99
}
 
100
 
 
101
static void
 
102
almanah_f_spot_event_factory_finalize (GObject *object)
 
103
{
 
104
        AlmanahFSpotEventFactoryPrivate *priv = ALMANAH_F_SPOT_EVENT_FACTORY_GET_PRIVATE (object);
 
105
 
 
106
        g_slist_foreach (priv->current_queries, (GFunc) cancel_query, object);
 
107
        g_slist_free (priv->current_queries);
 
108
 
 
109
        g_slist_foreach (priv->photos, (GFunc) g_object_unref,  NULL);
 
110
        g_slist_free (priv->photos);
 
111
 
 
112
        /* Chain up to the parent class */
 
113
        G_OBJECT_CLASS (almanah_f_spot_event_factory_parent_class)->finalize (object);
 
114
}
 
115
 
 
116
static void
 
117
query_info_complete_cb (DBusGProxy *proxy, DBusGProxyCall *call, AlmanahFSpotEventFactory *self)
 
118
{
 
119
        AlmanahFSpotEventFactoryPrivate *priv = self->priv;
 
120
        GError *error = NULL;
 
121
        GHashTable *properties;
 
122
        GValue *uri, *name;
 
123
        AlmanahEvent *event;
 
124
 
 
125
        /* Remove the call from the list of current queries */
 
126
        priv->current_queries = g_slist_remove (priv->current_queries, call);
 
127
 
 
128
        if (dbus_g_proxy_end_call (proxy, call, &error,
 
129
                                   dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &properties,
 
130
                                   G_TYPE_INVALID) == FALSE) {
 
131
                g_error ("Error getting photo properties: %s", error->message);
 
132
                g_error_free (error);
 
133
                exit (1);
 
134
        }
 
135
 
 
136
        name = g_hash_table_lookup (properties, "Name");
 
137
        uri = g_hash_table_lookup (properties, "Uri");
 
138
 
 
139
        if (almanah->debug == TRUE)
 
140
                g_debug ("Received properties for F-Spot photo \"%s\".", g_value_get_string (name));
 
141
 
 
142
        /* Create a new AlmanahFSpotPhotoEvent for the photo and add it to the list */
 
143
        event = ALMANAH_EVENT (almanah_f_spot_photo_event_new (g_value_get_string (uri), g_value_get_string (name)));
 
144
        priv->photos = g_slist_prepend (priv->photos, event);
 
145
        g_signal_emit_by_name (self, "events-updated");
 
146
 
 
147
        g_hash_table_destroy (properties);
 
148
}
 
149
 
 
150
static void
 
151
query_events_complete_cb (DBusGProxy *proxy, DBusGProxyCall *call, AlmanahFSpotEventFactory *self)
 
152
{
 
153
        AlmanahFSpotEventFactoryPrivate *priv = self->priv;
 
154
        GError *error = NULL;
 
155
        GArray *id_array;
 
156
        guint i;
 
157
 
 
158
        /* Remove the call from the list of current queries */
 
159
        priv->current_queries = g_slist_remove (priv->current_queries, call);
 
160
 
 
161
        if (dbus_g_proxy_end_call (proxy, call, &error,
 
162
                                   DBUS_TYPE_G_UINT_ARRAY, &id_array,
 
163
                                   G_TYPE_INVALID) == FALSE) {
 
164
                /* Ignore errors about unknown services or methods; it means the F-Spot service isn't available or is out-of-date */
 
165
                if (g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) == TRUE ||
 
166
                    g_error_matches (error, DBUS_GERROR, DBUS_GERROR_UNKNOWN_METHOD) == TRUE)
 
167
                        return;
 
168
 
 
169
                g_error ("Error getting photo list from F-Spot: %s", error->message);
 
170
                g_error_free (error);
 
171
                exit (1);
 
172
        }
 
173
 
 
174
        if (almanah->debug == TRUE)
 
175
                g_debug ("Received list of photos from F-Spot.");
 
176
 
 
177
        /* Now query for the photo information */
 
178
        for (i = 0; i < id_array->len; i++) {
 
179
                DBusGProxyCall *sub_call;
 
180
                guint photo_id;
 
181
 
 
182
                photo_id = g_array_index (id_array, guint, i);
 
183
                sub_call = dbus_g_proxy_begin_call (priv->proxy, "GetPhotoProperties", 
 
184
                                                    (DBusGProxyCallNotify) query_info_complete_cb, g_object_ref (self), g_object_unref,
 
185
                                                    G_TYPE_UINT, photo_id,
 
186
                                                    G_TYPE_INVALID);
 
187
                priv->current_queries = g_slist_prepend (priv->current_queries, sub_call);
 
188
        }
 
189
        g_array_free (id_array, TRUE);
 
190
}
 
191
 
 
192
static inline gint64
 
193
date_to_int64 (GDate *date)
 
194
{
 
195
        struct tm localtime_tm = { 0, };
 
196
 
 
197
        localtime_tm.tm_mday = g_date_get_day (date);
 
198
        localtime_tm.tm_mon = g_date_get_month (date) - 1;
 
199
        localtime_tm.tm_year = g_date_get_year (date) - 1900;
 
200
        localtime_tm.tm_isdst = -1;
 
201
 
 
202
        return mktime (&localtime_tm);
 
203
}
 
204
 
 
205
static void
 
206
cancel_query (DBusGProxyCall *call, AlmanahFSpotEventFactory *self)
 
207
{
 
208
        dbus_g_proxy_cancel_call (self->priv->proxy, call);
 
209
}
 
210
 
 
211
static void
 
212
query_events (AlmanahEventFactory *event_factory, GDate *date)
 
213
{
 
214
        DBusGProxyCall *call;
 
215
        GDate next_date;
 
216
        AlmanahFSpotEventFactoryPrivate *priv = ALMANAH_F_SPOT_EVENT_FACTORY (event_factory)->priv;
 
217
 
 
218
        /* Cancel all current queries */
 
219
        g_slist_foreach (priv->current_queries, (GFunc) cancel_query, event_factory);
 
220
        g_slist_free (priv->current_queries);
 
221
        priv->current_queries = NULL;
 
222
 
 
223
        /* Create a new list of photos for the new query */
 
224
        g_slist_foreach (priv->photos, (GFunc) g_object_unref, NULL);
 
225
        g_slist_free (priv->photos);
 
226
        priv->photos = NULL;
 
227
 
 
228
        /* Sort out the dates */
 
229
        next_date = *date;
 
230
        g_date_add_days (&next_date, 1);
 
231
 
 
232
        /* Execute the D-Bus query */
 
233
        call = dbus_g_proxy_begin_call (priv->proxy, "QueryByDate",
 
234
                                        (DBusGProxyCallNotify) query_events_complete_cb, g_object_ref (event_factory), g_object_unref,
 
235
                                        G_TYPE_INT64, date_to_int64 (date),
 
236
                                        G_TYPE_INT64, date_to_int64 (&next_date),
 
237
                                        G_TYPE_INVALID);
 
238
 
 
239
        /* Append the query to the list of current queries, so that it can be cancelled in future if we find
 
240
         * we need to query for events for a different date. */
 
241
        priv->current_queries = g_slist_prepend (priv->current_queries, call);
 
242
}
 
243
 
 
244
static GSList *
 
245
get_events (AlmanahEventFactory *event_factory, GDate *date)
 
246
{
 
247
        GSList *photos = ALMANAH_F_SPOT_EVENT_FACTORY (event_factory)->priv->photos;
 
248
        g_slist_foreach (photos, (GFunc) g_object_ref, NULL);
 
249
        return g_slist_copy (photos);
 
250
}