[gnome-online-accounts/wip/pocket: 2/4] Add Pocket support



commit 6aedcc5bffa57b0b19a4b029985410390e3f1aeb
Author: Bastien Nocera <hadess hadess net>
Date:   Fri Jul 19 17:08:20 2013 +0200

    Add Pocket support
    
    Based on the documentation at:
    http://getpocket.com/developer/docs/authentication
    
    Icons by Jakub Steiner originally from:
    https://raw.github.com/gnome-design-team/gnome-icons/master/web-accounts/tango/src/web-accounts.svg
    
    v2:
    - Make it work
    
    v3:
    - Fix the memory leaks
    - We didn't make apps crash by adding an account type,
      goa-daemon -r did:
    See https://bugzilla.gnome.org/show_bug.cgi?id=698726
    - Implement is_identity_node()
    - Partially implement is_deny_node(), see below
    
    v4:
    - Detect the Cancel button, but that only seems to work once
    
    v5:
    - Disable by default
    - Print enablement status at the end of configure
    - Show client ID as well
    - Fix crash when cookies were set
    
    v6:
    - Add icons by jimmac
    
    v7:
    - Chain up in finalize
    - Set error when processing the redirect URL
    - Update POTFILES.in
    
    TODO:
    - Sync network calls in build_authorization_uri() and
      process_redirect_url()
    - Cancel button doesn't work when we click "Sign Up" first
    
    Doc problems:
    - is_identity_node() shouldn't say it denies access...
    
    https://bugzilla.gnome.org/show_bug.cgi?id=704564

 configure.ac                            |   21 ++
 data/dbus-interfaces.xml                |   22 ++
 data/icons/16x16/Makefile.am            |    1 +
 data/icons/16x16/goa-account-pocket.png |  Bin 0 -> 685 bytes
 data/icons/22x22/Makefile.am            |    1 +
 data/icons/22x22/goa-account-pocket.png |  Bin 0 -> 836 bytes
 data/icons/24x24/Makefile.am            |    1 +
 data/icons/24x24/goa-account-pocket.png |  Bin 0 -> 798 bytes
 data/icons/32x32/Makefile.am            |    1 +
 data/icons/32x32/goa-account-pocket.png |  Bin 0 -> 1214 bytes
 data/icons/48x48/Makefile.am            |    1 +
 data/icons/48x48/goa-account-pocket.png |  Bin 0 -> 1582 bytes
 po/POTFILES.in                          |    1 +
 src/goabackend/Makefile.am              |    1 +
 src/goabackend/goabackendenums.h        |    1 +
 src/goabackend/goapocketprovider.c      |  497 +++++++++++++++++++++++++++++++
 src/goabackend/goapocketprovider.h      |   44 +++
 src/goabackend/goaprovider.c            |    4 +
 18 files changed, 596 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d27ab20..c89529c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -333,6 +333,26 @@ fi
 
 PKG_CHECK_MODULES(TP, telepathy-glib)
 
