diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index c80c058d..12331bfb 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -242,6 +242,7 @@ static Autocomplete logging_group_ac; static Autocomplete logging_group_color_ac; static Autocomplete color_ac; static Autocomplete correction_ac; +static Autocomplete avatar_ac; void cmd_ac_init(void) @@ -965,6 +966,11 @@ cmd_ac_init(void) autocomplete_add(correction_ac, "on"); autocomplete_add(correction_ac, "off"); autocomplete_add(correction_ac, "char"); + + avatar_ac = autocomplete_new(); + autocomplete_add(avatar_ac, "get"); + autocomplete_add(avatar_ac, "cmd"); + autocomplete_add(avatar_ac, "open"); } void @@ -1276,6 +1282,7 @@ cmd_ac_reset(ProfWin *window) autocomplete_reset(logging_group_color_ac); autocomplete_reset(color_ac); autocomplete_reset(correction_ac); + autocomplete_reset(avatar_ac); autocomplete_reset(script_ac); if (script_show_ac) { @@ -1429,6 +1436,7 @@ cmd_ac_uninit(void) autocomplete_free(logging_group_color_ac); autocomplete_free(color_ac); autocomplete_free(correction_ac); + autocomplete_free(avatar_ac); } static void @@ -3773,9 +3781,19 @@ _avatar_autocomplete(ProfWin *window, const char *const input, gboolean previous { char *result = NULL; + result = autocomplete_param_with_ac(input, "/avatar", avatar_ac, TRUE, previous); + if (result) { + return result; + } + jabber_conn_status_t conn_status = connection_get_status(); if (conn_status == JABBER_CONNECTED) { - result = autocomplete_param_with_func(input, "/avatar", roster_barejid_autocomplete, previous, NULL); + result = autocomplete_param_with_func(input, "/avatar get", roster_barejid_autocomplete, previous, NULL); + if (result) { + return result; + } + + result = autocomplete_param_with_func(input, "/avatar open", roster_barejid_autocomplete, previous, NULL); if (result) { return result; } diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 9c9340de..33a38703 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2343,20 +2343,27 @@ static struct cmd_t command_defs[] = }, { "/avatar", - parse_args, 1, 1, NULL, + parse_args, 2, 2, &cons_avatar_setting, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_avatar) CMD_TAGS( CMD_TAG_CHAT) CMD_SYN( - "/avatar ") + "/avatar get ", + "/avatar open ", + "/avatar cmd ") CMD_DESC( "Download avatar (XEP-0084) for a certain contact. " "If nothing happens after using this command the user either doesn't have an avatar set at all " "or doesn't use XEP-0084 to publish it.") CMD_ARGS( - { "", "JID to download avatar from."}) - CMD_NOEXAMPLES + { "get ", "Download the avatar. barejid is the JID to download avatar from."}, + { "cmd ", "Set a command to execute with 'avatar open'. Use your favourite image viewer here."}, + { "open ", "Download avatar and open it with command."}) + CMD_EXAMPLES( + "/avatar get someone@contacts.org", + "/avatar cmd xdg-open", + "/avatar open someone@contacts.org") }, { "/os", diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 5395a53e..1776c72e 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -8733,7 +8733,19 @@ cmd_color(ProfWin *window, const char *const command, gchar **args) gboolean cmd_avatar(ProfWin *window, const char *const command, gchar **args) { - avatar_get_by_nick(args[0]); + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (g_strcmp0(args[0], "get") == 0) { + avatar_get_by_nick(args[1], false); + } else if (g_strcmp0(args[0], "open") == 0) { + avatar_get_by_nick(args[1], true); + } else if (g_strcmp0(args[0], "cmd") == 0) { + prefs_set_string(PREF_AVATAR_CMD, args[1]); + cons_show("Avatar cmd set to: %s", args[1]); + } return TRUE; } diff --git a/src/config/preferences.c b/src/config/preferences.c index 589a6c92..6b9b5f23 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -1770,6 +1770,7 @@ _get_group(preference_t pref) case PREF_GRLOG: case PREF_LOG_ROTATE: case PREF_LOG_SHARED: + case PREF_AVATAR_CMD: return PREF_GROUP_LOGGING; case PREF_AUTOAWAY_CHECK: case PREF_AUTOAWAY_MODE: @@ -2048,6 +2049,8 @@ _get_key(preference_t pref) return "correction.allow"; case PREF_HISTORY_COLOR_MUC: return "history.muc.color"; + case PREF_AVATAR_CMD: + return "avatar.cmd"; default: return NULL; } @@ -2179,6 +2182,8 @@ _get_default_string(preference_t pref) return "false"; case PREF_HISTORY_COLOR_MUC: return "unanimous"; + case PREF_AVATAR_CMD: + return "xdg-open"; default: return NULL; } diff --git a/src/config/preferences.h b/src/config/preferences.h index a9993e5b..37040214 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -166,6 +166,7 @@ typedef enum { PREF_OCCUPANTS_WRAP, PREF_CORRECTION_ALLOW, PREF_HISTORY_COLOR_MUC, + PREF_AVATAR_CMD, } preference_t; typedef struct prof_alias_t { diff --git a/src/ui/console.c b/src/ui/console.c index f04f3d6f..2b9b8aad 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -2039,6 +2039,16 @@ cons_correction_setting(void) free(cc); } +void +cons_avatar_setting(void) +{ + char *pref = prefs_get_string(PREF_AVATAR_CMD); + + cons_show("Avatar command (/avatar cmd) : %s", pref); + + prefs_free_string(pref); +} + void cons_show_connection_prefs(void) { diff --git a/src/ui/ui.h b/src/ui/ui.h index f0cd296b..b3e512aa 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -319,6 +319,7 @@ void cons_winpos_setting(void); void cons_color_setting(void); void cons_os_setting(void); void cons_correction_setting(void); +void cons_avatar_setting(void); void cons_show_contact_online(PContact contact, Resource *resource, GDateTime *last_activity); void cons_show_contact_offline(PContact contact, char *resource, char *status); void cons_theme_properties(void); diff --git a/src/xmpp/avatar.c b/src/xmpp/avatar.c index 1a3a08b9..9d043cb3 100644 --- a/src/xmpp/avatar.c +++ b/src/xmpp/avatar.c @@ -48,13 +48,15 @@ #include "xmpp/stanza.h" #include "ui/ui.h" #include "config/files.h" +#include "config/preferences.h" typedef struct avatar_metadata { char *type; char *id; } avatar_metadata; -GHashTable *looking_for = NULL; // contains nicks/barejids from who we want to get the avatar +static GHashTable *looking_for = NULL; // contains nicks/barejids from who we want to get the avatar +static GHashTable *shall_open = NULL; // contains a list of nicks that shall not just downloaded but also opened static void _avatar_request_item_by_id(const char *jid, avatar_metadata *data); static int _avatar_metadata_handler(xmpp_stanza_t *const stanza, void *const userdata); @@ -81,10 +83,15 @@ avatar_pep_subscribe(void) g_hash_table_destroy(looking_for); } looking_for = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + if (shall_open) { + g_hash_table_destroy(shall_open); + } + shall_open = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); } gboolean -avatar_get_by_nick(const char* nick) +avatar_get_by_nick(const char* nick, gboolean open) { // in case we set the feature, remove it caps_remove_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY); @@ -95,6 +102,10 @@ avatar_get_by_nick(const char* nick) // add the feature. this will trigger the _avatar_metadata_notfication_handler handler caps_add_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY); + if (open) { + g_hash_table_insert(shall_open, strdup(nick), NULL); + } + return TRUE; } @@ -253,6 +264,20 @@ _avatar_request_item_result_handler(xmpp_stanza_t *const stanza, void *const use cons_show("Avatar saved as %s", filename->str); } + // if we shall open it + if (g_hash_table_contains(shall_open, from_attr)) { + GString *cmd = g_string_new(""); + + g_string_append_printf(cmd, "%s %s > /dev/null 2>&1", prefs_get_string(PREF_AVATAR_CMD), filename->str); + cons_show("Calling: %s", cmd->str); + FILE *stream = popen(cmd->str, "r"); + + pclose(stream); + g_string_free(cmd, TRUE); + + g_hash_table_remove(shall_open, from_attr); + } + g_string_free(filename, TRUE); free(de); diff --git a/src/xmpp/avatar.h b/src/xmpp/avatar.h index 707600b3..49c03750 100644 --- a/src/xmpp/avatar.h +++ b/src/xmpp/avatar.h @@ -39,6 +39,6 @@ #include void avatar_pep_subscribe(void); -gboolean avatar_get_by_nick(const char* nick); +gboolean avatar_get_by_nick(const char* nick, gboolean open); #endif