[libgdata] [youtube] Added support for recorded times and comment feed links
- From: Philip Withnall <pwithnall src gnome org>
- To: svn-commits-list gnome org
- Subject: [libgdata] [youtube] Added support for recorded times and comment feed links
- Date: Wed, 13 May 2009 02:52:40 -0400 (EDT)
commit b29ff8b0a5efbc44bd3559c1b1e01276b7e10a1f
Author: Philip Withnall <philip tecnocode co uk>
Date: Wed May 13 07:51:40 2009 +0100
[youtube] Added support for recorded times and comment feed links
Added tests to the YouTube test suite, and also fixed parsing
media:group/category elements.
---
docs/reference/gdata-sections.txt | 3 +
gdata/gdata-gdata.c | 6 +-
gdata/gdata-gdata.h | 7 +-
gdata/gdata.symbols | 3 +
gdata/services/youtube/gdata-youtube-video.c | 222 ++++++++++++++++----------
gdata/services/youtube/gdata-youtube-video.h | 3 +
gdata/tests/youtube.c | 129 +++++++++++++++
7 files changed, 281 insertions(+), 92 deletions(-)
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index d103564..6288fd4 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -306,11 +306,14 @@ gdata_youtube_video_set_is_private
gdata_youtube_video_is_draft
gdata_youtube_video_set_is_draft
gdata_youtube_video_get_state
+gdata_youtube_video_get_comments_feed_link
gdata_youtube_video_get_rating
gdata_youtube_video_get_restriction
gdata_youtube_video_get_title
gdata_youtube_video_set_title
gdata_youtube_video_get_uploaded
+gdata_youtube_video_get_recorded
+gdata_youtube_video_set_recorded
gdata_youtube_video_get_video_id
<SUBSECTION Standard>
GDATA_IS_YOUTUBE_VIDEO
diff --git a/gdata/gdata-gdata.c b/gdata/gdata-gdata.c
index 53f61a8..343e313 100644
--- a/gdata/gdata-gdata.c
+++ b/gdata/gdata-gdata.c
@@ -76,16 +76,17 @@ gdata_gd_rating_free (GDataGDRating *self)
* @href: the URI of the related feed
* @rel: the relationship between the related feed and the current item, or %NULL
* @count_hint: a hint about the number of items in the related feed
+ * @read_only: %TRUE if the feed is read-only, %FALSE otherwise
*
* Creates a new #GDataGDFeedLink. More information is available in the <ulink type="http"
* url="http://code.google.com/apis/gdata/elements.html#gdFeedLink">GData specification</ulink>.
*
- * Currently, readOnly and feed functionality is not implemented in #GDataGDFeedLink.
+ * Currently, embedded feed functionality is not implemented in #GDataGDFeedLink.
*
* Return value: a new #GDataGDFeedLink, or %NULL; free with gdata_gd_feed_link_free()
**/
GDataGDFeedLink *
-gdata_gd_feed_link_new (const gchar *href, const gchar *rel, guint count_hint)
+gdata_gd_feed_link_new (const gchar *href, const gchar *rel, guint count_hint, gboolean read_only)
{
GDataGDFeedLink *self;
@@ -95,6 +96,7 @@ gdata_gd_feed_link_new (const gchar *href, const gchar *rel, guint count_hint)
self->href = g_strdup (href);
self->rel = g_strdup (rel);
self->count_hint = count_hint;
+ self->read_only = read_only;
return self;
}
diff --git a/gdata/gdata-gdata.h b/gdata/gdata-gdata.h
index ed162b0..f6bbd77 100644
--- a/gdata/gdata-gdata.h
+++ b/gdata/gdata-gdata.h
@@ -53,22 +53,23 @@ void gdata_gd_rating_free (GDataGDRating *self);
* @href: the URI of the related feed
* @rel: the relationship between the related feed and the current item, or %NULL
* @count_hint: a hint about the number of items in the related feed
+ * @read_only: %TRUE if the feed is read-only, %FALSE otherwise
*
* A structure fully representing a GData "rating" element. The @href field is required, but the others are optional.
*
* See the <ulink type="http" url="http://code.google.com/apis/gdata/elements.html#gdFeedLink">GData specification</ulink>
* for more information.
*
- * Currently, readOnly and feed functionality is not implemented in #GDataGDFeedLink.
+ * Currently, embedded feed functionality is not implemented in #GDataGDFeedLink.
**/
typedef struct {
gchar *rel;
gchar *href;
guint count_hint;
- /* TODO: support readOnly and feed */
+ gboolean read_only;
} GDataGDFeedLink;
-GDataGDFeedLink *gdata_gd_feed_link_new (const gchar *href, const gchar *rel, guint count_hint) G_GNUC_WARN_UNUSED_RESULT;
+GDataGDFeedLink *gdata_gd_feed_link_new (const gchar *href, const gchar *rel, guint count_hint, gboolean read_only) G_GNUC_WARN_UNUSED_RESULT;
void gdata_gd_feed_link_free (GDataGDFeedLink *self);
/**
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index a323aaa..1844930 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -160,6 +160,9 @@ gdata_youtube_video_get_video_id
gdata_youtube_video_is_draft
gdata_youtube_video_set_is_draft
gdata_youtube_video_get_state
+gdata_youtube_video_get_comments_feed_link
+gdata_youtube_video_get_recorded
+gdata_youtube_video_set_recorded
gdata_youtube_state_new
gdata_youtube_state_free
gdata_calendar_calendar_get_type
diff --git a/gdata/services/youtube/gdata-youtube-video.c b/gdata/services/youtube/gdata-youtube-video.c
index f7e421e..5d35280 100644
--- a/gdata/services/youtube/gdata-youtube-video.c
+++ b/gdata/services/youtube/gdata-youtube-video.c
@@ -78,6 +78,8 @@ struct _GDataYouTubeVideoPrivate {
/* Other properties */
gboolean is_draft;
GDataYouTubeState *state;
+ GDataGDFeedLink *comments_feed_link;
+ GTimeVal recorded;
};
enum {
@@ -99,7 +101,9 @@ enum {
PROP_UPLOADED,
PROP_VIDEO_ID,
PROP_IS_DRAFT,
- PROP_STATE
+ PROP_STATE,
+ PROP_COMMENTS_FEED_LINK,
+ PROP_RECORDED
};
G_DEFINE_TYPE (GDataYouTubeVideo, gdata_youtube_video, GDATA_TYPE_ENTRY)
@@ -389,6 +393,37 @@ gdata_youtube_video_class_init (GDataYouTubeVideoClass *klass)
g_param_spec_pointer ("state",
"State", "Information describing the state of the video.",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataYouTubeVideo:comments-feed-link:
+ *
+ * A link to the video's comments feed. It points to a #GDataGDFeedLink.
+ *
+ * For more information, see the <ulink type="http"
+ * url="http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_gd:feedLink">online documentation</ulink>.
+ *
+ * Since: 0.3.0
+ **/
+ g_object_class_install_property (gobject_class, PROP_COMMENTS_FEED_LINK,
+ g_param_spec_pointer ("comments-feed-link",
+ "Comments feed link", "A link to the video's comments feed.",
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataYouTubeVideo:recorded:
+ *
+ * Specifies the time the video was originally recorded.
+ *
+ * For more information, see the <ulink type="http"
+ * url="http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_yt:recorded">online documentation</ulink>.
+ *
+ * Since: 0.3.0
+ **/
+ g_object_class_install_property (gobject_class, PROP_RECORDED,
+ g_param_spec_boxed ("recorded",
+ "Recorded", "Specifies the time the video was originally recorded.",
+ GDATA_TYPE_G_TIME_VAL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
@@ -420,6 +455,7 @@ gdata_youtube_video_finalize (GObject *object)
g_free (priv->video_id);
gdata_youtube_state_free (priv->state);
+ gdata_gd_feed_link_free (priv->comments_feed_link);
/* Chain up to the parent class */
G_OBJECT_CLASS (gdata_youtube_video_parent_class)->finalize (object);
@@ -488,6 +524,12 @@ gdata_youtube_video_get_property (GObject *object, guint property_id, GValue *va
case PROP_STATE:
g_value_set_pointer (value, priv->state);
break;
+ case PROP_COMMENTS_FEED_LINK:
+ g_value_set_pointer (value, priv->comments_feed_link);
+ break;
+ case PROP_RECORDED:
+ g_value_set_boxed (value, &(priv->recorded));
+ break;
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -507,9 +549,6 @@ gdata_youtube_video_set_property (GObject *object, guint property_id, const GVal
case PROP_NO_EMBED:
gdata_youtube_video_set_no_embed (self, g_value_get_boolean (value));
break;
- /*case PROP_RATING:
- gdata_youtube_video_set_rating (self, g_value_get_pointer (value));
- break;*/
case PROP_KEYWORDS:
gdata_youtube_video_set_keywords (self, g_value_get_string (value));
break;
@@ -528,6 +567,9 @@ gdata_youtube_video_set_property (GObject *object, guint property_id, const GVal
case PROP_IS_DRAFT:
gdata_youtube_video_set_is_draft (self, g_value_get_boolean (value));
break;
+ case PROP_RECORDED:
+ gdata_youtube_video_set_recorded (self, g_value_get_boxed (value));
+ break;
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -595,7 +637,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
label = xmlGetProp (node, (xmlChar*) "label");
content = xmlNodeListGetString (doc, node->children, TRUE);
- category = gdata_media_category_new ((gchar*) content, (gchar*) scheme, (gchar*) label);
+ category = gdata_media_category_new ((gchar*) content, (gchar*) label, (gchar*) scheme);
gdata_youtube_video_set_category (self, category);
} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
/* media:content */
@@ -841,7 +883,6 @@ parse_xml (GDataEntry *entry, xmlDoc *doc, xmlNode *node, GError **error)
xmlChar *min, *max, *num_raters, *average;
guint num_raters_uint;
gdouble average_double;
- /*GDataGDRating *rating;*/
min = xmlGetProp (node, (xmlChar*) "min");
if (min == NULL)
@@ -873,13 +914,11 @@ parse_xml (GDataEntry *entry, xmlDoc *doc, xmlNode *node, GError **error)
strtoul ((gchar*) max, NULL, 10),
num_raters_uint, average_double);
g_object_notify (G_OBJECT (self), "rating");
- /*gdata_youtube_video_set_rating (self, rating);*/
} else if (xmlStrcmp (node->name, (xmlChar*) "comments") == 0) {
/* gd:comments */
- xmlChar *rel, *href, *count_hint;
+ xmlChar *rel, *href, *count_hint, *read_only;
xmlNode *child_node;
guint count_hint_uint;
- /*GDataGDFeedLink *feed_link;*/
/* This is actually the child of the <comments> element */
child_node = node->children;
@@ -891,15 +930,18 @@ parse_xml (GDataEntry *entry, xmlDoc *doc, xmlNode *node, GError **error)
count_hint_uint = strtoul ((gchar*) count_hint, NULL, 10);
xmlFree (count_hint);
+ read_only = xmlGetProp (child_node, (xmlChar*) "readOnly");
rel = xmlGetProp (child_node, (xmlChar*) "rel");
href = xmlGetProp (child_node, (xmlChar*) "href");
- /* TODO */
- /*feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint);*/
- /*gdata_youtube_video_set_comments_feed_link (self, feed_link);*/
+ gdata_gd_feed_link_free (self->priv->comments_feed_link);
+ self->priv->comments_feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint,
+ ((xmlStrcmp (read_only, (xmlChar*) "true") == 0) ? TRUE : FALSE));
+ g_object_notify (G_OBJECT (self), "comments-feed-link");
xmlFree (rel);
xmlFree (href);
+ xmlFree (read_only);
} else if (xmlStrcmp (node->name, (xmlChar*) "statistics") == 0) {
/* yt:statistics */
xmlChar *view_count, *favorite_count;
@@ -933,7 +975,18 @@ parse_xml (GDataEntry *entry, xmlDoc *doc, xmlNode *node, GError **error)
gdata_youtube_video_set_no_embed (self, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "recorded") == 0) {
/* yt:recorded */
- g_message ("TODO: recorded unimplemented");
+ xmlChar *recorded;
+ GTimeVal recorded_timeval;
+
+ recorded = xmlNodeListGetString (doc, node->children, TRUE);
+ if (gdata_parser_time_val_from_date ((gchar*) recorded, &recorded_timeval) == FALSE) {
+ /* Error */
+ gdata_parser_error_not_iso8601_format ("recorded", "entry", (gchar*) recorded, error);
+ xmlFree (recorded);
+ return FALSE;
+ }
+ xmlFree (recorded);
+ gdata_youtube_video_set_recorded (self, &recorded_timeval);
} else if (xmlStrcmp (node->name, (xmlChar*) "control") == 0) {
/* app:control */
xmlNode *child_node;
@@ -984,9 +1037,7 @@ get_xml (GDataEntry *entry, GString *xml_string)
{
GDataYouTubeVideoPrivate *priv = GDATA_YOUTUBE_VIDEO (entry)->priv;
gchar *category;
- GList *contents, *thumbnails;
- /* TODO: Make sure read-only properties aren't represented here */
/* Chain up to the parent class */
GDATA_ENTRY_CLASS (gdata_youtube_video_parent_class)->get_xml (entry, xml_string);
@@ -1020,61 +1071,6 @@ get_xml (GDataEntry *entry, GString *xml_string)
g_free (keywords);
}
- for (contents = priv->contents; contents != NULL; contents = contents->next) {
- GDataMediaContent *content = (GDataMediaContent*) contents->data;
- gchar *uri, *type;
-
- uri = g_markup_escape_text (content->uri, -1);
- type = g_markup_escape_text (content->type, -1);
- g_string_append_printf (xml_string, "<media:content url='%s' type='%s'", uri, type);
- g_free (uri);
- g_free (type);
-
- if (content->is_default == TRUE)
- g_string_append (xml_string, " isDefault='true'");
- else
- g_string_append (xml_string, " isDefault='false'");
-
- switch (content->expression) {
- case GDATA_MEDIA_EXPRESSION_SAMPLE:
- g_string_append (xml_string, " expression='sample'");
- break;
- case GDATA_MEDIA_EXPRESSION_FULL:
- g_string_append (xml_string, " expression='full'");
- break;
- case GDATA_MEDIA_EXPRESSION_NONSTOP:
- g_string_append (xml_string, " expression='nonstop'");
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (content->duration != -1)
- g_string_append_printf (xml_string, " duration='%i'", content->duration);
- if (content->format != -1)
- g_string_append_printf (xml_string, " yt:format='%i'", content->format);
-
- g_string_append (xml_string, "/>");
- }
-
- if (priv->player_uri != NULL) {
- gchar *player_uri = g_markup_escape_text (priv->player_uri, -1);
- g_string_append_printf (xml_string, "<media:player url='%s'/>", player_uri);
- g_free (player_uri);
- }
-
- for (thumbnails = priv->thumbnails; thumbnails != NULL; thumbnails = thumbnails->next) {
- GDataMediaThumbnail *thumbnail = (GDataMediaThumbnail*) thumbnails->data;
- gchar *uri, *_time;
-
- uri = g_markup_escape_text (thumbnail->uri, -1);
- _time = gdata_media_thumbnail_build_time (thumbnail->time);
- g_string_append_printf (xml_string, "<media:thumbnail url='%s' height='%u' width='%u' time='%s'/>",
- uri, thumbnail->height, thumbnail->width, _time);
- g_free (uri);
- g_free (_time);
- }
-
if (priv->is_private == TRUE)
g_string_append (xml_string, "<yt:private/>");
@@ -1089,13 +1085,15 @@ get_xml (GDataEntry *entry, GString *xml_string)
g_free (location);
}
+ if (priv->recorded.tv_sec != 0 || priv->recorded.tv_usec != 0) {
+ gchar *recorded = gdata_parser_date_from_time_val (&(priv->recorded));
+ g_string_append_printf (xml_string, "<yt:recorded>%s</yt:recorded>", recorded);
+ g_free (recorded);
+ }
+
/* TODO:
- * - yt:recorded
* - georss:where
- * - Check all tags here are valid for insertions and updates
* - Check things are escaped (or not) as appropriate
- * - Write a function to encapsulate g_markup_escape_text and
- * g_string_append_printf to reduce the number of allocations
*/
}
@@ -1218,17 +1216,6 @@ gdata_youtube_video_get_rating (GDataYouTubeVideo *self)
return self->priv->rating;
}
-/* TODO: The only use for this is for adding a new rating, but there must be a better interface for that */
-/*void
-gdata_youtube_video_set_rating (GDataYouTubeVideo *self, GDataGDRating *rating)
-{
- g_return_if_fail (GDATA_IS_YOUTUBE_VIDEO (self));
-
- gdata_gd_rating_free (self->priv->rating); TODO: Not so happy about this memory management
- self->priv->rating = rating;
- g_object_notify (G_OBJECT (self), "rating");
-}*/
-
/**
* gdata_youtube_video_get_keywords:
* @self: a #GDataYouTubeVideo
@@ -1364,7 +1351,8 @@ gdata_youtube_video_get_category (GDataYouTubeVideo *self)
* @self: a #GDataYouTubeVideo
* @category: a new #GDataMediaCategory
*
- * Sets the #GDataYouTubeVideo:category property to the new category, @category.
+ * Sets the #GDataYouTubeVideo:category property to the new category, @category. The #GDataYouTubeVideo
+ * will take ownership of @category, so do not free it after returning from this function.
*
* @category must not be %NULL. For more information, see the <ulink type="http"
* url="http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_media:category">online documentation</ulink>.
@@ -1375,7 +1363,7 @@ gdata_youtube_video_set_category (GDataYouTubeVideo *self, GDataMediaCategory *c
g_return_if_fail (category != NULL);
g_return_if_fail (GDATA_IS_YOUTUBE_VIDEO (self));
- gdata_media_category_free (self->priv->category); /* TODO: not so happy about this memory management */
+ gdata_media_category_free (self->priv->category);
self->priv->category = category;
g_object_notify (G_OBJECT (self), "category");
}
@@ -1597,3 +1585,63 @@ gdata_youtube_video_get_state (GDataYouTubeVideo *self)
g_return_val_if_fail (GDATA_IS_YOUTUBE_VIDEO (self), NULL);
return self->priv->state;
}
+
+/**
+ * gdata_youtube_video_get_comments_feed_link:
+ * @self: a #GDataYouTubeVideo
+ *
+ * Gets the #GDataYouTubeVideo:comments-feed-link property.
+ *
+ * For more information, see the <ulink type="http"
+ * url="http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_gd:feedLink">online documentation</ulink>.
+ *
+ * Return value: a #GDataGDFeedLink to the video's comments feed, or %NULL
+ *
+ * Since: 0.3.0
+ **/
+GDataGDFeedLink *
+gdata_youtube_video_get_comments_feed_link (GDataYouTubeVideo *self)
+{
+ g_return_val_if_fail (GDATA_IS_YOUTUBE_VIDEO (self), NULL);
+ return self->priv->comments_feed_link;
+}
+
+/**
+ * gdata_youtube_video_get_recorded:
+ * @self: a #GDataYouTubeVideo
+ * @recorded: a #GTimeVal
+ *
+ * Gets the #GDataYouTubeVideo:recorded property and puts it in @recorded. If the property is unset,
+ * both fields in the #GTimeVal will be set to %0.
+ *
+ * Since: 0.3.0
+ **/
+void
+gdata_youtube_video_get_recorded (GDataYouTubeVideo *self, GTimeVal *recorded)
+{
+ g_return_if_fail (GDATA_IS_YOUTUBE_VIDEO (self));
+ *recorded = self->priv->recorded;
+}
+
+/**
+ * gdata_youtube_video_set_recorded:
+ * @self: a #GDataYouTubeVideo
+ * @recorded: the video's new recorded time
+ *
+ * Sets the #GDataYouTubeVideo:recorded property to the new recorded time, @recorded.
+ *
+ * Set @recorded to %NULL to unset the video's recorded time.
+ *
+ * Since: 0.3.0
+ **/
+void
+gdata_youtube_video_set_recorded (GDataYouTubeVideo *self, GTimeVal *recorded)
+{
+ g_return_if_fail (GDATA_IS_YOUTUBE_VIDEO (self));
+ if (recorded == NULL) {
+ self->priv->recorded.tv_sec = 0;
+ self->priv->recorded.tv_usec = 0;
+ } else {
+ self->priv->recorded = *recorded;
+ }
+}
diff --git a/gdata/services/youtube/gdata-youtube-video.h b/gdata/services/youtube/gdata-youtube-video.h
index 3cc0991..4dda5e4 100644
--- a/gdata/services/youtube/gdata-youtube-video.h
+++ b/gdata/services/youtube/gdata-youtube-video.h
@@ -93,6 +93,9 @@ const gchar *gdata_youtube_video_get_video_id (GDataYouTubeVideo *self);
gboolean gdata_youtube_video_is_draft (GDataYouTubeVideo *self);
void gdata_youtube_video_set_is_draft (GDataYouTubeVideo *self, gboolean is_draft);
GDataYouTubeState *gdata_youtube_video_get_state (GDataYouTubeVideo *self);
+GDataGDFeedLink *gdata_youtube_video_get_comments_feed_link (GDataYouTubeVideo *self);
+void gdata_youtube_video_get_recorded (GDataYouTubeVideo *self, GTimeVal *recorded);
+void gdata_youtube_video_set_recorded (GDataYouTubeVideo *self, GTimeVal *recorded);
G_END_DECLS
diff --git a/gdata/tests/youtube.c b/gdata/tests/youtube.c
index 9048cc5..ddd648e 100644
--- a/gdata/tests/youtube.c
+++ b/gdata/tests/youtube.c
@@ -371,6 +371,133 @@ test_parsing_app_control (void)
g_object_unref (video);
}
+static void
+test_parsing_yt_recorded (void)
+{
+ GDataYouTubeVideo *video;
+ GTimeVal recorded;
+ gchar *xml;
+ GError *error = NULL;
+
+ video = gdata_youtube_video_new_from_xml (
+ "<entry xmlns='http://www.w3.org/2005/Atom' "
+ "xmlns:media='http://search.yahoo.com/mrss/' "
+ "xmlns:yt='http://gdata.youtube.com/schemas/2007' "
+ "xmlns:gd='http://schemas.google.com/g/2005' "
+ "gd:etag='W/\"CEMFSX47eCp7ImA9WxVUGEw.\"'>"
+ "<id>tag:youtube.com,2008:video:JAagedeKdcQ</id>"
+ "<published>2006-05-16T14:06:37.000Z</published>"
+ "<updated>2009-03-23T12:46:58.000Z</updated>"
+ "<category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>"
+ "<title>Judas Priest - Painkiller</title>"
+ "<link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=JAagedeKdcQ'/>"
+ "<link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ?client=ytapi-google-jsdemo'/>"
+ "<author>"
+ "<name>eluves</name>"
+ "<uri>http://gdata.youtube.com/feeds/api/users/eluves</uri>"
+ "</author>"
+ "<media:group>"
+ "<media:title type='plain'>Judas Priest - Painkiller</media:title>"
+ "<media:credit role='uploader' scheme='urn:youtube'>eluves</media:credit>"
+ "<media:category label='Music' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Music</media:category>"
+ "</media:group>"
+ "<yt:recorded>2003-08-03</yt:recorded>"
+ "</entry>", -1, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_YOUTUBE_VIDEO (video));
+ g_clear_error (&error);
+
+ /* Test the recorded date */
+ gdata_youtube_video_get_recorded (video, &recorded);
+ g_assert_cmpint (recorded.tv_sec, ==, 1059868800);
+ g_assert_cmpint (recorded.tv_usec, ==, 0);
+
+ /* Update the state and see if the XML's written out OK */
+ recorded.tv_sec = 1128229200;
+ gdata_youtube_video_set_recorded (video, &recorded);
+
+ /* Check the XML */
+ xml = gdata_entry_get_xml (GDATA_ENTRY (video));
+ g_assert_cmpstr (xml, ==,
+ "<entry xmlns='http://www.w3.org/2005/Atom' "
+ "xmlns:media='http://search.yahoo.com/mrss/' "
+ "xmlns:gd='http://schemas.google.com/g/2005' "
+ "xmlns:yt='http://gdata.youtube.com/schemas/2007' "
+ "gd:etag='W/\"CEMFSX47eCp7ImA9WxVUGEw.\"'>"
+ "<title type='text'>Judas Priest - Painkiller</title>"
+ "<id>tag:youtube.com,2008:video:JAagedeKdcQ</id>"
+ "<updated>2009-03-23T12:46:58Z</updated>"
+ "<published>2006-05-16T14:06:37Z</published>"
+ "<category term='http://gdata.youtube.com/schemas/2007#video' scheme='http://schemas.google.com/g/2005#kind'/>"
+ "<link href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ?client=ytapi-google-jsdemo' rel='self' type='application/atom+xml'/>"
+ "<link href='http://www.youtube.com/watch?v=JAagedeKdcQ' rel='alternate' type='text/html'/>"
+ "<author>"
+ "<name>eluves</name>"
+ "<uri>http://gdata.youtube.com/feeds/api/users/eluves</uri>"
+ "</author>"
+ "<media:group>"
+ "<media:category label='Music' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Music</media:category>"
+ "<media:title type='plain'>Judas Priest - Painkiller</media:title>"
+ "</media:group>"
+ "<yt:recorded>2005-10-02</yt:recorded>"
+ "</entry>");
+ g_free (xml);
+
+ /* TODO: more tests on entry properties */
+
+ g_object_unref (video);
+}
+
+static void
+test_parsing_comments_feed_link (void)
+{
+ GDataYouTubeVideo *video;
+ GDataGDFeedLink *feed_link;
+ GError *error = NULL;
+
+ video = gdata_youtube_video_new_from_xml (
+ "<entry xmlns='http://www.w3.org/2005/Atom' "
+ "xmlns:media='http://search.yahoo.com/mrss/' "
+ "xmlns:yt='http://gdata.youtube.com/schemas/2007' "
+ "xmlns:gd='http://schemas.google.com/g/2005' "
+ "gd:etag='W/\"CEMFSX47eCp7ImA9WxVUGEw.\"'>"
+ "<id>tag:youtube.com,2008:video:JAagedeKdcQ</id>"
+ "<published>2006-05-16T14:06:37.000Z</published>"
+ "<updated>2009-03-23T12:46:58.000Z</updated>"
+ "<category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>"
+ "<title>Judas Priest - Painkiller</title>"
+ "<link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=JAagedeKdcQ'/>"
+ "<link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ?client=ytapi-google-jsdemo'/>"
+ "<author>"
+ "<name>eluves</name>"
+ "<uri>http://gdata.youtube.com/feeds/api/users/eluves</uri>"
+ "</author>"
+ "<media:group>"
+ "<media:title type='plain'>Judas Priest - Painkiller</media:title>"
+ "<media:credit role='uploader' scheme='urn:youtube'>eluves</media:credit>"
+ "<media:category label='Music' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Music</media:category>"
+ "</media:group>"
+ "<gd:comments>"
+ "<gd:feedLink href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ/comments' countHint='13021'/>"
+ "</gd:comments>"
+ "</entry>", -1, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_YOUTUBE_VIDEO (video));
+ g_clear_error (&error);
+
+ /* Test the feed link */
+ feed_link = gdata_youtube_video_get_comments_feed_link (video);
+ g_assert (feed_link != NULL);
+ g_assert (feed_link->rel == NULL);
+ g_assert_cmpstr (feed_link->href, ==, "http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ/comments");
+ g_assert_cmpuint (feed_link->count_hint, ==, 13021);
+ g_assert (feed_link->read_only == FALSE);
+
+ /* TODO: more tests on entry properties */
+
+ g_object_unref (video);
+}
+
int
main (int argc, char *argv[])
{
@@ -393,6 +520,8 @@ main (int argc, char *argv[])
if (g_test_slow () == TRUE)
g_test_add_func ("/youtube/upload/simple", test_upload_simple);
g_test_add_func ("/youtube/parsing/app:control", test_parsing_app_control);
+ g_test_add_func ("/youtube/parsing/comments/feedLink", test_parsing_comments_feed_link);
+ g_test_add_func ("/youtube/parsing/yt:recorded", test_parsing_yt_recorded);
retval = g_test_run ();
if (service != NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]