+# Pocket
+AC_ARG_ENABLE([pocket], [AS_HELP_STRING([--enable-pocket],
+                                              [Enable Pocket provider])],
+                                              [],
+                                              [enable_pocket=no])
+AC_ARG_WITH(pocket-client-id,
+            [AS_HELP_STRING([--with-pocket-client-id],
+                            [Pocket OAuth 2.0 client id])],
+                            [],
+                            [])
+if test "$with_pocket_client_id" = ""; then
+  with_pocket_client_id="16630-40b25246b56e8ad5310b2883"
+fi
+AC_DEFINE_UNQUOTED(GOA_POCKET_CLIENT_ID,
+                   ["$with_pocket_client_id"],
+                   [Pocket OAuth 2.0 client id])
+if test "$enable_pocket" != "no"; then
+  AC_DEFINE(GOA_POCKET_ENABLED, 1, [Enable Pocket data provider])
+fi
+
 # Kerberos
 AC_ARG_ENABLE([kerberos],
               [AS_HELP_STRING([--enable-kerberos],
@@ -522,6 +542,7 @@ echo "
        Facebook provider:              ${enable_facebook} (OAuth 2.0, id:${with_facebook_client_id})
        Windows Live provider:          ${enable_windows_live} (OAuth 2.0, id:${with_windows_live_client_id})
         Telepathy provider:             ${enable_telepathy}
+        Pocket provider:                ${enable_pocket} (id:${with_pocket_client_id})
 
        Maintainer mode:                ${USE_MAINTAINER_MODE}
        Building api docs:              ${enable_gtk_doc}
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
index fa4101f..531c722 100644
--- a/data/dbus-interfaces.xml
+++ b/data/dbus-interfaces.xml
@@ -203,6 +203,18 @@
     -->
     <property name="TicketingDisabled" type="b" access="readwrite"/>
 
+    <!-- ReadLaterDisabled:
+         @since: 3.10.0
+
+         If %TRUE, the account will not expose any
+         #org.gnome.OnlineAccounts.ReadLater interface. If the account does not
+         provide read-later-like capabilities, this property does nothing.
+
+         Note that the #org.gnomeOnlineAccounts.ReadLater interface is added or
+         removed from the account asynchronously.
+    -->
+    <property name="ReadLaterDisabled" type="b" access="readwrite"/>
+
     <!--
         Remove:
 
@@ -640,4 +652,14 @@
     <method name="GetTicket"/>
   </interface>
 
+  <!--
+      org.gnome.OnlineAccounts.ReadLater:
+      @since: 3.10.0
+
+      An account object implements this interface if it provides
+      read-later-like capabilities.
+  -->
+  <interface name="org.gnome.OnlineAccounts.ReadLater">
+  </interface>
+
 </node>
diff --git a/data/icons/16x16/Makefile.am b/data/icons/16x16/Makefile.am
index 763386b..1c229bd 100644
--- a/data/icons/16x16/Makefile.am
+++ b/data/icons/16x16/Makefile.am
@@ -7,6 +7,7 @@ icon_DATA =                             \
        goa-account-flickr.png          \
        goa-account-google.png          \
        goa-account-owncloud.png        \
+       goa-account-pocket.png          \
        goa-account-twitter.png         \
        goa-account-yahoo.png           \
        $(NULL)
diff --git a/data/icons/16x16/goa-account-pocket.png b/data/icons/16x16/goa-account-pocket.png
new file mode 100644
index 0000000..1b16bef
Binary files /dev/null and b/data/icons/16x16/goa-account-pocket.png differ
diff --git a/data/icons/22x22/Makefile.am b/data/icons/22x22/Makefile.am
index 811a0e5..0770827 100644
--- a/data/icons/22x22/Makefile.am
+++ b/data/icons/22x22/Makefile.am
@@ -7,6 +7,7 @@ icon_DATA =                             \
        goa-account-flickr.png          \
        goa-account-google.png          \
        goa-account-owncloud.png        \
+       goa-account-pocket.png          \
        goa-account-twitter.png         \
        goa-account-yahoo.png           \
        $(NULL)
diff --git a/data/icons/22x22/goa-account-pocket.png b/data/icons/22x22/goa-account-pocket.png
new file mode 100644
index 0000000..93b47b3
Binary files /dev/null and b/data/icons/22x22/goa-account-pocket.png differ
diff --git a/data/icons/24x24/Makefile.am b/data/icons/24x24/Makefile.am
index bb80cfa..6bf589b 100644
--- a/data/icons/24x24/Makefile.am
+++ b/data/icons/24x24/Makefile.am
@@ -6,6 +6,7 @@ icon_DATA =                             \
        goa-account-facebook.png        \
        goa-account-google.png          \
        goa-account-owncloud.png        \
+       goa-account-pocket.png          \
        goa-account-twitter.png         \
        goa-account-flickr.png          \
        goa-account-yahoo.png           \
diff --git a/data/icons/24x24/goa-account-pocket.png b/data/icons/24x24/goa-account-pocket.png
new file mode 100644
index 0000000..8211797
Binary files /dev/null and b/data/icons/24x24/goa-account-pocket.png differ
diff --git a/data/icons/32x32/Makefile.am b/data/icons/32x32/Makefile.am
index a306f59..4a123e8 100644
--- a/data/icons/32x32/Makefile.am
+++ b/data/icons/32x32/Makefile.am
@@ -7,6 +7,7 @@ icon_DATA =                             \
        goa-account-flickr.png          \
        goa-account-google.png          \
        goa-account-owncloud.png        \
+       goa-account-pocket.png          \
        goa-account-twitter.png         \
        goa-account-yahoo.png           \
        $(NULL)
diff --git a/data/icons/32x32/goa-account-pocket.png b/data/icons/32x32/goa-account-pocket.png
new file mode 100644
index 0000000..f07085d
Binary files /dev/null and b/data/icons/32x32/goa-account-pocket.png differ
diff --git a/data/icons/48x48/Makefile.am b/data/icons/48x48/Makefile.am
index 58b4766..2c64c72 100644
--- a/data/icons/48x48/Makefile.am
+++ b/data/icons/48x48/Makefile.am
@@ -6,6 +6,7 @@ icon_DATA =                             \
        goa-account-facebook.png        \
        goa-account-google.png          \
        goa-account-owncloud.png        \
+       goa-account-pocket.png          \
        goa-account-twitter.png         \
        goa-account-flickr.png          \
        goa-account-yahoo.png           \
diff --git a/data/icons/48x48/goa-account-pocket.png b/data/icons/48x48/goa-account-pocket.png
new file mode 100644
index 0000000..67ff580
Binary files /dev/null and b/data/icons/48x48/goa-account-pocket.png differ
diff --git a/po/POTFILES.in b/po/POTFILES.in
index baefce1..c2f85c8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@ src/goabackend/goakerberosprovider.c
 src/goabackend/goaoauth2provider.c
 src/goabackend/goaoauthprovider.c
 src/goabackend/goaowncloudprovider.c
+src/goabackend/goapocketprovider.c
 src/goabackend/goaprovider.c
 src/goabackend/goasmtpauthplain.c
 src/goabackend/goatelepathyprovider.c
diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am
index 87782a0..cb7680b 100644
--- a/src/goabackend/Makefile.am
+++ b/src/goabackend/Makefile.am
@@ -80,6 +80,7 @@ libgoa_backend_1_0_la_SOURCES =                                               \
        goawindowsliveprovider.h        goawindowsliveprovider.c        \
        goatelepathyfactory.h           goatelepathyfactory.c           \
        goatelepathyprovider.h          goatelepathyprovider.c          \
+       goapocketprovider.h             goapocketprovider.c             \
        goautils.h                      goautils.c                      \
        goaspinnerbutton.h              goaspinnerbutton.c              \
        goawebview.h                    goawebview.c                    \
diff --git a/src/goabackend/goabackendenums.h b/src/goabackend/goabackendenums.h
index 4ed7a24..b694980 100644
--- a/src/goabackend/goabackendenums.h
+++ b/src/goabackend/goabackendenums.h
@@ -91,6 +91,7 @@ typedef enum /*< flags >*/
   GOA_PROVIDER_FEATURE_PHOTOS    = 1 << 7,
   GOA_PROVIDER_FEATURE_FILES     = 1 << 8,
   GOA_PROVIDER_FEATURE_TICKETING = 1 << 9,
+  GOA_PROVIDER_FEATURE_READ_LATER= 1 << 10,
   GOA_PROVIDER_FEATURE_INVALID   = 0
 } GoaProviderFeatures;
 
diff --git a/src/goabackend/goapocketprovider.c b/src/goabackend/goapocketprovider.c
new file mode 100644
index 0000000..2793d28
--- /dev/null
+++ b/src/goabackend/goapocketprovider.c
@@ -0,0 +1,497 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Bastien Nocera <hadess hadess net>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include <rest/rest-proxy.h>
+#include <json-glib/json-glib.h>
+#include <webkit/webkit.h>
+
+#include "goalogging.h"
+#include "goaprovider.h"
+#include "goaprovider-priv.h"
+#include "goaoauth2provider.h"
+#include "goapocketprovider.h"
+
+#define V3_OAUTH_AUTHORIZE_URL "https://getpocket.com/v3/oauth/authorize";
+
+/**
+ * GoaPocketProvider:
+ *
+ * The #GoaPocketProvider structure contains only private data and should
+ * only be accessed using the provided API.
+ */
+struct _GoaPocketProvider
+{
+  /*< private >*/
+  GoaOAuth2Provider parent_instance;
+
+  /* request token as gathered from Step 2:
+   * http://getpocket.com/developer/docs/authentication */
+  gchar *code;
+  gchar *identity;
+};
+
+typedef struct _GoaPocketProviderClass GoaPocketProviderClass;
+
+struct _GoaPocketProviderClass
+{
+  GoaOAuth2ProviderClass parent_class;
+};
+
+/**
+ * SECTION:goapocketprovider
+ * @title: GoaPocketProvider
+ * @short_description: A provider for Pocket accounts
+ *
+ * #GoaPocketProvider is used for handling Pocket accounts.
+ */
+
+G_DEFINE_TYPE_WITH_CODE (GoaPocketProvider, goa_pocket_provider, GOA_TYPE_OAUTH2_PROVIDER,
+                         goa_provider_ensure_extension_points_registered ();
+                         g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
+                                                         g_define_type_id,
+                                                         "pocket",
+                                                         0));
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static const gchar *
+get_provider_type (GoaProvider *_provider)
+{
+  return "pocket";
+}
+
+static gchar *
+get_provider_name (GoaProvider *_provider,
+                   GoaObject   *object)
+{
+  return g_strdup (_("Pocket"));
+}
+
+static GoaProviderGroup
+get_provider_group (GoaProvider *_provider)
+{
+  return GOA_PROVIDER_GROUP_BRANDED;
+}
+
+static GoaProviderFeatures
+get_provider_features (GoaProvider *_provider)
+{
+  return GOA_PROVIDER_FEATURE_BRANDED |
+         GOA_PROVIDER_FEATURE_READ_LATER;
+}
+
+static const gchar *
+get_request_uri (GoaOAuth2Provider *provider)
+{
+  return "https://getpocket.com/v3/oauth/request";;
+}
+
+static const gchar *
+get_authorization_uri (GoaOAuth2Provider *provider)
+{
+  return "https://getpocket.com/auth/authorize";;
+}
+
+static const gchar *
+get_token_uri (GoaOAuth2Provider *provider)
+{
+  return NULL;
+}
+
+static const gchar *
+get_redirect_uri (GoaOAuth2Provider *provider)
+{
+  return "https://localhost";;
+}
+
+static const gchar *
+get_client_id (GoaOAuth2Provider *provider)
+{
+  return GOA_POCKET_CLIENT_ID;
+}
+
+static const gchar *
+get_client_secret (GoaOAuth2Provider *provider)
+{
+  return NULL;
+}
+
+static gchar *
+build_authorization_uri (GoaOAuth2Provider  *provider,
+                         const gchar        *authorization_uri,
+                         const gchar        *escaped_redirect_uri,
+                         const gchar        *escaped_client_id,
+                         const gchar        *escaped_scope)
+{
+  GoaPocketProvider *pocket = GOA_POCKET_PROVIDER (provider);
+  RestProxy *proxy;
+  RestProxyCall *call;
+  const gchar *payload;
+  gchar *code, *url;
+  GError *error = NULL;
+  GHashTable *hash;
+
+  g_clear_pointer (&pocket->code, g_free);
+
+  url = NULL;
+
+  proxy = rest_proxy_new (get_request_uri (provider), FALSE);
+  call = rest_proxy_new_call (proxy);
+
+  rest_proxy_call_set_method (call, "POST");
+  rest_proxy_call_add_header (call, "Content-Type", "application/x-www-form-urlencoded");
+  rest_proxy_call_add_param (call, "consumer_key", GOA_POCKET_CLIENT_ID);
+  rest_proxy_call_add_param (call, "redirect_uri", get_redirect_uri (provider));
+
+  if (!rest_proxy_call_sync (call, &error))
+    {
+      g_debug ("Call to %s failed: %s", get_redirect_uri (provider), error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  payload = rest_proxy_call_get_payload (call);
+  hash = soup_form_decode (payload);
+  code = g_strdup (g_hash_table_lookup (hash, "code"));
+  g_hash_table_unref (hash);
+
+  if (!code)
+    {
+      g_debug ("Failed to get code from answer to %s", get_redirect_uri (provider));
+      goto out;
+    }
+
+  url = g_strdup_printf ("%s"
+                         "?request_token=%s"
+                         "&redirect_uri=%s",
+                         authorization_uri,
+                         code,
+                         escaped_redirect_uri);
+
+  pocket->code = code;
+
+out:
+  g_clear_object (&call);
+  g_clear_object (&proxy);
+  return url;
+}
+
+static gboolean
+process_redirect_url (GoaOAuth2Provider            *provider,
+                      const gchar                  *redirect_url,
+                      gchar                       **access_token,
+                      GError                      **error)
+{
+  GoaPocketProvider *pocket = GOA_POCKET_PROVIDER (provider);
+  RestProxy *proxy;
+  RestProxyCall *call;
+  GHashTable *hash;
+  const gchar *payload;
+  gboolean ret;
+
+  ret = FALSE;
+
+  proxy = rest_proxy_new (V3_OAUTH_AUTHORIZE_URL, FALSE);
+  call = rest_proxy_new_call (proxy);
+
+  rest_proxy_call_set_method (call, "POST");
+  rest_proxy_call_add_header (call, "Content-Type", "application/x-www-form-urlencoded");
+  rest_proxy_call_add_param (call, "consumer_key", GOA_POCKET_CLIENT_ID);
+  rest_proxy_call_add_param (call, "code", pocket->code);
+
+  if (!rest_proxy_call_sync (call, error))
+    goto out;
+
+  payload = rest_proxy_call_get_payload (call);
+  hash = soup_form_decode (payload);
+  pocket->identity = g_strdup (g_hash_table_lookup (hash, "username"));
+  *access_token = g_strdup (g_hash_table_lookup (hash, "access_token"));
+  g_hash_table_unref (hash);
+
+  if (pocket->identity == NULL|| *access_token == NULL)
+    {
+      g_set_error (error,
+                   GOA_ERROR,
+                   GOA_ERROR_FAILED, /* TODO: more specific */
+                   _("No username or access_token"));
+      g_clear_pointer (&pocket->identity, g_free);
+      g_clear_pointer (access_token, g_free);
+      goto out;
+    }
+
+  ret = TRUE;
+
+out:
+  g_clear_object (&call);
+  g_clear_object (&proxy);
+  return ret;
+}
+
+static const gchar *
+get_authentication_cookie (GoaOAuth2Provider *provider)
+{
+  return NULL;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *
+get_identity_sync (GoaOAuth2Provider  *provider,
+                   const gchar        *access_token,
+                   gchar             **out_presentation_identity,
+                   GCancellable       *cancellable,
+                   GError            **error)
+{
+  GoaPocketProvider *pocket = GOA_POCKET_PROVIDER (provider);
+  if (out_presentation_identity != NULL)
+    *out_presentation_identity = g_strdup (pocket->identity);
+  return g_strdup (pocket->identity);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+is_deny_node (GoaOAuth2Provider *provider, WebKitDOMNode *node)
+{
+  WebKitDOMElement *element;
+  gboolean ret;
+  gchar *id;
+  gchar *class;
+  gchar *text;
+
+  id = NULL;
+  class = NULL;
+  text = NULL;
+  ret = FALSE;
+
+  if (!WEBKIT_DOM_IS_ELEMENT (node))
+    goto out;
+
+  element = WEBKIT_DOM_ELEMENT (node);
+
+  /* Desktop version */
+  id = webkit_dom_element_get_id (element);
+  if (g_strcmp0 (id, "denyButton") == 0)
+    {
+      ret = TRUE;
+      goto out;
+    }
+
+  /* Mobile version */
+  class = webkit_dom_element_get_class_name (element);
+  if (g_strcmp0 (class, "toolbarButton") != 0)
+    goto out;
+
+  /* FIXME: This only seems to work if we don't click on the "Sign Up"
+   * button, does the check need to be done again? */
+  text = webkit_dom_node_get_text_content (node);
+  if (g_strcmp0 (text, "Cancel") != 0)
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  g_free (id);
+  g_free (class);
+  g_free (text);
+  return ret;
+}
+
+static gboolean
+is_identity_node (GoaOAuth2Provider *provider, WebKitDOMHTMLInputElement *element)
+{
+  gboolean ret;
+  gchar *name;
+
+  ret = FALSE;
+
+  name = webkit_dom_html_input_element_get_name (element);
+  if (g_strcmp0 (name, "feed_id") != 0)
+    goto out;
+
+  ret = TRUE;
+
+out:
+  g_free (name);
+  return ret;
+
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+build_object (GoaProvider         *provider,
+              GoaObjectSkeleton   *object,
+              GKeyFile            *key_file,
+              const gchar         *group,
+              GDBusConnection     *connection,
+              gboolean             just_added,
+              GError             **error)
+{
+  GoaAccount *account;
+  GoaReadLater *readlater = NULL;
+  gboolean read_later_enabled;
+  gboolean ret = FALSE;
+
+  account = NULL;
+
+  /* Chain up */
+  if (!GOA_PROVIDER_CLASS (goa_pocket_provider_parent_class)->build_object (provider,
+                                                                            object,
+                                                                            key_file,
+                                                                            group,
+                                                                            connection,
+                                                                            just_added,
+                                                                            error))
+    goto out;
+
+  account = goa_object_get_account (GOA_OBJECT (object));
+
+  /* Read Later */
+  readlater = goa_object_get_read_later (GOA_OBJECT (object));
+  read_later_enabled = g_key_file_get_boolean (key_file, group, "ReadLaterEnabled", NULL);
+  if (read_later_enabled)
+    {
+      if (readlater == NULL)
+        {
+          readlater = goa_read_later_skeleton_new ();
+          goa_object_skeleton_set_read_later (object, readlater);
+        }
+    }
+  else
+    {
+      if (readlater != NULL)
+        goa_object_skeleton_set_read_later (object, NULL);
+    }
+
+  if (just_added)
+    {
+      goa_account_set_read_later_disabled (account, !read_later_enabled);
+
+      g_signal_connect (account,
+                        "notify::read-later-disabled",
+                        G_CALLBACK (goa_util_account_notify_property_cb),
+                        "ReadLaterEnabled");
+    }
+
+  ret = TRUE;
+
+ out:
+  if (readlater != NULL)
+    g_object_unref (readlater);
+  if (account != NULL)
+    g_object_unref (account);
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+show_account (GoaProvider         *provider,
+              GoaClient           *client,
+              GoaObject           *object,
+              GtkBox              *vbox,
+              GtkGrid             *grid,
+              G_GNUC_UNUSED GtkGrid *dummy)
+{
+  gint row;
+
+  row = 0;
+
+  goa_util_add_account_info (grid, row++, object);
+
+  goa_util_add_row_switch_from_keyfile_with_blurb (grid, row++, object,
+                                                   /* Translators: This is a label for a series of
+                                                    * options switches. For example: “Use for Mail”. */
+                                                   _("Use for"),
+                                                   "read-later-disabled",
+                                                   _("_Read Later"));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+add_account_key_values (GoaOAuth2Provider *provider,
+                        GVariantBuilder   *builder)
+{
+  g_variant_builder_add (builder, "{ss}", "ReadLaterEnabled", "true");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+get_use_mobile_browser (GoaOAuth2Provider *provider)
+{
+  return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+goa_pocket_provider_init (GoaPocketProvider *client)
+{
+}
+
+static void
+goa_pocket_provider_finalize (GObject *object)
+{
+  GoaPocketProvider *provider = GOA_POCKET_PROVIDER (object);
+
+  g_clear_pointer (&provider->code, g_free);
+  g_clear_pointer (&provider->identity, g_free);
+
+  G_OBJECT_CLASS (goa_pocket_provider_parent_class)->finalize (object);
+}
+
+static void
+goa_pocket_provider_class_init (GoaPocketProviderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GoaProviderClass *provider_class = GOA_PROVIDER_CLASS (klass);
+  GoaOAuth2ProviderClass *oauth2_class = GOA_OAUTH2_PROVIDER_CLASS (klass);
+
+  object_class->finalize = goa_pocket_provider_finalize;
+
+  provider_class->get_provider_type          = get_provider_type;
+  provider_class->get_provider_name          = get_provider_name;
+  provider_class->get_provider_group         = get_provider_group;
+  provider_class->get_provider_features      = get_provider_features;
+  provider_class->build_object               = build_object;
+  provider_class->show_account               = show_account;
+
+  oauth2_class->build_authorization_uri   = build_authorization_uri;
+  oauth2_class->get_authorization_uri     = get_authorization_uri;
+  oauth2_class->get_token_uri             = get_token_uri;
+  oauth2_class->get_redirect_uri          = get_redirect_uri;
+  oauth2_class->get_client_id             = get_client_id;
+  oauth2_class->get_client_secret         = get_client_secret;
+  oauth2_class->get_identity_sync         = get_identity_sync;
+  oauth2_class->is_deny_node              = is_deny_node;
+  oauth2_class->is_identity_node          = is_identity_node;
+  oauth2_class->add_account_key_values    = add_account_key_values;
+  oauth2_class->get_use_mobile_browser    = get_use_mobile_browser;
+  oauth2_class->process_redirect_url      = process_redirect_url;
+  oauth2_class->get_authentication_cookie = get_authentication_cookie;
+}
diff --git a/src/goabackend/goapocketprovider.h b/src/goabackend/goapocketprovider.h
new file mode 100644
index 0000000..e01337b
--- /dev/null
+++ b/src/goabackend/goapocketprovider.h
@@ -0,0 +1,44 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Bastien Nocera <hadess hadess net>
+ */
+
+#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION)
+#error "Only <goabackend/goabackend.h> can be included directly."
+#endif
+
+#ifndef __GOA_POCKET_PROVIDER_H__
+#define __GOA_POCKET_PROVIDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GOA_TYPE_POCKET_PROVIDER   (goa_pocket_provider_get_type ())
+#define GOA_POCKET_PROVIDER(o)     (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_POCKET_PROVIDER, 
GoaPocketProvider))
+#define GOA_IS_POCKET_PROVIDER(o)  (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_POCKET_PROVIDER))
+
+typedef struct _GoaPocketProvider GoaPocketProvider;
+
+GType goa_pocket_provider_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GOA_POCKET_PROVIDER_H__ */
diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c
index 5d4385e..8aba855 100644
--- a/src/goabackend/goaprovider.c
+++ b/src/goabackend/goaprovider.c
@@ -39,6 +39,7 @@
 #include "goaflickrprovider.h"
 #include "goawindowsliveprovider.h"
 #include "goatelepathyfactory.h"
+#include "goapocketprovider.h"
 
 #ifdef GOA_KERBEROS_ENABLED
 #include "goakerberosprovider.h"
@@ -788,6 +789,9 @@ ensure_builtins_loaded (void)
 #ifdef GOA_WINDOWS_LIVE_ENABLED
       type = GOA_TYPE_WINDOWS_LIVE_PROVIDER;
 #endif
+#ifdef GOA_POCKET_ENABLED
+      type = GOA_TYPE_POCKET_PROVIDER;
+#endif
 #ifdef GOA_EXCHANGE_ENABLED
       type = GOA_TYPE_EXCHANGE_PROVIDER;
 #endif


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