gsoc

Sign in or create your account | Project List | Help

gsoc Commit Details

Date:2009-07-27 21:21:59 (1 year 1 day ago)
Author:Adrien Bustany
Commit:79828a99b6224cdbb64f22e60b25a1b332f40657
Message:Facebook bridge : autotoolize

Files: bridges/facebook/AUTHORS (1 diff)
bridges/facebook/COPYING (0 diffs)
bridges/facebook/ChangeLog (0 diffs)
bridges/facebook/INSTALL (0 diffs)
bridges/facebook/Makefile (1 diff)
bridges/facebook/Makefile.am (1 diff)
bridges/facebook/NEWS (0 diffs)
bridges/facebook/README (0 diffs)
bridges/facebook/autogen.sh (1 diff)
bridges/facebook/config.h (1 diff)
bridges/facebook/configure.ac (1 diff)
bridges/facebook/data/Makefile.am (1 diff)
bridges/facebook/data/facebook.desktop (1 diff)
bridges/facebook/facebook.desktop (1 diff)
bridges/facebook/facebook.vala (1 diff)
bridges/facebook/po/LINGUAS (0 diffs)
bridges/facebook/po/POTFILES.in (1 diff)
bridges/facebook/po/POTFILES.skip (1 diff)
bridges/facebook/src/Makefile.am (1 diff)
bridges/facebook/src/facebook.vala (1 diff)

Change Details

