core: change name to Transifex.com
[siplcs.git] / src / core / sipe-group.c
blobcc5341b9cdf2011606d015cf1e355305de2d0f16
1 /**
2 * @file sipe-group.c
4 * pidgin-sipe
6 * Copyright (C) 2011-2013 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <glib.h>
29 #include "sipmsg.h"
30 #include "sip-soap.h"
31 #include "sip-transport.h"
32 #include "sipe-backend.h"
33 #include "sipe-buddy.h"
34 #include "sipe-core.h"
35 #include "sipe-core-private.h"
36 #include "sipe-group.h"
37 #include "sipe-nls.h"
38 #include "sipe-utils.h"
39 #include "sipe-xml.h"
41 struct group_user_context {
42 gchar *group_name;
43 gchar *user_name;
46 static void
47 sipe_group_context_destroy(gpointer data)
49 struct group_user_context *ctx = data;
50 g_free(ctx->group_name);
51 g_free(ctx->user_name);
52 g_free(ctx);
55 static gboolean
56 process_add_group_response(struct sipe_core_private *sipe_private,
57 struct sipmsg *msg,
58 struct transaction *trans)
60 if (msg->response == 200) {
61 struct sipe_group *group;
62 struct group_user_context *ctx = trans->payload->data;
63 sipe_xml *xml;
64 const sipe_xml *node;
65 char *group_id;
66 struct sipe_buddy *buddy;
68 xml = sipe_xml_parse(msg->body, msg->bodylen);
69 if (!xml) {
70 return FALSE;
73 node = sipe_xml_child(xml, "Body/addGroup/groupID");
74 if (!node) {
75 sipe_xml_free(xml);
76 return FALSE;
79 group_id = sipe_xml_data(node);
80 if (!group_id) {
81 sipe_xml_free(xml);
82 return FALSE;
85 group = g_new0(struct sipe_group, 1);
86 group->id = (int)g_ascii_strtod(group_id, NULL);
87 g_free(group_id);
88 group->name = g_strdup(ctx->group_name);
90 sipe_group_add(sipe_private, group);
92 if (ctx->user_name) {
93 buddy = g_hash_table_lookup(sipe_private->buddies, ctx->user_name);
94 if (buddy) {
95 buddy->groups = sipe_utils_slist_insert_unique_sorted(buddy->groups,
96 group,
97 (GCompareFunc)sipe_group_compare,
98 NULL);
99 sipe_group_update_buddy(sipe_private, buddy);
103 sipe_xml_free(xml);
104 return TRUE;
106 return FALSE;
110 sipe_group_compare(struct sipe_group *group1, struct sipe_group *group2) {
111 return group1->id - group2->id;
114 struct sipe_group*
115 sipe_group_find_by_id(struct sipe_core_private *sipe_private,
116 int id)
118 struct sipe_group *group;
119 GSList *entry;
121 if (!sipe_private)
122 return NULL;
124 entry = sipe_private->groups;
125 while (entry) {
126 group = entry->data;
127 if (group->id == id) {
128 return group;
130 entry = entry->next;
132 return NULL;
135 struct sipe_group*
136 sipe_group_find_by_name(struct sipe_core_private *sipe_private,
137 const gchar * name)
139 struct sipe_group *group;
140 GSList *entry;
142 if (!sipe_private || !name)
143 return NULL;
145 entry = sipe_private->groups;
146 while (entry) {
147 group = entry->data;
148 if (sipe_strequal(group->name, name)) {
149 return group;
151 entry = entry->next;
153 return NULL;
156 void
157 sipe_group_create(struct sipe_core_private *sipe_private,
158 const gchar *name,
159 const gchar *who)
161 struct transaction_payload *payload = g_new0(struct transaction_payload, 1);
162 struct group_user_context *ctx = g_new0(struct group_user_context, 1);
163 const gchar *soap_name = sipe_strequal(name, _("Other Contacts")) ? "~" : name;
164 gchar *request;
165 ctx->group_name = g_strdup(name);
166 ctx->user_name = g_strdup(who);
167 payload->destroy = sipe_group_context_destroy;
168 payload->data = ctx;
170 /* soap_name can contain restricted characters */
171 request = g_markup_printf_escaped("<m:name>%s</m:name>"
172 "<m:externalURI />",
173 soap_name);
174 sip_soap_request_cb(sipe_private,
175 "addGroup",
176 request,
177 process_add_group_response,
178 payload);
179 g_free(request);
182 gboolean sipe_group_rename(struct sipe_core_private *sipe_private,
183 struct sipe_group *group,
184 const gchar *name)
186 gboolean renamed = sipe_backend_buddy_group_rename(SIPE_CORE_PUBLIC,
187 group->name,
188 name);
189 if (renamed) {
190 g_free(group->name);
191 group->name = g_strdup(name);
193 return(renamed);
196 void
197 sipe_group_add(struct sipe_core_private *sipe_private,
198 struct sipe_group * group)
200 if (sipe_backend_buddy_group_add(SIPE_CORE_PUBLIC,group->name))
202 SIPE_DEBUG_INFO("added group %s (id %d)", group->name, group->id);
203 sipe_private->groups = g_slist_append(sipe_private->groups,
204 group);
206 else
208 SIPE_DEBUG_INFO("did not add group %s", group->name ? group->name : "");
212 void sipe_group_free(struct sipe_core_private *sipe_private,
213 struct sipe_group *group)
215 sipe_private->groups = g_slist_remove(sipe_private->groups,
216 group);
217 g_free(group->name);
218 g_free(group);
221 void sipe_group_remove(struct sipe_core_private *sipe_private,
222 struct sipe_group *group)
224 if (group) {
225 SIPE_DEBUG_INFO("removing group %s (id %d)", group->name, group->id);
226 sipe_backend_buddy_group_remove(SIPE_CORE_PUBLIC, group->name);
227 sipe_group_free(sipe_private, group);
231 void
232 sipe_core_group_rename(struct sipe_core_public *sipe_public,
233 const gchar *old_name,
234 const gchar *new_name)
236 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
237 struct sipe_group *s_group = sipe_group_find_by_name(sipe_private, old_name);
239 if (s_group) {
240 gchar *request;
241 SIPE_DEBUG_INFO("Renaming group %s to %s", old_name, new_name);
242 /* new_name can contain restricted characters */
243 request = g_markup_printf_escaped("<m:groupID>%d</m:groupID>"
244 "<m:name>%s</m:name>"
245 "<m:externalURI />",
246 s_group->id, new_name);
247 sip_soap_request(sipe_private,
248 "modifyGroup",
249 request);
250 g_free(request);
252 g_free(s_group->name);
253 s_group->name = g_strdup(new_name);
254 } else {
255 SIPE_DEBUG_INFO("Cannot find group %s to rename", old_name);
259 void
260 sipe_core_group_remove(struct sipe_core_public *sipe_public,
261 const gchar *name)
263 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
264 struct sipe_group *s_group = sipe_group_find_by_name(sipe_private, name);
266 if (s_group) {
267 gchar *request;
268 SIPE_DEBUG_INFO("Deleting group %s", name);
269 request = g_strdup_printf("<m:groupID>%d</m:groupID>",
270 s_group->id);
271 sip_soap_request(sipe_private,
272 "deleteGroup",
273 request);
274 g_free(request);
276 sipe_group_free(sipe_private, s_group);
277 } else {
278 SIPE_DEBUG_INFO("Cannot find group %s to delete", name);
283 * Returns string like "2 4 7 8" - group ids buddy belong to.
285 static gchar *sipe_get_buddy_groups_string(struct sipe_buddy *buddy)
287 int i = 0;
288 gchar *res;
289 //creating array from GList, converting int to gchar*
290 gchar **ids_arr = g_new(gchar *, g_slist_length(buddy->groups) + 1);
291 GSList *entry = buddy->groups;
293 if (!ids_arr) return NULL;
295 while (entry) {
296 struct sipe_group * group = entry->data;
297 ids_arr[i] = g_strdup_printf("%d", group->id);
298 entry = entry->next;
299 i++;
301 ids_arr[i] = NULL;
302 res = g_strjoinv(" ", ids_arr);
303 g_strfreev(ids_arr);
304 return res;
308 * Sends buddy update to server
310 static void send_buddy_update(struct sipe_core_private *sipe_private,
311 struct sipe_buddy *buddy,
312 const gchar *alias)
314 gchar *groups = sipe_get_buddy_groups_string(buddy);
316 if (groups) {
317 gchar *request;
318 SIPE_DEBUG_INFO("Saving buddy %s with alias '%s' and groups '%s'",
319 buddy->name, alias, groups);
321 /* alias can contain restricted characters */
322 request = g_markup_printf_escaped("<m:displayName>%s</m:displayName>"
323 "<m:groups>%s</m:groups>"
324 "<m:subscribed>true</m:subscribed>"
325 "<m:URI>%s</m:URI>"
326 "<m:externalURI />",
327 alias, groups, buddy->name);
328 g_free(groups);
330 sip_soap_request(sipe_private,
331 "setContact",
332 request);
333 g_free(request);
337 /* indicates that buddy information on the server needs updating */
338 void sipe_group_update_buddy(struct sipe_core_private *sipe_private,
339 struct sipe_buddy *buddy)
341 if (buddy) {
342 sipe_backend_buddy backend_buddy = sipe_backend_buddy_find(SIPE_CORE_PUBLIC,
343 buddy->name,
344 NULL);
345 if (backend_buddy) {
346 gchar *alias = sipe_backend_buddy_get_alias(SIPE_CORE_PUBLIC,
347 backend_buddy);
348 send_buddy_update(sipe_private, buddy, alias);
349 g_free(alias);
354 void sipe_core_group_set_alias(struct sipe_core_public *sipe_public,
355 const gchar *who,
356 const gchar *alias)
358 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
359 struct sipe_buddy *buddy = g_hash_table_lookup(sipe_private->buddies,
360 who);
362 if (buddy)
363 send_buddy_update(sipe_private, buddy, alias);
367 Local Variables:
368 mode: c
369 c-file-style: "bsd"
370 indent-tabs-mode: t
371 tab-width: 8
372 End: