satoriapi.c

changeset 0
cc7c1f9d20f7
child 1
98bcf06036b8
equal deleted inserted replaced
-1:000000000000 0:cc7c1f9d20f7
1 /*
2 * Purple Satori Plugin - Satori Protocol Plugin for Purple3
3 * Copyright (C) 2025 Gong Zhile
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
17 */
18
19 #include <glib.h>
20 #include <gio/gio.h>
21 #include <glib-object.h>
22 #include <json-glib/json-glib.h>
23 #include <libsoup/soup-message.h>
24 #include <libsoup/soup-session.h>
25
26
27 #include "purplesatoriconnection.h"
28 #include "satorimessage.h"
29 #include "satoriapi.h"
30
31 static void
32 satori_on_buddy_contacts_resp(SoupSession *session,
33 GAsyncResult *res,
34 PurpleSatoriConnection *con)
35 {
36 GError *error = NULL;
37 GBytes *resp = soup_session_send_and_read_finish(session, res, &error);
38
39 if (error) {
40 purple_debug_error("satori",
41 "refresh_buddy_contacts failed: %s",
42 error->message);
43 if (resp)
44 g_bytes_unref(resp);
45 g_error_free(error);
46 return;
47 }
48
49 gsize sz;
50 const gchar *ptr = g_bytes_get_data(resp, &sz), *next = NULL;
51
52 JsonParser *parser = json_parser_new();
53 if (!json_parser_load_from_data(parser, ptr, sz, NULL)) {
54 purple_debug_warning("satori", "bad json received from ws");
55 goto finish;
56 }
57
58 JsonObject *root = json_node_get_object(json_parser_get_root(parser));
59 JsonArray *data = json_object_get_array_member(root, "data");
60 next = json_object_get_string_member_with_default(
61 root, "next", NULL);
62
63 if (!data) goto finish;
64
65 PurpleAccount *acc = \
66 purple_connection_get_account(PURPLE_CONNECTION(con));
67 PurpleContactManager *manager = \
68 purple_contact_manager_get_default();
69
70 for (guint i = 0; i < json_array_get_length(data); i++) {
71 JsonObject *user_obj = json_array_get_object_element(data, i);
72
73 SatoriUser user = { 0 };
74 satori_user_from_json(user_obj, &user);
75
76 PurpleContact *contact = NULL;
77 PurpleContactInfo *info = NULL;
78 PurplePresence *presence = NULL;
79 PurplePerson *person = NULL;
80
81 gboolean new_contact = FALSE, new_person = FALSE;
82
83 contact = purple_contact_manager_find_with_id(manager, acc, user.id);
84 if (!PURPLE_IS_CONTACT(contact)) {
85 contact = purple_contact_new(acc, user.id);
86 new_contact = TRUE;
87 }
88
89 /* Initialize PurpleContactInfo */
90 info = PURPLE_CONTACT_INFO(contact);
91 purple_contact_info_set_username(info, user.id);
92 purple_contact_info_set_display_name(info, user.nick ?
93 user.nick : user.name);
94
95 /* Initialize PurplePerson */
96 person = purple_contact_info_get_person(info);
97 if (!PURPLE_IS_PERSON(person)) {
98 person = g_object_new(PURPLE_TYPE_PERSON,
99 "id", user.id, NULL);
100 new_person = TRUE;
101 }
102
103 if (new_person) {
104 purple_person_add_contact_info(person, info);
105 purple_contact_info_set_person(info, person);
106 g_clear_object(&person);
107 }
108
109 /* Initialize PurplePresence */
110 presence = purple_contact_info_get_presence(info);
111 purple_presence_set_primitive(presence,
112 PURPLE_PRESENCE_PRIMITIVE_AVAILABLE);
113
114 if (new_contact) {
115 purple_contact_manager_add(manager, contact);
116 g_clear_object(&contact);
117 }
118 }
119
120 finish:
121 if (next)
122 satori_refresh_buddy_contacts(con, next);
123
124 g_bytes_unref(resp);
125 g_object_unref(parser);
126 }
127
128 void
129 satori_refresh_buddy_contacts(PurpleSatoriConnection *con, const gchar *next)
130 {
131 GBytes *data = NULL;
132
133 {
134 JB_BEGIN_OBJ(b);
135 if (next)
136 JBA(b, "next", next);
137 JB_END_OBJ(data, b);
138 }
139
140 SoupMessage *msg = satori_message_new(
141 "POST", SATORI_ENDPOINT("/v1/friend.list"));
142 soup_message_set_request_body_from_bytes(msg, "application/json", data);
143
144 purple_satori_connection_send_and_read_async(
145 con, msg, 0, NULL,
146 (GAsyncReadyCallback) satori_on_buddy_contacts_resp,
147 PURPLE_SATORI_CONNECTION(con));
148
149 g_object_unref(msg);
150 g_bytes_unref(data);
151 }

mercurial