static void verify_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer userdata) { SwService *service = SW_SERVICE (weak_object); SwServiceTwitter *twitter = SW_SERVICE_TWITTER (service); SwServiceTwitterPrivate *priv = twitter->priv; RestXmlNode *node; SW_DEBUG (TWITTER, "Verified credentials"); node = node_from_call (call); if (!node) return; priv->credentials = CREDS_VALID; priv->user_id = g_strdup (rest_xml_node_find (node, "id")->content); priv->image_url = g_strdup (rest_xml_node_find (node, "profile_image_url")->content); priv->geotag_enabled = g_str_equal (rest_xml_node_find (node, "geo_enabled")->content, "true"); rest_xml_node_unref (node); sw_service_emit_capabilities_changed (service, get_dynamic_caps (service)); g_object_unref (call); }
static void verify_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer userdata) { MojitoService *service = MOJITO_SERVICE (weak_object); MojitoServiceTwitter *twitter = MOJITO_SERVICE_TWITTER (service); RestXmlNode *node; if (error) { sanity_check_date (call); g_message ("Error: %s", error->message); return; } MOJITO_DEBUG (TWITTER, "Authentication verified"); node = node_from_call (call); if (!node) return; twitter->priv->user_id = g_strdup (rest_xml_node_find (node, "id")->content); twitter->priv->image_url = g_strdup (rest_xml_node_find (node, "profile_image_url")->content); rest_xml_node_unref (node); mojito_service_emit_capabilities_changed (service, get_dynamic_caps (service)); if (twitter->priv->running) get_status_updates (twitter); }
static void _got_videos_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer user_data) { SwYoutubeItemView *item_view = SW_YOUTUBE_ITEM_VIEW (weak_object); SwYoutubeItemViewPrivate *priv = GET_PRIVATE (item_view); SwService *service; RestXmlNode *root, *node; if (error) { g_message (G_STRLOC ": error from Youtube: %s", error->message); /* TODO: cleanup or something */ return; } root = xml_node_from_call (call, "Youtube"); if (!root) return; node = rest_xml_node_find (root, "channel"); if (!node) return; /* Clean up the thumbnail mapping cache */ g_hash_table_remove_all (priv->thumb_map); service = sw_item_view_get_service (SW_ITEM_VIEW (item_view)); for (node = rest_xml_node_find (node, "item"); node; node = node->next) { SwItem *item; item = make_item (item_view, service, node); if (!sw_service_is_uid_banned (service, sw_item_get (item, "id"))) { sw_set_add (priv->set, (GObject *)item); } g_object_unref (item); } sw_item_view_set_from_set ((SwItemView *)item_view, priv->set); /* Save the results of this set to the cache */ sw_cache_save (service, priv->query, priv->params, priv->set); sw_set_empty (priv->set); rest_xml_node_unref (root); }
static SwItem * make_item (SwYoutubeItemView *item_view, SwService *service, RestXmlNode *node) { SwItem *item; char *author, *date, *url; RestXmlNode *subnode, *thumb_node; item = sw_item_new (); sw_item_set_service (item, service); /* <rss> <channel> <item> <guid isPermaLink="false">http://gdata.youtube.com/feeds/api/videos/<videoid></guid> <atom:updated>2010-02-13T06:17:32.000Z</atom:updated> <title>Video Title</title> <author>Author Name</author> <link>http://www.youtube.com/watch?v=<videoid>&feature=youtube_gdata</link> <media:group> <media:thumbnail url="http://i.ytimg.com/vi/<videoid>/default.jpg" height="90" width="120" time="00:03:00.500"/> </media:group> </item> </channel> </rss> */ sw_item_put (item, "id", xml_get_child_node_value (node, "guid")); date = xml_get_child_node_value (node, "atom:updated"); if (date != NULL) sw_item_put (item, "date", get_utc_date(date)); sw_item_put (item, "title", xml_get_child_node_value (node, "title")); sw_item_put (item, "url", xml_get_child_node_value (node, "link")); author = xml_get_child_node_value (node, "author"); sw_item_put (item, "author", author); /* media:group */ subnode = rest_xml_node_find (node, "media:group"); if (subnode){ thumb_node = rest_xml_node_find (subnode, "media:thumbnail"); url = (char *) rest_xml_node_get_attr (thumb_node, "url"); sw_item_request_image_fetch (item, TRUE, "thumbnail", url); } url = get_author_icon_url (item_view, author); sw_item_request_image_fetch (item, FALSE, "authoricon", url); g_free (url); return item; }
static void _got_videos_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer user_data) { SwVimeoItemView *item_view = SW_VIMEO_ITEM_VIEW (weak_object); SwVimeoItemViewPrivate *priv = GET_PRIVATE (item_view); SwService *service; RestXmlNode *root, *video_n; sw_call_list_remove (priv->calls, call); if (error) { g_message (G_STRLOC ": error from Vimeo: %s", error->message); /* TODO: cleanup or something */ return; } SW_DEBUG (VIMEO, "Got videos"); root = node_from_call (call); if (!root) return; SW_DEBUG (VIMEO, "Parsed videos"); service = sw_item_view_get_service (SW_ITEM_VIEW (item_view)); for (video_n = rest_xml_node_find (root, "video"); video_n; video_n = video_n->next) { SwItem *item; /* Vimeo is stupid and returns an empty <video> element if there are no videos, so check for this and skip it */ if (rest_xml_node_find (video_n, "url") == NULL) continue; item = make_item (item_view, service, video_n); if (!sw_service_is_uid_banned (service, sw_item_get (item, "id"))) { sw_set_add (priv->set, (GObject *)item); } g_object_unref (item); } rest_xml_node_unref (root); _update_if_done (item_view); }
static char * get_author_icon_url (SwYoutubeItemView *youtube, const char *author) { SwYoutubeItemViewPrivate *priv = GET_PRIVATE (youtube); RestProxyCall *call; RestXmlNode *root, *node; char *function, *url; url = g_hash_table_lookup (priv->thumb_map, author); if (url) return g_strdup (url); call = rest_proxy_new_call (priv->proxy); function = g_strdup_printf ("users/%s", author); rest_proxy_call_set_function (call, function); rest_proxy_call_sync (call, NULL); root = xml_node_from_call (call, "Youtube"); if (!root) return NULL; node = rest_xml_node_find (root, "media:thumbnail"); if (!node) return NULL; url = g_strdup (rest_xml_node_get_attr (node, "url")); g_free (function); if (url) g_hash_table_insert(priv->thumb_map, (gpointer)author, (gpointer)g_strdup (url)); return url; }
static void ggg_plan_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GggPlanDialog *dialog = GGG_PLAN_DIALOG (object); switch (property_id) { case PROP_PROVIDER: { RestXmlNode *node; node = g_value_get_boxed (value); populate_store (dialog->priv->store, node); gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->combo), 0); node = rest_xml_node_find (node, "name"); if (node && node->content && strlen (node->content) > 0) { char *str; /* TRANSLATORS: placeholder is service provider name, * e.g. "Vodafone" */ str = g_strdup_printf (_("Select your %s 3G Plan"), node->content); gtk_label_set_text (GTK_LABEL (dialog->priv->label), str); g_free (str); } else { gtk_label_set_text (GTK_LABEL (dialog->priv->label), _("Select your 3G Plan")); } } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static void _check_access_token_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer user_data) { RestXmlNode *root; GError *err = NULL; SwServiceVimeo *self = SW_SERVICE_VIMEO (weak_object); SwService *service = SW_SERVICE (self); SwServiceVimeoPrivate *priv = self->priv; root = node_from_call (call, &err); if (root == NULL) { g_assert (err != NULL); SW_DEBUG (VIMEO, "Invalid access token: %s", err->message); g_error_free (err); } else { RestXmlNode *username = rest_xml_node_find (root, "username"); priv->username = g_strdup (username->content); rest_proxy_bind (priv->simple_proxy, priv->username); rest_xml_node_unref (root); } sw_service_emit_capabilities_changed (service, get_dynamic_caps (service)); }
static void on_upload_cb (RestProxyCall *call, gsize total, gsize uploaded, const GError *error, GObject *weak_object, gpointer user_data) { SwServiceTwitter *twitter = SW_SERVICE_TWITTER (weak_object); RestXmlNode *root; char *tweet; int opid = GPOINTER_TO_INT (user_data); gint percent; if (error) { sw_photo_upload_iface_emit_photo_upload_progress (twitter, opid, -1, error->message); return; } /* Now post to Twitter */ root = node_from_call (call); if (root == NULL || g_strcmp0 (root->name, "image") != 0) { sw_photo_upload_iface_emit_photo_upload_progress (twitter, opid, -1, "Unexpected response from Twitpic"); if (root) rest_xml_node_unref (root); return; } /* This format is for tweets announcing twitpic URLs, "[tweet] [url]". */ tweet = g_strdup_printf (_("%s %s"), rest_xml_node_find (root, "text")->content, rest_xml_node_find (root, "url")->content); call = rest_proxy_new_call (twitter->priv->proxy); rest_proxy_call_set_method (call, "POST"); rest_proxy_call_set_function (call, "1/statuses/update.xml"); rest_proxy_call_add_param (call, "status", tweet); rest_proxy_call_async (call, on_upload_tweet_cb, (GObject *)twitter, NULL, NULL); percent = (gdouble) uploaded / (gdouble) total * 100; sw_photo_upload_iface_emit_photo_upload_progress (twitter, opid, percent, ""); rest_xml_node_unref (root); g_free (tweet); }
static void _got_status_updates_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer userdata) { SwTwitterItemView *item_view = SW_TWITTER_ITEM_VIEW (weak_object); SwTwitterItemViewPrivate *priv = GET_PRIVATE (item_view); RestXmlNode *root, *node; SwSet *set; SwService *service; if (error) { g_warning (G_STRLOC ": Error getting Tweets: %s", error->message); return; } root = _make_node_from_call (call); if (!root) return; set = sw_item_set_new (); SW_DEBUG (TWITTER, "Got tweets!"); service = sw_item_view_get_service (SW_ITEM_VIEW (item_view)); for (node = rest_xml_node_find (root, "status"); node; node = node->next) { SwItem *item; item = _make_item (item_view, node); sw_item_set_service (item, service); if (item) { if (!sw_service_is_uid_banned (service, sw_item_get (item, "id"))) { sw_set_add (set, (GObject *)item); } g_object_unref (item); } } sw_item_view_set_from_set (SW_ITEM_VIEW (item_view), set); /* Save the results of this set to the cache */ sw_cache_save (service, priv->query, priv->params, set); sw_set_unref (set); rest_xml_node_unref (root); }
static const char * get_child_content (RestXmlNode *node, const char *name) { g_assert (node); g_assert (name); node = rest_xml_node_find (node, name); if (node && node->content != '\0') return node->content; else return NULL; }
static void populate_store (GtkListStore *store, RestXmlNode *provider_node) { RestXmlNode *p_node, *name_node; for (p_node = rest_xml_node_find (provider_node, "apn"); p_node != NULL; p_node = p_node->next) { name_node = rest_xml_node_find (p_node, "name"); if (name_node) { gtk_list_store_insert_with_values (store, NULL, 0, 0, p_node, 1, name_node->content, -1); } else { gtk_list_store_insert_with_values (store, NULL, 0, 0, p_node, 1, rest_xml_node_get_attr (p_node, "value"), -1); } } }
static RestXmlNode * node_from_call (RestProxyCall *call, GError **error) { static RestXmlParser *parser = NULL; RestXmlNode *node; if (call == NULL) return NULL; if (parser == NULL) parser = rest_xml_parser_new (); if (!SOUP_STATUS_IS_SUCCESSFUL (rest_proxy_call_get_status_code (call))) { g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR, "HTTP error: %s (%d)", rest_proxy_call_get_status_message (call), rest_proxy_call_get_status_code (call)); return NULL; } node = rest_xml_parser_parse_from_data (parser, rest_proxy_call_get_payload (call), rest_proxy_call_get_payload_length (call)); /* Invalid XML, or incorrect root */ if (node == NULL || !g_str_equal (node->name, "rsp")) { g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR, "malformed remote response: %s", rest_proxy_call_get_payload (call)); if (node) rest_xml_node_unref (node); return NULL; } if (g_strcmp0 (rest_xml_node_get_attr (node, "stat"), "ok") != 0) { RestXmlNode *err; err = rest_xml_node_find (node, "err"); g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR, "remote Vimeo error: %s", err ? rest_xml_node_get_attr (err, "msg") : "unknown"); rest_xml_node_unref (node); return NULL; } return node; }
static RestXmlNode * xml_node_from_call (RestProxyCall *call, const char *name) { static RestXmlParser *parser = NULL; RestXmlNode *root; if (call == NULL) return NULL; if (parser == NULL) parser = rest_xml_parser_new (); if (!SOUP_STATUS_IS_SUCCESSFUL (rest_proxy_call_get_status_code (call))) { g_message ("Error from %s: %s (%d)", name, rest_proxy_call_get_status_message (call), rest_proxy_call_get_status_code (call)); return NULL; } root = rest_xml_parser_parse_from_data (parser, rest_proxy_call_get_payload (call), rest_proxy_call_get_payload_length (call)); if (root == NULL) { g_message ("Error from %s: %s", name, rest_proxy_call_get_payload (call)); return NULL; } /* Exception handling */ if (strcmp (name, "Youtube") == 0) { if (strcmp (root->name, "error_response") == 0) { RestXmlNode *node; node = rest_xml_node_find (root, "error_msg"); g_message ("Error response from Youtube: %s\n", node->content); rest_xml_node_unref (root); return NULL; } } return root; }
/* * For a given parent @node, get the child node called @name and return a copy * of the content, or NULL. If the content is the empty string, NULL is * returned. */ static char * xml_get_child_node_value (RestXmlNode *node, const char *name) { RestXmlNode *subnode; g_assert (node); g_assert (name); subnode = rest_xml_node_find (node, name); if (!subnode) return NULL; if (subnode->content && subnode->content[0]) return g_strdup (subnode->content); else return NULL; }
static RestXmlNode * node_from_call (RestProxyCall *call) { static RestXmlParser *parser = NULL; RestXmlNode *node; if (call == NULL) return NULL; if (parser == NULL) parser = rest_xml_parser_new (); if (!SOUP_STATUS_IS_SUCCESSFUL (rest_proxy_call_get_status_code (call))) { g_message (G_STRLOC ": error from Last.fm: %s (%d)", rest_proxy_call_get_status_message (call), rest_proxy_call_get_status_code (call)); return NULL; } node = rest_xml_parser_parse_from_data (parser, rest_proxy_call_get_payload (call), rest_proxy_call_get_payload_length (call)); /* No content, or wrong content */ if (node == NULL || strcmp (node->name, "lfm") != 0) { g_message (G_STRLOC ": cannot make Last.fm call"); /* TODO: display the payload if its short */ if (node) rest_xml_node_unref (node); return NULL; } if (strcmp (rest_xml_node_get_attr (node, "status"), "ok") != 0) { RestXmlNode *err_node; err_node = rest_xml_node_find (node, "error"); g_message (G_STRLOC ": cannot make Last.fm call: %s (code %s)", err_node->content, rest_xml_node_get_attr (err_node, "code")); rest_xml_node_unref (node); return NULL; } return node; }
static void _mobile_session_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer userdata) { const gchar *status; SwService *service = SW_SERVICE (weak_object); SwServiceLastfm *lastfm = SW_SERVICE_LASTFM (service); SwServiceLastfmPrivate *priv = lastfm->priv; RestXmlNode *node; priv->checked_with_server = TRUE; if (error) { g_message ("Error: %s", error->message); g_object_unref (call); sw_service_emit_capabilities_changed (service, get_dynamic_caps (service)); return; } node = node_from_call (call); if (!node) return; status = g_hash_table_lookup (node->attrs, "status"); if (g_strcmp0 (status, "ok") == 0) { RestXmlNode *session_key = rest_xml_node_find (node, "key"); if (session_key) { g_free (priv->session_key); priv->session_key = g_strdup (session_key->content); } } rest_xml_node_unref (node); g_object_unref (call); sw_service_emit_capabilities_changed (service, get_dynamic_caps (service)); }
static void tweets_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer userdata) { MojitoServiceTwitter *service = MOJITO_SERVICE_TWITTER (weak_object); RestXmlNode *root, *node; MojitoSet *set; if (error) { g_message ("Error: %s", error->message); return; } root = node_from_call (call); if (!root) return; set = mojito_item_set_new (); MOJITO_DEBUG (TWITTER, "Got tweets!"); for (node = rest_xml_node_find (root, "status"); node; node = node->next) { MojitoItem *item; /* TODO: skip the user's own tweets */ item = make_item (service, node); if (item) mojito_set_add (set, (GObject *)item); } mojito_service_emit_refreshed ((MojitoService *)service, set); /* TODO cleanup */ rest_xml_node_unref (root); }
static SwItem * make_item (SwVimeoItemView *item_view, SwService *service, RestXmlNode *video_n) { SwItem *item; item = sw_item_new (); sw_item_set_service (item, service); sw_item_put (item, "id", rest_xml_node_find (video_n, "url")->content); sw_item_put (item, "url", rest_xml_node_find (video_n, "url")->content); sw_item_put (item, "title", rest_xml_node_find (video_n, "title")->content); sw_item_put (item, "author", rest_xml_node_find (video_n, "user_name")->content); sw_item_take (item, "date", make_date (rest_xml_node_find (video_n, "upload_date")->content)); sw_item_request_image_fetch (item, FALSE, "thumbnail", rest_xml_node_find (video_n, "thumbnail_medium")->content); sw_item_request_image_fetch (item, FALSE, "authoricon", rest_xml_node_find (video_n, "user_portrait_medium")->content); return item; }
/** * flickr_proxy_is_successful: * @root: The root node of a parsed Flickr response * @error: #GError to set if the response was an error * * Examines the Flickr response and if it not a successful reply, set @error and * return FALSE. * * Returns: %TRUE if this response is successful, %FALSE otherwise. */ gboolean flickr_proxy_is_successful (RestXmlNode *root, GError **error) { RestXmlNode *node; g_return_val_if_fail (root, FALSE); if (strcmp (root->name, "rsp") != 0) { g_set_error (error, FLICKR_PROXY_ERROR, 0, "Unexpected response from Flickr (root node %s)", root->name); return FALSE; } if (strcmp (rest_xml_node_get_attr (root, "stat"), "ok") != 0) { node = rest_xml_node_find (root, "err"); g_set_error_literal (error,FLICKR_PROXY_ERROR, atoi (rest_xml_node_get_attr (node, "code")), rest_xml_node_get_attr (node, "msg")); return FALSE; } return TRUE; }
static MojitoItem * make_item (MojitoServiceTwitter *twitter, RestXmlNode *node) { MojitoServiceTwitterPrivate *priv = twitter->priv; MojitoItem *item; RestXmlNode *u_node, *n; const char *post_id, *user_id, *user_name, *date, *content; char *url; GMatchInfo *match_info; u_node = rest_xml_node_find (node, "user"); user_id = rest_xml_node_find (u_node, "id")->content; /* For friend only feeds, ignore our own tweets */ if (priv->type == FRIENDS && user_id && g_str_equal (user_id, priv->user_id)) { return NULL; } item = mojito_item_new (); mojito_item_set_service (item, (MojitoService *)twitter); post_id = rest_xml_node_find (node, "id")->content; mojito_item_put (item, "authorid", user_id); url = g_strdup_printf ("http://twitter.com/%s/statuses/%s", user_id, post_id); mojito_item_put (item, "id", url); mojito_item_take (item, "url", url); user_name = rest_xml_node_find (node, "name")->content; mojito_item_put (item, "author", user_name); content = rest_xml_node_find (node, "text")->content; if (g_regex_match (priv->twitpic_re, content, 0, &match_info)) { char *twitpic_id, *new_content; /* Construct the thumbnail URL and download the image */ twitpic_id = g_match_info_fetch (match_info, 1); url = g_strconcat ("http://twitpic.com/show/thumb/", twitpic_id, NULL); mojito_item_request_image_fetch (item, FALSE, "thumbnail", url); g_free (url); /* Remove the URL from the tweet and use that as the title */ new_content = g_regex_replace (priv->twitpic_re, content, -1, 0, "", 0, NULL); cleanup_twitpic (new_content); mojito_item_take (item, "title", new_content); /* Update the URL to point at twitpic */ url = g_strconcat ("http://twitpic.com/", twitpic_id, NULL); mojito_item_take (item, "url", url); g_free (twitpic_id); } mojito_item_put (item, "content", content); g_match_info_free (match_info); date = rest_xml_node_find (node, "created_at")->content; mojito_item_take (item, "date", make_date (date)); n = rest_xml_node_find (u_node, "location"); if (n && n->content) mojito_item_put (item, "location", n->content); n = rest_xml_node_find (u_node, "profile_image_url"); if (n && n->content) mojito_item_request_image_fetch (item, FALSE, "authoricon", n->content); return item; }
static SwItem * _make_item (SwTwitterItemView *item_view, RestXmlNode *node) { SwTwitterItemViewPrivate *priv = GET_PRIVATE (item_view); RestXmlNode *u_node, *n, *place_n; const char *post_id, *user_id, *user_name, *date, *content; char *url; GMatchInfo *match_info; SwItem *item; u_node = rest_xml_node_find (node, "user"); user_id = rest_xml_node_find (u_node, "screen_name")->content; item = sw_item_new (); post_id = rest_xml_node_find (node, "id")->content; sw_item_put (item, "authorid", user_id); url = g_strdup_printf ("http://twitter.com/%s/statuses/%s", user_id, post_id); sw_item_put (item, "id", url); sw_item_take (item, "url", url); user_name = rest_xml_node_find (u_node, "name")->content; sw_item_put (item, "author", user_name); content = rest_xml_node_find (node, "text")->content; if (g_regex_match (priv->twitpic_re, content, 0, &match_info)) { char *twitpic_id, *new_content; /* Construct the thumbnail URL and download the image */ twitpic_id = g_match_info_fetch (match_info, 1); url = g_strconcat ("http://twitpic.com/show/thumb/", twitpic_id, NULL); sw_item_request_image_fetch (item, TRUE, "thumbnail", url); g_free (url); /* Remove the URL from the tweet and use that as the title */ new_content = g_regex_replace (priv->twitpic_re, content, -1, 0, "", 0, NULL); _cleanup_twitpic (new_content); sw_item_take (item, "title", new_content); /* Update the URL to point at twitpic */ url = g_strconcat ("http://twitpic.com/", twitpic_id, NULL); sw_item_take (item, "url", url); g_free (twitpic_id); } /* sw_unescape_entities works in place */ sw_item_put (item, "content", sw_unescape_entities ((gchar *)content)); g_match_info_free (match_info); date = rest_xml_node_find (node, "created_at")->content; sw_item_take (item, "date", _make_date (date)); n = rest_xml_node_find (u_node, "location"); if (n && n->content) sw_item_put (item, "location", n->content); n = rest_xml_node_find (node, "geo"); if (n) { n = rest_xml_node_find (n, "georss:point"); if (n && n->content) { gchar **split_str; split_str = g_strsplit (n->content, " ", 2); if (split_str[0] && split_str[1]) { sw_item_put (item, "latitude", split_str[0]); sw_item_put (item, "longitude", split_str[1]); } g_strfreev (split_str); } } place_n = rest_xml_node_find (node, "place"); if (place_n) { n = rest_xml_node_find (place_n, "name"); if (n && n->content) { sw_item_put (item, "place_name", n->content); } n = rest_xml_node_find (place_n, "full_name"); if (n && n->content) { sw_item_put (item, "place_full_name", n->content); } } n = rest_xml_node_find (u_node, "profile_image_url"); if (n && n->content) sw_item_request_image_fetch (item, FALSE, "authoricon", n->content); return item; }
static void _get_friends_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer user_data) { SwLastfmContactView *contact_view = SW_LASTFM_CONTACT_VIEW (weak_object); SwLastfmContactViewPrivate *priv = GET_PRIVATE (weak_object); gboolean updated = FALSE; RestXmlNode *root, *node; sw_call_list_remove (priv->calls, call); if (error) { g_message (G_STRLOC ": error from Last.fm: %s", error->message); g_object_unref (call); return; } SW_DEBUG (LASTFM, "Got result of getFriends call"); root = node_from_call (call); g_object_unref (call); if (!root) return; SW_DEBUG (LASTFM, "Parsed results of getFriends call"); for (node = rest_xml_node_find (root, "user"); node; node = node->next) { SwContact *contact; SwService *service; const gchar *id; const gchar *realname; const gchar *url; service = sw_contact_view_get_service (SW_CONTACT_VIEW (contact_view)); contact = sw_contact_new (); sw_contact_set_service (contact, service); id = rest_xml_node_find (node, "name")->content; realname = rest_xml_node_find (node, "realname")->content; url = rest_xml_node_find (node, "url")->content; if (!id) { g_object_unref (contact); continue; } sw_contact_put (contact, "id", id); if (!realname) realname = id; sw_contact_put (contact, "name", realname); if (url) sw_contact_put (contact, "url", url); if (!sw_service_is_uid_banned (service, sw_contact_get (contact, "id"))) { sw_set_add (priv->set, (GObject *)contact); updated = TRUE; } /* No date, so use now at the timestamp */ sw_contact_take (contact, "date", sw_time_t_to_string (time (NULL))); g_object_unref (contact); } rest_xml_node_unref (root); if (updated) _update_if_done (contact_view); }
int main (int argc, char **argv) { RestProxy *proxy; RestProxyCall *call; GError *error = NULL; char pin[256]; RestXmlParser *parser; RestXmlNode *root, *node; g_type_init (); /* Create the proxy */ proxy = oauth_proxy_new (/* Consumer Key */ "NmUm6hxQ9a4u", /* Consumer Secret */ "t4FM7LiUeD4RBwKSPa6ichKPDh5Jx4kt", /* FireEagle endpoint */ "https://fireeagle.yahooapis.com/", FALSE); /* First stage authentication, this gets a request token. */ if (!oauth_proxy_request_token (OAUTH_PROXY (proxy), "oauth/request_token", "oob", &error)) g_error ("Cannot request token: %s", error->message); /* From the token construct a URL for the user to visit */ g_print ("Go to https://fireeagle.yahoo.net/oauth/authorize?oauth_token=%s then enter the verification code\n", oauth_proxy_get_token (OAUTH_PROXY (proxy))); /* Read the PIN */ fgets (pin, sizeof (pin), stdin); g_strchomp (pin); /* Second stage authentication, this gets an access token. */ if (!oauth_proxy_access_token (OAUTH_PROXY (proxy), "oauth/access_token", pin, &error)) g_error ("Cannot request token: %s", error->message); /* Get the user's current location */ call = rest_proxy_new_call (proxy); rest_proxy_call_set_function (call, "api/0.1/user"); if (!rest_proxy_call_run (call, NULL, &error)) g_error ("Cannot make call: %s", error->message); parser = rest_xml_parser_new (); root = rest_xml_parser_parse_from_data (parser, rest_proxy_call_get_payload (call), rest_proxy_call_get_payload_length (call)); g_object_unref (parser); g_object_unref (call); g_object_unref (proxy); node = rest_xml_node_find (root, "location"); node = rest_xml_node_find (node, "name"); g_print ("%s\n", node->content); return 0; }
static void mex_suggest_complete_cb (MexDownloadQueue *queue, const gchar *uri, const gchar *buffer, gsize count, const GError *error, gpointer userdata) { RestXmlNode *root, *n; RestXmlParser *parser; MexSearchPlugin *self = userdata; MexSearchPluginPrivate *priv = self->priv; priv->suggest_id = NULL; /* hide spinner */ mx_spinner_set_animating (MX_SPINNER (priv->spinner), FALSE); clutter_actor_hide (priv->spinner); if (error) { g_warning ("Error querying Google suggestions: %s", error->message); return; } parser = rest_xml_parser_new (); root = rest_xml_parser_parse_from_data (parser, buffer, count); if (!root) { g_warning ("Unknown error parsing Google suggestions XML"); g_object_unref (parser); return; } /* Clear model */ mex_model_clear (MEX_MODEL (priv->suggest_model)); /* Add new suggestions to model */ n = rest_xml_node_find (root, "CompleteSuggestion"); for (; n; n = n->next) { MexContent *content; const gchar *suggestion; RestXmlNode *node = rest_xml_node_find (n, "suggestion"); if (!node) continue; suggestion = rest_xml_node_get_attr (node, "data"); if (!suggestion) continue; content = MEX_CONTENT (mex_program_new (priv->suggest_model)); mex_content_set_metadata (content, MEX_CONTENT_METADATA_TITLE, suggestion); mex_content_set_metadata (content, MEX_CONTENT_METADATA_MIMETYPE, "x-mex/search"); mex_model_add_content (MEX_MODEL (priv->suggest_model), content); } /* Unref */ rest_xml_node_unref (root); g_object_unref (parser); }