Mercurial > pidgin.yaz
comparison libpurple/protocols/mxit/actions.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 | 0fd6d016c474 |
comparison
equal
deleted
inserted
replaced
28901:13e668ef158d | 28903:69aa4660401a |
---|---|
1 /* | |
2 * MXit Protocol libPurple Plugin | |
3 * | |
4 * -- handle MXit plugin actions -- | |
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 <stdlib.h> | |
28 #include <string.h> | |
29 #include <time.h> | |
30 | |
31 #include "purple.h" | |
32 | |
33 #include "protocol.h" | |
34 #include "mxit.h" | |
35 #include "roster.h" | |
36 #include "actions.h" | |
37 #include "splashscreen.h" | |
38 #include "cipher.h" | |
39 #include "profile.h" | |
40 | |
41 | |
42 /* MXit Moods */ | |
43 static const char* moods[] = { | |
44 /* 0 */ "None", | |
45 /* 1 */ "Angry", | |
46 /* 2 */ "Excited", | |
47 /* 3 */ "Grumpy", | |
48 /* 4 */ "Happy", | |
49 /* 5 */ "In Love", | |
50 /* 6 */ "Invincible", | |
51 /* 7 */ "Sad", | |
52 /* 8 */ "Hot", | |
53 /* 9 */ "Sick", | |
54 /* 10 */ "Sleepy" | |
55 }; | |
56 | |
57 | |
58 /*------------------------------------------------------------------------ | |
59 * The user has selected to change their current mood. | |
60 * | |
61 * @param gc The connection object | |
62 * @param fields The fields from the request pop-up | |
63 */ | |
64 static void mxit_cb_set_mood( PurpleConnection* gc, PurpleRequestFields* fields ) | |
65 { | |
66 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
67 int mood = purple_request_fields_get_choice( fields, "mood" ); | |
68 | |
69 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_set_mood (%i)\n", mood ); | |
70 | |
71 if ( !PURPLE_CONNECTION_IS_VALID( gc ) ) { | |
72 purple_debug_error( MXIT_PLUGIN_ID, "Unable to set mood; account offline.\n" ); | |
73 return; | |
74 } | |
75 | |
76 /* Save the new mood in session */ | |
77 session->mood = mood; | |
78 | |
79 /* now send the update to MXit */ | |
80 mxit_send_mood( session, mood ); | |
81 } | |
82 | |
83 | |
84 /*------------------------------------------------------------------------ | |
85 * Create and display the mood selection window to the user. | |
86 * | |
87 * @param action The action object | |
88 */ | |
89 static void mxit_cb_action_mood( PurplePluginAction* action ) | |
90 { | |
91 PurpleConnection* gc = (PurpleConnection*) action->context; | |
92 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
93 | |
94 PurpleRequestFields* fields = NULL; | |
95 PurpleRequestFieldGroup* group = NULL; | |
96 PurpleRequestField* field = NULL; | |
97 unsigned int i = 0; | |
98 | |
99 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_action_mood\n" ); | |
100 | |
101 fields = purple_request_fields_new(); | |
102 group = purple_request_field_group_new( NULL ); | |
103 purple_request_fields_add_group( fields, group ); | |
104 | |
105 /* show current mood */ | |
106 field = purple_request_field_string_new( "current", _( "Current Mood" ), _( moods[session->mood] ), FALSE ); | |
107 purple_request_field_string_set_editable( field, FALSE ); /* current mood field is not editable */ | |
108 purple_request_field_group_add_field( group, field ); | |
109 | |
110 /* add all moods to list */ | |
111 field = purple_request_field_choice_new( "mood", _( "New Mood" ), 0 ); | |
112 for ( i = 0; i < ARRAY_SIZE( moods ); i++ ) { | |
113 purple_request_field_choice_add( field, _( moods[i] ) ); | |
114 } | |
115 purple_request_field_set_required( field, TRUE ); | |
116 purple_request_field_choice_set_default_value( field, session->mood ); | |
117 purple_request_field_group_add_field( group, field ); | |
118 | |
119 /* (reference: "libpurple/request.h") */ | |
120 purple_request_fields( gc, _( "Mood" ), _( "Change your Mood" ), _( "How do you feel right now?" ), fields, _( "Set" ), | |
121 G_CALLBACK( mxit_cb_set_mood ), _( "Cancel" ), NULL, purple_connection_get_account( gc ), NULL, NULL, gc ); | |
122 } | |
123 | |
124 | |
125 /*------------------------------------------------------------------------ | |
126 * The user has selected to change their profile. | |
127 * | |
128 * @param gc The connection object | |
129 * @param fields The fields from the request pop-up | |
130 */ | |
131 static void mxit_cb_set_profile( PurpleConnection* gc, PurpleRequestFields* fields ) | |
132 { | |
133 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
134 PurpleRequestField* field = NULL; | |
135 const char* pin = NULL; | |
136 const char* pin2 = NULL; | |
137 const char* name = NULL; | |
138 const char* bday = NULL; | |
139 const char* err = NULL; | |
140 int len; | |
141 int i; | |
142 | |
143 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_set_profile\n" ); | |
144 | |
145 if ( !PURPLE_CONNECTION_IS_VALID( gc ) ) { | |
146 purple_debug_error( MXIT_PLUGIN_ID, "Unable to update profile; account offline.\n" ); | |
147 return; | |
148 } | |
149 | |
150 /* validate pin */ | |
151 pin = purple_request_fields_get_string( fields, "pin" ); | |
152 if ( !pin ) { | |
153 err = "The PIN you entered is invalid."; | |
154 goto out; | |
155 } | |
156 len = strlen( pin ); | |
157 if ( ( len < 4 ) || ( len > 10 ) ) { | |
158 err = "The PIN you entered has an invalid length [4-10]."; | |
159 goto out; | |
160 } | |
161 for ( i = 0; i < len; i++ ) { | |
162 if ( !g_ascii_isdigit( pin[i] ) ) { | |
163 err = "The PIN is invalid. It should only consist of digits [0-9]."; | |
164 goto out; | |
165 } | |
166 } | |
167 pin2 = purple_request_fields_get_string( fields, "pin2" ); | |
168 if ( ( !pin2 ) || ( strcmp( pin, pin2 ) != 0 ) ) { | |
169 err = "The two PINs you entered does not match."; | |
170 goto out; | |
171 } | |
172 | |
173 /* validate name */ | |
174 name = purple_request_fields_get_string( fields, "name" ); | |
175 if ( ( !name ) || ( strlen( name ) < 3 ) ) { | |
176 err = "The name you entered is invalid."; | |
177 goto out; | |
178 } | |
179 | |
180 /* validate birthdate */ | |
181 bday = purple_request_fields_get_string( fields, "bday" ); | |
182 if ( ( !bday ) || ( strlen( bday ) < 10 ) || ( !validateDate( bday ) ) ) { | |
183 err = "The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."; | |
184 goto out; | |
185 } | |
186 | |
187 out: | |
188 if ( !err ) { | |
189 struct MXitProfile* profile = session->profile; | |
190 GString* attributes = g_string_sized_new( 128 ); | |
191 char attrib[512]; | |
192 unsigned int acount = 0; | |
193 | |
194 /* all good, so we can now update the profile */ | |
195 | |
196 /* update pin */ | |
197 purple_account_set_password( session->acc, pin ); | |
198 g_free( session->encpwd ); | |
199 session->encpwd = mxit_encrypt_password( session ); | |
200 | |
201 /* update name */ | |
202 g_strlcpy( profile->nickname, name, sizeof( profile->nickname ) ); | |
203 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FULLNAME, CP_PROF_TYPE_UTF8, profile->nickname ); | |
204 g_string_append( attributes, attrib ); | |
205 acount++; | |
206 | |
207 /* update hidden */ | |
208 field = purple_request_fields_get_field( fields, "hidden" ); | |
209 profile->hidden = purple_request_field_bool_get_value( field ); | |
210 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROF_TYPE_BOOL, ( profile->hidden ) ? "1" : "0" ); | |
211 g_string_append( attributes, attrib ); | |
212 acount++; | |
213 | |
214 /* update birthday */ | |
215 strcpy( profile->birthday, bday ); | |
216 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROF_TYPE_UTF8, profile->birthday ); | |
217 g_string_append( attributes, attrib ); | |
218 acount++; | |
219 | |
220 /* update gender */ | |
221 if ( purple_request_fields_get_choice( fields, "male" ) == 0 ) | |
222 profile->male = FALSE; | |
223 else | |
224 profile->male = TRUE; | |
225 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_GENDER, CP_PROF_TYPE_BOOL, ( profile->male ) ? "1" : "0" ); | |
226 g_string_append( attributes, attrib ); | |
227 acount++; | |
228 | |
229 /* update title */ | |
230 name = purple_request_fields_get_string( fields, "title" ); | |
231 if ( !name ) | |
232 profile->title[0] = '\0'; | |
233 else | |
234 strcpy( profile->title, name ); | |
235 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_TITLE, CP_PROF_TYPE_UTF8, profile->title ); | |
236 g_string_append( attributes, attrib ); | |
237 acount++; | |
238 | |
239 /* update firstname */ | |
240 name = purple_request_fields_get_string( fields, "firstname" ); | |
241 if ( !name ) | |
242 profile->firstname[0] = '\0'; | |
243 else | |
244 strcpy( profile->firstname, name ); | |
245 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FIRSTNAME, CP_PROF_TYPE_UTF8, profile->firstname ); | |
246 g_string_append( attributes, attrib ); | |
247 acount++; | |
248 | |
249 /* update lastname */ | |
250 name = purple_request_fields_get_string( fields, "lastname" ); | |
251 if ( !name ) | |
252 profile->lastname[0] = '\0'; | |
253 else | |
254 strcpy( profile->lastname, name ); | |
255 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_LASTNAME, CP_PROF_TYPE_UTF8, profile->lastname ); | |
256 g_string_append( attributes, attrib ); | |
257 acount++; | |
258 | |
259 /* update email address */ | |
260 name = purple_request_fields_get_string( fields, "email" ); | |
261 if ( !name ) | |
262 profile->email[0] = '\0'; | |
263 else | |
264 strcpy( profile->email, name ); | |
265 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_EMAIL, CP_PROF_TYPE_UTF8, profile->email ); | |
266 g_string_append( attributes, attrib ); | |
267 acount++; | |
268 | |
269 /* update mobile number */ | |
270 name = purple_request_fields_get_string( fields, "mobilenumber" ); | |
271 if ( !name ) | |
272 profile->mobilenr[0] = '\0'; | |
273 else | |
274 strcpy( profile->mobilenr, name ); | |
275 g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_MOBILENR, CP_PROF_TYPE_UTF8, profile->mobilenr ); | |
276 g_string_append( attributes, attrib ); | |
277 acount++; | |
278 | |
279 /* send the profile update to MXit */ | |
280 mxit_send_extprofile_update( session, session->encpwd, acount, attributes->str ); | |
281 g_string_free( attributes, TRUE ); | |
282 } | |
283 else { | |
284 /* show error to user */ | |
285 mxit_popup( PURPLE_NOTIFY_MSG_ERROR, _( "Profile Update Error" ), _( err ) ); | |
286 } | |
287 } | |
288 | |
289 | |
290 /*------------------------------------------------------------------------ | |
291 * Display and update the user's profile. | |
292 * | |
293 * @param action The action object | |
294 */ | |
295 static void mxit_cb_action_profile( PurplePluginAction* action ) | |
296 { | |
297 PurpleConnection* gc = (PurpleConnection*) action->context; | |
298 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
299 struct MXitProfile* profile = session->profile; | |
300 | |
301 PurpleRequestFields* fields = NULL; | |
302 PurpleRequestFieldGroup* group = NULL; | |
303 PurpleRequestField* field = NULL; | |
304 | |
305 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_action_profile\n" ); | |
306 | |
307 /* ensure that we actually have the user's profile information */ | |
308 if ( !profile ) { | |
309 /* no profile information yet, so we cannot update */ | |
310 mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Profile" ), _( "Your profile information is not yet retrieved. Please try again later." ) ); | |
311 return; | |
312 } | |
313 | |
314 fields = purple_request_fields_new(); | |
315 group = purple_request_field_group_new( NULL ); | |
316 purple_request_fields_add_group( fields, group ); | |
317 | |
318 /* pin */ | |
319 field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE ); | |
320 purple_request_field_string_set_masked( field, TRUE ); | |
321 purple_request_field_group_add_field( group, field ); | |
322 field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), session->acc->password, FALSE ); | |
323 purple_request_field_string_set_masked( field, TRUE ); | |
324 purple_request_field_group_add_field( group, field ); | |
325 | |
326 /* display name */ | |
327 field = purple_request_field_string_new( "name", _( "Display Name" ), profile->nickname, FALSE ); | |
328 purple_request_field_group_add_field( group, field ); | |
329 | |
330 /* birthday */ | |
331 field = purple_request_field_string_new( "bday", _( "Birthday" ), profile->birthday, FALSE ); | |
332 purple_request_field_group_add_field( group, field ); | |
333 | |
334 /* gender */ | |
335 field = purple_request_field_choice_new( "male", _( "Gender" ), ( profile->male ) ? 1 : 0 ); | |
336 purple_request_field_choice_add( field, _( "Female" ) ); /* 0 */ | |
337 purple_request_field_choice_add( field, _( "Male" ) ); /* 1 */ | |
338 purple_request_field_group_add_field( group, field ); | |
339 | |
340 /* hidden */ | |
341 field = purple_request_field_bool_new( "hidden", _( "Hide my number" ), profile->hidden ); | |
342 purple_request_field_group_add_field( group, field ); | |
343 | |
344 /* title */ | |
345 field = purple_request_field_string_new( "title", _( "Title" ), profile->title, FALSE ); | |
346 purple_request_field_group_add_field( group, field ); | |
347 | |
348 /* first name */ | |
349 field = purple_request_field_string_new( "firstname", _( "First Name" ), profile->firstname, FALSE ); | |
350 purple_request_field_group_add_field( group, field ); | |
351 | |
352 /* last name */ | |
353 field = purple_request_field_string_new( "lastname", _( "Last Name" ), profile->lastname, FALSE ); | |
354 purple_request_field_group_add_field( group, field ); | |
355 | |
356 /* email */ | |
357 field = purple_request_field_string_new( "email", _( "Email" ), profile->email, FALSE ); | |
358 purple_request_field_group_add_field( group, field ); | |
359 | |
360 /* mobile number */ | |
361 field = purple_request_field_string_new( "mobilenumber", _( "Mobile Number" ), profile->mobilenr, FALSE ); | |
362 purple_request_field_group_add_field( group, field ); | |
363 | |
364 /* (reference: "libpurple/request.h") */ | |
365 purple_request_fields( gc, _( "Profile" ), _( "Update your Profile" ), _( "Here you can update your MXit profile" ), fields, _( "Set" ), | |
366 G_CALLBACK( mxit_cb_set_profile ), _( "Cancel" ), NULL, purple_connection_get_account( gc ), NULL, NULL, gc ); | |
367 } | |
368 | |
369 | |
370 /*------------------------------------------------------------------------ | |
371 * Display the current splash-screen, or a notification pop-up if one is not available. | |
372 * | |
373 * @param action The action object | |
374 */ | |
375 static void mxit_cb_action_splash( PurplePluginAction* action ) | |
376 { | |
377 PurpleConnection* gc = (PurpleConnection*) action->context; | |
378 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
379 | |
380 if ( splash_current( session ) != NULL ) | |
381 splash_display( session ); | |
382 else | |
383 mxit_popup( PURPLE_NOTIFY_MSG_INFO, _( "View Splash" ), _( "There is no splash-screen currently available" ) ); | |
384 } | |
385 | |
386 | |
387 /*------------------------------------------------------------------------ | |
388 * Display info about the plugin. | |
389 * | |
390 * @param action The action object | |
391 */ | |
392 static void mxit_cb_action_about( PurplePluginAction* action ) | |
393 { | |
394 char version[256]; | |
395 | |
396 g_snprintf( version, sizeof( version ), "MXit libPurple Plugin v%s\n" | |
397 "MXit Client Protocol v%s\n\n" | |
398 "Author:\nPieter Loubser\n\n" | |
399 "Contributors:\nAndrew Victor\n\n" | |
400 "Testers:\nBraeme Le Roux\n\n", | |
401 MXIT_PLUGIN_VERSION, MXIT_CP_RELEASE ); | |
402 | |
403 mxit_popup( PURPLE_NOTIFY_MSG_INFO, _( "About" ), version ); | |
404 } | |
405 | |
406 | |
407 /*------------------------------------------------------------------------ | |
408 * Associate actions with the MXit plugin. | |
409 * | |
410 * @param plugin The MXit protocol plugin | |
411 * @param context The connection context (if available) | |
412 * @return The list of plugin actions | |
413 */ | |
414 GList* mxit_actions( PurplePlugin* plugin, gpointer context ) | |
415 { | |
416 PurplePluginAction* action = NULL; | |
417 GList* m = NULL; | |
418 | |
419 /* display / change mood */ | |
420 action = purple_plugin_action_new( _( "Change Mood..." ), mxit_cb_action_mood ); | |
421 m = g_list_append( m, action ); | |
422 | |
423 /* display / change profile */ | |
424 action = purple_plugin_action_new( _( "Change Profile..." ), mxit_cb_action_profile ); | |
425 m = g_list_append( m, action ); | |
426 | |
427 /* display splash-screen */ | |
428 action = purple_plugin_action_new( _( "View Splash..." ), mxit_cb_action_splash ); | |
429 m = g_list_append( m, action ); | |
430 | |
431 /* display plugin version */ | |
432 action = purple_plugin_action_new( _( "About..." ), mxit_cb_action_about ); | |
433 m = g_list_append( m, action ); | |
434 | |
435 return m; | |
436 } | |
437 |