[gnome-maps] Add Check-in capabilities



commit 0294d555a970c755dbd63cfcec2d2af40509f601
Author: Damián Nohales <damiannohales gmail com>
Date:   Mon Jun 2 14:46:55 2014 -0300

    Add Check-in capabilities
    
    This only adds check-in capabilities necessary
    to implement a check-in UI.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=731113

 src/application.js                           |    3 +
 src/checkIn.js                               |  132 ++++++++++++++++++++++++++
 src/gnome-maps.js.gresource.xml              |    6 +
 src/socialService/facebookBackend.js         |  115 ++++++++++++++++++++++
 src/socialService/foursquareBackend.js       |  120 +++++++++++++++++++++++
 src/socialService/foursquareGoaAuthorizer.js |   95 ++++++++++++++++++
 src/socialService/serviceBackend.js          |  128 +++++++++++++++++++++++++
 src/socialService/socialPlace.js             |   47 +++++++++
 8 files changed, 646 insertions(+), 0 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 9315d30..0cd1506 100644
--- a/src/application.js
+++ b/src/application.js
@@ -30,6 +30,7 @@ const GtkClutter = imports.gi.GtkClutter;
 const Lang = imports.lang;
 const _ = imports.gettext.gettext;
 
+const CheckIn = imports.checkIn;
 const Format = imports.format;
 const Geoclue = imports.geoclue;
 const GeocodeService = imports.geocodeService;
@@ -50,6 +51,7 @@ let routeService = null;
 let geoclue = null;
 let geocodeService = null;
 let networkMonitor = null;
