aboutsummaryrefslogtreecommitdiffstats
path: root/facebook/facebook-data.c
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2015-08-24 17:01:16 -0400
committerjgeboski <jgeboski@gmail.com>2015-08-24 17:01:16 -0400
commit53cedfaca78278a64cc347e8ed51bb67363b3dcc (patch)
treedd2c6cac0c3d5d4af1cccaa9cbbc7a6ca4522572 /facebook/facebook-data.c
parent60a42307f24c617029efbb7bcd432d162706c692 (diff)
downloadbitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.gz
bitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.bz2
bitlbee-facebook-53cedfaca78278a64cc347e8ed51bb67363b3dcc.tar.xz
Imported changes from purple-facebook
Diffstat (limited to 'facebook/facebook-data.c')
-rw-r--r--facebook/facebook-data.c404
1 files changed, 404 insertions, 0 deletions
diff --git a/facebook/facebook-data.c b/facebook/facebook-data.c
new file mode 100644
index 0000000..443e00f
--- /dev/null
+++ b/facebook/facebook-data.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2014-2015 James Geboski <jgeboski@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include "facebook-api.h"
+#include "facebook-data.h"
+
+struct _FbDataPrivate
+{
+ FbApi *api;
+ struct im_connection *ic;
+ GQueue *msgs;
+ GQueue *tids;
+ GHashTable *evs;
+ GHashTable *gcs;
+};
+
+static const gchar *fb_props_strs[] = {
+ "cid",
+ "did",
+ "stoken",
+ "token"
+};
+
+G_DEFINE_TYPE(FbData, fb_data, G_TYPE_OBJECT);
+
+static void
+fb_data_dispose(GObject *obj)
+{
+ FbDataPrivate *priv = FB_DATA(obj)->priv;
+ GHashTableIter iter;
+ gpointer ptr;
+
+ g_object_unref(priv->api);
+ g_hash_table_iter_init(&iter, priv->evs);
+
+ while (g_hash_table_iter_next(&iter, NULL, &ptr)) {
+ g_hash_table_iter_remove(&iter);
+ b_event_remove(GPOINTER_TO_UINT(ptr));
+ }
+
+ g_hash_table_iter_init(&iter, priv->gcs);
+
+ while (g_hash_table_iter_next(&iter, NULL, &ptr)) {
+ g_hash_table_iter_remove(&iter);
+ imcb_chat_free(ptr);
+ }
+
+ g_queue_free_full(priv->msgs, (GDestroyNotify) fb_api_message_free);
+ g_queue_free_full(priv->tids, g_free);
+
+ g_hash_table_destroy(priv->evs);
+ g_hash_table_destroy(priv->gcs);
+}
+
+static void
+fb_data_class_init(FbDataClass *klass)
+{
+ GObjectClass *gklass = G_OBJECT_CLASS(klass);
+
+ gklass->dispose = fb_data_dispose;
+ g_type_class_add_private(klass, sizeof (FbDataPrivate));
+}
+
+static void
+fb_data_init(FbData *fata)
+{
+ FbDataPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE(fata, FB_TYPE_DATA, FbDataPrivate);
+ fata->priv = priv;
+
+ priv->api = fb_api_new();
+ priv->msgs = g_queue_new();
+ priv->tids = g_queue_new();
+ priv->evs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ priv->gcs = g_hash_table_new(g_direct_hash, g_direct_equal);
+}
+
+FbData *
+fb_data_new(account_t *acct)
+{
+ FbData *fata;
+ FbDataPrivate *priv;
+
+ fata = g_object_new(FB_TYPE_DATA, NULL);
+ priv = fata->priv;
+
+ priv->ic = imcb_new(acct);
+ priv->ic->proto_data = fata;
+ return fata;
+}
+
+gboolean
+fb_data_load(FbData *fata)
+{
+ account_t *acct;
+ const gchar *str;
+ FbDataPrivate *priv;
+ FbId id;
+ gboolean ret = TRUE;
+ guint i;
+ guint64 uint;
+ GValue val = G_VALUE_INIT;
+
+ g_return_val_if_fail(FB_IS_DATA(fata), FALSE);
+ priv = fata->priv;
+ acct = priv->ic->acc;
+
+ for (i = 0; i < G_N_ELEMENTS(fb_props_strs); i++) {
+ str = set_getstr(&acct->set, fb_props_strs[i]);
+
+ if (str == NULL) {
+ ret = FALSE;
+ }
+
+ g_value_init(&val, G_TYPE_STRING);
+ g_value_set_string(&val, str);
+ g_object_set_property(G_OBJECT(priv->api), fb_props_strs[i],
+ &val);
+ g_value_unset(&val);
+ }
+
+ str = set_getstr(&acct->set, "mid");
+
+ if (str != NULL) {
+ uint = g_ascii_strtoull(str, NULL, 10);
+ g_value_init(&val, G_TYPE_UINT64);
+ g_value_set_uint64(&val, uint);
+ g_object_set_property(G_OBJECT(priv->api), "mid", &val);
+ g_value_unset(&val);
+ } else {
+ ret = FALSE;
+ }
+
+ str = set_getstr(&acct->set, "uid");
+
+ if (str != NULL) {
+ id = FB_ID_FROM_STR(str);
+ g_value_init(&val, FB_TYPE_ID);
+ g_value_set_int64(&val, id);
+ g_object_set_property(G_OBJECT(priv->api), "uid", &val);
+ g_value_unset(&val);
+ } else {
+ ret = FALSE;
+ }
+
+ fb_api_rehash(priv->api);
+ return ret;
+}
+
+void
+fb_data_save(FbData *fata)
+{
+ account_t *acct;
+ const gchar *str;
+ FbDataPrivate *priv;
+ gchar *dup;
+ guint i;
+ guint64 uint;
+ GValue val = G_VALUE_INIT;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+ acct = priv->ic->acc;
+
+ for (i = 0; i < G_N_ELEMENTS(fb_props_strs); i++) {
+ g_value_init(&val, G_TYPE_STRING);
+ g_object_get_property(G_OBJECT(priv->api), fb_props_strs[i],
+ &val);
+ str = g_value_get_string(&val);
+ set_setstr(&acct->set, fb_props_strs[i], (gchar *) str);
+ g_value_unset(&val);
+ }
+
+ g_value_init(&val, G_TYPE_UINT64);
+ g_object_get_property(G_OBJECT(priv->api), "mid", &val);
+ uint = g_value_get_uint64(&val);
+ g_value_unset(&val);
+
+ dup = g_strdup_printf("%" G_GINT64_FORMAT, uint);
+ set_setstr(&acct->set, "mid", dup);
+ g_free(dup);
+
+ g_value_init(&val, G_TYPE_INT64);
+ g_object_get_property(G_OBJECT(priv->api), "uid", &val);
+ uint = g_value_get_int64(&val);
+ g_value_unset(&val);
+
+ dup = g_strdup_printf("%" FB_ID_FORMAT, uint);
+ set_setstr(&acct->set, "uid", dup);
+ g_free(dup);
+}
+
+void
+fb_data_add_groupchat(FbData *fata, struct groupchat *gc)
+{
+ FbDataPrivate *priv;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ g_hash_table_replace(priv->gcs, gc, gc);
+}
+
+void
+fb_data_remove_groupchat(FbData *fata, struct groupchat *gc)
+{
+ FbDataPrivate *priv;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ g_hash_table_remove(priv->gcs, gc);
+}
+
+void
+fb_data_add_thread_head(FbData *fata, FbId tid)
+{
+ FbDataPrivate *priv;
+ FbId *dtid;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ dtid = g_memdup(&tid, sizeof tid);
+ g_queue_push_head(priv->tids, dtid);
+}
+
+void
+fb_data_add_thread_tail(FbData *fata, FbId tid)
+{
+ FbDataPrivate *priv;
+ FbId *dtid;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ dtid = g_memdup(&tid, sizeof tid);
+ g_queue_push_tail(priv->tids, dtid);
+}
+
+void
+fb_data_clear_threads(FbData *fata)
+{
+ FbDataPrivate *priv;
+ GList *l;
+ GList *n;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ l = priv->tids->head;
+
+ while (l != NULL) {
+ n = l->next;
+ g_queue_delete_link(priv->tids, l);
+ g_free(l->data);
+ l = n;
+ }
+}
+
+FbId
+fb_data_get_thread(FbData *fata, guint n)
+{
+ FbDataPrivate *priv;
+ FbId *tid;
+
+ g_return_val_if_fail(FB_IS_DATA(fata), 0);
+ priv = fata->priv;
+
+ tid = g_queue_peek_nth(priv->tids, n);
+
+ if (tid == NULL) {
+ return 0;
+ }
+
+ return *tid;
+}
+
+void
+fb_data_add_timeout(FbData *fata, const gchar *name, guint interval,
+ b_event_handler func, gpointer data)
+{
+ FbDataPrivate *priv;
+ gchar *key;
+ guint id;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ fb_data_clear_timeout(fata, name, TRUE);
+
+ key = g_strdup(name);
+ id = b_timeout_add(interval, func, data);
+ g_hash_table_replace(priv->evs, key, GUINT_TO_POINTER(id));
+}
+
+void
+fb_data_clear_timeout(FbData *fata, const gchar *name, gboolean remove)
+{
+ FbDataPrivate *priv;
+ gpointer ptr;
+ guint id;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ ptr = g_hash_table_lookup(priv->evs, name);
+ id = GPOINTER_TO_UINT(ptr);
+
+ if ((id > 0) && remove) {
+ b_event_remove(id);
+ }
+
+ g_hash_table_remove(priv->evs, name);
+}
+
+FbApi *
+fb_data_get_api(FbData *fata)
+{
+ FbDataPrivate *priv;
+
+ g_return_val_if_fail(FB_IS_DATA(fata), NULL);
+ priv = fata->priv;
+
+ return priv->api;
+}
+
+struct im_connection *
+fb_data_get_connection(FbData *fata)
+{
+ FbDataPrivate *priv;
+
+ g_return_val_if_fail(FB_IS_DATA(fata), NULL);
+ priv = fata->priv;
+
+ return priv->ic;
+}
+
+void
+fb_data_add_message(FbData *fata, FbApiMessage *msg)
+{
+ FbDataPrivate *priv;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ g_queue_push_tail(priv->msgs, msg);
+}
+
+void
+fb_data_remove_message(FbData *fata, FbApiMessage *msg)
+{
+ FbDataPrivate *priv;
+
+ g_return_if_fail(FB_IS_DATA(fata));
+ priv = fata->priv;
+
+ g_queue_remove(priv->msgs, msg);
+}
+
+GSList *
+fb_data_take_messages(FbData *fata, FbId uid)
+{
+ FbApiMessage *msg;
+ FbDataPrivate *priv;
+ GList *l;
+ GList *prev;
+ GSList *msgs = NULL;
+
+ g_return_val_if_fail(FB_IS_DATA(fata), NULL);
+ priv = fata->priv;
+ l = priv->msgs->tail;
+
+ while (l != NULL) {
+ msg = l->data;
+ prev = l->prev;
+
+ if (msg->uid == uid) {
+ msgs = g_slist_prepend(msgs, msg);
+ g_queue_delete_link(priv->msgs, l);
+ }
+
+ l = prev;
+ }
+
+ return msgs;
+}