[grilo-plugins] podcasts: If the podcast feed provides a valid pubDate check this information to confirm if the podc
- From: Iago Toral Quiroga <itoral src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [grilo-plugins] podcasts: If the podcast feed provides a valid pubDate check this information to confirm if the podc
- Date: Thu, 2 Jun 2011 13:52:44 +0000 (UTC)
commit 0b4991866c2e4fb42d42f3b16d7d8304c18c13a1
Author: Iago Toral Quiroga <itoral igalia com>
Date: Thu Jun 2 15:48:45 2011 +0200
podcasts: If the podcast feed provides a valid pubDate check this
information to confirm if the podcast must be parsed again or not.
configure.ac | 16 ++++++++-----
src/media/podcasts/Makefile.am | 6 +++-
src/media/podcasts/grl-podcasts.c | 43 ++++++++++++++++++++++++++++++-------
3 files changed, 49 insertions(+), 16 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3d11fec..0a5ed20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,8 @@ AC_CHECK_HEADER([gcrypt.h], HAVE_GCRYPT=yes, HAVE_GCRYPT=no)
PKG_CHECK_MODULES(GTHREAD, gthread-2.0, HAVE_GTHREAD=yes, HAVE_GTHREAD=no)
+PKG_CHECK_MODULES(GMIME, gmime-2.4, HAVE_GMIME=yes, HAVE_GMIME=no)
+
PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.10,
HAVE_TRACKER_SPARQL=yes,
[PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.9,
@@ -415,16 +417,18 @@ AC_ARG_ENABLE(podcasts,
if test "x$HAVE_SQLITE" = "xno"; then
AC_MSG_ERROR([sqlite3 not found, install it or use --disable-podcasts])
fi
+ if test "x$HAVE_GMIME" = "xno"; then
+ AC_MSG_ERROR([gmime not found, install it or use --disable-podcasts])
+ fi
;;
esac
],
[
- if test "x$HAVE_GRLNET" = "xyes" -a "x$HAVE_XML" = "xyes"; then
- if test "x$HAVE_SQLITE" = "xyes"; then
- enable_podcasts=yes
- else
- enable_podcasts=no
- fi
+ if test "x$HAVE_GRLNET" = "xyes" -a \
+ "x$HAVE_XML" = "xyes" -a \
+ "x$HAVE_SQLITE" = "xyes" -a \
+ "x$HAVE_GMIME" = "xyes"; then
+ enable_podcasts=yes
else
enable_podcasts=no
fi
diff --git a/src/media/podcasts/Makefile.am b/src/media/podcasts/Makefile.am
index 2383042..74b87ee 100644
--- a/src/media/podcasts/Makefile.am
+++ b/src/media/podcasts/Makefile.am
@@ -11,13 +11,15 @@ libgrlpodcasts_la_CFLAGS = \
$(DEPS_CFLAGS) \
$(GRLNET_CFLAGS) \
$(XML_CFLAGS) \
- $(SQLITE_CFLAGS)
+ $(SQLITE_CFLAGS) \
+ $(GMIME_CFLAGS)
libgrlpodcasts_la_LIBADD = \
$(DEPS_LIBS) \
$(GRLNET_LIBS) \
$(XML_LIBS) \
- $(SQLITE_LIBS)
+ $(SQLITE_LIBS) \
+ $(GMIME_LIBS)
libgrlpodcasts_la_LDFLAGS = \
-module \
diff --git a/src/media/podcasts/grl-podcasts.c b/src/media/podcasts/grl-podcasts.c
index 253fa74..bbfde22 100644
--- a/src/media/podcasts/grl-podcasts.c
+++ b/src/media/podcasts/grl-podcasts.c
@@ -29,6 +29,7 @@
#include <libxml/xpath.h>
#include <sqlite3.h>
#include <string.h>
+#include <gmime/gmime-utils.h>
#include "grl-podcasts.h"
@@ -182,6 +183,7 @@ typedef struct {
typedef struct {
gchar *image;
gchar *desc;
+ gchar *published;
} PodcastData;
typedef struct {
@@ -212,6 +214,7 @@ typedef struct {
GrlMediaSourceResultCb callback;
guint error_code;
gboolean is_query;
+ time_t last_refreshed;
gpointer user_data;
} OperationSpec;
@@ -439,6 +442,7 @@ free_podcast_data (PodcastData *data)
{
g_free (data->image);
g_free (data->desc);
+ g_free (data->published);
g_slice_free (PodcastData, data);
}
@@ -982,7 +986,8 @@ parse_podcast_data (xmlDocPtr doc, xmlXPathObjectPtr xpathObj)
/* Loop through the podcast data (we skip the "item" tags, since
the podcast entries will be parsed later on */
- /* At the moment we are only interested in 'image' and 'description' tags */
+ /* At the moment we are only interested in
+ 'image', 'description' and 'pubDate' tags */
podcast_data = g_slice_new0 (PodcastData);
node = nodes->nodeTab[0]->xmlChildrenNode;
while (node && xmlStrcmp (node->name, (const xmlChar *) "item")) {
@@ -998,6 +1003,9 @@ parse_podcast_data (xmlDocPtr doc, xmlXPathObjectPtr xpathObj)
} else if (!xmlStrcmp (node->name, (const xmlChar *) "description")) {
podcast_data->desc =
(gchar *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
+ } else if (!xmlStrcmp (node->name, (const xmlChar *) "pubDate")) {
+ podcast_data->published =
+ (gchar *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
}
node = node->next;
}
@@ -1167,6 +1175,7 @@ parse_entry_idle (gpointer user_data)
static void
parse_feed (OperationSpec *os, const gchar *str, GError **error)
{
+ GrlPodcastsSource *source;
GrlMedia *podcast = NULL;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xpathCtx = NULL;
@@ -1176,6 +1185,8 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error)
GRL_DEBUG ("parse_feed");
+ source = GRL_PODCASTS_SOURCE (os->source);
+
doc = xmlParseDoc ((xmlChar *) str);
if (!doc) {
*error = g_error_new (GRL_CORE_ERROR,
@@ -1205,8 +1216,27 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error)
podcast_data = parse_podcast_data (doc, xpathObj);
xmlXPathFreeObject (xpathObj);
+ xpathObj = NULL;
+
+ /* Check podcast pubDate (if available), if it has not been updated
+ recently then we can use the cache and avoid parsing the feed */
+ if (podcast_data->published != NULL) {
+ time_t pub_time =
+ g_mime_utils_header_decode_date (podcast_data->published, NULL);
+ if (pub_time == 0) {
+ GRL_DEBUG ("Invalid podcast pubDate: '%s'", podcast_data->published);
+ /* We will parse the feed again just in case */
+ } else if (os->last_refreshed >= pub_time) {
+ GRL_DEBUG ("Podcast feed is up-to-date");
+ /* We do not need to parse again, we already have the contents in cache */
+ produce_podcast_contents_from_db (os);
+ g_slice_free (OperationSpec, os);
+ goto free_resources;
+ }
+ }
- /* Check podcast items */
+ /* The podcast has been updated since the last time
+ we processed it, we have to parse it again */
xpathObj = xmlXPathEvalExpression ((xmlChar *) "/rss/channel/item",
xpathCtx);
@@ -1220,17 +1250,14 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error)
/* Feed is ok, let's process it */
/* First, remove old entries for this podcast */
- remove_podcast_streams (GRL_PODCASTS_SOURCE (os->source)->priv->db,
- os->media_id, error);
+ remove_podcast_streams (source->priv->db, os->media_id, error);
if (*error) {
(*error)->code = os->error_code;
goto free_resources;
}
/* Then update the podcast data, including the last_refreshed date */
- touch_podcast (GRL_PODCASTS_SOURCE (os->source)->priv->db,
- os->media_id,
- podcast_data);
+ touch_podcast (source->priv->db, os->media_id, podcast_data);
/* If the feed contains no streams, notify and bail out */
stream_count = xpathObj->nodesetval ? xpathObj->nodesetval->nodeNr : 0;
@@ -1356,6 +1383,7 @@ produce_podcast_contents (OperationSpec *os)
lr_str = (gchar *) sqlite3_column_text (sql_stmt, PODCAST_LAST_REFRESHED);
GRL_DEBUG ("Podcast last-refreshed: '%s'", lr_str);
g_time_val_from_iso8601 (lr_str ? lr_str : "", &lr);
+ os->last_refreshed = lr.tv_sec;
g_get_current_time (&now);
now.tv_sec -= GRL_PODCASTS_SOURCE (os->source)->priv->cache_time;
if (now.tv_sec >= lr.tv_sec) {
@@ -1378,7 +1406,6 @@ produce_podcast_contents (OperationSpec *os)
g_error_free (error);
g_slice_free (OperationSpec, os);
}
-
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]