Mercurial > pidgin
diff src/status.c @ 10337:682201b69107
[gaim-migrate @ 11545]
* Preliminary reading of status.xml using xmlnode.[h|c]
* I made a few changes the blist.xml readering code that I think makes
it cleaner
* "gaim_statuses_find_saved" makes more sense to me than
"gaim_statuses_find_stored"
* struct GaimStatus isn't really supposed to be used for keeping the
saved statuses, is it? I don't see how that would work. It seems
to make more sense to have a separate data structure for it. Maybe
I'm not seeing things clearly.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 09 Dec 2004 03:55:19 +0000 |
parents | 2a132b73a6e6 |
children | 84d73473c019 |
line wrap: on
line diff
--- a/src/status.c Thu Dec 09 03:10:30 2004 +0000 +++ b/src/status.c Thu Dec 09 03:55:19 2004 +0000 @@ -26,9 +26,11 @@ #include "blist.h" #include "debug.h" +#include "notify.h" #include "prefs.h" #include "status.h" #include "util.h" +#include "xmlnode.h" /** * A type of status. @@ -120,30 +122,32 @@ char *name; } GaimStatusBuddyKey; - -#if 0 -static GList *stored_statuses = NULL; - -/* - * XXX This stuff should be removed in a few versions. It stores the - * old v1 status stuff so we can write it later. We don't write out - * the new status stuff, though. These should all die soon, as the - * old status.xml was created before the new status system's design - * was created. +/** + * The information of a snap-shot of the statuses of all + * your accounts. Basically these are your saved away messages. + * There is an overall status and message that applies to + * all your accounts, and then each individual account can + * optionally have a different custom status and message. * - * -- ChipX86 + * The changes to status.xml caused by the new status API + * are fully backward compatible. The new status API just + * adds the optional sub-statuses to the XML file. */ -typedef struct +struct _GaimStatusSaved { char *name; - char *state; + GaimStatusType *type; char *message; -} GaimStatusV1Info; + GList *individual; /**< A list of GaimStatusSavedSub's. */ +}; -static GList *v1_statuses = NULL; -#endif - +struct _GaimStatusSavedSub +{ + GaimAccount *account; + GaimStatusType *type; + char *message; +}; static int primitive_scores[] = { @@ -160,6 +164,7 @@ }; static GHashTable *buddy_presences = NULL; +static GList *saved_statuses = NULL; #define SCORE_IDLE 5 #define SCORE_IDLE_TIME 6 @@ -1645,15 +1650,21 @@ } const GList * -gaim_statuses_get_stored(void) +gaim_statuses_get_saved(void) +{ + return saved_statuses; +} + +GaimStatusSaved * +gaim_statuses_find_saved(const GaimStatusType *status_type, const char *id) { return NULL; } -GaimStatus * -gaim_statuses_find_stored(const GaimStatusType *status_type, const char *id) +const char * +gaim_statuses_saved_get_name(const GaimStatusSaved *saved_status) { - return NULL; + return saved_status->name; } void * @@ -1723,7 +1734,132 @@ { } +/** + * Parse a saved status and add it to the saved_statuses linked list. + * + * Here's an example of the XML for a saved status: + * <status name="Girls"> + * <state>away</state> + * <message>I like the way that they walk + * And it's chill to hear them talk + * And I can always make them smile + * From White Castle to the Nile</message> + * </status> + * + * I know. Moving, huh? + * + * TODO: Make sure the name is unique before adding it to the linked list. + */ +static void +gaim_statuses_read_parse_status(xmlnode *status) +{ + xmlnode *node; + const char *name, *state, *message; + GaimStatusSaved *new; + + name = xmlnode_get_attrib(status, "name"); + if (name == NULL) + name = "TODO: Make up something unique"; + + node = xmlnode_get_child(status, "state"); + if (node != NULL) { + state = xmlnode_get_data(node); + } + + node = xmlnode_get_child(status, "message"); + if (node != NULL) { + message = xmlnode_get_data(node); + } + + /* TODO: Need to read in substatuses here */ + + new = g_new0(GaimStatusSaved, 1); + + new->name = g_strdup(name); + /* TODO: Need to set type based on "state" */ + new->type = NULL; + if (message != NULL) + new->message = g_strdup(message); + + saved_statuses = g_list_append(saved_statuses, new); +} + +/** + * @return TRUE on success, FALSE on failure (if the file can not + * be opened, or if it contains invalid XML). + */ +gboolean +gaim_statuses_read(const char *filename) +{ + GError *error; + gchar *contents = NULL; + gsize length; + xmlnode *statuses, *status; + + gaim_debug_info("status", "Reading %s\n", filename); + + if (!g_file_get_contents(filename, &contents, &length, &error)) { + gaim_debug_error("status", "Error reading status.xml: %s\n", + error->message); + g_error_free(error); + return FALSE; + } + + statuses = xmlnode_from_str(contents, length); + + if (statuses == NULL) { + FILE *backup; + gchar *name; + gaim_debug_error("status", "Error parsing status.xml\n"); + name = g_build_filename(gaim_user_dir(), "status.xml~", NULL); + if ((backup = fopen(name, "w"))) { + fwrite(contents, length, 1, backup); + fclose(backup); + chmod(name, S_IRUSR | S_IWUSR); + } else { + gaim_debug_error("status", "Unable to write backup %s\n", name); + } + g_free(name); + g_free(contents); + return FALSE; + } + + g_free(contents); + + for (status = xmlnode_get_child(statuses, "status"); status != NULL; + status = xmlnode_get_next_twin(status)) { + gaim_statuses_read_parse_status(status); + } + + gaim_debug_info("status", "Finished reading status.xml\n"); + + xmlnode_free(statuses); + + return TRUE; +} + void gaim_statuses_load(void) { + const char *user_dir = gaim_user_dir(); + gchar *filename; + gchar *msg; + + if (user_dir == NULL) + return; + + filename = g_build_filename(user_dir, "status.xml", NULL); + + if (g_file_test(filename, G_FILE_TEST_EXISTS)) { + if (!gaim_statuses_read(filename)) { + msg = g_strdup_printf(_("An error was encountered parsing the " + "file containing your saved statuses (%s). They " + "have not been loaded, and the old file has been " + "renamed to status.xml~."), filename); + gaim_notify_error(NULL, NULL, _("Saved Statuses Error"), msg); + g_free(msg); + } + } + + g_free(filename); }