src/pounce.c

changeset 5866
5caedbcd1bb7
parent 5864
86822afeeab0
child 5872
754c63f29b77
equal deleted inserted replaced
5865:5b358b960d7d 5866:5caedbcd1bb7
18 * You should have received a copy of the GNU General Public License 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 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 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21 *
22 */ 22 */
23 #include <stdio.h>
24 #include <stdlib.h>
23 #include <string.h> 25 #include <string.h>
24 #include "gaim.h" 26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <glib.h>
29
30 #include "debug.h"
31 #include "pounce.h"
32 #include "util.h"
25 33
26 typedef struct 34 typedef struct
27 { 35 {
28 char *name; 36 char *name;
29 37
32 GHashTable *atts; 40 GHashTable *atts;
33 41
34 } GaimPounceActionData; 42 } GaimPounceActionData;
35 43
36 44
37 static GList *pounces = NULL; 45 static GList *pounces = NULL;
46 static guint pounces_save_timer = 0;
47 static gboolean pounces_loaded = FALSE;
38 48
39 static GaimPounceActionData * 49 static GaimPounceActionData *
40 find_action_data(const GaimPounce *pounce, const char *name) 50 find_action_data(const GaimPounce *pounce, const char *name)
41 { 51 {
42 GaimPounceActionData *action; 52 GaimPounceActionData *action;
57 g_free(action_data->name); 67 g_free(action_data->name);
58 68
59 g_hash_table_destroy(action_data->atts); 69 g_hash_table_destroy(action_data->atts);
60 70
61 g_free(action_data); 71 g_free(action_data);
72 }
73
74 static gboolean
75 pounces_save_cb(gpointer unused)
76 {
77 gaim_pounces_sync();
78 pounces_save_timer = 0;
79
80 return FALSE;
81 }
82
83 static void
84 schedule_pounces_save(void)
85 {
86 if (!pounces_save_timer)
87 pounces_save_timer = g_timeout_add(5000, pounces_save_cb, NULL);
62 } 88 }
63 89
64 GaimPounce * 90 GaimPounce *
65 gaim_pounce_new(const char *ui_type, GaimAccount *pouncer, 91 gaim_pounce_new(const char *ui_type, GaimAccount *pouncer,
66 const char *pouncee, GaimPounceEvent event, 92 const char *pouncee, GaimPounceEvent event,
106 132
107 if (pounce->free != NULL && pounce->data != NULL) 133 if (pounce->free != NULL && pounce->data != NULL)
108 pounce->free(pounce->data); 134 pounce->free(pounce->data);
109 135
110 g_free(pounce); 136 g_free(pounce);
137
138 schedule_pounces_save();
111 } 139 }
112 140
113 void 141 void
114 gaim_pounce_set_events(GaimPounce *pounce, GaimPounceEvent events) 142 gaim_pounce_set_events(GaimPounce *pounce, GaimPounceEvent events)
115 { 143 {
116 g_return_if_fail(pounce != NULL); 144 g_return_if_fail(pounce != NULL);
117 g_return_if_fail(pounce != GAIM_POUNCE_NONE); 145 g_return_if_fail(pounce != GAIM_POUNCE_NONE);
118 146
119 pounce->events = events; 147 pounce->events = events;
148
149 schedule_pounces_save();
120 } 150 }
121 151
122 void 152 void
123 gaim_pounce_set_pouncer(GaimPounce *pounce, GaimAccount *pouncer) 153 gaim_pounce_set_pouncer(GaimPounce *pounce, GaimAccount *pouncer)
124 { 154 {
125 g_return_if_fail(pounce != NULL); 155 g_return_if_fail(pounce != NULL);
126 g_return_if_fail(pouncer != NULL); 156 g_return_if_fail(pouncer != NULL);
127 157
128 pounce->pouncer = pouncer; 158 pounce->pouncer = pouncer;
159
160 schedule_pounces_save();
129 } 161 }
130 162
131 void 163 void
132 gaim_pounce_set_pouncee(GaimPounce *pounce, const char *pouncee) 164 gaim_pounce_set_pouncee(GaimPounce *pounce, const char *pouncee)
133 { 165 {
136 168
137 if (pounce->pouncee != NULL) 169 if (pounce->pouncee != NULL)
138 g_free(pounce->pouncee); 170 g_free(pounce->pouncee);
139 171
140 pounce->pouncee = (pouncee == NULL ? NULL : g_strdup(pouncee)); 172 pounce->pouncee = (pouncee == NULL ? NULL : g_strdup(pouncee));
173
174 schedule_pounces_save();
141 } 175 }
142 176
143 void 177 void
144 gaim_pounce_set_save(GaimPounce *pounce, gboolean save) 178 gaim_pounce_set_save(GaimPounce *pounce, gboolean save)
145 { 179 {
146 g_return_if_fail(pounce != NULL); 180 g_return_if_fail(pounce != NULL);
147 181
148 pounce->save = save; 182 pounce->save = save;
183
184 schedule_pounces_save();
149 } 185 }
150 186
151 void 187 void
152 gaim_pounce_action_register(GaimPounce *pounce, const char *name) 188 gaim_pounce_action_register(GaimPounce *pounce, const char *name)
153 { 189 {
162 action_data->enabled = FALSE; 198 action_data->enabled = FALSE;
163 action_data->atts = g_hash_table_new_full(g_str_hash, g_str_equal, 199 action_data->atts = g_hash_table_new_full(g_str_hash, g_str_equal,
164 g_free, g_free); 200 g_free, g_free);
165 201
166 g_hash_table_insert(pounce->actions, g_strdup(name), action_data); 202 g_hash_table_insert(pounce->actions, g_strdup(name), action_data);
203
204 schedule_pounces_save();
167 } 205 }
168 206
169 void 207 void
170 gaim_pounce_action_set_enabled(GaimPounce *pounce, const char *action, 208 gaim_pounce_action_set_enabled(GaimPounce *pounce, const char *action,
171 gboolean enabled) 209 gboolean enabled)
178 action_data = find_action_data(pounce, action); 216 action_data = find_action_data(pounce, action);
179 217
180 g_return_if_fail(action_data != NULL); 218 g_return_if_fail(action_data != NULL);
181 219
182 action_data->enabled = enabled; 220 action_data->enabled = enabled;
221
222 schedule_pounces_save();
183 } 223 }
184 224
185 void 225 void
186 gaim_pounce_action_set_attribute(GaimPounce *pounce, const char *action, 226 gaim_pounce_action_set_attribute(GaimPounce *pounce, const char *action,
187 const char *attr, const char *value) 227 const char *attr, const char *value)
199 if (value == NULL) 239 if (value == NULL)
200 g_hash_table_remove(action_data->atts, attr); 240 g_hash_table_remove(action_data->atts, attr);
201 else 241 else
202 g_hash_table_insert(action_data->atts, g_strdup(attr), 242 g_hash_table_insert(action_data->atts, g_strdup(attr),
203 g_strdup(value)); 243 g_strdup(value));
244
245 schedule_pounces_save();
204 } 246 }
205 247
206 void 248 void
207 gaim_pounce_set_data(GaimPounce *pounce, void *data) 249 gaim_pounce_set_data(GaimPounce *pounce, void *data)
208 { 250 {
292 334
293 g_return_if_fail(pouncer != NULL); 335 g_return_if_fail(pouncer != NULL);
294 g_return_if_fail(pouncee != NULL); 336 g_return_if_fail(pouncee != NULL);
295 g_return_if_fail(events != GAIM_POUNCE_NONE); 337 g_return_if_fail(events != GAIM_POUNCE_NONE);
296 338
297 for (l = gaim_get_pounces(); l != NULL; l = l_next) { 339 for (l = gaim_pounces_get_all(); l != NULL; l = l_next) {
298 pounce = (GaimPounce *)l->data; 340 pounce = (GaimPounce *)l->data;
299 l_next = l->next; 341 l_next = l->next;
300 342
301 if ((gaim_pounce_get_events(pounce) & events) && 343 if ((gaim_pounce_get_events(pounce) & events) &&
302 (gaim_pounce_get_pouncer(pounce) == pouncer) && 344 (gaim_pounce_get_pouncer(pounce) == pouncer) &&
321 363
322 g_return_val_if_fail(pouncer != NULL, NULL); 364 g_return_val_if_fail(pouncer != NULL, NULL);
323 g_return_val_if_fail(pouncee != NULL, NULL); 365 g_return_val_if_fail(pouncee != NULL, NULL);
324 g_return_val_if_fail(events != GAIM_POUNCE_NONE, NULL); 366 g_return_val_if_fail(events != GAIM_POUNCE_NONE, NULL);
325 367
326 for (l = gaim_get_pounces(); l != NULL; l = l->next) { 368 for (l = gaim_pounces_get_all(); l != NULL; l = l->next) {
327 pounce = (GaimPounce *)l->data; 369 pounce = (GaimPounce *)l->data;
328 370
329 if ((gaim_pounce_get_events(pounce) & events) && 371 if ((gaim_pounce_get_events(pounce) & events) &&
330 (gaim_pounce_get_pouncer(pounce) == pouncer) && 372 (gaim_pounce_get_pouncer(pounce) == pouncer) &&
331 !strcmp(gaim_pounce_get_pouncee(pounce), pouncee)) { 373 !strcmp(gaim_pounce_get_pouncee(pounce), pouncee)) {
335 } 377 }
336 378
337 return NULL; 379 return NULL;
338 } 380 }
339 381
382 gboolean
383 gaim_pounces_load(void)
384 {
385 pounces_loaded = TRUE;
386
387 return TRUE;
388 }
389
390 static void
391 write_action_parameter(gpointer key, gpointer value, gpointer user_data)
392 {
393 const char *name, *param_value;
394 FILE *fp;
395
396 param_value = (const char *)value;
397 name = (const char *)key;
398 fp = (FILE *)user_data;
399
400 fprintf(fp, " <param name='%s'>%s</param>\n", name, param_value);
401 }
402
403 static void
404 write_action_parameter_list(gpointer key, gpointer value, gpointer user_data)
405 {
406 GaimPounceActionData *action_data;
407 const char *action;
408 FILE *fp;
409
410 action_data = (GaimPounceActionData *)value;
411 action = (const char *)key;
412 fp = (FILE *)user_data;
413
414 if (!action_data->enabled)
415 return;
416
417 fprintf(fp, " <action type='%s'", action);
418
419 if (g_hash_table_size(action_data->atts) == 0) {
420 fprintf(fp, "/>\n");
421 }
422 else {
423 fprintf(fp, ">\n");
424
425 g_hash_table_foreach(action_data->atts, write_action_parameter, fp);
426
427 fprintf(fp, " </action>\n");
428 }
429 }
430
431 static void
432 gaim_pounces_write(FILE *fp, GaimPounce *pounce)
433 {
434 GaimAccount *pouncer;
435 GaimPounceEvent events;
436 char *pouncer_name;
437
438 pouncer = gaim_pounce_get_pouncer(pounce);
439 events = gaim_pounce_get_events(pounce);
440
441 pouncer_name = g_markup_escape_text(gaim_account_get_username(pouncer), -1);
442
443 fprintf(fp, " <pounce ui='%s'>\n", pounce->ui_type);
444 fprintf(fp, " <account protocol='%s'>%s</account>\n",
445 pouncer->protocol_id, pouncer_name);
446 fprintf(fp, " <pouncee>%s</pouncee>\n", gaim_pounce_get_pouncee(pounce));
447 fprintf(fp, " <events>\n");
448
449 if (events & GAIM_POUNCE_SIGNON)
450 fprintf(fp, " <event type='sign-on'>\n");
451 if (events & GAIM_POUNCE_SIGNOFF)
452 fprintf(fp, " <event type='sign-off'>\n");
453 if (events & GAIM_POUNCE_AWAY)
454 fprintf(fp, " <event type='away'>\n");
455 if (events & GAIM_POUNCE_AWAY_RETURN)
456 fprintf(fp, " <event type='return-from-away'>\n");
457 if (events & GAIM_POUNCE_IDLE)
458 fprintf(fp, " <event type='idle'>\n");
459 if (events & GAIM_POUNCE_IDLE_RETURN)
460 fprintf(fp, " <event type='return-from-idle'>\n");
461 if (events & GAIM_POUNCE_TYPING)
462 fprintf(fp, " <event type='start-typing'>\n");
463 if (events & GAIM_POUNCE_TYPING_STOPPED)
464 fprintf(fp, " <event type='stop-typing'>\n");
465
466 fprintf(fp, " </events>\n");
467 fprintf(fp, " <actions>\n");
468
469 g_hash_table_foreach(pounce->actions, write_action_parameter_list, fp);
470
471 fprintf(fp, " </actions>\n");
472 fprintf(fp, " </pounce>\n");
473
474 g_free(pouncer_name);
475 }
476
477 void
478 gaim_pounces_sync(void)
479 {
480 FILE *fp;
481 const char *user_dir = gaim_user_dir();
482 char *filename;
483 char *filename_real;
484
485 if (!pounces_loaded) {
486 gaim_debug(GAIM_DEBUG_WARNING, "pounces",
487 "Writing pounces to disk.\n");
488 schedule_pounces_save();
489 return;
490 }
491
492 if (user_dir == NULL)
493 return;
494
495 gaim_debug(GAIM_DEBUG_INFO, "pounces", "Writing pounces to disk.\n");
496
497 fp = fopen(user_dir, "r");
498
499 if (fp == NULL)
500 mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
501 else
502 fclose(fp);
503
504 filename = g_build_filename(user_dir, "pounces.xml.save", NULL);
505
506 if ((fp = fopen(filename, "w")) != NULL) {
507 GList *l;
508
509 fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
510 fprintf(fp, "<pounces>\n");
511
512 for (l = gaim_pounces_get_all(); l != NULL; l = l->next)
513 gaim_pounces_write(fp, l->data);
514
515 fprintf(fp, "</pounces>\n");
516
517 fclose(fp);
518 chmod(filename, S_IRUSR | S_IWUSR);
519 }
520 else {
521 gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Unable to write %s\n",
522 filename);
523 }
524
525 filename_real = g_build_filename(user_dir, "pounces.xml", NULL);
526
527 if (rename(filename, filename_real) < 0) {
528 gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Error renaming %s to %s\n",
529 filename, filename_real);
530 }
531
532 g_free(filename);
533 g_free(filename_real);
534 }
535
340 GList * 536 GList *
341 gaim_get_pounces(void) 537 gaim_pounces_get_all(void)
342 { 538 {
343 return pounces; 539 return pounces;
344 } 540 }

mercurial