[totem-pl-parser] plparse: Simplify ITMS link parsing
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem-pl-parser] plparse: Simplify ITMS link parsing
- Date: Fri, 15 Apr 2016 13:50:32 +0000 (UTC)
commit 71eaa864fe06f76398807ac3befd7b8576839347
Author: Bastien Nocera <hadess hadess net>
Date: Fri Apr 15 15:47:43 2016 +0200
plparse: Simplify ITMS link parsing
Instead of simply following the link and trying to guess what the end
format might be, parse the ITMS ID from the link, and grab the RSS
URL from the resulting json.
With inspiration from:
https://github.com/vocalapp/vocal/blob/master/src/Utils/iTunesProvider.vala
plparse/totem-pl-parser-podcast.c | 182 +++++++++----------------------------
1 files changed, 43 insertions(+), 139 deletions(-)
---
diff --git a/plparse/totem-pl-parser-podcast.c b/plparse/totem-pl-parser-podcast.c
index 9fa68ac..01e7263 100644
--- a/plparse/totem-pl-parser-podcast.c
+++ b/plparse/totem-pl-parser-podcast.c
@@ -603,87 +603,15 @@ totem_pl_parser_add_xml_feed (TotemPlParser *parser,
#endif /* !HAVE_GMIME */
}
-static GByteArray *
-totem_pl_parser_load_http_itunes (const char *uri,
- gboolean debug)
-{
- SoupMessage *msg;
- SoupSession *session;
- GByteArray *data;
-
- if (debug)
- g_print ("Loading ITMS playlist '%s'\n", uri);
-
- session = soup_session_sync_new_with_options (
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
- SOUP_SESSION_USER_AGENT, "iTunes/10.0.0",
- SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE,
- NULL);
-
- msg = soup_message_new (SOUP_METHOD_GET, uri);
- soup_session_send_message (session, msg);
- if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
- data = g_byte_array_new ();
- g_byte_array_append (data,
- (guchar *) msg->response_body->data,
- msg->response_body->length);
- } else {
- return NULL;
- }
- g_object_unref (msg);
- g_object_unref (session);
-
- return data;
-}
-
-static const char *
-totem_pl_parser_parse_plist (xml_node_t *item)
-{
- for (item = item->child; item != NULL; item = item->next) {
- /* What we're looking for looks like:
- * <key>action</key>
- * <dict>
- * <key>kind</key><string>Goto</string>
- * <key>url</key><string>URL</string>
- */
- if (g_ascii_strcasecmp (item->name, "key") == 0
- && g_ascii_strcasecmp (item->data, "action") == 0) {
- xml_node_t *node = item->next;
-
- if (node && g_ascii_strcasecmp (node->name, "[CDATA]") == 0)
- node = node->next;
- if (node && g_ascii_strcasecmp (node->name, "dict") == 0) {
- for (node = node->child; node != NULL; node = node->next) {
- if (g_ascii_strcasecmp (node->name, "key") == 0 &&
- g_ascii_strcasecmp (node->data, "url") == 0 &&
- node->next != NULL) {
- node = node->next;
- if (g_ascii_strcasecmp (node->name, "string") == 0)
- return node->data;
- }
- }
- }
- } else {
- const char *ret;
-
- ret = totem_pl_parser_parse_plist (item);
- if (ret != NULL)
- return ret;
- }
- }
-
- return NULL;
-}
-
static char *
-totem_pl_parser_parse_html (char *data, gsize len, gboolean debug)
+totem_pl_parser_parse_json (char *data, gsize len, gboolean debug)
{
char *s, *end;
- s = g_strstr_len (data, len, "feed-url=\"");
+ s = g_strstr_len (data, len, "feedUrl\":\"");
if (s == NULL)
return NULL;
- s += strlen ("feed-url=\"");
+ s += strlen ("feedUrl\":\"");
if (*s == '\0')
return NULL;
end = g_strstr_len (s, len - (s - data), "\"");
@@ -692,59 +620,33 @@ totem_pl_parser_parse_html (char *data, gsize len, gboolean debug)
return g_strndup (s, end - s);
}
-static GFile *
-totem_pl_parser_get_feed_uri (char *data, gsize len, gboolean debug)
+static char *
+get_itms_id (GFile *file)
{
- xml_node_t* doc;
- const char *uri;
- GFile *ret = NULL;
- GByteArray *content;
-
- uri = NULL;
-
- /* Probably HTML, look for feed-url */
- if (g_strstr_len (data, len, "feed-url") != NULL) {
- char *feed_uri;
- feed_uri = totem_pl_parser_parse_html (data, len, debug);
- if (debug)
- g_print ("Found feed-url in HTML: '%s'\n", feed_uri);
- if (feed_uri == NULL)
- return NULL;
- ret = g_file_new_for_uri (feed_uri);
- g_free (feed_uri);
- return ret;
- }
+ char *uri, *start, *end, *id;
- doc = totem_pl_parser_parse_xml_relaxed (data, len);
- if (doc == NULL)
+ uri = g_file_get_uri (file);
+ if (!uri)
return NULL;
- /* If the document has no name */
- if (doc->name == NULL || g_ascii_strcasecmp (doc->name, "plist") != 0)
- goto out;
-
- /* Redirect plist? Find a goto action */
- uri = totem_pl_parser_parse_plist (doc);
-
- if (debug) {
- if (uri == NULL)
- g_print ("Did not find redirect URL in: %.*s\n", (int) len, data);
- else
- g_print ("Found redirect URL: %s\n", uri);
+ start = strstr (uri, "/id");
+ if (!start) {
+ g_free (uri);
+ return NULL;
}
- if (uri == NULL)
- goto out;
+ end = strchr (start, '?');
+ if (!end)
+ end = strchr (start, '#');
+ if (!end || end - start <= 3) {
+ g_free (uri);
+ return NULL;
+ }
- content = totem_pl_parser_load_http_itunes (uri, debug);
- if (!content)
- goto out;
- ret = totem_pl_parser_get_feed_uri ((char *) content->data, content->len, debug);
- g_byte_array_free (content, TRUE);
+ id = g_strndup (start + 3, end - start - 3);
+ g_free (uri);
-out:
- xml_parser_free_tree (doc);
- return ret;
+ return id;
}
TotemPlParserResult
@@ -757,35 +659,37 @@ totem_pl_parser_add_itms (TotemPlParser *parser,
#ifndef HAVE_GMIME
WARN_NO_GMIME;
#else
- GByteArray *content;
- char *itms_uri;
- GFile *feed_file;
+ GFile *json_file, *feed_file;
TotemPlParserResult ret;
+ char *contents, *id, *json_uri, *feed_url;
+ gsize len;
- if (g_file_has_uri_scheme (file, "itms") != FALSE ||
- g_file_has_uri_scheme (file, "itmss") != FALSE) {
- itms_uri= g_file_get_uri (file);
- memcpy (itms_uri, "http", 4);
- } else if (g_file_has_uri_scheme (file, "http") != FALSE) {
- itms_uri = g_file_get_uri (file);
- } else {
+ id = get_itms_id (file);
+ if (id == NULL) {
+ DEBUG(file, g_print ("Could not get ITMS ID for URL '%s'", uri));
return TOTEM_PL_PARSER_RESULT_ERROR;
}
- /* Load the file using iTunes user-agent */
- content = totem_pl_parser_load_http_itunes (itms_uri, totem_pl_parser_is_debugging_enabled (parser));
- g_free (itms_uri);
+ DEBUG(file, g_print ("Got ID '%s' for URL '%s'", id, uri));
- if (!content)
+ json_uri = g_strdup_printf ("https://itunes.apple.com/lookup?id=%s&entity=podcast", id);
+ g_free (id);
+ json_file = g_file_new_for_uri (json_uri);
+ g_free (json_uri);
+
+ if (g_file_load_contents (json_file, NULL, &contents, &len, NULL, NULL) == FALSE) {
+ g_object_unref (json_file);
return TOTEM_PL_PARSER_RESULT_ERROR;
+ }
- /* And look in the file for the feedURL */
- feed_file = totem_pl_parser_get_feed_uri ((char *) content->data, content->len,
- totem_pl_parser_is_debugging_enabled (parser));
- g_byte_array_free (content, TRUE);
- if (feed_file == NULL)
+ feed_url = totem_pl_parser_parse_json (contents, len, totem_pl_parser_is_debugging_enabled (parser));
+ g_free (contents);
+ if (feed_url == NULL)
return TOTEM_PL_PARSER_RESULT_ERROR;
+ feed_file = g_file_new_for_uri (feed_url);
+ g_free (feed_url);
+
DEBUG(feed_file, g_print ("Found feed URI: %s\n", uri));
ret = totem_pl_parser_add_rss (parser, feed_file, NULL, parse_data, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]