diff options
author | Bastien Nocera <hadess@hadess.net> | 2015-07-19 15:00:38 +0200 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2015-07-21 14:38:45 +0200 |
commit | b53c916d12dfc393991155e126859103f681142d (patch) | |
tree | 338a09e824ebd3879ae87e3deb39d646c781a9fb | |
parent | b6c474d99085af80b5058ef385bc54617bf0521a (diff) | |
download | grilo-plugins-b53c916d12dfc393991155e126859103f681142d.tar.gz |
pocket: Remove stand-alone C pocket plugin
It's been replaced by a Lua version.
-rw-r--r-- | configure.ac | 53 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/pocket/Makefile.am | 48 | ||||
-rw-r--r-- | src/pocket/channel-pocket.svg | 137 | ||||
-rw-r--r-- | src/pocket/gnome-pocket.c | 1052 | ||||
-rw-r--r-- | src/pocket/gnome-pocket.h | 124 | ||||
-rw-r--r-- | src/pocket/grl-pocket.c | 393 | ||||
-rw-r--r-- | src/pocket/grl-pocket.h | 76 | ||||
-rw-r--r-- | src/pocket/grl-pocket.xml | 10 | ||||
-rw-r--r-- | src/pocket/pocket.gresource.xml | 6 |
11 files changed, 1 insertions, 1905 deletions
diff --git a/configure.ac b/configure.ac index f480ad5..bdc98c3 100644 --- a/configure.ac +++ b/configure.ac @@ -144,8 +144,6 @@ PKG_CHECK_MODULES(OAUTH, oauth, HAVE_OAUTH=yes, HAVE_OAUTH=no) PKG_CHECK_MODULES(GOA, [goa-1.0 >= 3.7.1], HAVE_GOA=yes, HAVE_GOA=no) -PKG_CHECK_MODULES(GOA_WITH_POCKET, [goa-1.0 >= 3.11.4], HAVE_GOA_WITH_POCKET=yes, HAVE_GOA_WITH_POCKET=no) - PKG_CHECK_MODULES(TOTEM_PL_PARSER, totem-plparser >= 3.4.1, HAVE_TOTEM_PL_PARSER=yes, HAVE_TOTEM_PL_PARSER=no) PKG_CHECK_MODULES(TOTEM_PL_PARSER_MINI, totem-plparser-mini >= 3.4.1, HAVE_TOTEM_PL_PARSER_MINI=yes, HAVE_TOTEM_PL_PARSER_MINI=no) @@ -505,56 +503,6 @@ fi AC_SUBST(DEPS_FLICKR_LIBS) # ---------------------------------------------------------- -# BUILD POCKET PLUGIN -# ---------------------------------------------------------- - -AC_ARG_ENABLE(pocket, - AC_HELP_STRING([--enable-pocket], - [enable Pocket plugin (default: auto)]), - [ - case "$enableval" in - yes) - if test "x$HAVE_JSON_GLIB" = "xno"; then - AC_MSG_ERROR([json-glib not found, install it or use --disable-pocket]) - fi - if test "x$HAVE_GOA_WITH_POCKET" = "xno"; then - AC_MSG_ERROR([goa-1.0 >= 3.11.4 not found, install it or use --disable-pocket]) - fi - if test "x$HAVE_REST" = "xno"; then - AC_MSG_ERROR([rest >= 0.7.90 not found, install it or use --disable-pocket]) - fi - if test "x$HAVE_TOTEM_PL_PARSER" = "xno"; then - AC_MSG_ERROR([totem-pl-parser not found, install it or use --disable-pocket]) - fi - ;; - esac - ], - [ - if test "x$HAVE_JSON_GLIB" = "xyes" -a "x$HAVE_GOA_WITH_POCKET" = "xyes" -a "x$HAVE_REST" = "xyes" -a "x$HAVE_TOTEM_PL_PARSER" = "xyes"; then - enable_pocket=yes - else - enable_pocket=no - fi - ]) - -AM_CONDITIONAL([POCKET_PLUGIN], [test "x$enable_pocket" = "xyes"]) -GRL_PLUGINS_ALL="$GRL_PLUGINS_ALL pocket" -if test "x$enable_pocket" = "xyes" -then - GRL_PLUGINS_ENABLED="$GRL_PLUGINS_ENABLED pocket" -fi - -POCKET_PLUGIN_ID="grl-pocket" -AC_SUBST(POCKET_PLUGIN_ID) -AC_DEFINE_UNQUOTED([POCKET_PLUGIN_ID], ["$POCKET_PLUGIN_ID"], [Pocket plugin ID]) - -DEPS_POCKET_CFLAGS="$DEPS_CFLAGS $JSON_CFLAGS $GOA_WITH_POCKET_CFLAGS $REST_CFLAGS $TOTEM_PL_PARSER_CFLAGS" -AC_SUBST(DEPS_POCKET_CFLAGS) - -DEPS_POCKET_LIBS="$DEPS_LIBS $JSON_LIBS $GOA_WITH_POCKET_LIBS $REST_LIBS $TOTEM_PL_PARSER_LIBS" -AC_SUBST(DEPS_POCKET_LIBS) - -# ---------------------------------------------------------- # BUILD PODCASTS PLUGIN # ---------------------------------------------------------- @@ -1446,7 +1394,6 @@ AC_CONFIG_FILES([ src/metadata-store/Makefile src/opensubtitles/Makefile src/optical-media/Makefile - src/pocket/Makefile src/podcasts/Makefile src/raitv/Makefile src/shoutcast/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index c373a8e..45c1ecd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,7 +15,6 @@ src/magnatune/grl-magnatune.c src/metadata-store/grl-metadata-store.c src/opensubtitles/grl-opensubtitles.c src/optical-media/grl-optical-media.c -src/pocket/grl-pocket.c src/podcasts/grl-podcasts.c src/raitv/grl-raitv.c src/shoutcast/grl-shoutcast.c diff --git a/src/Makefile.am b/src/Makefile.am index 92a0a31..d0b9e14 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,10 +70,6 @@ if OPTICAL_MEDIA_PLUGIN SUBDIRS += optical-media endif -if POCKET_PLUGIN -SUBDIRS += pocket -endif - if PODCASTS_PLUGIN SUBDIRS += podcasts endif @@ -117,6 +113,6 @@ endif DIST_SUBDIRS = \ apple-trailers bliptv bookmarks dleyna dmap filesystem flickr freebox gravatar jamendo \ lastfm-albumart local-metadata lua-factory magnatune metadata-store opensubtitles \ - optical-media pocket podcasts raitv shoutcast thetvdb tmdb tracker vimeo youtube + optical-media podcasts raitv shoutcast thetvdb tmdb tracker vimeo youtube -include $(top_srcdir)/git.mk diff --git a/src/pocket/Makefile.am b/src/pocket/Makefile.am deleted file mode 100644 index 74611e2..0000000 --- a/src/pocket/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# -# Makefile.am -# -# Author: Bastien Nocera <hadess@hadess.net> -# -# Copyright (C) 2013 Bastien Nocera - -include $(top_srcdir)/gtester.mk - -ext_LTLIBRARIES = libgrlpocket.la - -libgrlpocket_la_CFLAGS = \ - $(DEPS_POCKET_CFLAGS) \ - -DG_LOG_DOMAIN=\"GrlPocket\" \ - -DLOCALEDIR=\"$(localedir)\" - -libgrlpocket_la_LIBADD = \ - $(DEPS_POCKET_LIBS) - -libgrlpocket_la_LDFLAGS = \ - -no-undefined \ - -module \ - -avoid-version - -libgrlpocket_la_SOURCES = \ - grl-pocket.c \ - grl-pocket.h \ - gnome-pocket.h \ - gnome-pocket.c \ - pocketresources.h \ - pocketresources.c - -pocketresources.h: pocket.gresource.xml - $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $(srcdir)/pocket.gresource.xml \ - --target=$@ --sourcedir=$(srcdir) --c-name _grl_pocket --generate-header -pocketresources.c: pocket.gresource.xml pocketresources.h channel-pocket.svg - $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $(srcdir)/pocket.gresource.xml \ - --target=$@ --sourcedir=$(srcdir) --c-name _grl_pocket --generate-source - -extdir = $(GRL_PLUGINS_DIR) -pocketxmldir = $(GRL_PLUGINS_DIR) -pocketxml_DATA = $(POCKET_PLUGIN_ID).xml - -EXTRA_DIST += $(pocketxml_DATA) channel-pocket.svg pocket.gresource.xml - -CLEANFILES = pocketresources.h pocketresources.c - --include $(top_srcdir)/git.mk diff --git a/src/pocket/channel-pocket.svg b/src/pocket/channel-pocket.svg deleted file mode 100644 index 90e834c..0000000 --- a/src/pocket/channel-pocket.svg +++ /dev/null @@ -1,137 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="256" - height="256" - id="svg2" - version="1.1" - inkscape:version="0.48.4 r9939" - sodipodi:docname="channel-youtube.svg"> - <defs - id="defs4"> - <clipPath - id="clipPath6193" - clipPathUnits="userSpaceOnUse"> - <path - id="path6195" - d="m 1600,2252.8 5020,0 0,3650 -5020,0 0,-3650 z" /> - </clipPath> - <linearGradient - id="linearGradient6181" - spreadMethod="pad" - gradientTransform="matrix(-3.593e-5,822,822,3.593e-5,411,0)" - gradientUnits="userSpaceOnUse" - y2="0" - x2="1" - y1="0" - x1="0"> - <stop - id="stop6183" - offset="0" - style="stop-opacity:1;stop-color:#c01e25" /> - <stop - id="stop6185" - offset="1" - style="stop-opacity:1;stop-color:#e62426" /> - </linearGradient> - <clipPath - id="clipPath6177" - clipPathUnits="userSpaceOnUse"> - <path - id="path6179" - d="M 8220,0 0,0 l 0,8220 8220,0 0,-8220 m -6620,5902.8 0,-3650 5020,0 0,3650 -5020,0" /> - </clipPath> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#505050" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="1" - inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="120.49386" - inkscape:cy="175.09957" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - borderlayer="true" - inkscape:showpageshadow="false" - inkscape:window-width="2560" - inkscape:window-height="1374" - inkscape:window-x="0" - inkscape:window-y="27" - inkscape:window-maximized="1" - inkscape:snap-bbox="true" - inkscape:object-nodes="true" /> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(0,-796.36218)"> - <g - transform="matrix(630.025,0,0,-458.9,-77.5125,1218.8747)" - id="g6197" /> - <path - style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" - d="m 30.115602,817.66358 197.356268,0 8.00002,11.43214 L 235,1033.6169 l -212.5,0 -0.384417,-204.52118 z" - id="rect7653" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccccc" /> - <path - style="color:#000000;fill:#ee4055;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" - d="m 70.934854,870.79411 c -8.818633,0 -15.925195,7.19797 -15.925195,16.13479 l 0,34.39697 c 0,46.31516 24.636814,78.60443 72.990311,78.60443 47.87064,0 72.99037,-32.01415 72.99037,-78.60443 l 0,-34.39697 c 0,-8.93682 -7.1065,-16.13479 -15.92514,-16.13479 z m 90.664866,36.33346 c 2.50474,0 5.01393,0.98537 6.937,2.93364 3.84636,3.89713 3.84636,10.22089 0,14.11802 l -32.84559,33.2774 c -2.11228,2.13974 -4.94066,4.42546 -7.6911,4.21491 -2.7505,0.21336 -5.57882,-2.07517 -7.69116,-4.21491 l -32.845583,-33.2774 c -3.846309,-3.89713 -3.846309,-10.22089 0,-14.11802 1.923126,-1.94827 4.457406,-2.90276 6.967205,-2.90276 2.50986,0 4.98384,0.95449 6.906958,2.90276 l 26.66258,27.01316 26.66252,-27.01316 c 1.92324,-1.94827 4.43236,-2.93364 6.93717,-2.93364 z" - id="path4636" - inkscape:connector-curvature="0" - sodipodi:nodetypes="sssssssssssscssssscss" /> - <g - transform="matrix(5.6146396,0,0,5.6146396,-2740.2871,170.98003)" - style="display:inline;enable-background:new" - id="g10051"> - <path - style="color:#000000;fill:#75d4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" - d="m 493.42485,115 7.57515,0 0,2.03613 -9,0 z" - id="rect10035" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;fill:#50b6b1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" - d="m 501,115 10,0 0,2.03613 -10.40074,0 z" - id="rect10037" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;fill:#e94055;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" - d="m 511,115 10,0 0.44526,2.03613 -10.44526,0 z" - id="rect10039" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;fill:#e8a945;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" - d="m 521,115 7.57515,0 1.42485,2.03613 -8.59926,0 z" - id="rect10041" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - </g> - </g> -</svg> diff --git a/src/pocket/gnome-pocket.c b/src/pocket/gnome-pocket.c deleted file mode 100644 index 2013624..0000000 --- a/src/pocket/gnome-pocket.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2013 Bastien Nocera <hadess@hadess.net> - * - * This program 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 pocket version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Implementation of: - * http://getpocket.com/developer/docs/overview - */ - -//#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <glib/gstdio.h> -#define GOA_API_IS_SUBJECT_TO_CHANGE 1 -#include <goa/goa.h> -#include <rest/rest-proxy.h> -#include <rest/rest-proxy-call.h> -#include <json-glib/json-glib.h> - -#include "gnome-pocket.h" - -static gpointer -gnome_pocket_item_copy (gpointer boxed) -{ - GnomePocketItem *src = boxed; - - GnomePocketItem *dest = g_new (GnomePocketItem, 1); - dest->id = g_strdup (src->id); - dest->url = g_strdup (src->url); - dest->title = g_strdup (src->title); - dest->favorite = src->favorite; - dest->status = src->status; - dest->is_article = src->is_article; - dest->has_image = src->has_image; - dest->has_video = src->has_video; - dest->time_added = src->time_added; - dest->tags = g_strdupv (src->tags); - - return dest; -} - -static void -gnome_pocket_item_free (gpointer boxed) -{ - GnomePocketItem *item = boxed; - - g_free (item->id); - g_free (item->url); - g_free (item->title); - g_strfreev (item->tags); - g_free (item); -} - -static char * -get_string_for_element (JsonReader *reader, - const char *element) -{ - char *ret; - - if (!json_reader_read_member (reader, element)) { - json_reader_end_member (reader); - return NULL; - } - ret = g_strdup (json_reader_get_string_value (reader)); - if (ret && *ret == '\0') - g_clear_pointer (&ret, g_free); - json_reader_end_member (reader); - - return ret; -} - -static int -get_int_for_element (JsonReader *reader, - const char *element) -{ - int ret; - - if (!json_reader_read_member (reader, element)) { - json_reader_end_member (reader); - return -1; - } - ret = atoi (json_reader_get_string_value (reader)); - json_reader_end_member (reader); - - return ret; -} - -static gint64 -get_time_added (JsonReader *reader) -{ - gint64 ret; - - if (!json_reader_read_member (reader, "time_added")) { - json_reader_end_member (reader); - return -1; - } - ret = g_ascii_strtoll (json_reader_get_string_value (reader), NULL, 0); - json_reader_end_member (reader); - - return ret; -} - -static GnomePocketItem * -parse_item (JsonReader *reader) -{ - GnomePocketItem *item; - - item = g_new0 (GnomePocketItem, 1); - item->id = g_strdup (json_reader_get_member_name (reader)); - if (!item->id) - goto bail; - - /* If the item is archived or deleted, we don't need - * anything more here */ - item->status = get_int_for_element (reader, "status"); - if (item->status != POCKET_STATUS_NORMAL) - goto end; - - item->url = get_string_for_element (reader, "resolved_url"); - if (!item->url) - item->url = get_string_for_element (reader, "given_url"); - - item->title = get_string_for_element (reader, "resolved_title"); - if (!item->title) - item->title = get_string_for_element (reader, "given_title"); - if (!item->title) - item->title = g_strdup ("PLACEHOLDER"); /* FIXME generate from URL */ - - item->favorite = get_int_for_element (reader, "favorite"); - item->is_article = get_int_for_element (reader, "is_article"); - if (item->is_article == -1) - item->is_article = FALSE; - item->has_image = get_int_for_element (reader, "has_image"); - if (item->has_image == -1) - item->has_image = POCKET_HAS_MEDIA_FALSE; - item->has_video = get_int_for_element (reader, "has_video"); - if (item->has_video == -1) - item->has_video = POCKET_HAS_MEDIA_FALSE; - - item->time_added = get_time_added (reader); - - if (json_reader_read_member (reader, "tags")) - item->tags = json_reader_list_members (reader); - json_reader_end_member (reader); - - if (json_reader_read_member (reader, "image")) - item->thumbnail_url = get_string_for_element (reader, "src"); - json_reader_end_member (reader); - - goto end; - -bail: - g_clear_pointer (&item, gnome_pocket_item_free); - -end: - return item; -} - -GnomePocketItem * -gnome_pocket_item_from_string (const char *str) -{ - JsonParser *parser; - JsonReader *reader; - GnomePocketItem *item = NULL; - char **members = NULL; - - parser = json_parser_new (); - if (!json_parser_load_from_data (parser, str, -1, NULL)) - return NULL; - - reader = json_reader_new (json_parser_get_root (parser)); - members = json_reader_list_members (reader); - if (!members) - goto bail; - - if (!json_reader_read_member (reader, members[0])) - goto bail; - - item = parse_item (reader); - -bail: - g_clear_pointer (&members, g_strfreev); - g_clear_object (&reader); - g_clear_object (&parser); - - return item; -} - -static void -builder_add_int_as_str (JsonBuilder *builder, - const char *name, - int value) -{ - char *tmp; - - json_builder_set_member_name (builder, name); - tmp = g_strdup_printf ("%d", value); - json_builder_add_string_value (builder, tmp); - g_free (tmp); -} - -static void -builder_add_int64_as_str (JsonBuilder *builder, - const char *name, - gint64 value) -{ - char *tmp; - - json_builder_set_member_name (builder, name); - tmp = g_strdup_printf ("%" G_GINT64_FORMAT, value); - json_builder_add_string_value (builder, tmp); - g_free (tmp); -} - -char * -gnome_pocket_item_to_string (GnomePocketItem *item) -{ - char *ret = NULL; - JsonBuilder *builder; - JsonGenerator *gen; - JsonNode *root; - - builder = json_builder_new (); - - json_builder_begin_object (builder); - json_builder_set_member_name (builder, item->id); - - json_builder_begin_object (builder); - - json_builder_set_member_name (builder, "item_id"); - json_builder_add_string_value (builder, item->id); - - json_builder_set_member_name (builder, "resolved_url"); - json_builder_add_string_value (builder, item->url); - - json_builder_set_member_name (builder, "resolved_title"); - json_builder_add_string_value (builder, item->title); - - builder_add_int_as_str (builder, "favorite", item->favorite); - builder_add_int_as_str (builder, "status", item->status); - builder_add_int_as_str (builder, "is_article", item->is_article); - builder_add_int_as_str (builder, "has_image", item->has_image); - builder_add_int_as_str (builder, "has_video", item->has_video); - builder_add_int64_as_str (builder, "time_added", item->time_added); - - if (item->thumbnail_url) { - json_builder_set_member_name (builder, "image"); - json_builder_begin_object (builder); - - json_builder_set_member_name (builder, "item_id"); - json_builder_add_string_value (builder, item->id); - json_builder_set_member_name (builder, "src"); - json_builder_add_string_value (builder, item->thumbnail_url); - - json_builder_end_object (builder); - } - - json_builder_end_object (builder); - json_builder_end_object (builder); - - gen = json_generator_new (); - root = json_builder_get_root (builder); - json_generator_set_root (gen, root); - ret = json_generator_to_data (gen, NULL); - - json_node_free (root); - g_object_unref (gen); - g_object_unref (builder); - - return ret; -} - -G_DEFINE_BOXED_TYPE(GnomePocketItem, gnome_pocket_item, gnome_pocket_item_copy, gnome_pocket_item_free) - -enum { - PROP_0, - PROP_AVAILABLE -}; - -G_DEFINE_TYPE (GnomePocket, gnome_pocket, G_TYPE_OBJECT); - -#define GNOME_POCKET_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GNOME_TYPE_POCKET, GnomePocketPrivate)) - -struct _GnomePocketPrivate { - GCancellable *cancellable; - GoaClient *client; - GoaOAuth2Based *oauth2; - char *access_token; - char *consumer_key; - RestProxy *proxy; - - /* List data */ - gboolean cache_loaded; - gint64 since; - GList *items; /* GnomePocketItem */ -}; - -gboolean -gnome_pocket_refresh_finish (GnomePocket *self, - GAsyncResult *res, - GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); - gboolean ret = FALSE; - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == gnome_pocket_refresh); - - if (!g_simple_async_result_propagate_error (simple, error)) - ret = g_simple_async_result_get_op_res_gboolean (simple); - - return ret; -} - -/* FIXME */ -static char *cache_path = NULL; - -static char * -gnome_pocket_item_get_path (GnomePocketItem *item) -{ - g_return_val_if_fail (item != NULL, NULL); - return g_build_filename (cache_path, item->id, NULL); -} - -static void -gnome_pocket_item_save (GnomePocketItem *item) -{ - char *path; - char *str; - - g_return_if_fail (item != NULL); - - path = gnome_pocket_item_get_path (item); - str = gnome_pocket_item_to_string (item); - g_file_set_contents (path, str, -1, NULL); - g_free (str); - g_free (path); -} - -static void -gnome_pocket_item_remove (GnomePocketItem *item) -{ - char *path; - - g_return_if_fail (item != NULL); - - path = gnome_pocket_item_get_path (item); - g_unlink (path); - g_free (path); -} - -static void -update_list (GnomePocket *self, - GList *updated_items) -{ - GHashTable *removed; /* key=id, value=gboolean */ - GList *added; - GList *l; - - if (updated_items == NULL) - return; - - removed = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - added = NULL; - for (l = updated_items; l != NULL; l = l->next) { - GnomePocketItem *item = l->data; - - if (item->status != POCKET_STATUS_NORMAL) { - g_hash_table_insert (removed, - g_strdup (item->id), - GINT_TO_POINTER (1)); - gnome_pocket_item_free (item); - } else { - added = g_list_prepend (added, item); - gnome_pocket_item_save (item); - } - } - - added = g_list_reverse (added); - self->priv->items = g_list_concat (added, self->priv->items); - - /* And remove the old items */ - for (l = self->priv->items; l != NULL; l = l->next) { - GnomePocketItem *item = l->data; - - if (g_hash_table_lookup (removed, item->id)) { - /* Item got removed */ - self->priv->items = g_list_delete_link (self->priv->items, l); - - gnome_pocket_item_remove (item); - gnome_pocket_item_free (item); - } - } - - g_hash_table_destroy (removed); -} - -static gint64 -load_since (GnomePocket *self) -{ - char *path; - char *contents = NULL; - gint64 since = 0; - - path = g_build_filename (cache_path, "since", NULL); - g_file_get_contents (path, &contents, NULL, NULL); - g_free (path); - - if (contents != NULL) { - since = g_ascii_strtoll (contents, NULL, 0); - g_free (contents); - } - - return since; -} - -static void -save_since (GnomePocket *self) -{ - char *str; - char *path; - - if (self->priv->since == 0) - return; - - str = g_strdup_printf ("%" G_GINT64_FORMAT, self->priv->since); - path = g_build_filename (cache_path, "since", NULL); - g_file_set_contents (path, str, -1, NULL); - g_free (path); - g_free (str); -} - -static int -sort_items (gconstpointer a, - gconstpointer b) -{ - GnomePocketItem *item_a = (gpointer) a; - GnomePocketItem *item_b = (gpointer) b; - - /* We sort newest first */ - if (item_a->time_added < item_b->time_added) - return 1; - if (item_b->time_added < item_a->time_added) - return -1; - return 0; -} - -static GList * -parse_json (JsonParser *parser, - gint64 *since) -{ - JsonReader *reader; - GList *ret; - int num; - - reader = json_reader_new (json_parser_get_root (parser)); - *since = 0; - ret = NULL; - - num = json_reader_count_members (reader); - if (num < 0) - goto bail; - - /* Grab the since */ - if (json_reader_read_member (reader, "since")) - *since = json_reader_get_int_value (reader); - json_reader_end_member (reader); - - /* Grab the list */ - if (json_reader_read_member (reader, "list")) { - char **members; - guint i; - - members = json_reader_list_members (reader); - if (members != NULL) { - for (i = 0; members[i] != NULL; i++) { - GnomePocketItem *item; - - if (!json_reader_read_member (reader, members[i])) { - json_reader_end_member (reader); - continue; - } - item = parse_item (reader); - if (item) - ret = g_list_prepend (ret, item); - json_reader_end_member (reader); - } - } - g_strfreev (members); - } - json_reader_end_member (reader); - - ret = g_list_sort (ret, sort_items); - -bail: - g_clear_object (&reader); - return ret; -} - -static void -refresh_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - GSimpleAsyncResult *simple = user_data; - gboolean ret; - - ret = rest_proxy_call_invoke_finish (REST_PROXY_CALL (object), res, &error); - if (!ret) { - g_simple_async_result_set_from_error (simple, error); - } else { - JsonParser *parser; - - parser = json_parser_new (); - if (json_parser_load_from_data (parser, - rest_proxy_call_get_payload (REST_PROXY_CALL (object)), - rest_proxy_call_get_payload_length (REST_PROXY_CALL (object)), - NULL)) { - GList *updated_items; - GnomePocket *self; - - self = GNOME_POCKET (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); - updated_items = parse_json (parser, &self->priv->since); - if (self->priv->since != 0) - save_since (self); - update_list (self, updated_items); - } - g_object_unref (parser); - } - g_simple_async_result_set_op_res_gboolean (simple, ret); - - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - g_clear_error (&error); -} - -void -gnome_pocket_refresh (GnomePocket *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - RestProxyCall *call; - GSimpleAsyncResult *simple; - - g_return_if_fail (GNOME_IS_POCKET (self)); - g_return_if_fail (self->priv->consumer_key && self->priv->access_token); - - simple = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - gnome_pocket_refresh); - - g_simple_async_result_set_check_cancellable (simple, cancellable); - - call = rest_proxy_new_call (self->priv->proxy); - rest_proxy_call_set_method (call, "POST"); - rest_proxy_call_set_function (call, "v3/get"); - rest_proxy_call_add_param (call, "consumer_key", self->priv->consumer_key); - rest_proxy_call_add_param (call, "access_token", self->priv->access_token); - - if (self->priv->since > 0) { - char *since; - since = g_strdup_printf ("%" G_GINT64_FORMAT, self->priv->since); - rest_proxy_call_add_param (call, "since", since); - g_free (since); - } - - /* To get the image/images/authors/videos item details */ - rest_proxy_call_add_param (call, "detailType", "complete"); - rest_proxy_call_add_param (call, "tags", "1"); - - rest_proxy_call_invoke_async (call, cancellable, refresh_cb, simple); -} - -gboolean -gnome_pocket_add_url_finish (GnomePocket *self, - GAsyncResult *res, - GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); - gboolean ret = FALSE; - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == gnome_pocket_add_url); - - if (!g_simple_async_result_propagate_error (simple, error)) - ret = g_simple_async_result_get_op_res_gboolean (simple); - - return ret; -} - -static void -add_url_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - GSimpleAsyncResult *simple = user_data; - gboolean ret; - - ret = rest_proxy_call_invoke_finish (REST_PROXY_CALL (object), res, &error); - if (!ret) - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_set_op_res_gboolean (simple, ret); - - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - g_clear_error (&error); -} - -void -gnome_pocket_add_url (GnomePocket *self, - const char *url, - const char *tweet_id, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - RestProxyCall *call; - GSimpleAsyncResult *simple; - - g_return_if_fail (GNOME_IS_POCKET (self)); - g_return_if_fail (url); - g_return_if_fail (self->priv->consumer_key && self->priv->access_token); - - simple = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - gnome_pocket_add_url); - - g_simple_async_result_set_check_cancellable (simple, cancellable); - - call = rest_proxy_new_call (self->priv->proxy); - rest_proxy_call_set_method (call, "POST"); - rest_proxy_call_set_function (call, "v3/add"); - rest_proxy_call_add_param (call, "consumer_key", self->priv->consumer_key); - rest_proxy_call_add_param (call, "access_token", self->priv->access_token); - rest_proxy_call_add_param (call, "url", url); - if (tweet_id) - rest_proxy_call_add_param (call, "tweet_id", tweet_id); - - rest_proxy_call_invoke_async (call, cancellable, add_url_cb, simple); -} - -static void -parse_cached_data (GnomePocket *self) -{ - GDir *dir; - const char *name; - - dir = g_dir_open (cache_path, 0, NULL); - if (!dir) - return; - - self->priv->since = load_since (self); - - name = g_dir_read_name (dir); - while (name) { - JsonParser *parser = NULL; - JsonReader *reader = NULL; - char *full_path = NULL; - char **members; - GnomePocketItem *item; - - if (g_strcmp0 (name, "since") == 0) - goto next; - - full_path = g_build_filename (cache_path, name, NULL); - parser = json_parser_new (); - if (!json_parser_load_from_file (parser, full_path, NULL)) - goto next; - - reader = json_reader_new (json_parser_get_root (parser)); - members = json_reader_list_members (reader); - if (!members) - goto next; - - if (!json_reader_read_member (reader, members[0])) - goto next; - - item = parse_item (reader); - if (!item) - g_warning ("Could not parse cached file '%s'", full_path); - else - self->priv->items = g_list_prepend (self->priv->items, item); - -next: - g_clear_object (&reader); - g_clear_object (&parser); - g_free (full_path); - - name = g_dir_read_name (dir); - } - g_dir_close (dir); - - self->priv->items = g_list_sort (self->priv->items, sort_items); -} - -static void -load_cached_thread (GTask *task, - gpointer source_object, - gpointer task_data, - GCancellable *cancellable) -{ - GnomePocket *self = GNOME_POCKET (source_object); - - parse_cached_data (self); - self->priv->cache_loaded = TRUE; - g_task_return_boolean (task, TRUE); -} - -void -gnome_pocket_load_cached (GnomePocket *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - - g_return_if_fail (GNOME_IS_POCKET (self)); - g_return_if_fail (!self->priv->cache_loaded); - - task = g_task_new (self, cancellable, callback, user_data); - g_task_run_in_thread (task, load_cached_thread); - g_object_unref (task); -} - -gboolean -gnome_pocket_load_cached_finish (GnomePocket *self, - GAsyncResult *res, - GError **error) -{ - GTask *task = G_TASK (res); - - g_return_val_if_fail (g_task_is_valid (res, self), NULL); - - return g_task_propagate_boolean (task, error); -} - -GList * -gnome_pocket_load_from_file (GnomePocket *self, - const char *filename, - GError **error) -{ - GList *ret; - gint64 since; - JsonParser *parser; - - parser = json_parser_new (); - if (!json_parser_load_from_file (parser, filename, error)) { - g_object_unref (parser); - return NULL; - } - - ret = parse_json (parser, &since); - g_object_unref (parser); - - return ret; -} - -static const char * -bool_to_str (gboolean b) -{ - return b ? "True" : "False"; -} - -static const char * -inclusion_to_str (PocketMediaInclusion inc) -{ - switch (inc) { - case POCKET_HAS_MEDIA_FALSE: - return "False"; - case POCKET_HAS_MEDIA_INCLUDED: - return "Included"; - case POCKET_IS_MEDIA: - return "Is media"; - default: - g_assert_not_reached (); - } -} - -void -gnome_pocket_print_item (GnomePocketItem *item) -{ - GDateTime *date; - char *date_str; - - g_return_if_fail (item != NULL); - - date = g_date_time_new_from_unix_utc (item->time_added); - date_str = g_date_time_format (date, "%F %R"); - g_date_time_unref (date); - - g_print ("Item: %s\n", item->id); - g_print ("\tTime added: %s\n", date_str); - g_print ("\tURL: %s\n", item->url); - if (item->thumbnail_url) - g_print ("\tThumbnail URL: %s\n", item->thumbnail_url); - g_print ("\tTitle: %s\n", item->title); - g_print ("\tFavorite: %s\n", bool_to_str (item->favorite)); - g_print ("\tIs article: %s\n", bool_to_str (item->is_article)); - g_print ("\tHas Image: %s\n", inclusion_to_str (item->has_image)); - g_print ("\tHas Video: %s\n", inclusion_to_str (item->has_video)); - if (item->tags != NULL) { - guint i; - g_print ("\tTags: "); - for (i = 0; item->tags[i] != NULL; i++) - g_print ("%s, ", item->tags[i]); - g_print ("\n"); - } - - g_free (date_str); -} - -GList * -gnome_pocket_get_items (GnomePocket *self) -{ - g_return_val_if_fail (self->priv->cache_loaded, NULL); - return self->priv->items; -} - -static void -gnome_pocket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - GnomePocket *self = GNOME_POCKET (object); - - switch (property_id) { - case PROP_AVAILABLE: - g_value_set_boolean (value, self->priv->access_token && self->priv->consumer_key); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); - break; - } -} - -static void -gnome_pocket_finalize (GObject *object) -{ - GnomePocketPrivate *priv = GNOME_POCKET (object)->priv; - - g_cancellable_cancel (priv->cancellable); - g_clear_object (&priv->cancellable); - - g_clear_object (&priv->proxy); - g_clear_object (&priv->oauth2); - g_clear_object (&priv->client); - g_clear_pointer (&priv->access_token, g_free); - g_clear_pointer (&priv->consumer_key, g_free); - - G_OBJECT_CLASS (gnome_pocket_parent_class)->finalize (object); -} - -static void -gnome_pocket_class_init (GnomePocketClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - cache_path = g_build_filename (g_get_user_cache_dir (), "pocket", NULL); - g_mkdir_with_parents (cache_path, 0700); - - object_class->get_property = gnome_pocket_get_property; - object_class->finalize = gnome_pocket_finalize; - - g_object_class_install_property (object_class, - PROP_AVAILABLE, - g_param_spec_boolean ("available", - "Available", - "If Read Pocket is available", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_type_class_add_private (object_class, sizeof (GnomePocketPrivate)); -} - -static void -got_access_token (GObject *object, - GAsyncResult *res, - GnomePocket *self) -{ - GError *error = NULL; - char *access_token; - - if (!goa_oauth2_based_call_get_access_token_finish (GOA_OAUTH2_BASED (object), - &access_token, - NULL, - res, - &error)) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - return; - } - g_warning ("Failed to get access token: %s", error->message); - g_error_free (error); - return; - } - - self->priv->access_token = access_token; - self->priv->consumer_key = goa_oauth2_based_dup_client_id (GOA_OAUTH2_BASED (object)); - - g_object_notify (G_OBJECT (self), "available"); -} - -static void -handle_accounts (GnomePocket *self) -{ - GList *accounts, *l; - GoaOAuth2Based *oauth2 = NULL; - - g_clear_object (&self->priv->oauth2); - g_clear_pointer (&self->priv->access_token, g_free); - g_clear_pointer (&self->priv->consumer_key, g_free); - - accounts = goa_client_get_accounts (self->priv->client); - - for (l = accounts; l != NULL; l = l->next) { - GoaObject *object = GOA_OBJECT (l->data); - GoaAccount *account; - - account = goa_object_peek_account (object); - - /* Find a Pocket account that doesn't have "Read Pocket" disabled */ - if (g_strcmp0 (goa_account_get_provider_type (account), "pocket") == 0 && - !goa_account_get_read_later_disabled (account)) { - oauth2 = goa_object_get_oauth2_based (object); - break; - } - } - - g_list_free_full (accounts, (GDestroyNotify) g_object_unref); - - if (!oauth2) { - g_object_notify (G_OBJECT (self), "available"); - g_debug ("Could not find a Pocket account"); - return; - } - - self->priv->oauth2 = oauth2; - - goa_oauth2_based_call_get_access_token (oauth2, - self->priv->cancellable, - (GAsyncReadyCallback) got_access_token, - self); -} - -static void -account_added_cb (GoaClient *client, - GoaObject *object, - GnomePocket *self) -{ - if (self->priv->oauth2 != NULL) { - /* Don't care, already have an account */ - return; - } - - handle_accounts (self); -} - -static void -account_changed_cb (GoaClient *client, - GoaObject *object, - GnomePocket *self) -{ - GoaOAuth2Based *oauth2; - - oauth2 = goa_object_get_oauth2_based (object); - if (oauth2 == self->priv->oauth2) - handle_accounts (self); - - g_object_unref (oauth2); -} - -static void -account_removed_cb (GoaClient *client, - GoaObject *object, - GnomePocket *self) -{ - GoaOAuth2Based *oauth2; - - oauth2 = goa_object_get_oauth2_based (object); - if (oauth2 == self->priv->oauth2) - handle_accounts (self); - - g_object_unref (oauth2); -} - -static void -client_ready_cb (GObject *source_object, - GAsyncResult *res, - GnomePocket *self) -{ - GoaClient *client; - GError *error = NULL; - - client = goa_client_new_finish (res, &error); - if (client == NULL) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - return; - } - g_warning ("Failed to get GoaClient: %s", error->message); - g_error_free (error); - return; - } - - self->priv->client = client; - g_signal_connect (self->priv->client, "account-added", - G_CALLBACK (account_added_cb), self); - g_signal_connect (self->priv->client, "account-changed", - G_CALLBACK (account_changed_cb), self); - g_signal_connect (self->priv->client, "account-removed", - G_CALLBACK (account_removed_cb), self); - - handle_accounts (self); -} - -static void -gnome_pocket_init (GnomePocket *self) -{ - self->priv = GNOME_POCKET_GET_PRIVATE (self); - self->priv->cancellable = g_cancellable_new (); - self->priv->proxy = rest_proxy_new ("https://getpocket.com/", FALSE); - - goa_client_new (self->priv->cancellable, - (GAsyncReadyCallback) client_ready_cb, self); -} - -GnomePocket * -gnome_pocket_new (void) -{ - return g_object_new (GNOME_TYPE_POCKET, NULL); -} - -/* - * vim: sw=2 ts=8 cindent noai bs=2 - */ diff --git a/src/pocket/gnome-pocket.h b/src/pocket/gnome-pocket.h deleted file mode 100644 index b5aee62..0000000 --- a/src/pocket/gnome-pocket.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright © 2013 Bastien Nocera <hadess@hadess.net> - * - * This program 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 pocket version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef GNOME_POCKET_H -#define GNOME_POCKET_H - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define POCKET_FAVORITE TRUE -#define POCKET_NOT_FAVORITE FALSE - -typedef enum { - POCKET_STATUS_NORMAL = 0, - POCKET_STATUS_ARCHIVED = 1, - POCKET_STATUS_DELETED = 2 -} PocketItemStatus; - -#define POCKET_IS_ARTICLE TRUE -#define POCKET_IS_NOT_ARTICLE FALSE - -typedef enum { - POCKET_HAS_MEDIA_FALSE = 0, - POCKET_HAS_MEDIA_INCLUDED = 1, - POCKET_IS_MEDIA = 2 -} PocketMediaInclusion; - -typedef struct { - char *id; - char *url; - char *title; - char *thumbnail_url; - gboolean favorite; - PocketItemStatus status; - gboolean is_article; - PocketMediaInclusion has_image; - PocketMediaInclusion has_video; - gint64 time_added; - char **tags; -} GnomePocketItem; - -#define GNOME_TYPE_POCKET_ITEM (gnome_pocket_item_get_type ()) - -GType gnome_pocket_item_get_type (void) G_GNUC_CONST; -char *gnome_pocket_item_to_string (GnomePocketItem *item); -GnomePocketItem *gnome_pocket_item_from_string (const char *str); -void gnome_pocket_print_item (GnomePocketItem *item); - -#define GNOME_TYPE_POCKET (gnome_pocket_get_type ()) -#define GNOME_POCKET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNOME_TYPE_POCKET, GnomePocket)) -#define GNOME_POCKET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GNOME_TYPE_POCKET, GnomePocketClass)) -#define GNOME_IS_POCKET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNOME_TYPE_POCKET)) -#define GNOME_IS_POCKET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNOME_TYPE_POCKET)) -#define GNOME_POCKET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GNOME_TYPE_POCKET, GnomePocketClass)) - -typedef struct _GnomePocketPrivate GnomePocketPrivate; - -typedef struct -{ - GObject parent; - - /*< private >*/ - GnomePocketPrivate *priv; -} GnomePocket; - -typedef struct -{ - GObjectClass parent; -} GnomePocketClass; - -GType gnome_pocket_get_type (void); - -GnomePocket *gnome_pocket_new (void); -void gnome_pocket_add_url (GnomePocket *self, - const char *url, - const char *tweet_id, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean gnome_pocket_add_url_finish (GnomePocket *self, - GAsyncResult *res, - GError **error); -void gnome_pocket_refresh (GnomePocket *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean gnome_pocket_refresh_finish (GnomePocket *self, - GAsyncResult *res, - GError **error); -GList *gnome_pocket_get_items (GnomePocket *self); - -void gnome_pocket_load_cached (GnomePocket *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean gnome_pocket_load_cached_finish (GnomePocket *self, - GAsyncResult *res, - GError **error); - -/* Debug functions */ -GList *gnome_pocket_load_from_file (GnomePocket *self, - const char *filename, - GError **error); - -G_END_DECLS - -#endif /* GNOME_POCKET_H */ diff --git a/src/pocket/grl-pocket.c b/src/pocket/grl-pocket.c deleted file mode 100644 index 9f76102..0000000 --- a/src/pocket/grl-pocket.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (C) 2013 Bastien Nocera - * - * Contact: Bastien Nocera <hadess@hadess.net> - * - * 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; version 2.1 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <grilo.h> -#include <gio/gio.h> -#include <glib/gi18n-lib.h> -#include <string.h> -#include <stdlib.h> -#include <totem-pl-parser-mini.h> - -#include "grl-pocket.h" -#include "gnome-pocket.h" - -/* --------- Logging -------- */ - -#define GRL_LOG_DOMAIN_DEFAULT pocket_log_domain -GRL_LOG_DOMAIN_STATIC(pocket_log_domain); - -/* --- Plugin information --- */ - -#define PLUGIN_ID POCKET_PLUGIN_ID - -#define SOURCE_ID "grl-pocket" -#define SOURCE_NAME _("Pocket") -#define SOURCE_DESC _("A source for browsing Pocket videos") - -/* --- Grilo Pocket Private --- */ - -#define GRL_POCKET_SOURCE_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE((object), \ - GRL_POCKET_SOURCE_TYPE, \ - GrlPocketSourcePrivate)) - -struct _GrlPocketSourcePrivate { - GnomePocket *pocket; - gboolean cache_loaded; -}; - -/* --- Data types --- */ - -typedef struct { - GrlSourceBrowseSpec *bs; - GCancellable *cancellable; - GrlPocketSource *source; -} OperationData; - -static GrlPocketSource *grl_pocket_source_new (GnomePocket *pocket); - -gboolean grl_pocket_plugin_init (GrlRegistry *registry, - GrlPlugin *plugin, - GList *configs); - -static const GList *grl_pocket_source_supported_keys (GrlSource *source); - -static void grl_pocket_source_cancel (GrlSource *source, - guint operation_id); -static void grl_pocket_source_browse (GrlSource *source, - GrlSourceBrowseSpec *bs); - -/* =================== Pocket Plugin =============== */ - -static void -is_available (GObject *gobject, - GParamSpec *pspec, - GrlPlugin *plugin) -{ - gboolean avail; - GrlPocketSource *source; - GnomePocket *pocket; - - source = g_object_get_data (G_OBJECT (plugin), "source"); - pocket = g_object_get_data (G_OBJECT (plugin), "pocket"); - g_object_get (pocket, "available", &avail, NULL); - - if (!avail) { - GrlRegistry *registry; - - if (source == NULL) - return; - - GRL_DEBUG ("Removing Pocket"); - - registry = grl_registry_get_default (); - - grl_registry_unregister_source (registry, - GRL_SOURCE (source), - NULL); - } else { - GrlRegistry *registry; - - if (source != NULL) - return; - - GRL_DEBUG ("Adding Pocket"); - - source = grl_pocket_source_new (pocket); - registry = grl_registry_get_default (); - - g_object_set_data (G_OBJECT (plugin), "source", source); - grl_registry_register_source (registry, - plugin, - GRL_SOURCE (source), - NULL); - } -} - -gboolean -grl_pocket_plugin_init (GrlRegistry *registry, - GrlPlugin *plugin, - GList *configs) -{ - GnomePocket *pocket; - - GRL_LOG_DOMAIN_INIT (pocket_log_domain, "pocket"); - - GRL_DEBUG ("%s", __FUNCTION__); - - /* Initialize i18n */ - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - - pocket = gnome_pocket_new (); - g_object_set_data (G_OBJECT (plugin), "pocket", pocket); - g_signal_connect (pocket, "notify::available", - G_CALLBACK (is_available), plugin); - - return TRUE; -} - -static void -grl_pocket_plugin_deinit (GrlPlugin *plugin) -{ - GnomePocket *pocket; - - GRL_DEBUG ("grl_pocket_plugin_deinit"); - - pocket = g_object_get_data (G_OBJECT (plugin), "pocket"); - g_clear_object (&pocket); - g_object_set_data (G_OBJECT (plugin), "pocket", NULL); -} - -GRL_PLUGIN_REGISTER (grl_pocket_plugin_init, - grl_pocket_plugin_deinit, - PLUGIN_ID); - -/* ================== Pocket GObject ================ */ - - -G_DEFINE_TYPE (GrlPocketSource, - grl_pocket_source, - GRL_TYPE_SOURCE); - -static GrlPocketSource * -grl_pocket_source_new (GnomePocket *pocket) -{ - GIcon *icon; - GFile *file; - GrlPocketSource *object; - - g_return_val_if_fail (GNOME_IS_POCKET (pocket), NULL); - - GRL_DEBUG ("%s", __FUNCTION__); - - file = g_file_new_for_uri ("resource:///org/gnome/grilo/plugins/pocket/channel-pocket.svg"); - icon = g_file_icon_new (file); - g_object_unref (file); - object = g_object_new (GRL_POCKET_SOURCE_TYPE, - "source-id", SOURCE_ID, - "source-name", SOURCE_NAME, - "source-desc", SOURCE_DESC, - "supported-media", GRL_MEDIA_TYPE_VIDEO, - "source-icon", icon, - NULL); - g_object_unref (icon); - GRL_POCKET_SOURCE (object)->priv->pocket = pocket; - - return object; -} - -static void -grl_pocket_source_class_init (GrlPocketSourceClass * klass) -{ - GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass); - - source_class->supported_keys = grl_pocket_source_supported_keys; - source_class->browse = grl_pocket_source_browse; - source_class->cancel = grl_pocket_source_cancel; - - g_type_class_add_private (klass, sizeof (GrlPocketSourcePrivate)); -} - -static void -grl_pocket_source_init (GrlPocketSource *source) -{ - source->priv = GRL_POCKET_SOURCE_GET_PRIVATE(source); -} - -/* ================== API Implementation ================ */ - -static const GList * -grl_pocket_source_supported_keys (GrlSource *source) -{ - static GList *keys = NULL; - if (!keys) { - keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ID, - GRL_METADATA_KEY_TITLE, - GRL_METADATA_KEY_URL, - GRL_METADATA_KEY_FAVOURITE, - GRL_METADATA_KEY_CREATION_DATE, - NULL); - } - return keys; -} - -static GrlMedia * -item_to_media (GnomePocketItem *item) -{ - GrlMedia *ret; - GDateTime *date; - gboolean has_video; - - /* There are a few false positives, but this makes detection - * much faster as well */ - has_video = (item->has_video == POCKET_HAS_MEDIA_INCLUDED || - item->has_video == POCKET_IS_MEDIA); - if (!has_video) { - GRL_DEBUG ("Ignoring ID %s as it wasn't detected as a video, or as including a video (URL: %s)", - item->id, item->url); - return NULL; - } - - if (!totem_pl_parser_can_parse_from_uri (item->url, FALSE)) { - GRL_DEBUG ("Ignoring ID %s as it wasn't detected as from a videosite (URL: %s)", - item->id, item->url); - return NULL; - } - - ret = grl_media_video_new (); - grl_media_set_url (ret, item->url); - grl_media_set_title (ret, item->title); - grl_media_set_favourite (ret, item->favorite); - grl_media_set_thumbnail (ret, item->thumbnail_url); - - date = g_date_time_new_from_unix_utc (item->time_added); - grl_media_set_creation_date (ret, date); - g_date_time_unref (date); - - return ret; -} - -static void -refresh_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - OperationData *op_data = user_data; - GError *error = NULL; - GList *items, *l; - - if (gnome_pocket_refresh_finish (op_data->source->priv->pocket, - res, &error) == FALSE) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - goto out; - } - - op_data->bs->callback (op_data->bs->source, - op_data->bs->operation_id, - NULL, - 0, - op_data->bs->user_data, - error); - goto out; - } - - items = gnome_pocket_get_items (op_data->source->priv->pocket); - for (l = items; l != NULL; l = l->next) { - GnomePocketItem *item = l->data; - GrlMedia *media; - - media = item_to_media (item); - if (media == NULL) - continue; - - op_data->bs->callback (op_data->bs->source, - op_data->bs->operation_id, - media, - GRL_SOURCE_REMAINING_UNKNOWN, - op_data->bs->user_data, - NULL); - } - - op_data->bs->callback (op_data->bs->source, - op_data->bs->operation_id, - NULL, - 0, - op_data->bs->user_data, - NULL); - -out: - g_clear_object (&op_data->cancellable); - g_slice_free (OperationData, op_data); -} - -static void -load_cached_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - OperationData *op_data = user_data; - GError *error = NULL; - - if (gnome_pocket_load_cached_finish (op_data->source->priv->pocket, - res, &error) == FALSE) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - goto out; - } - } - - op_data->source->priv->cache_loaded = TRUE; - gnome_pocket_refresh (op_data->source->priv->pocket, - op_data->cancellable, - refresh_cb, - op_data); - return; - -out: - g_clear_object (&op_data->cancellable); - g_slice_free (OperationData, op_data); -} - -static void -grl_pocket_source_browse (GrlSource *source, - GrlSourceBrowseSpec *bs) -{ - GrlPocketSourcePrivate *priv = GRL_POCKET_SOURCE (source)->priv; - OperationData *op_data; - - GRL_DEBUG (__FUNCTION__); - - op_data = g_slice_new0 (OperationData); - op_data->bs = bs; - op_data->cancellable = g_cancellable_new (); - op_data->source = GRL_POCKET_SOURCE (source); - grl_operation_set_data (bs->operation_id, op_data); - - if (!priv->cache_loaded) { - gnome_pocket_load_cached (priv->pocket, - op_data->cancellable, - load_cached_cb, - op_data); - } else { - gnome_pocket_refresh (priv->pocket, - op_data->cancellable, - refresh_cb, - op_data); - } -} - -static void -grl_pocket_source_cancel (GrlSource *source, - guint operation_id) -{ - OperationData *op_data; - - GRL_DEBUG ("grl_pocket_source_cancel"); - - op_data = (OperationData *) grl_operation_get_data (operation_id); - if (op_data) - g_cancellable_cancel (op_data->cancellable); -} diff --git a/src/pocket/grl-pocket.h b/src/pocket/grl-pocket.h deleted file mode 100644 index 7c51530..0000000 --- a/src/pocket/grl-pocket.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2013 Bastien Nocera - * - * Contact: Bastien Nocera <hadess@hadess.net> - * - * 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; version 2.1 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef _GRL_POCKET_SOURCE_H_ -#define _GRL_POCKET_SOURCE_H_ - -#include <grilo.h> - -#define GRL_POCKET_SOURCE_TYPE \ - (grl_pocket_source_get_type ()) - -#define GRL_POCKET_SOURCE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - GRL_POCKET_SOURCE_TYPE, \ - GrlPocketSource)) - -#define GRL_IS_POCKET_SOURCE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - GRL_POCKET_SOURCE_TYPE)) - -#define GRL_POCKET_SOURCE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GRL_POCKET_SOURCE_TYPE, \ - GrlPocketSourceClass)) - -#define GRL_IS_POCKET_SOURCE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass) \ - GRL_POCKET_SOURCE_TYPE)) - -#define GRL_POCKET_SOURCE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - GRL_POCKET_SOURCE_TYPE, \ - GrlPocketSourceClass)) - - -typedef struct _GrlPocketSource GrlPocketSource; -typedef struct _GrlPocketSourcePrivate GrlPocketSourcePrivate; - -struct _GrlPocketSource { - - GrlSource parent; - - /*< private >*/ - GrlPocketSourcePrivate *priv; -}; - -typedef struct _GrlPocketSourceClass GrlPocketSourceClass; - -struct _GrlPocketSourceClass { - - GrlSourceClass parent_class; - -}; - -GType grl_pocket_source_get_type (void); - -#endif /* _GRL_POCKET_SOURCE_H_ */ diff --git a/src/pocket/grl-pocket.xml b/src/pocket/grl-pocket.xml deleted file mode 100644 index b841836..0000000 --- a/src/pocket/grl-pocket.xml +++ /dev/null @@ -1,10 +0,0 @@ -<plugin> - <info> - <name>Pocket</name> - <module>libgrlpocket</module> - <description>A plugin for Pocket videos</description> - <author>GNOME</author> - <license>LGPL</license> - <site>http://www.gnome.org</site> - </info> -</plugin> diff --git a/src/pocket/pocket.gresource.xml b/src/pocket/pocket.gresource.xml deleted file mode 100644 index 1f7d95c..0000000 --- a/src/pocket/pocket.gresource.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<gresources> - <gresource prefix="/org/gnome/grilo/plugins/pocket"> - <file compressed="false">channel-pocket.svg</file> - </gresource> -</gresources> |