6 * Copyright (C) 2011-12 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
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"
38 #include "sipe-utils.h"
41 struct group_user_context
{
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
);
56 process_add_group_response(struct sipe_core_private
*sipe_private
,
58 struct transaction
*trans
)
60 if (msg
->response
== 200) {
61 struct sipe_group
*group
;
62 struct group_user_context
*ctx
= trans
->payload
->data
;
66 struct sipe_buddy
*buddy
;
68 xml
= sipe_xml_parse(msg
->body
, msg
->bodylen
);
73 node
= sipe_xml_child(xml
, "Body/addGroup/groupID");
79 group_id
= sipe_xml_data(node
);
85 group
= g_new0(struct sipe_group
, 1);
86 group
->id
= (int)g_ascii_strtod(group_id
, NULL
);
88 group
->name
= g_strdup(ctx
->group_name
);
90 sipe_group_add(sipe_private
, group
);
93 buddy
= g_hash_table_lookup(sipe_private
->buddies
, ctx
->user_name
);
95 buddy
->groups
= slist_insert_unique_sorted(buddy
->groups
, group
, (GCompareFunc
)sipe_group_compare
);
98 sipe_core_group_set_user(SIPE_CORE_PUBLIC
, ctx
->user_name
);
108 sipe_group_compare(struct sipe_group
*group1
, struct sipe_group
*group2
) {
109 return group1
->id
- group2
->id
;
113 sipe_group_find_by_id(struct sipe_core_private
*sipe_private
,
116 struct sipe_group
*group
;
122 entry
= sipe_private
->groups
;
125 if (group
->id
== id
) {
134 sipe_group_find_by_name(struct sipe_core_private
*sipe_private
,
137 struct sipe_group
*group
;
140 if (!sipe_private
|| !name
)
143 entry
= sipe_private
->groups
;
146 if (sipe_strequal(group
->name
, name
)) {
155 sipe_group_create(struct sipe_core_private
*sipe_private
,
159 struct transaction_payload
*payload
= g_new0(struct transaction_payload
, 1);
160 struct group_user_context
*ctx
= g_new0(struct group_user_context
, 1);
161 const gchar
*soap_name
= sipe_strequal(name
, _("Other Contacts")) ? "~" : name
;
163 ctx
->group_name
= g_strdup(name
);
164 ctx
->user_name
= g_strdup(who
);
165 payload
->destroy
= sipe_group_context_destroy
;
168 /* soap_name can contain restricted characters */
169 request
= g_markup_printf_escaped("<m:name>%s</m:name>"
172 sip_soap_request_cb(sipe_private
,
175 process_add_group_response
,
180 gboolean
sipe_group_rename(struct sipe_core_private
*sipe_private
,
181 struct sipe_group
*group
,
184 gboolean renamed
= sipe_backend_buddy_group_rename(SIPE_CORE_PUBLIC
,
189 group
->name
= g_strdup(name
);
195 sipe_group_add(struct sipe_core_private
*sipe_private
,
196 struct sipe_group
* group
)
198 if (sipe_backend_buddy_group_add(SIPE_CORE_PUBLIC
,group
->name
))
200 SIPE_DEBUG_INFO("added group %s (id %d)", group
->name
, group
->id
);
201 sipe_private
->groups
= g_slist_append(sipe_private
->groups
,
206 SIPE_DEBUG_INFO("did not add group %s", group
->name
? group
->name
: "");
210 void sipe_group_free(struct sipe_core_private
*sipe_private
,
211 struct sipe_group
*group
)
213 sipe_private
->groups
= g_slist_remove(sipe_private
->groups
,
219 void sipe_group_remove(struct sipe_core_private
*sipe_private
,
220 struct sipe_group
*group
)
223 SIPE_DEBUG_INFO("removing group %s (id %d)", group
->name
, group
->id
);
224 sipe_backend_buddy_group_remove(SIPE_CORE_PUBLIC
, group
->name
);
225 sipe_group_free(sipe_private
, group
);
230 sipe_core_group_rename(struct sipe_core_public
*sipe_public
,
231 const gchar
*old_name
,
232 const gchar
*new_name
)
234 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
235 struct sipe_group
*s_group
= sipe_group_find_by_name(sipe_private
, old_name
);
239 SIPE_DEBUG_INFO("Renaming group %s to %s", old_name
, new_name
);
240 /* new_name can contain restricted characters */
241 request
= g_markup_printf_escaped("<m:groupID>%d</m:groupID>"
242 "<m:name>%s</m:name>"
244 s_group
->id
, new_name
);
245 sip_soap_request(sipe_private
,
250 g_free(s_group
->name
);
251 s_group
->name
= g_strdup(new_name
);
253 SIPE_DEBUG_INFO("Cannot find group %s to rename", old_name
);
258 sipe_core_group_remove(struct sipe_core_public
*sipe_public
,
261 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
262 struct sipe_group
*s_group
= sipe_group_find_by_name(sipe_private
, name
);
266 SIPE_DEBUG_INFO("Deleting group %s", name
);
267 request
= g_strdup_printf("<m:groupID>%d</m:groupID>",
269 sip_soap_request(sipe_private
,
274 sipe_group_free(sipe_private
, s_group
);
276 SIPE_DEBUG_INFO("Cannot find group %s to delete", name
);
281 * Returns string like "2 4 7 8" - group ids buddy belong to.
283 static gchar
*sipe_get_buddy_groups_string(struct sipe_buddy
*buddy
)
287 //creating array from GList, converting int to gchar*
288 gchar
**ids_arr
= g_new(gchar
*, g_slist_length(buddy
->groups
) + 1);
289 GSList
*entry
= buddy
->groups
;
291 if (!ids_arr
) return NULL
;
294 struct sipe_group
* group
= entry
->data
;
295 ids_arr
[i
] = g_strdup_printf("%d", group
->id
);
300 res
= g_strjoinv(" ", ids_arr
);
306 * Sends buddy update to server
308 void sipe_core_group_set_user(struct sipe_core_public
*sipe_public
,
311 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
312 struct sipe_buddy
*buddy
= g_hash_table_lookup(sipe_private
->buddies
, who
);
313 sipe_backend_buddy backend_buddy
= sipe_backend_buddy_find(sipe_public
, who
, NULL
);
315 if (buddy
&& backend_buddy
) {
316 gchar
*groups
= sipe_get_buddy_groups_string(buddy
);
319 gchar
*alias
= sipe_backend_buddy_get_alias(sipe_public
, backend_buddy
);
321 SIPE_DEBUG_INFO("Saving buddy %s with alias %s and groups %s", who
, alias
, groups
);
323 /* alias can contain restricted characters */
324 request
= g_markup_printf_escaped("<m:displayName>%s</m:displayName>"
325 "<m:groups>%s</m:groups>"
326 "<m:subscribed>true</m:subscribed>"
329 alias
, groups
, buddy
->name
);
333 sip_soap_request(sipe_private
,