/soc/2012/tomkiewicz/gg: 41e5ff454167: Gadu-Gadu: ggp_purple_req...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Thu Jul 5 13:31:52 EDT 2012
Changeset: 41e5ff4541677bbd3613cfdcc6d4466fe73087ec
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-06-29 22:36 +0200
Branch: soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/41e5ff454167
Description:
Gadu-Gadu: ggp_purple_request_processing implementation; refactoring of account registration (first stage); cancellable token request
diffstat:
libpurple/protocols/gg/Makefile.am | 4 +-
libpurple/protocols/gg/account.c | 221 ++++++++++++++++++++++++++++++++++--
libpurple/protocols/gg/account.h | 5 +-
libpurple/protocols/gg/gg.c | 163 +--------------------------
libpurple/protocols/gg/purple.c | 50 ++++++++
libpurple/protocols/gg/purple.h | 38 ++++++
libpurple/protocols/gg/utils.c | 14 --
libpurple/protocols/gg/utils.h | 14 --
8 files changed, 310 insertions(+), 199 deletions(-)
diffs (truncated from 710 to 300 lines):
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -63,7 +63,9 @@
account.h \
account.c \
deprecated.h \
- deprecated.c
+ deprecated.c \
+ purple.h \
+ purple.c
AM_CFLAGS = $(st)
diff --git a/libpurple/protocols/gg/account.c b/libpurple/protocols/gg/account.c
--- a/libpurple/protocols/gg/account.c
+++ b/libpurple/protocols/gg/account.c
@@ -2,23 +2,35 @@
#include <libgadu.h>
#include <debug.h>
+#include <request.h>
#include "deprecated.h"
+#include "purple.h"
+#include "utils.h"
+
+/*******************************************************************************
+ * Token requesting.
+ ******************************************************************************/
typedef struct
{
ggp_account_token_cb callback;
+ PurpleConnection *gc;
void *user_data;
struct gg_http *h;
+ ggp_purple_request_processing_handle *req_processing;
guint inpa;
} ggp_account_token_reqdata;
static void ggp_account_token_handler(gpointer _reqdata, gint fd, PurpleInputCondition cond);
-static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token);
+/* user cancel isn't a failure */
+static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token, gboolean failure);
-/***********************/
+static void ggp_account_token_request_cancel(PurpleConnection *gc, void *_reqdata);
+
+/******************************************************************************/
void ggp_account_token_free(ggp_account_token *token)
{
@@ -27,12 +39,24 @@
g_free(token);
}
-static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token)
+static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token, gboolean failure)
{
- reqdata->callback(token, reqdata->user_data);
+ g_assert(!failure || !token); // failure => not token
+
+ if (reqdata->req_processing)
+ {
+ ggp_purple_request_processing_done(reqdata->req_processing);
+ reqdata->req_processing = NULL;
+ }
+ reqdata->callback(reqdata->gc, token, reqdata->user_data);
purple_input_remove(reqdata->inpa);
gg_token_free(reqdata->h);
g_free(reqdata);
+
+ if (failure)
+ purple_notify_error(purple_connection_get_account(reqdata->gc),
+ _("Token Error"),
+ _("Unable to fetch the token.\n"), NULL);
}
void ggp_account_token_request(PurpleConnection *gc, ggp_account_token_cb callback, void *user_data)
@@ -42,7 +66,7 @@
if (!ggp_deprecated_setup_proxy(gc))
{
- callback(NULL, user_data);
+ callback(gc, NULL, user_data);
return;
}
@@ -50,32 +74,44 @@
if (!h)
{
- callback(NULL, user_data);
+ callback(gc, NULL, user_data);
return;
}
reqdata = g_new(ggp_account_token_reqdata, 1);
reqdata->callback = callback;
+ reqdata->gc = gc;
reqdata->user_data = user_data;
reqdata->h = h;
-
+ reqdata->req_processing = ggp_purple_request_processing(gc, NULL, reqdata, ggp_account_token_request_cancel);
reqdata->inpa = purple_input_add(h->fd, PURPLE_INPUT_READ, ggp_account_token_handler, reqdata);
}
+static void ggp_account_token_request_cancel(PurpleConnection *gc, void *_reqdata)
+{
+ ggp_account_token_reqdata *reqdata = _reqdata;
+
+ purple_debug_info("gg", "ggp_account_token_request_cancel\n");
+ reqdata->req_processing = NULL;
+ gg_http_stop(reqdata->h);
+ ggp_account_token_cb_call(reqdata, NULL, FALSE);
+}
+
static void ggp_account_token_handler(gpointer _reqdata, gint fd, PurpleInputCondition cond)
{
ggp_account_token_reqdata *reqdata = _reqdata;
struct gg_token *token_info;
ggp_account_token *token;
- purple_debug_info("gg", "ggp_account_token_handler: got fd update [check=%d, state=%d]\n",
+ //TODO: verbose mode
+ purple_debug_misc("gg", "ggp_account_token_handler: got fd update [check=%d, state=%d]\n",
reqdata->h->check, reqdata->h->state);
- if (reqdata->h->state == GG_STATE_ERROR || gg_token_watch_fd(reqdata->h) == -1)
+ if (gg_token_watch_fd(reqdata->h) == -1 || reqdata->h->state == GG_STATE_ERROR)
{
purple_debug_error("gg", "ggp_account_token_handler: failed to request token: %d\n",
reqdata->h->error);
- ggp_account_token_cb_call(reqdata, NULL);
+ ggp_account_token_cb_call(reqdata, NULL, TRUE);
return;
}
@@ -92,10 +128,11 @@
{
purple_debug_error("gg", "ggp_account_token_handler: failed to fetch token: %d\n",
reqdata->h->error); // TODO: will anything be here in that case?
- ggp_account_token_cb_call(reqdata, NULL);
+ ggp_account_token_cb_call(reqdata, NULL, TRUE);
return;
}
+ purple_debug_info("gg", "ggp_account_token_handler: got token\n");
token = g_new(ggp_account_token, 1);
@@ -104,5 +141,165 @@
token->size = reqdata->h->body_size;
token->data = g_memdup(reqdata->h->body, token->size);
- ggp_account_token_cb_call(reqdata, token);
+ ggp_account_token_cb_call(reqdata, token, FALSE);
}
+
+/*******************************************************************************
+ * New account registration.
+ ******************************************************************************/
+
+typedef struct
+{
+ ggp_account_token *token;
+ PurpleConnection *gc;
+} ggp_account_register_data;
+
+static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data);
+static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success);
+
+/******************************************************************************/
+
+static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success)
+{
+ PurpleAccount *account = purple_connection_get_account(register_data->gc);
+
+ ggp_account_token_free(register_data->token);
+ g_free(register_data);
+
+ purple_account_disconnect(account);
+ purple_account_register_completed(account, TRUE);
+}
+
+void ggp_account_register(PurpleAccount *account)
+{
+ PurpleConnection *gc = purple_account_get_connection(account);
+
+ purple_debug_info("gg", "ggp_account_register\n");
+
+ ggp_account_token_request(gc, ggp_account_register_dialog, NULL);
+}
+
+static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data)
+{
+ PurpleAccount *account = purple_connection_get_account(gc);
+ PurpleRequestFields *fields;
+ PurpleRequestFieldGroup *group;
+ PurpleRequestField *field;
+ ggp_account_register_data *register_data;
+
+ purple_debug_info("gg", "ggp_account_register_dialog(%x, %x, %x)\n",
+ (unsigned int)gc, (unsigned int)token, (unsigned int)user_data);
+ if (!token)
+ {
+ purple_account_disconnect(account);
+ purple_account_register_completed(account, FALSE);
+ return;
+ }
+
+ // TODO: required fields
+ fields = purple_request_fields_new();
+ group = purple_request_field_group_new(NULL);
+ purple_request_fields_add_group(fields, group);
+
+ field = purple_request_field_string_new("email", _("Email"), "", FALSE);
+ purple_request_field_group_add_field(group, field);
+
+ field = purple_request_field_string_new("password1", _("Password"), "",
+ FALSE);
+ purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_group_add_field(group, field);
+
+ field = purple_request_field_string_new("password2", _("Password (again)"), "",
+ FALSE);
+ purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_group_add_field(group, field);
+
+ //TODO: move it into a new group?
+ field = purple_request_field_string_new("token_value",
+ _("Enter captcha text"), "", FALSE);
+ purple_request_field_group_add_field(group, field);
+
+ field = purple_request_field_image_new("token_image", _("Captcha"),
+ token->data, token->size);
+ purple_request_field_group_add_field(group, field);
+
+ register_data = g_new(ggp_account_register_data, 1);
+ register_data->gc = gc;
+ register_data->token = token;
+
+ purple_request_fields(gc,
+ _("Register New Gadu-Gadu Account"),
+ _("Register New Gadu-Gadu Account"),
+ _("Please, fill in the following fields"), fields,
+ _("OK"), G_CALLBACK(ggp_account_register_dialog_ok),
+ _("Cancel"), G_CALLBACK(ggp_account_register_dialog_cancel),
+ account, NULL, NULL, register_data);
+}
+
+static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+{
+ purple_debug_info("gg", "ggp_account_register_dialog_cancel(%x, %x)\n",
+ (unsigned int)register_data, (unsigned int)fields);
+
+ ggp_account_register_completed(register_data, FALSE);
+}
+
+static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+{
+ PurpleAccount *account = purple_connection_get_account(register_data->gc);
+ const gchar *email, *password1, *password2, *token_value;
+ struct gg_http *h;
+ struct gg_pubdir *register_result;
+ uin_t uin;
+
+ purple_debug_info("gg", "ggp_account_register_dialog_ok(%x, %x)\n",
+ (unsigned int)register_data, (unsigned int)fields);
+
+ email = purple_request_fields_get_string(fields, "email");
+ password1 = purple_request_fields_get_string(fields, "password1");
+ password2 = purple_request_fields_get_string(fields, "password2");
+ token_value = purple_request_fields_get_string(fields, "token_value");
+
+ g_assert(email != NULL);
+ g_assert(password1 != NULL);
+ g_assert(password2 != NULL);
+ g_assert(token_value != NULL);
+
+ if (g_utf8_collate(password1, password2) != 0)
+ {
+ purple_debug_warning("gg", "ggp_account_register_dialog_ok: validation failed - passwords does not match\n");
+ purple_notify_error(purple_connection_get_account(register_data->gc),
+ _("TODO: title"),
+ _("Passwords do not match"), NULL);
+ ggp_account_register_completed(register_data, FALSE);
+ return;
+ }
+
+ purple_debug_info("gg", "ggp_account_register_dialog_ok: validation ok [token id=%s, value=%s]\n",
+ register_data->token->id, token_value);
+ h = gg_register3(email, password1, register_data->token->id, token_value, 0); // TODO: async (use code from ggp_account_token_handler)
+ if (h == NULL || !(register_result = h->data) || !register_result->success)
+ {
More information about the Commits
mailing list