+let checkInManager = null;
 
 const Application = new Lang.Class({
     Name: 'Application',
@@ -146,6 +148,7 @@ const Application = new Lang.Class({
         networkMonitor = Gio.NetworkMonitor.get_default();
         networkMonitor.connect('network-changed',
                                this._checkNetwork.bind(this));
+        checkInManager = new CheckIn.CheckInManager();
     },
 
     _createWindow: function() {
diff --git a/src/checkIn.js b/src/checkIn.js
new file mode 100644
index 0000000..8d2ede3
--- /dev/null
+++ b/src/checkIn.js
@@ -0,0 +1,132 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const GObject = imports.gi.GObject;
+const Goa = imports.gi.Goa;
+const Lang = imports.lang;
+
+const FacebookBackend = imports.socialService.facebookBackend;
+const FoursquareBackend = imports.socialService.foursquareBackend;
+
+const CheckInManager = new Lang.Class({
+    Name: 'CheckInManager',
+    Extends: GObject.Object,
+    Signals: {
+        'accounts-refreshed': { }
+    },
+    Properties: {
+        'hasCheckIn': GObject.ParamSpec.boolean('hasCheckIn',
+                                                '',
+                                                '',
+                                                GObject.ParamFlags.READABLE)
+    },
+
+    _init: function() {
+        this.parent();
+
+        this._goaClient = Goa.Client.new_sync(null);
+        this._accounts = [];
+        this._authorizers = {};
+        this._backends = {};
+
+        this._initBackends();
+
+        this._goaClient.connect('account-added', this._refreshGoaAccounts.bind(this));
+        this._goaClient.connect('account-changed', this._refreshGoaAccounts.bind(this));
+        this._goaClient.connect('account-removed', this._refreshGoaAccounts.bind(this));
+
+        this._refreshGoaAccounts();
+    },
+
+    _initBackends: function() {
+        let facebookBackend = new FacebookBackend.FacebookBackend();
+        this._backends[facebookBackend.name] = facebookBackend;
+
+        let foursquareBackend = new FoursquareBackend.FoursquareBackend();
+        this._backends[foursquareBackend.name] = foursquareBackend;
+    },
+
+    _refreshGoaAccounts: function() {
+        let accounts = this._goaClient.get_accounts();
+        this._accounts = [];
+        this._accountsCount = 0;
+        this._authorizers = {};
+
+        accounts.forEach((function(object) {
+            if (!object.get_account())
+                return;
+
+            if (!object.get_maps())
+                return;
+
+            let accountId = object.get_account().id;
+            this._accounts.push(object);
+
+            this._authorizers[accountId] = this._getBackend(object).createAuthorizer(object);
+        }).bind(this));
+
+        this.emit('accounts-refreshed');
+        this.notify('hasCheckIn');
+    },
+
+    get client() {
+        return this._goaClient;
+    },
+
+    get accounts() {
+        return this._accounts;
+    },
+
+    get hasCheckIn() {
+        return this._accounts.length > 0;
+    },
+
+    _getAuthorizer: function(account) {
+        return this._authorizers[account.get_account().id];
+    },
+
+    _getBackend: function(account) {
+        return this._backends[account.get_account().provider_type];
+    },
+
+    performCheckIn: function(account, checkIn, callback, cancellable) {
+        this._getBackend(account)
+            .performCheckIn(this._getAuthorizer(account), checkIn, callback, cancellable);
+    },
+
+    findPlaces: function(account, latitude, longitude, distance, callback, cancellable) {
+        this._getBackend(account)
+            .findPlaces(this._getAuthorizer(account), latitude, longitude, distance, callback, cancellable);
+    }
+});
+
+const CheckIn = new Lang.Class({
+    Name: 'CheckIn',
+
+    _init: function() {
+        this.message = null;
+        this.place = null;
+        this.privacy = null;
+        this.broadcastFacebook = false;
+        this.broadcastTwitter = false;
+    }
+});
diff --git a/src/gnome-maps.js.gresource.xml b/src/gnome-maps.js.gresource.xml
index b06b5da..9d7c4bf 100644
--- a/src/gnome-maps.js.gresource.xml
+++ b/src/gnome-maps.js.gresource.xml
@@ -2,6 +2,7 @@
 <gresources>
   <gresource prefix="/org/gnome/maps">
     <file>application.js</file>
+    <file>checkIn.js</file>
     <file>config.js</file>
     <file>contextMenu.js</file>
     <file>epaf.js</file>
@@ -39,6 +40,11 @@
     <file>sidebar.js</file>
     <file>userLocationMarker.js</file>
     <file>userLocationBubble.js</file>
+    <file>socialService/facebookBackend.js</file>
+    <file>socialService/foursquareBackend.js</file>
+    <file>socialService/foursquareGoaAuthorizer.js</file>
+    <file>socialService/serviceBackend.js</file>
+    <file>socialService/socialPlace.js</file>
     <file>utils.js</file>
     <file>zoomControl.js</file>
   </gresource>
diff --git a/src/socialService/facebookBackend.js b/src/socialService/facebookBackend.js
new file mode 100644
index 0000000..87d1f9a
--- /dev/null
+++ b/src/socialService/facebookBackend.js
@@ -0,0 +1,115 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const GFBGraph = imports.gi.GFBGraph;
+const Lang = imports.lang;
+
+const ServiceBackend = imports.socialService.serviceBackend;
+const SocialPlace = imports.socialService.socialPlace;
+
+const _PLACE_LINK_FORMAT = 'https://www.facebook.com/%s';
+
+const FacebookBackend = new Lang.Class({
+    Name: 'SocialServiceFacebookBackend',
+    Extends: ServiceBackend.ServiceBackend,
+
+    get name() {
+        return 'facebook';
+    },
+
+    createRestCall: function(authorizer) {
+        return GFBGraph.new_rest_call(authorizer);
+    },
+
+    refreshAuthorization: function(authorizer, cancellable) {
+        return authorizer.refresh_authorization(cancellable);
+    },
+
+    getAuthorizerAccount: function(authorizer) {
+        return authorizer.goa_object;
+    },
+
+    createAuthorizer: function(account) {
+        return new GFBGraph.GoaAuthorizer({ goa_object: account });
+    },
+
+    isTokenInvalid: function(restCall, data) {
+        return data.error &&
+               (data.error.code === 2500 || data.error.code === 104 || data.error.code === 190);
+    },
+
+    isInvalidCall: function(restCall, data) {
+        return !data || data.error;
+    },
+
+    getCallResultCode: function(restCall, data) {
+        return data ?
+            (data.error ? data.error.code : null) :
+            restCall.get_status_code();
+    },
+
+    getCallResultMessage: function(restCall, data) {
+        return data ?
+            (data.error ? data.error.message : null) :
+            restCall.get_status_message();
+    },
+
+    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) {
+        this.callAsync(authorizer,
+                       'POST',
+                       'me/feed',
+                       {
+                           'message': checkIn.message,
+                           'place': checkIn.place.id,
+                           'privacy_value': checkIn.privacy
+                       },
+                       callback,
+                       cancellable);
+    },
+
+    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+        this.callAsync(authorizer,
+                       'GET',
+                       'search',
+                       {
+                           'type': 'place',
+                           'center': latitude + ',' + longitude,
+                           'distance': distance
+                       },
+                       callback,
+                       cancellable);
+    },
+
+    createPlaces: function(rawData) {
+        return rawData.data.map(function(place) {
+            let link = _PLACE_LINK_FORMAT.format(place.id);
+
+            return new SocialPlace.SocialPlace({ id: place.id,
+                                                 name: place.name,
+                                                 latitude: place.location.latitude,
+                                                 longitude: place.location.longitude,
+                                                 category: place.category,
+                                                 link: link,
+                                                 originalData: place });
+        });
+    }
+});
diff --git a/src/socialService/foursquareBackend.js b/src/socialService/foursquareBackend.js
new file mode 100644
index 0000000..26fbdae
--- /dev/null
+++ b/src/socialService/foursquareBackend.js
@@ -0,0 +1,120 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Lang = imports.lang;
+
+const FoursquareGoaAuthorizer = imports.socialService.foursquareGoaAuthorizer;
+const ServiceBackend = imports.socialService.serviceBackend;
+const SocialPlace = imports.socialService.socialPlace;
+
+const _PLACE_LINK_FORMAT = 'https://foursquare.com/v/foursquare-hq/%s';
+
+const FoursquareBackend = new Lang.Class({
+    Name: 'SocialServiceFoursquareBackend',
+    Extends: ServiceBackend.ServiceBackend,
+
+    get name() {
+        return 'foursquare';
+    },
+
+    createRestCall: function(authorizer) {
+        return FoursquareGoaAuthorizer.newRestCall(authorizer);
+    },
+
+    refreshAuthorization: function(authorizer, cancellable) {
+        return authorizer.refreshAuthorization(cancellable);
+    },
+
+    getAuthorizerAccount: function(authorizer) {
+        return authorizer.goaObject;
+    },
+
+    createAuthorizer: function(account) {
+        return new FoursquareGoaAuthorizer.FoursquareGoaAuthorizer({ goaObject: account });
+    },
+
+    isTokenInvalid: function(restCall, data) {
+        return data.meta.code === 401 || data.meta.code === 403;
+    },
+
+    isInvalidCall: function(restCall, data) {
+        return !data || data.meta.code !== 200;
+    },
+
+    getCallResultCode: function(restCall, data) {
+        return data ? data.meta.code : restCall.get_status_code();
+    },
+
+    getCallResultMessage: function(restCall, data) {
+        return data ? data.meta.errorDetail : restCall.get_status_message();
+    },
+
+    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) {
+        let broadcast = checkIn.privacy;
+
+        if (checkIn.broadcastFacebook)
+            broadcast += ',facebook';
+
+        if (checkIn.broadcastTwitter)
+            broadcast += ',twitter';
+
+        this.callAsync(authorizer,
+                       'POST',
+                       'checkins/add',
+                       {
+                           'shout': checkIn.message,
+                           'venueId': checkIn.place.id,
+                           'broadcast': broadcast
+                       },
+                       callback,
+                       cancellable);
+    },
+
+    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+        this.callAsync(authorizer,
+                       'GET',
+                       'venues/search',
+                       {
+                           'll': latitude + ',' + longitude,
+                           'radius': distance,
+                           'intent': 'checkin'
+                       },
+                       callback,
+                       cancellable);
+    },
+
+    createPlaces: function(rawData) {
+        return rawData.response.venues.map(function(place) {
+            let link = _PLACE_LINK_FORMAT.format(place.id);
+
+            return new SocialPlace.SocialPlace({ id: place.id,
+                                                 name: place.name,
+                                                 latitude: place.location.lat,
+                                                 longitude: place.location.lng,
+                                                 category: place.categories.length > 0 ?
+                                                     place.categories[0].name :
+                                                     null,
+                                                 link: link,
+                                                 originalData: place });
+        });
+    }
+});
diff --git a/src/socialService/foursquareGoaAuthorizer.js b/src/socialService/foursquareGoaAuthorizer.js
new file mode 100644
index 0000000..f68b774
--- /dev/null
+++ b/src/socialService/foursquareGoaAuthorizer.js
@@ -0,0 +1,95 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Rest = imports.gi.Rest;
+const Lang = imports.lang;
+
+const _FOURSQUARE_API_VERSION = '20140226';
+
+const FoursquareGoaAuthorizer = new Lang.Class({
+    Name: 'FoursquareGoaAuthorizer',
+
+    _init: function(params) {
+        if (!params.goaObject) {
+            logError('FoursquareGoaAuthorizer requires goaObject parameter');
+            return;
+        }
+
+        this.goaObject = params.goaObject;
+    },
+
+    get goaObject() {
+        return this._goaObject;
+    },
+
+    set goaObject(object) {
+        this._goaObject = object;
+        this._accessToken = null;
+    },
+
+    _refreshAccessToken: function(cancellable) {
+        if (this._accessToken)
+            return true;
+
+        let getAccessTokenResult = this.goaObject.get_oauth2_based().call_get_access_token_sync(cancellable);
+
+        if (getAccessTokenResult[0]) {
+            this._accessToken = getAccessTokenResult[1];
+            return true;
+        }
+
+        return false;
+    },
+
+    processCall: function(restCall) {
+        this._refreshAccessToken(null);
+        restCall.add_param('oauth_token', this._accessToken);
+        restCall.add_param('v', _FOURSQUARE_API_VERSION);
+    },
+
+    processMessage: function(soupMessage) {
+        this._refreshAccessToken(null);
+        let uri = soupMessage.get_uri();
+        uri.set_query(uri, 'oauth_token' + this._accessToken + '&v=' + _FOURSQUARE_API_VERSION);
+    },
+
+    refreshAuthorization: function(cancellable) {
+        let ensureCredentialsResult = this.goaObject.get_account().call_ensure_credentials_sync(cancellable);
+        if (ensureCredentialsResult[0]) {
+            this._accessToken = null;
+            return this._refreshAccessToken(cancellable);
+        }
+
+        return false;
+    }
+});
+
+function newRestCall(authorizer)
+{
+    let proxy = new Rest.Proxy({ url_format: 'https://api.foursquare.com/v2',
+                                 binding_required: false });
+    let restCall = proxy.new_call();
+
+    authorizer.processCall(restCall);
+
+    return restCall;
+}
diff --git a/src/socialService/serviceBackend.js b/src/socialService/serviceBackend.js
new file mode 100644
index 0000000..7eaafa0
--- /dev/null
+++ b/src/socialService/serviceBackend.js
@@ -0,0 +1,128 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Lang = imports.lang;
+
+const Utils = imports.utils;
+
+const ServiceBackend = new Lang.Class({
+    Name: 'SocialServiceServiceBackend',
+    Abstract: true,
+
+    //Abstract
+    get name() { },
+
+    //Abstract
+    createRestCall: function(authorizer) { },
+
+    //Abstract
+    refreshAuthorization: function(authorizer, cancellable) { },
+
+    //Abstract
+    getAuthorizerAccount: function(authorizer) { },
+
+    //Abstract
+    createAuthorizer: function(account) { },
+
+    //Abstract
+    isTokenInvalid: function(restCall, parsedPayload) { },
+
+    //Abstract
+    isInvalidCall: function(restCall, parsedPayload) { },
+
+    //Abstract
+    getCallResultCode: function(restCall, parsedPayload) { },
+
+    //Abstract
+    getCallResultMessage: function(restCall, parsedPayload) { },
+
+    callAsync: function(authorizer, method, func, params, callback, cancellable, mustRefreshToken) {
+        mustRefreshToken = mustRefreshToken || true;
+        cancellable = cancellable || null;
+
+        let restCall = this.createRestCall(authorizer);
+
+        method = method.toUpperCase();
+        restCall.set_method(method);
+
+        for (let key in params)
+            restCall.add_param(key, params[key].toString());
+
+        restCall.set_function(func);
+
+        Utils.debug(this.name + ': ' + func);
+
+        restCall.invoke_async(cancellable, (function(call, result) {
+            let data = JSON.parse(call.get_payload());
+            let account = this.getAuthorizerAccount(authorizer);
+
+            if (data && this.isTokenInvalid(call, data))
+                if (mustRefreshToken) {
+                    //Unauthorized token error, we need to refresh the token
+                    Utils.debug(this.name + ': The token is not authorized, refreshing token');
+                    try {
+                        this.refreshAuthorization(authorizer, cancellable);
+                        this.callAsync(authorizer, method, func, params, callback, cancellable, false);
+                    } catch(error) {
+                        callback(account, data, { code: 401,
+                                                  message: null });
+                    }
+                } else
+                    callback(account, data, { code: 401,
+                                              message: null });
+            else if (this.isInvalidCall(call, data))
+                callback(account, data, { code: this.getCallResultCode(call, data),
+                                          message: this.getCallResultMessage(call, data) });
+            else
+                callback(account, data, null);
+        }).bind(this));
+    },
+
+    performCheckIn: function(authorizer, checkIn, callback, cancellable) {
+        callback = callback || function() {};
+        this._realPerformCheckIn(authorizer, checkIn, callback, cancellable);
+    },
+
+    //Abstract
+    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) { },
+
+    findPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+        callback = callback || function() {};
+        this._realFindPlaces(authorizer,
+                             latitude,
+                             longitude,
+                             distance,
+                             (function(account, data, error) {
+                                 if (!error)
+                                     callback(account, this.createPlaces(data), error);
+                                 else
+                                     callback(account, [], error);
+                             }).bind(this),
+                             cancellable);
+    },
+
+    //Abstract
+    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) { },
+
+    //Abstract
+    createPlaces: function(rawData) { }
+});
diff --git a/src/socialService/socialPlace.js b/src/socialService/socialPlace.js
new file mode 100644
index 0000000..fbfc5f5
--- /dev/null
+++ b/src/socialService/socialPlace.js
@@ -0,0 +1,47 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Geocode = imports.gi.GeocodeGlib;
+const GObject = imports.gi.GObject;
+const Lang = imports.lang;
+
+const SocialPlace = new Lang.Class({
+    Name: 'SocialServiceSocialPlace',
+    Extends: GObject.Object,
+
+    _init: function(params) {
+        this.parent();
+
+        this.id = params.id;
+        this.name = params.name;
+        this.latitude = params.latitude;
+        this.longitude = params.longitude;
+        this.category = params.category;
+        this.link = params.link;
+        this.originalData = params.originalData;
+    },
+
+    get location() {
+        return new Geocode.Location({ latitude: parseFloat(this.latitude),
+                                      longitude: parseFloat(this.longitude) });
+    }
+});


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]