Author: akv
Date: 2009-12-24 18:01:25 +0100 (Thu, 24 Dec 2009)
New Revision: 2840

Added:
   trunk/plugins/output-facebook/
   trunk/plugins/output-facebook/facebook.c
   trunk/plugins/output-facebook/facebook.h
Log:
Initial commit for facebook plugin.

Added: trunk/plugins/output-facebook/facebook.c
===================================================================
--- trunk/plugins/output-facebook/facebook.c                            (rev 0)
+++ trunk/plugins/output-facebook/facebook.c    2009-12-24 17:01:25 UTC (rev 
2840)
@@ -0,0 +1,301 @@
+/*
+ * 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"));
+
+       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;
+       header = curl_slist_append(header, "Content-Type: multipart/form-data; 
boundary=boundary");
+       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("--boundary\r\n");
+                                       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--boundary\r\n");
+                               }
+                       }
+                       g_string_append_printf(str, 
"--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", 
"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));
+
+       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->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;
+}
+
+gboolean
+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 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 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 FALSE;
+
+       return TRUE;
+}
+
+void
+facebook_close()
+{
+       curl_easy_cleanup(fb->curl);
+}
+
+/* END PUBLIC FUNCTIONS */

Added: trunk/plugins/output-facebook/facebook.h
===================================================================
--- trunk/plugins/output-facebook/facebook.h                            (rev 0)
+++ trunk/plugins/output-facebook/facebook.h    2009-12-24 17:01:25 UTC (rev 
2840)
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+       /* 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);
+gboolean facebook_get_session();
+void facebook_close();
+
+#endif /* FACEBOOK_H */


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to