bridges/facebook/AUTHORS
1Adrien Bustany <madcat@mymadcat.com>
bridges/facebook/COPYING
bridges/facebook/ChangeLog
bridges/facebook/INSTALL
bridges/facebook/Makefile
1VALAC=valac
2
3VALAFLAGS=-v -g --thread --vapidir=. --vapidir=.. --pkg dbus-glib-1 --pkg rest --pkg gnome-keyring-1 --pkg tracker-bridge --pkg uuid -X --include=config.h -D DEBUG -X -I.. -X -L.. -X -ltracker-bridge
4
5.SUFFIXES:.vala
6
7SOURCES=facebook.vala
8TARGET=facebook_bridge
9
10$(TARGET) : $(SOURCES) Makefile
11    $(VALAC) $(VALAFLAGS) -o $(TARGET) $(SOURCES)
12
13C : $(SOURCES)
14    $(VALAC) $(VALAFLAGS) -C $(SOURCES)
bridges/facebook/Makefile.am
1SUBDIRS=src po data
2
3EXTRA_DIST= \
4    intltool-extract.in \
5    intltool-merge.in \
6    intltool-update.in
7
8DISTCLEANFILES= \
9    intltool-extract \
10    intltool-merge \
11    intltool-update
12
bridges/facebook/NEWS
bridges/facebook/README
bridges/facebook/autogen.sh
1#!/bin/sh
2# Run this to generate all the initial makefiles, etc.
3
4srcdir=`dirname $0`
5test -z "$srcdir" && srcdir=.
6
7PKG_NAME="tracker-bridge-facebook"
8
9. gnome-autogen.sh
bridges/facebook/config.h
1#define GETTEXT_PACKAGE "FacebookBridge"
2
bridges/facebook/configure.ac
1AC_INIT([tracker-bridge-facebook], [0.1.0], [http://bugzilla.gnome.org/enter_bug.cgi?product=tracker], [tracker-bridge-facebook])
2AC_CONFIG_SRCDIR([src/facebook.vala])
3AC_CONFIG_HEADERS(config.h)
4AM_INIT_AUTOMAKE([dist-bzip2])
5
6AC_SUBST(PACKAGE_URL, [http://www.tracker-project.org])
7
8AC_PROG_CC
9AM_PROG_CC_C_O
10AC_DISABLE_STATIC
11AC_PROG_LIBTOOL
12
13AC_PATH_PROG(VALAC, valac, valac)
14AC_SUBST(VALAC)
15
16AH_TEMPLATE([GETTEXT_PACKAGE], [Package name for gettext])
17GETTEXT_PACKAGE=tracker-bridge-facebook
18AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE")
19AC_SUBST(GETTEXT_PACKAGE)
20AM_GLIB_GNU_GETTEXT
21IT_PROG_INTLTOOL([0.35.0])
22AM_MAINTAINER_MODE
23
24AC_SUBST(CFLAGS)
25AC_SUBST(CPPFLAGS)
26AC_SUBST(LDFLAGS)
27
28GLIB_REQUIRED=2.12.0
29DBUS_REQUIRED=0.60
30TRACKERBRIDGE_REQUIRED=0.1
31GNOMEKEYRING_REQUIRED=2.26
32REST_REQUIRED=0.4
33UUID_REQUIRED=1.41
34
35PKG_CHECK_MODULES(GLIB2, glib-2.0 >= $GLIB_REQUIRED)
36AC_SUBST(GLIB2_CFLAGS)
37AC_SUBST(GLIB2_LIBS)
38
39PKG_CHECK_MODULES(GOBJECT, gobject-2.0 >= $GLIB_REQUIRED)
40AC_SUBST(GOBJECT_CFLAGS)
41AC_SUBST(GOBJECT_LIBS)
42
43PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= $GLIB_REQUIRED)
44AC_SUBST(GOBJECT_CFLAGS)
45AC_SUBST(GOBJECT_LIBS)
46
47PKG_CHECK_MODULES(DBUS, [dbus-1 >= $DBUS_REQUIRED dbus-glib-1 >= $DBUS_REQUIRED])
48AC_SUBST(DBUS_CFLAGS)
49AC_SUBST(DBUS_LIBS)
50
51PKG_CHECK_MODULES(TRACKERBRIDGE, tracker-bridge-0.1 >= $TRACKERBRIDGE_REQUIRED)
52AC_SUBST(TRACKERBRIDGE_CFLAGS)
53AC_SUBST(TRACKERBRIDGE_LIBS)
54
55PKG_CHECK_MODULES(GNOMEKEYRING, gnome-keyring-1 >= $GNOMEKEYRING_REQUIRED)
56AC_SUBST(GNOMEKEYRING_CFLAGS)
57AC_SUBST(GNOMEKEYRING_LIBS)
58
59PKG_CHECK_MODULES(REST, rest >= $REST_REQUIRED)
60AC_SUBST(REST_CFLAGS)
61AC_SUBST(REST_LIBS)
62
63PKG_CHECK_MODULES(UUID, uuid >= $UUID_REQUIRED)
64AC_SUBST(UUID_CFLAGS)
65AC_SUBST(UUID_LIBS)
66
67AC_CONFIG_FILES([Makefile
68    src/Makefile
69    data/Makefile
70    po/Makefile.in])
71
72AC_OUTPUT
bridges/facebook/data/Makefile.am
1desktopdir=$(datadir)/tracker/bridges
2desktop_DATA= \
3    facebook.desktop
bridges/facebook/data/facebook.desktop
1[Desktop Entry]
2Encoding=UTF-8
3Type=Service
4Name=Facebook
5Comment=Index your pictures on Facebook
6Icon=/usr/share/hplip/data/images/48x48/prog.png
7X-DBus-Name=org.freedesktop.Tracker.FacebookBridge
8X-DBus-Path=/org/freedesktop/Tracker/Bridge
9X-Tracker-Bridge-AuthScheme=Token
bridges/facebook/facebook.desktop
1[Desktop Entry]
2Encoding=UTF-8
3Type=Service
4Name=Facebook
5Comment=Index your pictures on Facebook
6Icon=/usr/share/hplip/data/images/48x48/prog.png
7X-DBus-Name=org.freedesktop.Tracker.FacebookBridge
8X-DBus-Path=/org/freedesktop/Tracker/Bridge
9X-Tracker-Bridge-AuthScheme=Token
bridges/facebook/facebook.vala
1using Tracker;
2using Rest;
3
4public class FacebookBridge : Object, Tracker.Bridge {
5    private const string SERVICE_NAME = "Facebook";
6    private const string API_KEY = "a07366931355e51525938ade2d0df2fb";
7    private const string SHARED_SECRET = "dd34c9d53460953bfd3b5aa87c09b538";
8    private const string TRACKER_NAME = "org.freedesktop.Tracker";
9    private const string TRACKER_RESOURCES_PATH = "/org/freedesktop/Tracker/Resources";
10    private const string TRACKER_RESOURCES_INTERFACE = "org.freedesktop.Tracker.Resources";
11    private const string FACEBOOK_REST = "https://api.facebook.com/restserver.php";
12
13    private DBus.Connection conn;
14    dynamic DBus.Object tracker;
15
16    private Proxy rest;
17    private string auth_token;
18    private string session = null;
19    private string secret = SHARED_SECRET;
20
21    private string username = null; // Is actually the numeric user ID
22
23    private uint bridge_status;
24
25    public FacebookBridge ()
26    {
27        rest = new Proxy (FACEBOOK_REST, false);
28
29        set_bridge_status (Bridge.Status.NotAuthenticated);
30
31        try {
32            conn = DBus.Bus.get (DBus.BusType.SESSION);
33        } catch (Error e) {
34            critical ("Cannot connect to session bus : %s\n", e.message);
35        }
36
37        tracker = conn.get_object (TRACKER_NAME, TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE);
38
39    }
40
41    // DBus signals callbacks
42    public HashTable<string, string> GetAssociationData ()
43    {
44        var ret = new HashTable<string, string> (str_hash, str_equal);
45        ProxyCall c = rest.new_call ();
46        c.add_param ("method", "auth.createToken");
47        XmlNode node = runCall (c);
48
49        if (node.name != "auth_createToken_response") {
50#if DEBUG
51            critical ("Got answer %s\n", c.get_payload ());
52            critical ("Couldn't get authentification token");
53#endif
54            Error (DBusErrorCode.AuthenticationError, "");
55            return ret;
56        }
57
58        auth_token = node.content;
59        string url = "http://www.facebook.com/login.php?api_key=%s&v=1.0&auth_token=%s".printf (API_KEY, auth_token);
60        ret.insert ("url", url);
61
62        ret.insert ("post_message", _("A last browser window will now open, which will allow you to grant Tracker permanent access to your Facebook account. You're not obliged to do so, but if you choose not to grant Tracker a permanent access, you'll need to login again every 24 hours."));
63        ret.insert ("post_url", "http://www.facebook.com/authorize.php?api_key=%s&v=1.0&ext_perm=offline_access".printf (API_KEY));
64        return ret;
65    }
66
67    // This supposes we have a valid auth_token. Else, well, it'll just fail...
68    public void FinishAssociation (HashTable<string, string> data)
69    {
70        ProxyCall c = rest.new_call ();
71        c.add_param ("method", "auth.getSession");
72        c.add_param ("auth_token", auth_token);
73
74        {
75            XmlNode node = runCall (c);
76
77            if (node.name != "auth_getSession_response") {
78#if DEBUG
79                critical ("Got answer %s\n", c.get_payload ());
80                critical ("Couldn't get session token");
81#endif
82                Error (DBusErrorCode.AuthenticationError, "");
83                return;
84            }
85
86            username = node.find ("uid").content;
87            secret = node.find ("secret").content;
88            session = node.find ("session_key").content;
89        }
90
91        var pwdData = new HashTable<string, string> (str_hash, str_equal);
92        pwdData.insert ("session", session);
93        Tracker.passwordProvider.save (username, SERVICE_NAME, secret, "Authentication token for Facebook", pwdData);
94
95        c = rest.new_call ();
96        c.add_params ("method", "users.getInfo",
97                      "uids", username,
98                      "fields", "last_name,first_name",
99                      null);
100        XmlNode node = runCall (c);
101
102        if (node.name != "users_getInfo_response") {
103#if DEBUG
104            critical ("Got answer %s\n", c.get_payload ());
105            critical ("Couldn't get user info");
106#endif
107            Error (DBusErrorCode.AuthenticationError, _("Couldn't get user information"));
108            return;
109        }
110
111        string realname = node.find ("first_name").content + " " + node.find ("last_name").content;
112
113        set_bridge_status (Bridge.Status.Authenticated, realname);
114    }
115
116    public void Authenticate ()
117    {
118        var pwdData = Tracker.passwordProvider.search (null, SERVICE_NAME);
119
120        if (pwdData != null) {
121            username = pwdData.lookup ("username");
122            session = pwdData.lookup ("session");
123            secret = pwdData.lookup ("secret");
124
125            ProxyCall c = rest.new_call ();
126            c.add_params ("method", "users.getInfo",
127                            "uids", username,
128                            "fields", "last_name,first_name",
129                            null);
130            XmlNode node = runCall (c);
131
132            if (node.name != "users_getInfo_response") {
133#if DEBUG
134                critical ("Couldn't get user info\nGot answer %s\n", c.get_payload ());
135#endif
136                Error (DBusErrorCode.AuthenticationError, _("Couldn't get user information"));
137                set_bridge_status (Bridge.Status.WrongToken);
138                if (node.find ("error_code").content == "102") { // Session key invalid or no longer valid
139                    session = null;
140                    secret = SHARED_SECRET;
141                }
142                return;
143            }
144
145            string realname = node.find ("first_name").content + " " + node.find ("last_name").content;
146            set_bridge_status (Bridge.Status.Authenticated, realname);
147
148        } else {
149            set_bridge_status (Bridge.Status.NotAuthenticated);
150            return;
151        }
152    }
153
154    public uint GetStatus ()
155    {
156        return bridge_status;
157    }
158
159    public void Pull ()
160    {
161
162        set_bridge_status (Bridge.Status.Working);
163
164        var c = rest.new_call ();
165        c.add_params ("method", "fql.query",
166                      "query", "SELECT pid,src_big,caption FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner='%s')".printf (username));
167        XmlNode root = runCall (c);
168
169        XmlNode current = root.find ("photo");
170        while (current != null) {
171            if (current.find ("src_big") == null) continue; // FIXME not always wanted
172            try {
173                string urn = "urn:uuid:%s".printf (uuid_generate_string ());
174                string uri = current.find ("src_big").content;
175
176                tracker.SparqlUpdate ("insert {<%s> a nmm:Photo}".printf (urn));
177                tracker.SparqlUpdate ("insert {<%s> a nfo:RemoteDataObject}".printf (uri));
178
179                string caption = current.find ("caption").content;
180                if (caption != null)
181                    tracker.SparqlUpdate ("insert {<%s> rdfs:label '%s'}".printf (urn, caption));
182            } catch (Error e) {
183                critical ("Error while inserting data into Tracker : %s", e.message);
184            }
185            current = current.next;
186        }
187    }
188
189    public void Shutdown ()
190    {
191#if DEBUG
192        stdout.printf ("Shutting down...\n");
193#endif
194        loop.quit ();
195    }
196
197    // Private functions
198    private void set_bridge_status (Tracker.Bridge.Status s, string message = "")
199    {
200        bridge_status = s;
201        StatusChanged ((uint)s, message);
202    }
203
204    private XmlNode? runCall (ProxyCall c)
205    {
206        signCall (c);
207
208        try {
209            c.run (null);
210        } catch (Error e) {
211            critical ("Error in REST call : %s\n", e.message);
212            return null;
213        }
214
215        var parser = new XmlParser ();
216        weak XmlNode ret = parser.parse_from_data (c.get_payload (), c.get_payload_length ());
217        return ret;
218    }
219
220    // Add version, api_key, call_id and sig
221    private void signCall (ProxyCall c)
222    {
223        var time = TimeVal ();
224        var callid = "%ld".printf(1000000*(time.tv_sec) + time.tv_usec);
225        c.add_params ("v", "1.0",
226                      "api_key", API_KEY,
227                      "call_id", callid,
228                      null);
229
230        if (session != null)
231            c.add_param ("session_key", session);
232
233        string sig = "";
234        var par = c.get_params ();
235        List<weak string> keys = par.get_keys ().copy ();
236        keys.sort ((CompareFunc)strcmp);
237
238        for (int i = 0 ; i < keys.length () ; ++i) {
239            sig += keys.nth_data (i) + "=" + par.lookup (keys.nth_data (i));
240        }
241        sig += secret;
242
243        sig = Checksum.compute_for_string (ChecksumType.MD5, sig);
244
245        c.add_param ("sig", sig);
246    }
247}
248
249MainLoop loop;
250
251void main ()
252{
253    loop = new MainLoop (null, false);
254
255    Environment.set_application_name ("FacebookBrige");
256
257    try {
258        var conn = DBus.Bus.get (DBus.BusType.SESSION);
259        dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
260
261        uint request_name_result = bus.request_name ("org.freedesktop.Tracker.FacebookBridge", (uint)0);
262        if (request_name_result != DBus.RequestNameReply.PRIMARY_OWNER) {
263            critical ("Somebody already got our name on the bus !");
264            return;
265        }
266
267#if DEBUG
268        stdout.printf ("Creating the bridge...\n");
269#endif
270
271        var bridge = new FacebookBridge ();
272        conn.register_object ("/org/freedesktop/Tracker/Bridge", bridge);
273
274
275        loop.run ();
276    } catch (Error e) {
277        critical ("Cannot start the bridge : %s", e.message);
278    }
279}
bridges/facebook/po/LINGUAS
bridges/facebook/po/POTFILES.in
1src/facebook.vala
bridges/facebook/po/POTFILES.skip
1src/facebook.c
bridges/facebook/src/Makefile.am
1AM_CPPFLAGS = \
2    -include $(CONFIG_HEADER)
3
4VALAINCLUDES= \
5    --pkg dbus-glib-1 \
6    --pkg tracker-bridge \
7    --pkg rest \
8    --pkg uuid \
9    --thread
10
11libexec_PROGRAMS=tracker-bridge-facebook
12
13tracker_bridge_facebook_VALASOURCES= \
14    facebook.vala
15
16tracker_bridge_facebook_SOURCES= \
17    $(tracker_bridge_facebook_VALASOURCES:.vala=.c)
18
19tracker-bridge-facebook.vala.stamp: $(tracker_bridge_facebook_VALASOURCES)
20    $(VALAC) -C $(VALAINCLUDES) $(VALAFLAGS) $^
21    touch $@
22
23tracker_bridge_facebook_CFLAGS= \
24    -DSHAREDIR=\""$(datadir)"\" \
25    -DLOCALEDIR=\""$(localedir)"\" \
26    -I$(top_srcdir)/src \
27    $(WARN_CFLAGS) \
28    $(GLIB2_CFLAGS) \
29    $(GOBJECT_CFLAGS) \
30    $(GTHREAD_CFLAGS) \
31    $(DBUS_CFLAGS) \
32    $(TRACKERBRIDGE_CFLAGS) \
33    $(REST_CFLAGS) \
34    $(UUID_CFLAGS)
35
36tracker_bridge_facebook_LDADD= \
37    $(GLIB2_LIBS) \
38    $(GOBJECT_LIBS) \
39    $(GTHREAD_LIBS) \
40    $(DBUS_LIBS) \
41    $(TRACKERBRIDGE_LIBS) \
42    $(REST_LIBS) \
43    $(UUID_LIBS)
44
45BUILT_SOURCES= \
46    tracker-bridge-facebook.vala.stamp
47
48CLEANFILES= $(BUILT_SOURCES)
49
50EXTRA_DIST= \
51    tracker-bridge-facebook.vala.stamp \
52    $(tracker_bridge_facebook_SOURCES) \
53    $(tracker_bridge_facebook_VALASOURCES)
54
55MAINTAINERCLEANFILES= \
56    $(tracker_bridge_facebook_SOURCES) \
57    tracker-bridge-facebook.vala.stamp
bridges/facebook/src/facebook.vala
1using Tracker;
2using Rest;
3
4public class FacebookBridge : Object, Tracker.Bridge {
5    private const string SERVICE_NAME = "Facebook";
6    private const string API_KEY = "a07366931355e51525938ade2d0df2fb";
7    private const string SHARED_SECRET = "dd34c9d53460953bfd3b5aa87c09b538";
8    private const string TRACKER_NAME = "org.freedesktop.Tracker";
9    private const string TRACKER_RESOURCES_PATH = "/org/freedesktop/Tracker/Resources";
10    private const string TRACKER_RESOURCES_INTERFACE = "org.freedesktop.Tracker.Resources";
11    private const string FACEBOOK_REST = "https://api.facebook.com/restserver.php";
12
13    private DBus.Connection conn;
14    dynamic DBus.Object tracker;
15
16    private Proxy rest;
17    private string auth_token;
18    private string session = null;
19    private string secret = SHARED_SECRET;
20
21    private string username = null; // Is actually the numeric user ID
22
23    private uint bridge_status;
24
25    public FacebookBridge ()
26    {
27        rest = new Proxy (FACEBOOK_REST, false);
28
29        set_bridge_status (Bridge.Status.NotAuthenticated);
30
31        try {
32            conn = DBus.Bus.get (DBus.BusType.SESSION);
33        } catch (Error e) {
34            critical ("Cannot connect to session bus : %s\n", e.message);
35        }
36
37        tracker = conn.get_object (TRACKER_NAME, TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE);
38
39    }
40
41    // DBus signals callbacks
42    public HashTable<string, string> GetAssociationData ()
43    {
44        var ret = new HashTable<string, string> (str_hash, str_equal);
45        ProxyCall c = rest.new_call ();
46        c.add_param ("method", "auth.createToken");
47        XmlNode node = runCall (c);
48
49        if (node.name != "auth_createToken_response") {
50#if DEBUG
51            critical ("Got answer %s\n", c.get_payload ());
52            critical ("Couldn't get authentification token");
53#endif
54            Error (DBusErrorCode.AuthenticationError, "");
55            return ret;
56        }
57
58        auth_token = node.content;
59        string url = "http://www.facebook.com/login.php?api_key=%s&v=1.0&auth_token=%s".printf (API_KEY, auth_token);
60        ret.insert ("url", url);
61
62        ret.insert ("post_message", _("A last browser window will now open, which will allow you to grant Tracker permanent access to your Facebook account. You're not obliged to do so, but if you choose not to grant Tracker a permanent access, you'll need to login again every 24 hours."));
63        ret.insert ("post_url", "http://www.facebook.com/authorize.php?api_key=%s&v=1.0&ext_perm=offline_access".printf (API_KEY));
64        return ret;
65    }
66
67    // This supposes we have a valid auth_token. Else, well, it'll just fail...
68    public void FinishAssociation (HashTable<string, string> data)
69    {
70        ProxyCall c = rest.new_call ();
71        c.add_param ("method", "auth.getSession");
72        c.add_param ("auth_token", auth_token);
73
74        {
75            XmlNode node = runCall (c);
76
77            if (node.name != "auth_getSession_response") {
78#if DEBUG
79                critical ("Got answer %s\n", c.get_payload ());
80                critical ("Couldn't get session token");
81#endif
82                Error (DBusErrorCode.AuthenticationError, "");
83                return;
84            }
85
86            username = node.find ("uid").content;
87            secret = node.find ("secret").content;
88            session = node.find ("session_key").content;
89        }
90
91        var pwdData = new HashTable<string, string> (str_hash, str_equal);
92        pwdData.insert ("session", session);
93        Tracker.passwordProvider.save (username, SERVICE_NAME, secret, "Authentication token for Facebook", pwdData);
94
95        c = rest.new_call ();
96        c.add_params ("method", "users.getInfo",
97                      "uids", username,
98                      "fields", "last_name,first_name",
99                      null);
100        XmlNode node = runCall (c);
101
102        if (node.name != "users_getInfo_response") {
103#if DEBUG
104            critical ("Got answer %s\n", c.get_payload ());
105            critical ("Couldn't get user info");
106#endif
107            Error (DBusErrorCode.AuthenticationError, _("Couldn't get user information"));
108            return;
109        }
110
111        string realname = node.find ("first_name").content + " " + node.find ("last_name").content;
112
113        set_bridge_status (Bridge.Status.Authenticated, realname);
114    }
115
116    public void Authenticate ()
117    {
118        var pwdData = Tracker.passwordProvider.search (null, SERVICE_NAME);
119
120        if (pwdData != null) {
121            username = pwdData.lookup ("username");
122            session = pwdData.lookup ("session");
123            secret = pwdData.lookup ("secret");
124
125            ProxyCall c = rest.new_call ();
126            c.add_params ("method", "users.getInfo",
127                            "uids", username,
128                            "fields", "last_name,first_name",
129                            null);
130            XmlNode node = runCall (c);
131
132            if (node.name != "users_getInfo_response") {
133#if DEBUG
134                critical ("Couldn't get user info\nGot answer %s\n", c.get_payload ());
135#endif
136                Error (DBusErrorCode.AuthenticationError, _("Couldn't get user information"));
137                set_bridge_status (Bridge.Status.WrongToken);
138                if (node.find ("error_code").content == "102") { // Session key invalid or no longer valid
139                    session = null;
140                    secret = SHARED_SECRET;
141                }
142                return;
143            }
144
145            string realname = node.find ("first_name").content + " " + node.find ("last_name").content;
146            set_bridge_status (Bridge.Status.Authenticated, realname);
147
148        } else {
149            set_bridge_status (Bridge.Status.NotAuthenticated);
150            return;
151        }
152    }
153
154    public uint GetStatus ()
155    {
156        return bridge_status;
157    }
158
159    public void Pull ()
160    {
161
162        set_bridge_status (Bridge.Status.Working);
163
164        var c = rest.new_call ();
165        c.add_params ("method", "fql.query",
166                      "query", "SELECT pid,src_big,caption FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner='%s')".printf (username));
167        XmlNode root = runCall (c);
168
169        XmlNode current = root.find ("photo");
170        while (current != null) {
171            if (current.find ("src_big") == null) continue; // FIXME not always wanted
172            try {
173                string urn = "urn:uuid:%s".printf (uuid_generate_string ());
174                string uri = current.find ("src_big").content;
175
176                tracker.SparqlUpdate ("insert {<%s> a nmm:Photo}".printf (urn));
177                tracker.SparqlUpdate ("insert {<%s> a nfo:RemoteDataObject}".printf (uri));
178
179                string caption = current.find ("caption").content;
180                if (caption != null)
181                    tracker.SparqlUpdate ("insert {<%s> rdfs:label '%s'}".printf (urn, caption));
182            } catch (Error e) {
183                critical ("Error while inserting data into Tracker : %s", e.message);
184            }
185            current = current.next;
186        }
187    }
188
189    public void Shutdown ()
190    {
191#if DEBUG
192        stdout.printf ("Shutting down...\n");
193#endif
194        loop.quit ();
195    }
196
197    // Private functions
198    private void set_bridge_status (Tracker.Bridge.Status s, string message = "")
199    {
200        bridge_status = s;
201        StatusChanged ((uint)s, message);
202    }
203
204    private XmlNode? runCall (ProxyCall c)
205    {
206        signCall (c);
207
208        try {
209            c.run (null);
210        } catch (Error e) {
211            critical ("Error in REST call : %s\n", e.message);
212            return null;
213        }
214
215        var parser = new XmlParser ();
216        weak XmlNode ret = parser.parse_from_data (c.get_payload (), c.get_payload_length ());
217        return ret;
218    }
219
220    // Add version, api_key, call_id and sig
221    private void signCall (ProxyCall c)
222    {
223        var time = TimeVal ();
224        var callid = "%ld".printf(1000000*(time.tv_sec) + time.tv_usec);
225        c.add_params ("v", "1.0",
226                      "api_key", API_KEY,
227                      "call_id", callid,
228                      null);
229
230        if (session != null)
231            c.add_param ("session_key", session);
232
233        string sig = "";
234        var par = c.get_params ();
235        List<weak string> keys = par.get_keys ().copy ();
236        keys.sort ((CompareFunc)strcmp);
237
238        for (int i = 0 ; i < keys.length () ; ++i) {
239            sig += keys.nth_data (i) + "=" + par.lookup (keys.nth_data (i));
240        }
241        sig += secret;
242
243        sig = Checksum.compute_for_string (ChecksumType.MD5, sig);
244
245        c.add_param ("sig", sig);
246    }
247}
248
249MainLoop loop;
250
251void main ()
252{
253    loop = new MainLoop (null, false);
254
255    Environment.set_application_name ("FacebookBrige");
256
257    try {
258        var conn = DBus.Bus.get (DBus.BusType.SESSION);
259        dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
260
261        uint request_name_result = bus.request_name ("org.freedesktop.Tracker.FacebookBridge", (uint)0);
262        if (request_name_result != DBus.RequestNameReply.PRIMARY_OWNER) {
263            critical ("Somebody already got our name on the bus !");
264            return;
265        }
266
267#if DEBUG
268        stdout.printf ("Creating the bridge...\n");
269#endif
270
271        var bridge = new FacebookBridge ();
272        conn.register_object ("/org/freedesktop/Tracker/Bridge", bridge);
273
274
275        loop.run ();
276    } catch (Error e) {
277        critical ("Cannot start the bridge : %s", e.message);
278    }
279}

Archive Download the corresponding diff file

Branches:
master