Author: abrander
Date: 2009-12-27 22:17:23 +0100 (Sun, 27 Dec 2009)
New Revision: 2859
Added:
trunk/plugins/output-facebook/rs-facebook-client.c
trunk/plugins/output-facebook/rs-facebook-client.h
Removed:
trunk/plugins/output-facebook/facebook.c
trunk/plugins/output-facebook/facebook.h
Modified:
trunk/plugins/output-facebook/Makefile.am
trunk/plugins/output-facebook/output-facebook.c
Log:
GObjectified Facebook client library.
Modified: trunk/plugins/output-facebook/Makefile.am
===================================================================
--- trunk/plugins/output-facebook/Makefile.am 2009-12-27 21:14:51 UTC (rev
2858)
+++ trunk/plugins/output-facebook/Makefile.am 2009-12-27 21:17:23 UTC (rev
2859)
@@ -2,6 +2,7 @@
AM_CFLAGS =\
-Wall\
+ -Wstrict-aliasing=0\
-O4
AM_CXXFLAGS = $(AM_CFLAGS)
@@ -18,4 +19,6 @@
output_facebook_la_LIBADD = @PACKAGE_LIBS@
output_facebook_la_LDFLAGS = -module -avoid-version -L/usr/lib -lcurl
-output_facebook_la_SOURCES = output-facebook.c facebook.c
+output_facebook_la_SOURCES = output-facebook.c output-facebook.h \
+ rs-facebook-client.c rs-facebook-client.h \
+ rs-facebook-client-param.c rs-facebook-client-param.h
Deleted: trunk/plugins/output-facebook/facebook.c
===================================================================
--- trunk/plugins/output-facebook/facebook.c 2009-12-27 21:14:51 UTC (rev
2858)
+++ trunk/plugins/output-facebook/facebook.c 2009-12-27 21:17:23 UTC (rev
2859)
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Anders Brander <[email protected]> and
- * Anders Kvist <[email protected]>
- *
- * 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 later 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.
- */
-
-#include <string.h>
-#include <curl/curl.h>
-#include <glib-2.0/glib.h>
-#include <libxml/encoding.h>
-#include "facebook.h"
-
-static facebook *fb = NULL;
-
-gboolean request(gchar *method, GList *params, GString *result);
-static gint sort_alphabetical(gconstpointer a, gconstpointer b);
-GString *get_param_string(GList *params, gboolean separate);
-gchar *get_signature(GList *params);
-size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userp);
-gboolean xml_error(gchar *xml, gint length);
-gchar *parse_xml_response(gchar *xml, gint length, gchar *key, gboolean root);
-
-gboolean
-request(gchar *method, GList *params, GString *result)
-{
- curl_easy_reset(fb->curl);
-
-#ifdef fb_debug
- curl_easy_setopt(fb->curl, CURLOPT_VERBOSE, TRUE);
-#endif
-
- curl_easy_setopt(fb->curl, CURLOPT_URL, fb->server);
-
- params = g_list_append(params, g_strdup_printf("api_key=%s",
fb->api_key));
- params = g_list_append(params, g_strdup_printf("method=%s", method));
- params = g_list_append(params, g_strdup_printf("v=1.0"));
- params = g_list_append(params, g_strdup_printf("call_id=%d",
fb->call_id));
-
- fb->call_id++;
-
- if(fb->session_key)
- params = g_list_append(params,
g_strdup_printf("session_key=%s", fb->session_key));
-
- params = g_list_sort(params, sort_alphabetical);
-
- params = g_list_append(params,
g_strdup_printf("sig=%s",get_signature(params)));
-
- GString *query = get_param_string(params, TRUE);
-
- struct curl_slist *header = NULL;
- gchar *temp = g_strdup_printf("Content-Type: multipart/form-data;
boundary=%s", fb->boundary);
- header = curl_slist_append(header, temp);
- g_free(temp);
- header = curl_slist_append(header, "MIME-version: 1.0;");
-
- curl_easy_setopt(fb->curl, CURLOPT_POST, TRUE);
- curl_easy_setopt(fb->curl, CURLOPT_POSTFIELDS, query->str);
- curl_easy_setopt(fb->curl, CURLOPT_POSTFIELDSIZE, query->len);
- curl_easy_setopt(fb->curl, CURLOPT_WRITEFUNCTION, write_callback);
- curl_easy_setopt(fb->curl, CURLOPT_WRITEDATA, result);
- curl_easy_setopt(fb->curl, CURLOPT_HTTPHEADER, header);
- fb->res = curl_easy_perform(fb->curl);
- fb->call_id++;
- return (fb->res == 0);
-}
-
-static gint
-sort_alphabetical(gconstpointer a, gconstpointer b)
-{
- gchar *str1 = (gchar *) a;
- gchar *str2 = (gchar *) b;
-
- return g_strcmp0(str1, str2);
-}
-
-GString *
-get_param_string(GList *params, gboolean separate)
-{
- GString *str = g_string_new("");
- GString *image = NULL;
-
- gint i;
-
- for (i = 0; i < g_list_length(params); i++)
- {
- if (separate)
- {
- gchar **split = g_strsplit(g_list_nth_data(params, i),
"=", 0);
- if(g_strcmp0(split[0], "filename") == 0)
- {
- gchar *contents;
- gsize length;
- if (g_file_get_contents(split[1], &contents,
&length, NULL))
- {
-
- image = g_string_new("--");
- g_string_append_printf(image, "%s\r\n",
fb->boundary);
- g_string_append_printf(image,
"Content-Disposition: form-data; filename=%s\r\n", split[1]);
- g_string_append_printf(image,
"Content-Type: image/jpg\r\n\r\n");
- image = g_string_append_len(image,
contents, length);
- g_string_append_printf(image,
"\r\n--%s\r\n", fb->boundary);
- }
- }
- g_string_append_printf(str,
"--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n",
fb->boundary, split[0], split[1]);
- } else {
- str = g_string_append(str, g_list_nth_data(params, i));
- }
- }
-
- if (image)
- str = g_string_append_len(str, image->str, image->len);
-
- return str;
-}
-
-gchar *
-get_signature(GList *params)
-{
- GString *str = get_param_string(params, FALSE);
- str = g_string_append(str, fb->secret);
- gchar *signature = g_compute_checksum_for_string(G_CHECKSUM_MD5,
str->str, strlen(str->str));
- g_string_free(str, TRUE);
- return signature;
-}
-
-size_t
-write_callback(void *ptr, size_t size, size_t nmemb, void *userp)
-{
- GString *string = (GString *) userp;
- string = g_string_append_len(string, (char *) ptr, size * nmemb);
- return (size * nmemb);
-}
-
-gboolean
-xml_error(gchar *xml, gint length)
-{
- gchar *error_code = parse_xml_response(xml, length, "error_code",
FALSE);
- gchar *error_msg = parse_xml_response(xml, length, "error_msg", FALSE);
-
- if (error_code)
- {
- printf("error: %s\n", error_msg);
- g_free(error_code);
- g_free(error_msg);
- return TRUE;
- }
- g_free(error_code);
- g_free(error_msg);
- return FALSE;
-}
-
-gchar *
-parse_xml_response(gchar *xml, gint length, gchar *key, gboolean root)
-{
- xmlDocPtr doc = xmlParseMemory(xml, length);
- xmlNodePtr cur;
-
- cur = xmlDocGetRootElement(doc);
-
- if (!root)
- cur = cur->xmlChildrenNode;
-
- gchar *result = NULL;
-
- while (cur)
- {
- if ((!xmlStrcmp(cur->name, BAD_CAST(key))))
- result = xmlNodeListGetString(doc,
cur->xmlChildrenNode, 1);
-
- cur = cur->next;
- }
- return result;
-}
-
-/* BEGIN PUBLIC FUNCTIONS */
-
-gboolean
-facebook_upload_photo(const gchar *filename, const char *caption)
-{
- GList *params = NULL;
- GString *xml = g_string_new("");
-
- params = g_list_append(params, g_strdup_printf("filename=%s",
filename));
- params = g_list_append(params, g_strdup_printf("caption=%s", caption));
-
- if (!request("facebook.Photos.upload", params, xml))
- return FALSE;
-
- if (g_utf8_strlen(xml->str, 1048576) == 0)
- return FALSE;
-
- gboolean error = xml_error(xml->str, strlen(xml->str));
- if (error)
- return FALSE;
-
- g_string_free(xml, TRUE);
- return TRUE;
-}
-
-
-gboolean
-facebook_init(gchar *my_key, gchar *my_secret, gchar *my_server)
-{
- fb = g_malloc(sizeof(facebook));
- fb->api_key = my_key;
- fb->secret = my_secret;
- fb->server = my_server;
- fb->call_id = 0;
- fb->token = NULL;
- fb->session_key = NULL;
- fb->boundary = g_compute_checksum_for_string(G_CHECKSUM_MD5,
"boundary", strlen("boundary"));
-
- fb->curl = curl_easy_init();
- if(!fb->curl)
- {
- g_error("Could not initialize curl.");
- return FALSE;
- }
- return TRUE;
-}
-
-gboolean
-facebook_get_token()
-{
- GList *params = NULL;
- GString *xml = g_string_new("");
-
- if (!request("facebook.auth.createToken", params, xml))
- return FALSE;
-
- if (g_utf8_strlen(xml->str, 1048576) == 0)
- return FALSE;
-
- /* Check for errors */
- gboolean error = xml_error(xml->str, strlen(xml->str));
- if (error)
- return FALSE;
-
- /* Get auth token */
- fb->token = parse_xml_response(xml->str, strlen(xml->str),
"auth_createToken_response", TRUE);
-
- if (!fb->token)
- return FALSE;
-
- return TRUE;
-}
-
-gchar *
-facebook_get_auth_url(gchar *url)
-{
- GString *str = g_string_new(url);
- str = g_string_append(str, "?api_key=");
- str = g_string_append(str, fb->api_key);
- str = g_string_append(str, "&auth_token=");
- str = g_string_append(str, fb->token);
-
- gchar *ret = str->str;
- g_string_free(str, FALSE);
-
- return ret;
-}
-
-void
-facebook_set_session(gchar *session)
-{
- fb->session_key = session;
-}
-
-gchar *
-facebook_get_session()
-{
- GList *params = NULL;
- GString *xml = g_string_new("");
-
- params = g_list_append(params, g_strdup_printf("auth_token=%s",
fb->token));
-
- if (!request("facebook.auth.getSession", params, xml))
- return NULL;
-
- if (g_utf8_strlen(xml->str, 1048576) == 0)
- return NULL;
-
- /* Check for errors */
- gboolean error = xml_error(xml->str, strlen(xml->str));
- if (error)
- return NULL;
-
- /* Get session_key */
- fb->session_key = parse_xml_response(xml->str, strlen(xml->str),
"session_key", FALSE);
- g_string_free(xml, TRUE);
-
- if (!fb->session_key)
- return NULL;
-
- return fb->session_key;
-}
-
-gboolean
-facebook_ping()
-{
- GList *params = NULL;
- GString *xml = g_string_new("");
-
- if (!request("facebook.users.isAppAdded", params, xml))
- return FALSE;
-
- if (g_utf8_strlen(xml->str, 1048576) == 0)
- return FALSE;
-
- gboolean error = xml_error(xml->str, strlen(xml->str));
- if (error)
- return FALSE;
-
- gchar *result = parse_xml_response(xml->str, strlen(xml->str),
"users_isAppAdded_response", TRUE);
-
- if (g_strcmp0(result, "1") != 0)
- return FALSE;
-
- g_string_free(xml, TRUE);
- return TRUE;
-}
-
-void
-facebook_close()
-{
- curl_easy_cleanup(fb->curl);
- g_free(fb);
-}
-
-/* END PUBLIC FUNCTIONS */
Deleted: trunk/plugins/output-facebook/facebook.h
===================================================================
--- trunk/plugins/output-facebook/facebook.h 2009-12-27 21:14:51 UTC (rev
2858)
+++ trunk/plugins/output-facebook/facebook.h 2009-12-27 21:17:23 UTC (rev
2859)
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Anders Brander <[email protected]> and
- * Anders Kvist <[email protected]>
- *
- * 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 later 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 FACEBOOK_H
-#define FACEBOOK_H
-
-#include <glib-2.0/glib.h>
-#include <curl/curl.h>
-
-typedef struct {
- gchar *api_key;
- gchar *secret;
- gchar *token;
- gchar *server;
- gchar *session_key;
- gchar *boundary;
-
- /* curl */
- CURL *curl;
- CURLcode res;
- gint call_id;
-} facebook;
-
-gboolean facebook_upload_photo(const gchar *filename, const char *caption);
-gboolean facebook_init(gchar *my_key, gchar *my_secret, gchar *my_server);
-gboolean facebook_get_token();
-gchar * facebook_get_auth_url(gchar *url);
-void facebook_set_session(gchar *session);
-gchar * facebook_get_session();
-gboolean facebook_ping();
-void facebook_close();
-
-#endif /* FACEBOOK_H */
Modified: trunk/plugins/output-facebook/output-facebook.c
===================================================================
--- trunk/plugins/output-facebook/output-facebook.c 2009-12-27 21:14:51 UTC
(rev 2858)
+++ trunk/plugins/output-facebook/output-facebook.c 2009-12-27 21:17:23 UTC
(rev 2859)
@@ -31,7 +31,7 @@
#include "output-facebook.h"
#include <unistd.h>
#include <string.h>
-#include "facebook.h"
+#include "rs-facebook-client.h"
/* Ugly HACK - conf_interface.c|h needs to be ported to librawstudio */
gchar *rs_conf_get_string (const gchar * name);
@@ -215,7 +215,7 @@
}
gboolean
-auth_popup(gchar *text, gchar *auth_url)
+auth_popup(const gchar *text, const gchar *auth_url)
{
/* FIXME: move this to librawstudio */
@@ -272,31 +272,53 @@
}
static gboolean
+deal_with_error(GError **error)
+{
+ if (!*error)
+ return FALSE;
+
+ g_warning("Error from Facebook: '%s'", (*error)->message);
+
+ gdk_threads_enter();
+ GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
+ "Error: '%s'", (*error)->message);
+
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Unhandled error from
Facebook"));
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
GTK_RESPONSE_CLOSE);
+
+ g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy),
NULL);
+
+ gtk_widget_show (dialog);
+
+ gdk_threads_leave();
+
+ g_clear_error(error);
+
+ return TRUE;
+}
+
+static gboolean
execute (RSOutput * output, RSFilter * filter)
{
+ GError *error = NULL;
RSFacebook *facebook = RS_FACEBOOK (output);
- if (!facebook_init(FACEBOOK_API_KEY, FACEBOOK_SECRET_KEY,
FACEBOOK_SERVER))
- return FALSE;
-
gchar *session = rs_conf_get_string("facebook_session");
+ RSFacebookClient *facebook_client =
rs_facebook_client_new(FACEBOOK_API_KEY, FACEBOOK_SECRET_KEY, session);
+ g_free(session);
- if (session)
- facebook_set_session(session);
+ gboolean ping = rs_facebook_client_ping(facebook_client, &error);
+ deal_with_error(&error);
- if(!facebook_ping())
+ if (!ping)
{
-
- facebook_set_session(NULL);
-
- if (!facebook_get_token())
- return FALSE;
-
- gchar *url = facebook_get_auth_url(FACEBOOK_LOGIN);
+ const gchar *url =
rs_facebook_client_get_auth_url(facebook_client, FACEBOOK_LOGIN, &error);
+ deal_with_error(&error);
if (!auth_popup(_("Rawstudio needs to be authenticated before
it will be able to upload photos to your Facebook account."), url))
return FALSE;
- gchar *session = facebook_get_session();
+ const gchar *session =
rs_facebook_client_get_session_key(facebook_client, &error);
+ deal_with_error(&error);
if (!session)
return FALSE;
@@ -310,12 +332,12 @@
rs_output_execute (jpegsave, filter);
g_object_unref (jpegsave);
- if(!facebook_upload_photo(temp_file, facebook->caption))
- return FALSE;
+ gboolean ret = rs_facebook_client_upload_image(facebook_client,
temp_file, facebook->caption, &error);
+ deal_with_error(&error);
unlink (temp_file);
g_free (temp_file);
- facebook_close();
+ g_object_unref(facebook_client);
- return TRUE;
+ return ret;
}
Added: trunk/plugins/output-facebook/rs-facebook-client.c
===================================================================
--- trunk/plugins/output-facebook/rs-facebook-client.c
(rev 0)
+++ trunk/plugins/output-facebook/rs-facebook-client.c 2009-12-27 21:17:23 UTC
(rev 2859)
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <[email protected]> and
+ * Anders Kvist <[email protected]>
+ *
+ * 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 later 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.
+ */
+
+#include <curl/curl.h>
+#include <libxml/encoding.h>
+#include "rs-facebook-client.h"
+
+#define HTTP_BOUNDARY "4wncn84cq4ncto874ytnv90w43htn"
+
+/**
+ * Get a quark used to describe Facebook error domain
+ * @return A quark touse in GErrors from Facebook code
+ */
+GQuark
+rs_facebook_client_error_quark(void)
+{
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+ static GQuark quark;
+
+ g_static_mutex_lock(&lock);
+ if (!quark)
+ quark =
g_quark_from_static_string("rawstudio_facebook_client_error");
+ g_static_mutex_unlock(&lock);
+
+ return quark;
+}
+
+struct _RSFacebookClient {
+ GObject parent;
+
+ const gchar *api_key;
+ const gchar *secret;
+
+ gchar *session_key;
+ gchar *auth_token;
+ gchar *auth_url;
+
+ CURL *curl;
+};
+
+G_DEFINE_TYPE(RSFacebookClient, rs_facebook_client, G_TYPE_OBJECT)
+
+static void
+rs_facebook_client_finalize(GObject *object)
+{
+ RSFacebookClient *facebook = RS_FACEBOOK_CLIENT(object);
+
+ g_free(facebook->session_key);
+ g_free(facebook->auth_token);
+ g_free(facebook->auth_url);
+
+ curl_easy_cleanup(facebook->curl);
+
+ G_OBJECT_CLASS(rs_facebook_client_parent_class)->finalize(object);
+}
+
+static void
+rs_facebook_client_class_init(RSFacebookClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->finalize = rs_facebook_client_finalize;
+}
+
+static void
+rs_facebook_client_init(RSFacebookClient *facebook)
+{
+ facebook->curl = curl_easy_init();
+}
+
+static gchar *
+xml_simple_response(const GString *xml, const gchar *needle, const gboolean
root)
+{
+ xmlDocPtr doc = xmlParseMemory(xml->str, xml->len);
+ xmlNodePtr cur;
+
+ cur = xmlDocGetRootElement(doc);
+
+ if (!root)
+ cur = cur->xmlChildrenNode;
+
+ gchar *result = NULL;
+
+ while (cur)
+ {
+ if ((!xmlStrcmp(cur->name, BAD_CAST(needle))))
+ result = (gchar *) xmlNodeListGetString(doc,
cur->xmlChildrenNode, 1);
+
+ cur = cur->next;
+ }
+ return result;
+}
+
+static gboolean
+xml_error(const GString *xml, GError **error)
+{
+ gchar *error_code = xml_simple_response(xml, "error_code", FALSE);
+ gchar *error_msg = xml_simple_response(xml, "error_msg", FALSE);
+
+ if (error_code)
+ {
+ g_set_error(error, RS_FACEBOOK_CLIENT_ERROR_DOMAIN, 0, "%s",
error_msg);
+ g_free(error_code);
+ g_free(error_msg);
+ return TRUE;
+ }
+ g_free(error_code);
+ g_free(error_msg);
+ return FALSE;
+}
+
+static size_t
+write_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ GString *string = (GString *) userp;
+ g_string_append_len(string, (char *) ptr, size * nmemb);
+ return (size * nmemb);
+}
+
+static gboolean
+facebook_client_request(RSFacebookClient *facebook, const gchar *method,
RSFacebookClientParam *param, GString *content, GError **error)
+{
+ volatile static gint call_id = 0;
+ CURLcode result;
+ struct curl_slist *header = NULL;
+ gint post_length = 0;
+ gchar *post_str;
+
+ /* We start by resetting all CURL parameters */
+ curl_easy_reset(facebook->curl);
+
+#ifdef fb_debug
+ curl_easy_setopt(facebook->curl, CURLOPT_VERBOSE, TRUE);
+#endif /* fb_debug */
+
+ g_atomic_int_inc(&call_id);
+
+ curl_easy_setopt(facebook->curl, CURLOPT_URL,
"api.facebook.com/restserver.php");
+ rs_facebook_client_param_add_string(param, "api_key2",
facebook->api_key);
+ rs_facebook_client_param_add_string(param, "method", method);
+ rs_facebook_client_param_add_string(param, "v", "1.0");
+ rs_facebook_client_param_add_integer(param, "call_id",
g_atomic_int_get(&call_id));
+
+ /* If we have a session key, we will use it */
+ if(facebook->session_key)
+ rs_facebook_client_param_add_string(param, "session_key",
facebook->session_key);
+
+ header = curl_slist_append(header, "Content-Type: multipart/form-data;
boundary=" HTTP_BOUNDARY);
+ header = curl_slist_append(header, "MIME-version: 1.0;");
+
+ post_str = rs_facebook_client_param_get_post(param, facebook->secret,
HTTP_BOUNDARY, &post_length);
+
+ curl_easy_setopt(facebook->curl, CURLOPT_POST, TRUE);
+ curl_easy_setopt(facebook->curl, CURLOPT_POSTFIELDS, post_str);
+ curl_easy_setopt(facebook->curl, CURLOPT_POSTFIELDSIZE, post_length);
+ curl_easy_setopt(facebook->curl, CURLOPT_WRITEFUNCTION, write_callback);
+ curl_easy_setopt(facebook->curl, CURLOPT_WRITEDATA, content);
+ curl_easy_setopt(facebook->curl, CURLOPT_HTTPHEADER, header);
+ result = curl_easy_perform(facebook->curl);
+
+ curl_slist_free_all(header);
+ g_free(post_str);
+ g_object_unref(param);
+
+ if (xml_error(content, error))
+ return FALSE;
+
+ return (result==0);
+}
+
+static const gchar *
+facebook_client_get_auth_token(RSFacebookClient *facebook, GError **error)
+{
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+
+ g_static_mutex_lock(&lock);
+ if (!facebook->auth_token)
+ {
+ GString *content = g_string_new("");
+ facebook_client_request(facebook, "facebook.auth.createToken",
rs_facebook_client_param_new(), content, error);
+ facebook->auth_token = xml_simple_response(content,
"auth_createToken_response", TRUE);
+ g_string_free(content, TRUE);
+ }
+ g_static_mutex_unlock(&lock);
+
+ return facebook->auth_token;
+}
+
+/**
+ * Initializes a new RSFacebookClient
+ * @param api_key The API key from Facebook
+ * @param secret The secret provided by Facebook
+ * @param session_key The stored session key or NULL if you haven't got one yet
+ * @return A new RSFacebookClient, this must be unreffed
+ */
+RSFacebookClient *
+rs_facebook_client_new(const gchar *api_key, const gchar *secret, const gchar
*session_key)
+{
+ RSFacebookClient *facebook = g_object_new(RS_TYPE_FACEBOOK_CLIENT,
NULL);
+
+ facebook->api_key = api_key;
+ facebook->secret = secret;
+
+ rs_facebook_client_set_session_key(facebook, session_key);
+
+ return facebook;
+}
+
+
+/**
+ * Get the url that the user must visit to authenticate this application
(api_key)
+ * @param facebook A RSFacebookClient
+ * @param base_url A prefix URL, "http://api.facebook.com/login.php" would
make sense
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return A URL that the user can visit to authenticate this application.
Thisshould not be freed
+ */
+const gchar *
+rs_facebook_client_get_auth_url(RSFacebookClient *facebook, const gchar
*base_url, GError **error)
+{
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+
+ g_assert(RS_IS_FACEBOOK_CLIENT(facebook));
+
+ g_static_mutex_lock(&lock);
+ if (!facebook->auth_url)
+ facebook->auth_url =
g_strdup_printf("%s?api_key=%s&auth_token=%s", base_url, facebook->api_key,
facebook_client_get_auth_token(facebook, error));
+ g_static_mutex_unlock(&lock);
+
+ return facebook->auth_url;
+}
+
+/**
+ * Get the session key as returned from Facebook
+ * @param facebook A RSFacebookClient
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return The session key from Facebook or NULL on error
+ */
+const gchar *
+rs_facebook_client_get_session_key(RSFacebookClient *facebook, GError **error)
+{
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+
+ g_assert(RS_IS_FACEBOOK_CLIENT(facebook));
+
+ g_static_mutex_lock(&lock);
+ RSFacebookClientParam *param = rs_facebook_client_param_new();
+
+ rs_facebook_client_param_add_string(param, "auth_token",
facebook->auth_token);
+ GString *content = g_string_new("");
+ facebook_client_request(facebook, "facebook.auth.getSession", param,
content, error);
+
+ g_free(facebook->session_key);
+ facebook->session_key = xml_simple_response(content, "session_key",
FALSE);
+ g_string_free(content, TRUE);
+ g_static_mutex_unlock(&lock);
+
+ return facebook->session_key;
+}
+
+/**
+ * Set the session key, this can be used to cache the session_key
+ * @param facebook A RSFacebookClient
+ * @param session_key A new session key to use
+ */
+void
+rs_facebook_client_set_session_key(RSFacebookClient *facebook, const gchar
*session_key)
+{
+ g_assert(RS_IS_FACEBOOK_CLIENT(facebook));
+
+ g_free(facebook->session_key);
+
+ facebook->session_key = g_strdup(session_key);
+}
+
+/**
+ * Check if we are authenticated to Facebook
+ * @param facebook A RSFacebookClient
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return TRUE if we're authenticated both by the Facebook API and by the
end-user, FALSE otherwise
+ */
+gboolean
+rs_facebook_client_ping(RSFacebookClient *facebook, GError **error)
+{
+ gboolean ret = FALSE;
+ g_assert(RS_IS_FACEBOOK_CLIENT(facebook));
+
+ GString *content = g_string_new("");
+ facebook_client_request(facebook, "facebook.users.isAppAdded",
rs_facebook_client_param_new(), content, error);
+ gchar *result = xml_simple_response(content,
"users_isAppAdded_response", TRUE);
+ g_string_free(content, TRUE);
+
+ if (result && g_str_equal(result, "1"))
+ ret = TRUE;
+
+ g_free(result);
+
+ return ret;
+}
+
+/**
+ * Upload a photo to Facebook, will be placed in the registered applications
default photo folder
+ * @param facebook A RSFacebookClient
+ * @param filename Full path to an image to upload. JPEG, PNG, TIFF accepted
+ * @param caption The caption to use for the image
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return TRUE on success, FALSE otherwise
+ */
+gboolean
+rs_facebook_client_upload_image(RSFacebookClient *facebook, const gchar
*filename, const gchar *caption, GError **error)
+{
+ g_assert(RS_IS_FACEBOOK_CLIENT(facebook));
+ g_return_val_if_fail(filename != NULL, FALSE);
+ g_return_val_if_fail(g_path_is_absolute(filename), FALSE);
+
+ RSFacebookClientParam *param = rs_facebook_client_param_new();
+
+ rs_facebook_client_param_add_string(param, "filename", filename);
+ if (caption)
+ rs_facebook_client_param_add_string(param, "caption", caption);
+
+ GString *content = g_string_new("");
+ facebook_client_request(facebook, "facebook.photos.upload", param,
content, error);
+
+ g_string_free(content, TRUE);
+
+ return TRUE;
+}
Added: trunk/plugins/output-facebook/rs-facebook-client.h
===================================================================
--- trunk/plugins/output-facebook/rs-facebook-client.h
(rev 0)
+++ trunk/plugins/output-facebook/rs-facebook-client.h 2009-12-27 21:17:23 UTC
(rev 2859)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <[email protected]> and
+ * Anders Kvist <[email protected]>
+ *
+ * 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 later 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 RS_FACEBOOK_CLIENT_H
+#define RS_FACEBOOK_CLIENT_H
+
+#include <glib-object.h>
+#include "rs-facebook-client-param.h"
+
+G_BEGIN_DECLS
+
+/**
+ * Get a quark used to describe Facebook error domain
+ * @return A quark touse in GErrors from Facebook code
+ */
+GQuark
+rs_facebook_client_error_quark(void);
+
+#define RS_FACEBOOK_CLIENT_ERROR_DOMAIN rs_facebook_client_error_quark()
+
+#define RS_TYPE_FACEBOOK_CLIENT rs_facebook_client_get_type()
+#define RS_FACEBOOK_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
RS_TYPE_FACEBOOK_CLIENT, RSFacebookClient))
+#define RS_FACEBOOK_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
RS_TYPE_FACEBOOK_CLIENT, RSFacebookClientClass))
+#define RS_IS_FACEBOOK_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
RS_TYPE_FACEBOOK_CLIENT))
+#define RS_IS_FACEBOOK_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
RS_TYPE_FACEBOOK_CLIENT))
+#define RS_FACEBOOK_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
RS_TYPE_FACEBOOK_CLIENT, RSFacebookClientClass))
+
+typedef struct _RSFacebookClient RSFacebookClient;
+
+typedef struct {
+ GObjectClass parent_class;
+} RSFacebookClientClass;
+
+GType rs_facebook_client_get_type(void);
+
+/**
+ * Initializes a new RSFacebookClient
+ * @param api_key The API key from Facebook
+ * @param secret The secret provided by Facebook
+ * @param session_key The stored session key or NULL if you haven't got one yet
+ * @return A new RSFacebookClient, this must be unreffed
+ */
+RSFacebookClient *
+rs_facebook_client_new(const gchar *api_key, const gchar *secret, const gchar
*session_key);
+
+/**
+ * Get the url that the user must visit to authenticate this application
(api_key)
+ * @param facebook A RSFacebookClient
+ * @param base_url A prefix URL, "http://api.facebook.com/login.php" would
make sense
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return A URL that the user can visit to authenticate this application.
Thisshould not be freed
+ */
+const gchar *
+rs_facebook_client_get_auth_url(RSFacebookClient *facebook, const gchar
*base_url, GError **error);
+
+/**
+ * Get the session key as returned from Facebook
+ * @param facebook A RSFacebookClient
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return The session key from Facebook or NULL on error
+ */
+const gchar *
+rs_facebook_client_get_session_key(RSFacebookClient *facebook, GError **error);
+
+/**
+ * Set the session key, this can be used to cache the session_key
+ * @param facebook A RSFacebookClient
+ * @param session_key A new session key to use
+ */
+void
+rs_facebook_client_set_session_key(RSFacebookClient *facebook, const gchar
*session_key);
+
+/**
+ * Check if we are authenticated to Facebook
+ * @param facebook A RSFacebookClient
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return TRUE if we're authenticated both by the Facebook API and by the
end-user, FALSE otherwise
+ */
+gboolean
+rs_facebook_client_ping(RSFacebookClient *facebook, GError **error);
+
+/**
+ * Upload a photo to Facebook, will be placed in the registered applications
default photo folder
+ * @param facebook A RSFacebookClient
+ * @param filename Full path to an image to upload. JPEG, PNG, TIFF accepted
+ * @param caption The caption to use for the image
+ * @param error NULL or a pointer to a GError * initialized to NULL
+ * @return TRUE on success, FALSE otherwise
+ */
+gboolean
+rs_facebook_client_upload_image(RSFacebookClient *facebook, const gchar
*filename, const gchar *caption, GError **error);
+
+G_END_DECLS
+
+#endif /* RS_FACEBOOK_CLIENT_H */
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit