mirror of
https://github.com/profanity-im/profanity.git
synced 2025-02-02 15:08:15 -05:00
xep-0084/avatar: add option to open avatar directly
Change: `/avatar me@somewhere.org` -> `/avatar get me@somewhere.org` New: `/avatar cmd feh` `/avatar open me@somewhere.org` Implement https://github.com/profanity-im/profanity/issues/1281
This commit is contained in:
parent
7e62d458ee
commit
52e7e596aa
@ -242,6 +242,7 @@ static Autocomplete logging_group_ac;
|
|||||||
static Autocomplete logging_group_color_ac;
|
static Autocomplete logging_group_color_ac;
|
||||||
static Autocomplete color_ac;
|
static Autocomplete color_ac;
|
||||||
static Autocomplete correction_ac;
|
static Autocomplete correction_ac;
|
||||||
|
static Autocomplete avatar_ac;
|
||||||
|
|
||||||
void
|
void
|
||||||
cmd_ac_init(void)
|
cmd_ac_init(void)
|
||||||
@ -965,6 +966,11 @@ cmd_ac_init(void)
|
|||||||
autocomplete_add(correction_ac, "on");
|
autocomplete_add(correction_ac, "on");
|
||||||
autocomplete_add(correction_ac, "off");
|
autocomplete_add(correction_ac, "off");
|
||||||
autocomplete_add(correction_ac, "char");
|
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
|
void
|
||||||
@ -1276,6 +1282,7 @@ cmd_ac_reset(ProfWin *window)
|
|||||||
autocomplete_reset(logging_group_color_ac);
|
autocomplete_reset(logging_group_color_ac);
|
||||||
autocomplete_reset(color_ac);
|
autocomplete_reset(color_ac);
|
||||||
autocomplete_reset(correction_ac);
|
autocomplete_reset(correction_ac);
|
||||||
|
autocomplete_reset(avatar_ac);
|
||||||
|
|
||||||
autocomplete_reset(script_ac);
|
autocomplete_reset(script_ac);
|
||||||
if (script_show_ac) {
|
if (script_show_ac) {
|
||||||
@ -1429,6 +1436,7 @@ cmd_ac_uninit(void)
|
|||||||
autocomplete_free(logging_group_color_ac);
|
autocomplete_free(logging_group_color_ac);
|
||||||
autocomplete_free(color_ac);
|
autocomplete_free(color_ac);
|
||||||
autocomplete_free(correction_ac);
|
autocomplete_free(correction_ac);
|
||||||
|
autocomplete_free(avatar_ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3773,9 +3781,19 @@ _avatar_autocomplete(ProfWin *window, const char *const input, gboolean previous
|
|||||||
{
|
{
|
||||||
char *result = NULL;
|
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();
|
jabber_conn_status_t conn_status = connection_get_status();
|
||||||
if (conn_status == JABBER_CONNECTED) {
|
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) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2343,20 +2343,27 @@ static struct cmd_t command_defs[] =
|
|||||||
},
|
},
|
||||||
|
|
||||||
{ "/avatar",
|
{ "/avatar",
|
||||||
parse_args, 1, 1, NULL,
|
parse_args, 2, 2, &cons_avatar_setting,
|
||||||
CMD_NOSUBFUNCS
|
CMD_NOSUBFUNCS
|
||||||
CMD_MAINFUNC(cmd_avatar)
|
CMD_MAINFUNC(cmd_avatar)
|
||||||
CMD_TAGS(
|
CMD_TAGS(
|
||||||
CMD_TAG_CHAT)
|
CMD_TAG_CHAT)
|
||||||
CMD_SYN(
|
CMD_SYN(
|
||||||
"/avatar <barejid>")
|
"/avatar get <barejid>",
|
||||||
|
"/avatar open <barejid>",
|
||||||
|
"/avatar cmd <command>")
|
||||||
CMD_DESC(
|
CMD_DESC(
|
||||||
"Download avatar (XEP-0084) for a certain contact. "
|
"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 "
|
"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.")
|
"or doesn't use XEP-0084 to publish it.")
|
||||||
CMD_ARGS(
|
CMD_ARGS(
|
||||||
{ "<barejid>", "JID to download avatar from."})
|
{ "get <barejid>", "Download the avatar. barejid is the JID to download avatar from."},
|
||||||
CMD_NOEXAMPLES
|
{ "cmd <command>", "Set a command to execute with 'avatar open'. Use your favourite image viewer here."},
|
||||||
|
{ "open <barejid>", "Download avatar and open it with command."})
|
||||||
|
CMD_EXAMPLES(
|
||||||
|
"/avatar get someone@contacts.org",
|
||||||
|
"/avatar cmd xdg-open",
|
||||||
|
"/avatar open someone@contacts.org")
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "/os",
|
{ "/os",
|
||||||
|
@ -8733,7 +8733,19 @@ cmd_color(ProfWin *window, const char *const command, gchar **args)
|
|||||||
gboolean
|
gboolean
|
||||||
cmd_avatar(ProfWin *window, const char *const command, gchar **args)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1770,6 +1770,7 @@ _get_group(preference_t pref)
|
|||||||
case PREF_GRLOG:
|
case PREF_GRLOG:
|
||||||
case PREF_LOG_ROTATE:
|
case PREF_LOG_ROTATE:
|
||||||
case PREF_LOG_SHARED:
|
case PREF_LOG_SHARED:
|
||||||
|
case PREF_AVATAR_CMD:
|
||||||
return PREF_GROUP_LOGGING;
|
return PREF_GROUP_LOGGING;
|
||||||
case PREF_AUTOAWAY_CHECK:
|
case PREF_AUTOAWAY_CHECK:
|
||||||
case PREF_AUTOAWAY_MODE:
|
case PREF_AUTOAWAY_MODE:
|
||||||
@ -2048,6 +2049,8 @@ _get_key(preference_t pref)
|
|||||||
return "correction.allow";
|
return "correction.allow";
|
||||||
case PREF_HISTORY_COLOR_MUC:
|
case PREF_HISTORY_COLOR_MUC:
|
||||||
return "history.muc.color";
|
return "history.muc.color";
|
||||||
|
case PREF_AVATAR_CMD:
|
||||||
|
return "avatar.cmd";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2179,6 +2182,8 @@ _get_default_string(preference_t pref)
|
|||||||
return "false";
|
return "false";
|
||||||
case PREF_HISTORY_COLOR_MUC:
|
case PREF_HISTORY_COLOR_MUC:
|
||||||
return "unanimous";
|
return "unanimous";
|
||||||
|
case PREF_AVATAR_CMD:
|
||||||
|
return "xdg-open";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,7 @@ typedef enum {
|
|||||||
PREF_OCCUPANTS_WRAP,
|
PREF_OCCUPANTS_WRAP,
|
||||||
PREF_CORRECTION_ALLOW,
|
PREF_CORRECTION_ALLOW,
|
||||||
PREF_HISTORY_COLOR_MUC,
|
PREF_HISTORY_COLOR_MUC,
|
||||||
|
PREF_AVATAR_CMD,
|
||||||
} preference_t;
|
} preference_t;
|
||||||
|
|
||||||
typedef struct prof_alias_t {
|
typedef struct prof_alias_t {
|
||||||
|
@ -2039,6 +2039,16 @@ cons_correction_setting(void)
|
|||||||
free(cc);
|
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
|
void
|
||||||
cons_show_connection_prefs(void)
|
cons_show_connection_prefs(void)
|
||||||
{
|
{
|
||||||
|
@ -319,6 +319,7 @@ void cons_winpos_setting(void);
|
|||||||
void cons_color_setting(void);
|
void cons_color_setting(void);
|
||||||
void cons_os_setting(void);
|
void cons_os_setting(void);
|
||||||
void cons_correction_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_online(PContact contact, Resource *resource, GDateTime *last_activity);
|
||||||
void cons_show_contact_offline(PContact contact, char *resource, char *status);
|
void cons_show_contact_offline(PContact contact, char *resource, char *status);
|
||||||
void cons_theme_properties(void);
|
void cons_theme_properties(void);
|
||||||
|
@ -48,13 +48,15 @@
|
|||||||
#include "xmpp/stanza.h"
|
#include "xmpp/stanza.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "config/files.h"
|
#include "config/files.h"
|
||||||
|
#include "config/preferences.h"
|
||||||
|
|
||||||
typedef struct avatar_metadata {
|
typedef struct avatar_metadata {
|
||||||
char *type;
|
char *type;
|
||||||
char *id;
|
char *id;
|
||||||
} avatar_metadata;
|
} 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 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);
|
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);
|
g_hash_table_destroy(looking_for);
|
||||||
}
|
}
|
||||||
looking_for = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
|
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
|
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
|
// in case we set the feature, remove it
|
||||||
caps_remove_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY);
|
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
|
// add the feature. this will trigger the _avatar_metadata_notfication_handler handler
|
||||||
caps_add_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY);
|
caps_add_feature(XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY);
|
||||||
|
|
||||||
|
if (open) {
|
||||||
|
g_hash_table_insert(shall_open, strdup(nick), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
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);
|
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);
|
g_string_free(filename, TRUE);
|
||||||
free(de);
|
free(de);
|
||||||
|
|
||||||
|
@ -39,6 +39,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
void avatar_pep_subscribe(void);
|
void avatar_pep_subscribe(void);
|
||||||
gboolean avatar_get_by_nick(const char* nick);
|
gboolean avatar_get_by_nick(const char* nick, gboolean open);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user