diff options
| author | dequis <dx@dxzone.com.ar> | 2016-12-26 20:52:24 -0300 | 
|---|---|---|
| committer | dequis <dx@dxzone.com.ar> | 2016-12-26 20:52:24 -0300 | 
| commit | 1882b70857d9b8f9d68caa668e79614f376fb850 (patch) | |
| tree | 5f1167efe62adf279f99ecd3bab26f28e1ad870b /protocols | |
| parent | a04705bfde7c623605ee0e8449efd61ecc5c0b62 (diff) | |
purple: add support for extra groupchat settings (helps with SIPE)
This adds channel settings prefixed by purple_. For example jabber now
has purple_room and purple_server which are decomposed variants of our
own 'room' setting. Okay, that doesn't sound very useful.
It also adds some sync from the values returned by chat_info_defaults()
- so if the plugin figures something out in there, we save it in our
own settings.
In the case of SIPE this adds a new setting, purple_uri, which can be
set with the ma-chan:// uri for a persistent chat.
This solves the issue with the SIPE plugin only knowing how to do name
lookups after doing 'chat list' - now it just needs to work once, and we
save the real URI in our settings.
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/purple/purple.c | 93 | 
1 files changed, 93 insertions, 0 deletions
| diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c index 4c560818..7c65aa97 100644 --- a/protocols/purple/purple.c +++ b/protocols/purple/purple.c @@ -762,6 +762,7 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c  	PurpleConversation *conv;  	struct groupchat *gc;  	GList *info, *l; +	GString *missing_settings = NULL;  	if (!pi->chat_info || !pi->chat_info_defaults ||  	    !(info = pi->chat_info(purple_account_get_connection(pd->account)))) { @@ -787,6 +788,30 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c  			g_hash_table_replace(chat_hash, "password", g_strdup(password));  		} else if (strcmp(pce->identifier, "passwd") == 0) {  			g_hash_table_replace(chat_hash, "passwd", g_strdup(password)); +		} else { +			char *key, *value; + +			key = g_strdup_printf("purple_%s", pce->identifier); +			str_reject_chars(key, " -", '_'); + +			if ((value = set_getstr(sets, key))) { +				/* sync from bitlbee to the prpl */ +				g_hash_table_replace(chat_hash, (char *) pce->identifier, g_strdup(value)); +			} else if ((value = g_hash_table_lookup(chat_hash, pce->identifier))) { +				/* if the bitlbee one was empty, sync from prpl to bitlbee */ +				set_setstr(sets, key, value); +			} + +			g_free(key); +		} + +		if (pce->required && !g_hash_table_lookup(chat_hash, pce->identifier)) { +			if (!missing_settings) { +				missing_settings = g_string_new(NULL); +				g_string_printf(missing_settings, +					"Can't join %s. The following settings are required: ", room); +			} +			g_string_append_printf(missing_settings, "%s, ", pce->identifier);  		}  		g_free(pce); @@ -794,6 +819,17 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c  	g_list_free(info); +	if (missing_settings) { +		/* remove the ", " from the end */ +		g_string_truncate(missing_settings, missing_settings->len - 2); + +		imcb_error(ic, missing_settings->str); + +		g_string_free(missing_settings, TRUE); +		g_hash_table_destroy(chat_hash); +		return NULL; +	} +  	/* do this before serv_join_chat to handle cases where prplcb_conv_new is called immediately (not async) */  	gc = imcb_chat_new(ic, room); @@ -829,6 +865,61 @@ void purple_chat_list(struct im_connection *ic, const char *server)  	}  } +/* handles either prpl->chat_(add|free)_settings depending on the value of 'add' */ +static void purple_chat_update_settings(account_t *acc, set_t **head, gboolean add) +{ +	PurplePlugin *prpl = purple_plugins_find_with_id((char *) acc->prpl->data); +	PurplePluginProtocolInfo *pi = prpl->info->extra_info; +	GList *info, *l; + +	if (!pi->chat_info || !pi->chat_info_defaults) { +		return; +	} + +	/* hack / leap of faith: pass a NULL here because we don't have a connection yet. +	 * i reviewed all the built-in prpls and a bunch of third-party ones and none +	 * of them seem to need this parameter at all, so... i hope it never crashes */ +	info = pi->chat_info(NULL); + +	for (l = info; l; l = l->next) { +		struct proto_chat_entry *pce = l->data; +		char *key; + +		if (strcmp(pce->identifier, "handle") == 0 || +		    strcmp(pce->identifier, "password") == 0 || +		    strcmp(pce->identifier, "passwd") == 0) { +			/* skip these, they are handled above */ +			g_free(pce); +			continue; +		} + +		key = g_strdup_printf("purple_%s", pce->identifier); +		str_reject_chars(key, " -", '_'); + +		if (add) { +			set_add(head, key, NULL, NULL, NULL); +		} else { +			set_del(head, key); +		} + +		g_free(key); +		g_free(pce); +	} + +	g_list_free(NULL); +	g_list_free(info); +} + +static void purple_chat_add_settings(account_t *acc, set_t **head) +{ +	purple_chat_update_settings(acc, head, TRUE); +} + +static void purple_chat_free_settings(account_t *acc, set_t **head) +{ +	purple_chat_update_settings(acc, head, FALSE); +} +  void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle);  static void purple_ui_init(); @@ -1766,6 +1857,8 @@ void purple_initmodule()  	funcs.chat_leave = purple_chat_leave;  	funcs.chat_join = purple_chat_join;  	funcs.chat_list = purple_chat_list; +	funcs.chat_add_settings = purple_chat_add_settings; +	funcs.chat_free_settings = purple_chat_free_settings;  	funcs.transfer_request = purple_transfer_request;  	help = g_string_new("BitlBee libpurple module supports the following IM protocols:\n"); | 
