--- a/spasm-account.c Tue May 16 22:54:51 2017 -0500
+++ b/spasm-account.c Thu May 18 19:38:28 2017 -0500
@@ -18,19 +18,22 @@
#include "spasm-account.h"
+#include "spasm-const.h" +/****************************************************************************** + *****************************************************************************/ struct _PurpleSpasmAccount {
PurpleConnection *connection;
GCancellable *cancellable;
- GSocketClient *socket_client;
- GSocketConnection *socket_connection;
- GOutputStream *output_stream;
- GDataInputStream *input_stream;
@@ -46,12 +49,14 @@
gboolean twitter_connected;
+ PurpleSpasmChatService *chat; /******************************************************************************
*****************************************************************************/
+static PurpleSpasmAccount * purple_spasm_account_new(PurpleAccount *account, PurpleConnection *connection) {
PurpleSpasmAccount *sa = NULL;
@@ -68,100 +73,19 @@
purple_spasm_account_free(PurpleSpasmAccount *sa) {
g_free(sa->access_token);
- g_object_unref(G_OBJECT(sa->socket_connection));
- g_object_unref(G_OBJECT(sa->output_stream));
- g_object_unref(G_OBJECT(sa->input_stream));
- g_object_unref(G_OBJECT(sa->session));
+ purple_spasm_chat_service_free(sa->chat);
-purple_spasm_account_get_account(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
-purple_spasm_account_get_connection(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
-purple_spasm_account_set_socket_connection(
- PurpleSpasmAccount *sa,
- GSocketConnection *socket_connection)
- if(sa->socket_connection)
- g_object_unref(G_OBJECT(sa->socket_connection));
- sa->socket_connection = socket_connection;
-purple_spasm_account_set_output_stream(
- PurpleSpasmAccount *sa,
- GOutputStream *output_stream)
- g_object_unref(G_OBJECT(sa->output_stream));
- sa->output_stream = output_stream;
-purple_spasm_account_set_input_stream(
- PurpleSpasmAccount *sa,
- GDataInputStream *input_stream)
- g_object_unref(G_OBJECT(sa->input_stream));
- sa->input_stream = input_stream;
-purple_spasm_account_get_input_stream(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
- return g_object_ref(sa->input_stream);
-purple_spasm_account_get_cancellable(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
- return sa->cancellable;
-purple_spasm_account_get_session(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
- return g_object_ref(G_OBJECT(sa->session));
-purple_spasm_account_set_access_token(PurpleSpasmAccount *sa,
+_purple_spasm_account_set_access_token(PurpleSpasmAccount *sa, const gchar *access_token)
@@ -169,15 +93,8 @@
sa->access_token = g_strdup(access_token);
-purple_spasm_account_get_access_token(const PurpleSpasmAccount *sa) {
- g_return_val_if_fail(sa, NULL);
- return sa->access_token;
-purple_spasm_account_update_profile(PurpleSpasmAccount *sa, JsonParser *parser) {
+_purple_spasm_account_update_profile(PurpleSpasmAccount *sa, JsonParser *parser) { const gchar *str_attr = NULL;
@@ -221,6 +138,174 @@
+/****************************************************************************** + *****************************************************************************/ +static void _purple_spasm_oauth_login(PurpleSpasmAccount *sa); +_purple_spasm_login_test_cb(PurpleSpasmAccount *sa, JsonParser *parser, + GError *error, gpointer data) + PurpleAccount *account = NULL; + PurpleConnection *connection = NULL; + purple_debug_info("spasm", "oauth token invalid, re-authenticating : %s\n", error->message); + _purple_spasm_oauth_login(sa); + account = purple_spasm_account_get_account(sa); + connection = purple_account_get_connection(account); + error = _purple_spasm_account_update_profile(sa, parser); + err_msg = g_strdup_printf( + "failed to update profile : %s", + purple_connection_error(connection, err_msg); + sa->chat = purple_spasm_chat_service_new(sa); + purple_spasm_chat_service_connect(sa->chat); +_purple_spasm_access_token_input_cb(gpointer data, const gchar *access_token) { + PurpleAccount *account = NULL; + PurpleConnection *connection = NULL; + PurpleSpasmAccount *sa = PURPLE_SPASM_ACCOUNT(data); + account = purple_spasm_account_get_account(sa); + purple_account_set_remember_password(account, TRUE); + _purple_spasm_account_set_access_token(sa, access_token); + purple_account_set_password(account, access_token); + connection = purple_spasm_account_get_connection(sa); + purple_connection_update_progress(connection, "Verifying", 2, 3); + purple_spasm_get_user(sa, _purple_spasm_login_test_cb, NULL); +_purple_spasm_access_token_cancel_cb(gpointer data) { + PurpleSpasmAccount *sa = PURPLE_SPASM_ACCOUNT(data); + purple_connection_error( + purple_spasm_account_get_connection(sa), + "User cancelled authorization" + purple_spasm_account_free(sa); +_purple_spasm_oauth_login(PurpleSpasmAccount *sa) { + PurpleAccount *account = NULL; + PurpleConnection *connection = NULL; + gchar *state = NULL, *uri = NULL; + const gchar *username = NULL; + account = purple_spasm_account_get_account(sa); + connection = purple_account_get_connection(account); + purple_connection_update_progress( + username = purple_account_get_username(account); + state = g_strdup_printf("%s,%s", PURPLE_SPASM_PLUGIN_ID, username); + PURPLE_SPASM_OAUTH2_URI, + PURPLE_SPASM_OAUTH2_CLIENT_ID, + PURPLE_SPASM_OAUTH2_REDIRECT_URI, + PURPLE_SPASM_OAUTH2_SCOPES, + /* send off the oauth implicit request */ + purple_notify_uri(connection, uri); + "Enter the access token from https://pidgin.im/oauth.html which should have opened in your web browser", + "OK", G_CALLBACK(_purple_spasm_access_token_input_cb), + "Cancel", G_CALLBACK(_purple_spasm_access_token_cancel_cb), +/****************************************************************************** + *****************************************************************************/ +purple_spasm_account_get_account(const PurpleSpasmAccount *sa) { + g_return_val_if_fail(sa, NULL); +purple_spasm_account_get_connection(const PurpleSpasmAccount *sa) { + g_return_val_if_fail(sa, NULL); +purple_spasm_account_get_cancellable(const PurpleSpasmAccount *sa) { + g_return_val_if_fail(sa, NULL); + return sa->cancellable; +purple_spasm_account_get_session(const PurpleSpasmAccount *sa) { + g_return_val_if_fail(sa, NULL); + return g_object_ref(G_OBJECT(sa->session)); +purple_spasm_account_get_access_token(const PurpleSpasmAccount *sa) { + g_return_val_if_fail(sa, NULL); + return sa->access_token; purple_spasm_account_get_display_name(const PurpleSpasmAccount *sa) {
g_return_val_if_fail(sa, NULL);
@@ -290,3 +375,27 @@
return sa->twitter_connected;
+purple_spasm_account_login(PurpleAccount *account) { + PurpleConnection *pc = NULL; + PurpleSpasmAccount *sa = NULL; + const gchar *password = NULL; + pc = purple_account_get_connection(account); + sa = purple_spasm_account_new(account, pc); + purple_connection_set_protocol_data(pc, sa); + purple_connection_set_state(pc, PURPLE_CONNECTING); + /* try to load the password */ + password = purple_account_get_password(account); + _purple_spasm_account_set_access_token(sa, password); + purple_spasm_get_user(sa, _purple_spasm_login_test_cb, NULL); + _purple_spasm_oauth_login(sa); --- a/spasm-account.h Tue May 16 22:54:51 2017 -0500
+++ b/spasm-account.h Thu May 18 19:38:28 2017 -0500
@@ -33,29 +33,24 @@
typedef struct _PurpleSpasmAccount PurpleSpasmAccount;
-PurpleSpasmAccount *purple_spasm_account_new(PurpleAccount *account, PurpleConnection *connection);
-void purple_spasm_account_free(PurpleSpasmAccount *sa);
+// PurpleSpasmAccount *purple_spasm_account_new(PurpleAccount *account, PurpleConnection *connection); +// void purple_spasm_account_free(PurpleSpasmAccount *sa); PurpleAccount *purple_spasm_account_get_account(const PurpleSpasmAccount *sa);
PurpleConnection *purple_spasm_account_get_connection(const PurpleSpasmAccount *sa);
-void purple_spasm_account_set_socket_connection(PurpleSpasmAccount *sa, GSocketConnection *socket_connection);
-void purple_spasm_account_set_output_stream(PurpleSpasmAccount *sa, GOutputStream *output_stream);
-void purple_spasm_account_set_input_stream(PurpleSpasmAccount *sa, GDataInputStream *input_stream);
-GDataInputStream *purple_spasm_account_get_input_stream(const PurpleSpasmAccount *sa);
+void purple_spasm_account_login(PurpleAccount *account); GCancellable *purple_spasm_account_get_cancellable(const PurpleSpasmAccount *sa);
SoupSession *purple_spasm_account_get_session(const PurpleSpasmAccount *sa);
-void purple_spasm_account_set_access_token(PurpleSpasmAccount *sa, const gchar *access_token);
const gchar * purple_spasm_account_get_access_token(const PurpleSpasmAccount *sa);
-GError *purple_spasm_account_update_profile(PurpleSpasmAccount *sa, JsonParser *parser);
const gchar *purple_spasm_account_get_display_name(const PurpleSpasmAccount *sa);
const gchar *purple_spasm_account_get_id(const PurpleSpasmAccount *sa);
const gchar *purple_spasm_account_get_name(const PurpleSpasmAccount *sa);
--- a/spasm-chat.c Tue May 16 22:54:51 2017 -0500
+++ b/spasm-chat.c Thu May 18 19:38:28 2017 -0500
@@ -23,16 +23,28 @@
/******************************************************************************
+ *****************************************************************************/ +struct _PurpleSpasmChatService { + PurpleSpasmAccount *sa; + GSocketClient *socket_client; + GSocketConnection *socket_connection; + GOutputStream *output_stream; + GDataInputStream *input_stream; +/****************************************************************************** *****************************************************************************/
-static void _purple_spasm_chat_read(PurpleSpasmAccount *sa);
+static void _purple_spasm_chat_read(PurpleSpasmChatService *chat); _purple_spasm_chat_read_cb(GObject *obj, GAsyncResult *res, gpointer data) {
- PurpleSpasmAccount *sa = (PurpleSpasmAccount *)data;
+ PurpleSpasmChatService *chat = (PurpleSpasmChatService *)data; buffer = g_data_input_stream_read_line_finish(
G_DATA_INPUT_STREAM(obj),
@@ -58,7 +70,7 @@
- purple_spasm_account_get_connection(sa),
+ purple_spasm_account_get_connection(chat->sa), @@ -71,17 +83,17 @@
- _purple_spasm_chat_read(sa);
+ _purple_spasm_chat_read(chat); -_purple_spasm_chat_read(PurpleSpasmAccount *sa) {
+_purple_spasm_chat_read(PurpleSpasmChatService *chat) { g_data_input_stream_read_line_async(
- purple_spasm_account_get_input_stream(sa),
- purple_spasm_account_get_cancellable(sa),
+ purple_spasm_account_get_cancellable(chat->sa), _purple_spasm_chat_read_cb,
@@ -92,22 +104,20 @@
_purple_spasm_chat_login_cb(GObject *obj, GAsyncResult *res, gpointer data) {
GCancellable *cancellable = NULL;
- GOutputStream *output = NULL;
- GSocketConnection *socket_connection = NULL;
PurpleConnection *purple_connection = NULL;
- PurpleSpasmAccount *sa = (PurpleSpasmAccount *)data;
+ PurpleSpasmChatService *chat = (PurpleSpasmChatService *)data; gboolean success = FALSE;
- cancellable = purple_spasm_account_get_cancellable(sa);
- purple_connection = purple_spasm_account_get_connection(sa);
+ cancellable = purple_spasm_account_get_cancellable(chat->sa); + purple_connection = purple_spasm_account_get_connection(chat->sa); - socket_connection = g_socket_client_connect_to_host_finish(
+ chat->socket_connection = g_socket_client_connect_to_host_finish( - if(socket_connection == NULL) {
+ if(chat->socket_connection == NULL) { g_prefix_error(&error, "failed to connect: ");
@@ -121,18 +131,16 @@
- purple_spasm_account_set_socket_connection(sa, socket_connection);
- output = g_io_stream_get_output_stream(G_IO_STREAM(socket_connection));
+ chat->output_stream = g_io_stream_get_output_stream(G_IO_STREAM(chat->socket_connection)); success = g_output_stream_printf(
- purple_spasm_account_get_access_token(sa)
+ purple_spasm_account_get_access_token(chat->sa) @@ -147,16 +155,16 @@
- g_output_stream_flush(output, NULL, NULL);
+ g_output_stream_flush(chat->output_stream, NULL, NULL); /* now try to use our nick */
success = g_output_stream_printf(
- purple_spasm_account_get_name(sa)
+ purple_spasm_account_get_name(chat->sa) @@ -172,31 +180,49 @@
- g_output_stream_flush(output, NULL, NULL);
+ g_output_stream_flush(chat->output_stream, NULL, NULL); - purple_spasm_account_set_input_stream(
- g_data_input_stream_new(
- g_io_stream_get_input_stream(G_IO_STREAM(socket_connection))
+ chat->input_stream = g_data_input_stream_new( + g_io_stream_get_input_stream(G_IO_STREAM(chat->socket_connection)) - _purple_spasm_chat_read(sa);
+ _purple_spasm_chat_read(chat); +PurpleSpasmChatService * +purple_spasm_chat_service_new(PurpleSpasmAccount *sa) { + PurpleSpasmChatService *chat = NULL; + g_return_val_if_fail(sa, NULL); + chat = g_slice_new0(PurpleSpasmChatService); -purple_spasm_chat_login(PurpleSpasmAccount *sa) {
- GSocketClient *socket_client = NULL;
+purple_spasm_chat_service_free(PurpleSpasmChatService *chat) { + g_object_unref(chat->input_stream); + g_object_unref(chat->output_stream); + g_object_unref(chat->socket_client); + g_object_unref(chat->socket_connection); - socket_client = g_socket_client_new();
+ g_slice_free(PurpleSpasmChatService, chat); +purple_spasm_chat_service_connect(PurpleSpasmChatService *chat) { + g_return_if_fail(chat); + chat->socket_client = g_socket_client_new(); g_socket_client_connect_to_host_async(
PURPLE_SPASM_CHAT_HOSTNAME,
- purple_spasm_account_get_cancellable(sa),
+ purple_spasm_account_get_cancellable(chat->sa), _purple_spasm_chat_login_cb,
--- a/spasm-chat.h Tue May 16 22:54:51 2017 -0500
+++ b/spasm-chat.h Thu May 18 19:38:28 2017 -0500
@@ -22,11 +22,16 @@
+typedef struct _PurpleSpasmChatService PurpleSpasmChatService; #include "spasm-account.h"
-void purple_spasm_chat_login(PurpleSpasmAccount *sa);
+PurpleSpasmChatService *purple_spasm_chat_service_new(PurpleSpasmAccount *sa); +void purple_spasm_chat_service_free(PurpleSpasmChatService *chat); +void purple_spasm_chat_service_connect(PurpleSpasmChatService *chat); --- a/spasm.c Tue May 16 22:54:51 2017 -0500
+++ b/spasm.c Thu May 18 19:38:28 2017 -0500
@@ -33,7 +33,6 @@
#include "spasm-account.h"
/******************************************************************************
@@ -79,7 +78,7 @@
.options = OPT_PROTO_NO_PASSWORD,
- .login = purple_spasm_login,
+ .login = purple_spasm_account_login, .close = _purple_spasm_close,
.list_icon = _purple_spasm_list_icon,