comparison libpurple/protocols/mxit/roster.c @ 28903:69aa4660401a

Initial addition of the MXit protocol plugin, provided by the MXit folks themselves.
author John Bailey <rekkanoryo@rekkanoryo.org>
date Sun, 08 Nov 2009 23:55:56 +0000
parents
children 5f80ab7ac183
comparison
equal deleted inserted replaced
28901:13e668ef158d 28903:69aa4660401a
1 /*
2 * MXit Protocol libPurple Plugin
3 *
4 * -- user roster management (mxit contacts) --
5 *
6 * Pieter Loubser <libpurple@mxit.com>
7 *
8 * (C) Copyright 2009 MXit Lifestyle (Pty) Ltd.
9 * <http://www.mxitlifestyle.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 */
25
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #include "purple.h"
31
32 #include "protocol.h"
33 #include "mxit.h"
34 #include "roster.h"
35
36
37 struct contact_invite {
38 struct MXitSession* session; /* MXit session object */
39 struct contact* contact; /* The contact performing the invite */
40 };
41
42
43 /*========================================================================================================================
44 * Presence / Status
45 */
46
47 /* statuses (reference: libpurple/status.h) */
48 static struct status
49 {
50 PurpleStatusPrimitive primative;
51 int mxit;
52 const char* id;
53 const char* name;
54 } const mxit_statuses[] = {
55 /* primative, no, id, name */
56 { PURPLE_STATUS_OFFLINE, MXIT_PRESENCE_OFFLINE, "offline", "Offline" }, /* 0 */
57 { PURPLE_STATUS_AVAILABLE, MXIT_PRESENCE_ONLINE, "online", "Available" }, /* 1 */
58 { PURPLE_STATUS_AWAY, MXIT_PRESENCE_AWAY, "away", "Away" }, /* 2 */
59 { PURPLE_STATUS_AVAILABLE, MXIT_PRESENCE_AVAILABLE, "chat", "Chatty" }, /* 3 */
60 { PURPLE_STATUS_UNAVAILABLE, MXIT_PRESENCE_DND, "dnd", "Do Not Disturb" } /* 4 */
61 };
62
63
64 /*------------------------------------------------------------------------
65 * Return list of supported statuses. (see status.h)
66 *
67 * @param account The MXit account object
68 * @return List of PurpleStatusType
69 */
70 GList* mxit_status_types( PurpleAccount* account )
71 {
72 GList* statuslist = NULL;
73 PurpleStatusType* type;
74 unsigned int i;
75
76 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) {
77 const struct status* status = &mxit_statuses[i];
78
79 /* add mxit status (reference: "libpurple/status.h") */
80 type = purple_status_type_new_with_attrs( status->primative, status->id, status->name, TRUE, TRUE, FALSE,
81 "message", _( "Message" ), purple_value_new( PURPLE_TYPE_STRING ),
82 NULL );
83
84 statuslist = g_list_append( statuslist, type );
85 }
86
87 return statuslist;
88 }
89
90
91 /*------------------------------------------------------------------------
92 * Returns the MXit presence code, given the unique status ID.
93 *
94 * @param id The status ID
95 * @return The MXit presence code
96 */
97 int mxit_convert_presence( const char* id )
98 {
99 unsigned int i;
100
101 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) {
102 if ( strcmp( mxit_statuses[i].id, id ) == 0 ) /* status found! */
103 return mxit_statuses[i].mxit;
104 }
105
106 return -1;
107 }
108
109
110 /*------------------------------------------------------------------------
111 * Returns the MXit presence as a string, given the MXit presence ID.
112 *
113 * @param no The MXit presence I (see above)
114 * @return The presence as a text string
115 */
116 const char* mxit_convert_presence_to_name( short no )
117 {
118 unsigned int i;
119
120 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) {
121 if ( mxit_statuses[i].mxit == no ) /* status found! */
122 return _( mxit_statuses[i].name );
123 }
124
125 return "";
126 }
127
128
129 /*========================================================================================================================
130 * Moods
131 */
132
133 /*------------------------------------------------------------------------
134 * Returns the MXit mood as a string, given the MXit mood's ID.
135 *
136 * @param id The MXit mood ID (see roster.h)
137 * @return The mood as a text string
138 */
139 const char* mxit_convert_mood_to_name( short id )
140 {
141 switch ( id ) {
142 case MXIT_MOOD_ANGRY :
143 return _( "Angry" );
144 case MXIT_MOOD_EXCITED :
145 return _( "Excited" );
146 case MXIT_MOOD_GRUMPY :
147 return _( "Grumpy" );
148 case MXIT_MOOD_HAPPY :
149 return _( "Happy" );
150 case MXIT_MOOD_INLOVE :
151 return _( "In Love" );
152 case MXIT_MOOD_INVINCIBLE :
153 return _( "Invincible" );
154 case MXIT_MOOD_SAD :
155 return _( "Sad" );
156 case MXIT_MOOD_HOT :
157 return _( "Hot" );
158 case MXIT_MOOD_SICK :
159 return _( "Sick" );
160 case MXIT_MOOD_SLEEPY :
161 return _( "Sleepy" );
162 case MXIT_MOOD_NONE :
163 default :
164 return "";
165 }
166 }
167
168
169 /*========================================================================================================================
170 * Subscription Types
171 */
172
173 /*------------------------------------------------------------------------
174 * Returns a Contact subscription type as a string.
175 *
176 * @param subtype The subscription type
177 * @return The subscription type as a text string
178 */
179 const char* mxit_convert_subtype_to_name( short subtype )
180 {
181 switch ( subtype ) {
182 case MXIT_SUBTYPE_BOTH :
183 return _( "Both" );
184 case MXIT_SUBTYPE_PENDING :
185 return _( "Pending" );
186 case MXIT_SUBTYPE_ASK :
187 return _( "Invited" );
188 case MXIT_SUBTYPE_REJECTED :
189 return _( "Rejected" );
190 case MXIT_SUBTYPE_DELETED :
191 return _( "Deleted" );
192 case MXIT_SUBTYPE_NONE :
193 return _( "None" );
194 default :
195 return "";
196 }
197 }
198
199
200 /*========================================================================================================================
201 * Calls from the MXit Protocol layer
202 */
203
204 #if 0
205 /*------------------------------------------------------------------------
206 * Dump a contact's info the the debug console.
207 *
208 * @param contact The contact
209 */
210 static void dump_contact( struct contact* contact )
211 {
212 purple_debug_info( MXIT_PLUGIN_ID, "CONTACT: name='%s', alias='%s', group='%s', type='%i', presence='%i', mood='%i'\n",
213 contact->username, contact->alias, contact->groupname, contact->type, contact->presence, contact->mood );
214 }
215 #endif
216
217
218 #if 0
219 /*------------------------------------------------------------------------
220 * Move a buddy from one group to another
221 *
222 * @param buddy the buddy to move between groups
223 * @param group the new group to move the buddy to
224 */
225 static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, PurpleBuddy* buddy, PurpleGroup* group )
226 {
227 struct contact* contact = NULL;
228 PurpleGroup* current_group = purple_buddy_get_group( buddy );
229 PurpleBuddy* newbuddy = NULL;
230
231 /* make sure the groups actually differs */
232 if ( strcmp( current_group->name, group->name ) != 0 ) {
233 /* groupnames does not match, so we need to make the update */
234
235 purple_debug_info( MXIT_PLUGIN_ID, "Moving '%s' from group '%s' to '%s'\n", buddy->alias, current_group->name, group->name );
236
237 /*
238 * XXX: libPurple does not currently provide an API to change or rename the group name
239 * for a specific buddy. One option is to remove the buddy from the list and re-adding
240 * him in the new group, but by doing that makes the buddy go offline and then online
241 * again. This is really not ideal and very iretating, but how else then?
242 */
243
244 /* create new buddy */
245 newbuddy = purple_buddy_new( session->acc, buddy->name, buddy->alias );
246 newbuddy->proto_data = buddy->proto_data;
247 buddy->proto_data = NULL;
248
249 /* remove the buddy */
250 purple_blist_remove_buddy( buddy );
251
252 /* add buddy */
253 purple_blist_add_buddy( newbuddy, NULL, group, NULL );
254
255 /* now re-instate his presence again */
256 contact = newbuddy->proto_data;
257 if ( contact ) {
258
259 /* update the buddy's status (reference: "libpurple/prpl.h") */
260 if ( contact->statusMsg )
261 purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL );
262 else
263 purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, NULL );
264
265 /* update avatar */
266 if ( contact->avatarId ) {
267 mxit_get_avatar( session, newbuddy->name, contact->avatarId );
268 g_free( contact->avatarId );
269 contact->avatarId = NULL;
270 }
271 }
272
273 return newbuddy;
274 }
275 else
276 return buddy;
277 }
278 #endif
279
280
281 /*------------------------------------------------------------------------
282 * A contact update packet was received from the MXit server, so update the buddy's
283 * information.
284 *
285 * @param session The MXit session object
286 * @param contact The contact
287 */
288 void mxit_update_contact( struct MXitSession* session, struct contact* contact )
289 {
290 PurpleBuddy* buddy = NULL;
291 PurpleGroup* group = NULL;
292 const char* id = NULL;
293
294 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_contact: user='%s' alias='%s' group='%s'\n", contact->username, contact->alias, contact->groupname );
295
296 /*
297 * libPurple requires all contacts to be in a group.
298 * So if this MXit contact isn't in a group, pretend it is.
299 */
300 if ( *contact->groupname == '\0' ) {
301 strcpy( contact->groupname, MXIT_DEFAULT_GROUP );
302 }
303
304 /* find or create a group for this contact */
305 group = purple_find_group( contact->groupname );
306 if ( !group )
307 group = purple_group_new( contact->groupname );
308
309 /* see if the buddy is not in the group already */
310 buddy = purple_find_buddy_in_group( session->acc, contact->username, group );
311 if ( !buddy ) {
312 /* buddy not found in the group */
313
314 /* lets try finding him in all groups */
315 buddy = purple_find_buddy( session->acc, contact->username );
316 if ( buddy ) {
317 /* ok, so we found him in another group. to switch him between groups we must delete him and add him again. */
318 purple_blist_remove_buddy( buddy );
319 buddy = NULL;
320 }
321
322 /* create new buddy */
323 buddy = purple_buddy_new( session->acc, contact->username, contact->alias );
324 buddy->proto_data = contact;
325
326 /* add new buddy to list */
327 purple_blist_add_buddy( buddy, NULL, group, NULL );
328 }
329 else {
330 /* buddy was found in the group */
331
332 /* now update the buddy's alias */
333 purple_blist_alias_buddy( buddy, contact->alias );
334
335 /* replace the buddy's contact struct */
336 if ( buddy->proto_data )
337 free( buddy->proto_data );
338 buddy->proto_data = contact;
339 }
340
341 /* load buddy's avatar id */
342 id = purple_buddy_icons_get_checksum_for_user( buddy );
343 if ( id )
344 contact->avatarId = g_strdup( id );
345 else
346 contact->avatarId = NULL;
347
348 /* update the buddy's status (reference: "libpurple/prpl.h") */
349 purple_prpl_got_user_status( session->acc, contact->username, mxit_statuses[contact->presence].id, NULL );
350 }
351
352
353 /*------------------------------------------------------------------------
354 * A presence update packet was received from the MXit server, so update the buddy's
355 * information.
356 *
357 * @param session The MXit session object
358 * @param username The contact which presence to update
359 * @param presence The new presence state for the contact
360 * @param mood The new mood for the contact
361 * @param customMood The custom mood identifier
362 * @param statusMsg This is the contact's status message
363 * @param avatarId This is the contact's avatar id
364 */
365 void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, const char* avatarId )
366 {
367 PurpleBuddy* buddy = NULL;
368 struct contact* contact = NULL;
369
370 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: user='%s' presence=%i mood=%i customMood='%s' statusMsg='%s' avatar='%s'\n",
371 username, presence, mood, customMood, statusMsg, avatarId );
372
373 if ( ( presence < MXIT_PRESENCE_OFFLINE ) || ( presence > MXIT_PRESENCE_DND ) ) {
374 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: invalid presence state %i\n", presence );
375 return; /* ignore packet */
376 }
377
378 /* find the buddy information for this contact (reference: "libpurple/blist.h") */
379 buddy = purple_find_buddy( session->acc, username );
380 if ( !buddy ) {
381 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: unable to find the buddy '%s'\n", username );
382 return;
383 }
384
385 contact = buddy->proto_data;
386 if ( !contact )
387 return;
388
389 contact->presence = presence;
390 contact->mood = mood;
391
392 g_strlcpy( contact->customMood, customMood, sizeof( contact->customMood ) );
393 // TODO: Download custom mood frame.
394
395 /* update status message */
396 if ( contact->statusMsg ) {
397 g_free( contact->statusMsg );
398 contact->statusMsg = NULL;
399 }
400 if ( statusMsg[0] != '\0' )
401 contact->statusMsg = g_strdup( statusMsg );
402
403 /* update avatarId */
404 if ( ( contact->avatarId ) && ( g_ascii_strcasecmp( contact->avatarId, avatarId ) == 0 ) ) {
405 /* avatar has not changed - do nothing */
406 }
407 else if ( avatarId[0] != '\0' ) { /* avatar has changed */
408 if ( contact->avatarId )
409 g_free( contact->avatarId );
410 contact->avatarId = g_strdup( avatarId );
411
412 /* Send request to download new avatar image */
413 mxit_get_avatar( session, username, avatarId );
414 }
415 else /* clear current avatar */
416 purple_buddy_icons_set_for_user( session->acc, username, NULL, 0, NULL );
417
418 /* update the buddy's status (reference: "libpurple/prpl.h") */
419 if ( contact->statusMsg )
420 purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL );
421 else
422 purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL );
423 }
424
425
426 /*------------------------------------------------------------------------
427 * update the blist cached by libPurple. We need to do this to keep
428 * libPurple and MXit's rosters in sync with each other.
429 *
430 * @param session The MXit session object
431 */
432 void mxit_update_blist( struct MXitSession* session )
433 {
434 PurpleBuddy* buddy = NULL;
435 GSList* list = NULL;
436 unsigned int i;
437
438 /* remove all buddies we did not receive a roster update for.
439 * these contacts must have been removed from another client */
440 list = purple_find_buddies( session->acc, NULL );
441
442 for ( i = 0; i < g_slist_length( list ); i++ ) {
443 buddy = g_slist_nth_data( list, i );
444
445 if ( !buddy->proto_data ) {
446 /* this buddy should be removed, because we did not receive him in our roster update from MXit */
447 purple_debug_info( MXIT_PLUGIN_ID, "Removed 'old' buddy from the blist '%s' (%s)\n", buddy->alias, buddy->name );
448 purple_blist_remove_buddy( buddy );
449 }
450 }
451
452 /* tell the UI to update the blist */
453 purple_blist_add_account( session->acc );
454 }
455
456
457 /*------------------------------------------------------------------------
458 * The user authorized an invite (subscription request).
459 *
460 * @param user_data Object associated with the invite
461 */
462 static void mxit_cb_buddy_auth( gpointer user_data )
463 {
464 struct contact_invite* invite = (struct contact_invite*) user_data;
465
466 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_buddy_auth '%s'\n", invite->contact->username );
467
468 /* send a allow subscription packet to MXit */
469 mxit_send_allow_sub( invite->session, invite->contact->username, invite->contact->alias );
470
471 /* freeup invite object */
472 if ( invite->contact->msg )
473 g_free( invite->contact->msg );
474 g_free( invite->contact );
475 g_free( invite );
476 }
477
478
479 /*------------------------------------------------------------------------
480 * The user rejected an invite (subscription request).
481 *
482 * @param user_data Object associated with the invite
483 */
484 static void mxit_cb_buddy_deny( gpointer user_data )
485 {
486 struct contact_invite* invite = (struct contact_invite*) user_data;
487
488 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_buddy_deny '%s'\n", invite->contact->username );
489
490 /* send a deny subscription packet to MXit */
491 mxit_send_deny_sub( invite->session, invite->contact->username );
492
493 /* freeup invite object */
494 if ( invite->contact->msg )
495 g_free( invite->contact->msg );
496 g_free( invite->contact );
497 g_free( invite );
498 }
499
500
501 /*------------------------------------------------------------------------
502 * A new subscription request packet was received from the MXit server.
503 * Prompt user to accept or reject it.
504 *
505 * @param session The MXit session object
506 * @param contact The contact performing the invite
507 */
508 void mxit_new_subscription( struct MXitSession* session, struct contact* contact )
509 {
510 struct contact_invite* invite;
511
512 purple_debug_info( MXIT_PLUGIN_ID, "mxit_new_subscription from '%s' (%s)\n", contact->username, contact->alias );
513
514 invite = g_new0( struct contact_invite, 1 );
515 invite->session = session;
516 invite->contact = contact;
517
518 /* (reference: "libpurple/account.h") */
519 purple_account_request_authorization( session->acc, contact->username, NULL, contact->alias, contact->msg, FALSE, mxit_cb_buddy_auth, mxit_cb_buddy_deny, invite );
520 }
521
522
523 /*------------------------------------------------------------------------
524 * Return TRUE if this is a MXit Chatroom contact.
525 *
526 * @param session The MXit session object
527 * @param username The username of the contact
528 */
529 gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* username )
530 {
531 PurpleBuddy* buddy;
532 struct contact* contact = NULL;
533
534 /* find the buddy */
535 buddy = purple_find_buddy( session->acc, username );
536 if ( !buddy ) {
537 purple_debug_warning( MXIT_PLUGIN_ID, "is_mxit_chatroom_contact: unable to find the buddy '%s'\n", username );
538 return FALSE;
539 }
540
541 contact = buddy->proto_data;
542 if ( !contact )
543 return FALSE;
544
545 return ( contact->type == MXIT_TYPE_CHATROOM );
546 }
547
548
549 /*========================================================================================================================
550 * Callbacks from libpurple
551 */
552
553 /*------------------------------------------------------------------------
554 * The user has added a buddy to the list, so send an invite request.
555 *
556 * @param gc The connection object
557 * @param buddy The new buddy
558 * @param group The group of the new buddy
559 */
560 void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group )
561 {
562 struct MXitSession* session = (struct MXitSession*) gc->proto_data;
563 GSList* list = NULL;
564 PurpleBuddy* mxbuddy = NULL;
565 unsigned int i;
566
567 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy '%s' (group='%s')\n", buddy->name, group->name );
568
569 list = purple_find_buddies( session->acc, buddy->name );
570 if ( g_slist_length( list ) == 1 ) {
571 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 1) (list:%i)\n", g_slist_length( list ) );
572 /*
573 * we only send an invite to MXit when the user is not already inside our
574 * blist. this is done because purple does an add_buddy() call when
575 * you accept an invite. so in that case the user is already
576 * in our blist and ready to be chatted to.
577 */
578 mxit_send_invite( session, buddy->name, buddy->alias, group->name );
579 }
580 else {
581 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 2) (list:%i)\n", g_slist_length( list ) );
582 /*
583 * we already have the buddy in our list, so we will only update
584 * his information here and not send another invite message
585 */
586
587 /* find the correct buddy */
588 for ( i = 0; i < g_slist_length( list ); i++ ) {
589 mxbuddy = g_slist_nth_data( list, i );
590
591 if ( mxbuddy->proto_data != NULL ) {
592 /* this is our REAL MXit buddy! */
593
594 /* now update the buddy's alias */
595 purple_blist_alias_buddy( mxbuddy, buddy->alias );
596
597 /* now update the buddy's group */
598 // mxbuddy = mxit_update_buddy_group( session, mxbuddy, group );
599
600 /* send the update to the MXit server */
601 mxit_send_update_contact( session, mxbuddy->name, mxbuddy->alias, group->name );
602 }
603 }
604 }
605
606 /*
607 * we remove the buddy here from the buddy list because the MXit server
608 * will send us a proper contact update packet if this succeeds. now
609 * we do not have to worry about error handling in case of adding an
610 * invalid contact. so the user will still see the contact as offline
611 * until he eventually accepts the invite.
612 */
613 purple_blist_remove_buddy( buddy );
614
615 g_slist_free( list );
616 }
617
618
619 /*------------------------------------------------------------------------
620 * The user has removed a buddy from the list.
621 *
622 * @param gc The connection object
623 * @param buddy The buddy being removed
624 * @param group The group the buddy was in
625 */
626 void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group )
627 {
628 struct MXitSession* session = (struct MXitSession*) gc->proto_data;
629
630 purple_debug_info( MXIT_PLUGIN_ID, "mxit_remove_buddy '%s'\n", buddy->name );
631
632 mxit_send_remove( session, buddy->name );
633 }
634
635
636 /*------------------------------------------------------------------------
637 * The user changed the buddy's alias.
638 *
639 * @param gc The connection object
640 * @param who The username of the buddy
641 * @param alias The new alias
642 */
643 void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias )
644 {
645 struct MXitSession* session = (struct MXitSession*) gc->proto_data;
646 PurpleBuddy* buddy = NULL;
647 PurpleGroup* group = NULL;
648
649 purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_alias '%s' to '%s\n", who, alias );
650
651 /* find the buddy */
652 buddy = purple_find_buddy( session->acc, who );
653 if ( !buddy ) {
654 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_alias: unable to find the buddy '%s'\n", who );
655 return;
656 }
657
658 /* find buddy group */
659 group = purple_buddy_get_group( buddy );
660 if ( !group ) {
661 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_alias: unable to find the group for buddy '%s'\n", who );
662 return;
663 }
664
665 mxit_send_update_contact( session, who, alias, group->name );
666 }
667
668
669 /*------------------------------------------------------------------------
670 * The user changed the group for a single buddy.
671 *
672 * @param gc The connection object
673 * @param who The username of the buddy
674 * @param old_group The old group's name
675 * @param new_group The new group's name
676 */
677 void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group )
678 {
679 struct MXitSession* session = (struct MXitSession*) gc->proto_data;
680 PurpleBuddy* buddy = NULL;
681
682 purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_group from '%s' to '%s'\n", old_group, new_group );
683
684 /* find the buddy */
685 buddy = purple_find_buddy( session->acc, who );
686 if ( !buddy ) {
687 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_group: unable to find the buddy '%s'\n", who );
688 return;
689 }
690
691 mxit_send_update_contact( session, who, buddy->alias, new_group );
692 }
693
694
695 /*------------------------------------------------------------------------
696 * The user has selected to rename a group, so update all contacts in that
697 * group.
698 *
699 * @param gc The connection object
700 * @param old_name The old group name
701 * @param group The updated group object
702 * @param moved_buddies The buddies affected by the rename
703 */
704 void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies )
705 {
706 struct MXitSession* session = (struct MXitSession*) gc->proto_data;
707 PurpleBuddy* buddy = NULL;
708 GList* item = NULL;
709
710 purple_debug_info( MXIT_PLUGIN_ID, "mxit_rename_group from '%s' to '%s\n", old_name, group->name );
711
712 // TODO: Might be more efficient to use the "rename group" command (cmd=29).
713
714 /* loop through all the contacts in the group and send updates */
715 item = moved_buddies;
716 while ( item ) {
717 buddy = item->data;
718 mxit_send_update_contact( session, buddy->name, buddy->alias, group->name );
719 item = g_list_next( item );
720 }
721 }
722