mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Cache capabilities to file
This commit is contained in:
parent
9f7a8cea81
commit
60a18c3c8d
@ -342,6 +342,7 @@ _cons_show_caps(const char * const fulljid, Resource *resource)
|
|||||||
feature = g_slist_next(feature);
|
feature = g_slist_next(feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
caps_destroy(caps);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cons_show("No capabilities found for %s", fulljid);
|
cons_show("No capabilities found for %s", fulljid);
|
||||||
@ -777,6 +778,7 @@ _cons_show_account(ProfAccount *account)
|
|||||||
if ((caps->os != NULL) || (caps->os_version != NULL)) {
|
if ((caps->os != NULL) || (caps->os_version != NULL)) {
|
||||||
win_save_newline(console);
|
win_save_newline(console);
|
||||||
}
|
}
|
||||||
|
caps_destroy(caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
ordered_resources = g_list_next(ordered_resources);
|
ordered_resources = g_list_next(ordered_resources);
|
||||||
|
@ -277,6 +277,7 @@ win_show_info(ProfWin *window, PContact contact)
|
|||||||
if ((caps->os != NULL) || (caps->os_version != NULL)) {
|
if ((caps->os != NULL) || (caps->os_version != NULL)) {
|
||||||
win_save_newline(window);
|
win_save_newline(window);
|
||||||
}
|
}
|
||||||
|
caps_destroy(caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
ordered_resources = g_list_next(ordered_resources);
|
ordered_resources = g_list_next(ordered_resources);
|
||||||
|
@ -50,23 +50,69 @@
|
|||||||
#include "xmpp/stanza.h"
|
#include "xmpp/stanza.h"
|
||||||
#include "xmpp/form.h"
|
#include "xmpp/form.h"
|
||||||
|
|
||||||
static GHashTable *capabilities;
|
static gchar *cache_loc;
|
||||||
|
static GKeyFile *cache;
|
||||||
|
|
||||||
static GHashTable *jid_lookup;
|
static GHashTable *jid_lookup;
|
||||||
|
|
||||||
static void _caps_destroy(Capabilities *caps);
|
static void _caps_destroy(Capabilities *caps);
|
||||||
|
static gchar* _get_cache_file(void);
|
||||||
|
static void _save_cache(void);
|
||||||
|
static Capabilities * _caps_get(const char * const caps_str);
|
||||||
|
|
||||||
void
|
void
|
||||||
caps_init(void)
|
caps_init(void)
|
||||||
{
|
{
|
||||||
capabilities = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
log_info("Loading capabilities cache");
|
||||||
(GDestroyNotify)_caps_destroy);
|
cache_loc = _get_cache_file();
|
||||||
|
|
||||||
|
cache = g_key_file_new();
|
||||||
|
g_key_file_load_from_file(cache, cache_loc, G_KEY_FILE_KEEP_COMMENTS,
|
||||||
|
NULL);
|
||||||
|
|
||||||
jid_lookup = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
jid_lookup = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
caps_add(const char * const ver, Capabilities *caps)
|
caps_add(const char * const ver, Capabilities *caps)
|
||||||
{
|
{
|
||||||
g_hash_table_insert(capabilities, strdup(ver), caps);
|
gboolean cached = g_key_file_has_group(cache, ver);
|
||||||
|
if (!cached) {
|
||||||
|
if (caps->category) {
|
||||||
|
g_key_file_set_string(cache, ver, "category", caps->category);
|
||||||
|
}
|
||||||
|
if (caps->type) {
|
||||||
|
g_key_file_set_string(cache, ver, "type", caps->type);
|
||||||
|
}
|
||||||
|
if (caps->name) {
|
||||||
|
g_key_file_set_string(cache, ver, "name", caps->name);
|
||||||
|
}
|
||||||
|
if (caps->software) {
|
||||||
|
g_key_file_set_string(cache, ver, "software", caps->software);
|
||||||
|
}
|
||||||
|
if (caps->software_version) {
|
||||||
|
g_key_file_set_string(cache, ver, "software_version", caps->software_version);
|
||||||
|
}
|
||||||
|
if (caps->os) {
|
||||||
|
g_key_file_set_string(cache, ver, "os", caps->os);
|
||||||
|
}
|
||||||
|
if (caps->os_version) {
|
||||||
|
g_key_file_set_string(cache, ver, "os_version", caps->os_version);
|
||||||
|
}
|
||||||
|
if (caps->features) {
|
||||||
|
GSList *curr_feature = caps->features;
|
||||||
|
int num = g_slist_length(caps->features);
|
||||||
|
const gchar* features_list[num];
|
||||||
|
int curr = 0;
|
||||||
|
while (curr_feature) {
|
||||||
|
features_list[curr++] = strdup(curr_feature->data);
|
||||||
|
curr_feature = g_slist_next(curr_feature);
|
||||||
|
}
|
||||||
|
g_key_file_set_string_list(cache, ver, "features", features_list, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
_save_cache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -78,13 +124,81 @@ caps_map(const char * const jid, const char * const ver)
|
|||||||
gboolean
|
gboolean
|
||||||
caps_contains(const char * const caps_ver)
|
caps_contains(const char * const caps_ver)
|
||||||
{
|
{
|
||||||
return (g_hash_table_lookup(capabilities, caps_ver) != NULL);
|
return (g_key_file_has_group(cache, caps_ver));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Capabilities *
|
static Capabilities *
|
||||||
_caps_get(const char * const caps_str)
|
_caps_get(const char * const caps_str)
|
||||||
{
|
{
|
||||||
return g_hash_table_lookup(capabilities, caps_str);
|
if (g_key_file_has_group(cache, caps_str)) {
|
||||||
|
Capabilities *new_caps = malloc(sizeof(struct capabilities_t));
|
||||||
|
|
||||||
|
char *category = g_key_file_get_string(cache, caps_str, "category", NULL);
|
||||||
|
if (category) {
|
||||||
|
new_caps->category = strdup(category);
|
||||||
|
} else {
|
||||||
|
new_caps->category = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *type = g_key_file_get_string(cache, caps_str, "type", NULL);
|
||||||
|
if (type) {
|
||||||
|
new_caps->type = strdup(type);
|
||||||
|
} else {
|
||||||
|
new_caps->type = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *name = g_key_file_get_string(cache, caps_str, "name", NULL);
|
||||||
|
if (name) {
|
||||||
|
new_caps->name = strdup(name);
|
||||||
|
} else {
|
||||||
|
new_caps->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *software = g_key_file_get_string(cache, caps_str, "software", NULL);
|
||||||
|
if (software) {
|
||||||
|
new_caps->software = strdup(software);
|
||||||
|
} else {
|
||||||
|
new_caps->software = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *software_version = g_key_file_get_string(cache, caps_str, "software_version", NULL);
|
||||||
|
if (software_version) {
|
||||||
|
new_caps->software_version = strdup(software_version);
|
||||||
|
} else {
|
||||||
|
new_caps->software_version = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *os = g_key_file_get_string(cache, caps_str, "os", NULL);
|
||||||
|
if (os) {
|
||||||
|
new_caps->os = strdup(os);
|
||||||
|
} else {
|
||||||
|
new_caps->os = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *os_version = g_key_file_get_string(cache, caps_str, "os_version", NULL);
|
||||||
|
if (os_version) {
|
||||||
|
new_caps->os_version = strdup(os_version);
|
||||||
|
} else {
|
||||||
|
new_caps->os_version = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsize features_len = 0;
|
||||||
|
gchar **features = g_key_file_get_string_list(cache, caps_str, "features", &features_len, NULL);
|
||||||
|
if (features != NULL && features_len > 0) {
|
||||||
|
GSList *features_list = NULL;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < features_len; i++) {
|
||||||
|
features_list = g_slist_append(features_list, strdup(features[i]));
|
||||||
|
}
|
||||||
|
new_caps->features = features_list;
|
||||||
|
g_strfreev(features);
|
||||||
|
} else {
|
||||||
|
new_caps->features = NULL;
|
||||||
|
}
|
||||||
|
return new_caps;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Capabilities *
|
static Capabilities *
|
||||||
@ -92,7 +206,7 @@ _caps_lookup(const char * const jid)
|
|||||||
{
|
{
|
||||||
char *ver = g_hash_table_lookup(jid_lookup, jid);
|
char *ver = g_hash_table_lookup(jid_lookup, jid);
|
||||||
if (ver) {
|
if (ver) {
|
||||||
Capabilities *caps = g_hash_table_lookup(capabilities, ver);
|
Capabilities *caps = _caps_get(ver);
|
||||||
if (caps) {
|
if (caps) {
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
@ -116,7 +230,6 @@ caps_create_sha1_str(xmpp_stanza_t * const query)
|
|||||||
FormField *field = NULL;
|
FormField *field = NULL;
|
||||||
GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)form_destroy);
|
GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)form_destroy);
|
||||||
|
|
||||||
|
|
||||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||||
while (child) {
|
while (child) {
|
||||||
if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) {
|
if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) {
|
||||||
@ -213,13 +326,13 @@ caps_create_sha1_str(xmpp_stanza_t * const query)
|
|||||||
Capabilities *
|
Capabilities *
|
||||||
caps_create(xmpp_stanza_t *query)
|
caps_create(xmpp_stanza_t *query)
|
||||||
{
|
{
|
||||||
const char *category = NULL;
|
char *category = NULL;
|
||||||
const char *type = NULL;
|
char *type = NULL;
|
||||||
const char *name = NULL;
|
char *name = NULL;
|
||||||
const char *software = NULL;
|
char *software = NULL;
|
||||||
const char *software_version = NULL;
|
char *software_version = NULL;
|
||||||
const char *os = NULL;
|
char *os = NULL;
|
||||||
const char *os_version = NULL;
|
char *os_version = NULL;
|
||||||
GSList *features = NULL;
|
GSList *features = NULL;
|
||||||
|
|
||||||
xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
|
xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
|
||||||
@ -241,13 +354,13 @@ caps_create(xmpp_stanza_t *query)
|
|||||||
formField = field->data;
|
formField = field->data;
|
||||||
if (formField->values != NULL) {
|
if (formField->values != NULL) {
|
||||||
if (strcmp(formField->var, "software") == 0) {
|
if (strcmp(formField->var, "software") == 0) {
|
||||||
software = formField->values->data;
|
software = strdup(formField->values->data);
|
||||||
} else if (strcmp(formField->var, "software_version") == 0) {
|
} else if (strcmp(formField->var, "software_version") == 0) {
|
||||||
software_version = formField->values->data;
|
software_version = strdup(formField->values->data);
|
||||||
} else if (strcmp(formField->var, "os") == 0) {
|
} else if (strcmp(formField->var, "os") == 0) {
|
||||||
os = formField->values->data;
|
os = strdup(formField->values->data);
|
||||||
} else if (strcmp(formField->var, "os_version") == 0) {
|
} else if (strcmp(formField->var, "os_version") == 0) {
|
||||||
os_version = formField->values->data;
|
os_version = strdup(formField->values->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
field = g_slist_next(field);
|
field = g_slist_next(field);
|
||||||
@ -284,22 +397,22 @@ caps_create(xmpp_stanza_t *query)
|
|||||||
new_caps->name = NULL;
|
new_caps->name = NULL;
|
||||||
}
|
}
|
||||||
if (software != NULL) {
|
if (software != NULL) {
|
||||||
new_caps->software = strdup(software);
|
new_caps->software = software;
|
||||||
} else {
|
} else {
|
||||||
new_caps->software = NULL;
|
new_caps->software = NULL;
|
||||||
}
|
}
|
||||||
if (software_version != NULL) {
|
if (software_version != NULL) {
|
||||||
new_caps->software_version = strdup(software_version);
|
new_caps->software_version = software_version;
|
||||||
} else {
|
} else {
|
||||||
new_caps->software_version = NULL;
|
new_caps->software_version = NULL;
|
||||||
}
|
}
|
||||||
if (os != NULL) {
|
if (os != NULL) {
|
||||||
new_caps->os = strdup(os);
|
new_caps->os = os;
|
||||||
} else {
|
} else {
|
||||||
new_caps->os = NULL;
|
new_caps->os = NULL;
|
||||||
}
|
}
|
||||||
if (os_version != NULL) {
|
if (os_version != NULL) {
|
||||||
new_caps->os_version = strdup(os_version);
|
new_caps->os_version = os_version;
|
||||||
} else {
|
} else {
|
||||||
new_caps->os_version = NULL;
|
new_caps->os_version = NULL;
|
||||||
}
|
}
|
||||||
@ -393,7 +506,8 @@ caps_create_query_response_stanza(xmpp_ctx_t * const ctx)
|
|||||||
static void
|
static void
|
||||||
_caps_close(void)
|
_caps_close(void)
|
||||||
{
|
{
|
||||||
g_hash_table_destroy(capabilities);
|
g_key_file_free(cache);
|
||||||
|
cache = NULL;
|
||||||
g_hash_table_destroy(jid_lookup);
|
g_hash_table_destroy(jid_lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,10 +529,32 @@ _caps_destroy(Capabilities *caps)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
_get_cache_file(void)
|
||||||
|
{
|
||||||
|
gchar *xdg_data = xdg_get_data_home();
|
||||||
|
GString *cache_file = g_string_new(xdg_data);
|
||||||
|
g_string_append(cache_file, "/profanity/capscache");
|
||||||
|
gchar *result = strdup(cache_file->str);
|
||||||
|
g_free(xdg_data);
|
||||||
|
g_string_free(cache_file, TRUE);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_save_cache(void)
|
||||||
|
{
|
||||||
|
gsize g_data_size;
|
||||||
|
gchar *g_cache_data = g_key_file_to_data(cache, &g_data_size, NULL);
|
||||||
|
g_file_set_contents(cache_loc, g_cache_data, g_data_size, NULL);
|
||||||
|
g_free(g_cache_data);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
capabilities_init_module(void)
|
capabilities_init_module(void)
|
||||||
{
|
{
|
||||||
caps_get = _caps_get;
|
|
||||||
caps_lookup = _caps_lookup;
|
caps_lookup = _caps_lookup;
|
||||||
caps_close = _caps_close;
|
caps_close = _caps_close;
|
||||||
|
caps_destroy = _caps_destroy;
|
||||||
}
|
}
|
||||||
|
@ -193,9 +193,9 @@ void (*iq_send_caps_request)(const char * const to, const char * const id,
|
|||||||
const char * const node, const char * const ver);
|
const char * const node, const char * const ver);
|
||||||
|
|
||||||
// caps functions
|
// caps functions
|
||||||
Capabilities* (*caps_get)(const char * const caps_str);
|
|
||||||
Capabilities* (*caps_lookup)(const char * const jid);
|
Capabilities* (*caps_lookup)(const char * const jid);
|
||||||
void (*caps_close)(void);
|
void (*caps_close)(void);
|
||||||
|
void (*caps_destroy)(Capabilities *caps);
|
||||||
|
|
||||||
gboolean (*bookmark_add)(const char *jid, const char *nick, const char *password, const char *autojoin_str);
|
gboolean (*bookmark_add)(const char *jid, const char *nick, const char *password, const char *autojoin_str);
|
||||||
gboolean (*bookmark_update)(const char *jid, const char *nick, const char *password, const char *autojoin_str);
|
gboolean (*bookmark_update)(const char *jid, const char *nick, const char *password, const char *autojoin_str);
|
||||||
|
Loading…
Reference in New Issue
Block a user