comparison 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
comparison
equal deleted inserted replaced
10336:114d3ac8ff5a 10337:682201b69107
24 */ 24 */
25 #include "internal.h" 25 #include "internal.h"
26 26
27 #include "blist.h" 27 #include "blist.h"
28 #include "debug.h" 28 #include "debug.h"
29 #include "notify.h"
29 #include "prefs.h" 30 #include "prefs.h"
30 #include "status.h" 31 #include "status.h"
31 #include "util.h" 32 #include "util.h"
33 #include "xmlnode.h"
32 34
33 /** 35 /**
34 * A type of status. 36 * A type of status.
35 */ 37 */
36 struct _GaimStatusType 38 struct _GaimStatusType
118 { 120 {
119 GaimAccount *account; 121 GaimAccount *account;
120 char *name; 122 char *name;
121 } GaimStatusBuddyKey; 123 } GaimStatusBuddyKey;
122 124
123 125 /**
124 #if 0 126 * The information of a snap-shot of the statuses of all
125 static GList *stored_statuses = NULL; 127 * your accounts. Basically these are your saved away messages.
126 128 * There is an overall status and message that applies to
127 /* 129 * all your accounts, and then each individual account can
128 * XXX This stuff should be removed in a few versions. It stores the 130 * optionally have a different custom status and message.
129 * old v1 status stuff so we can write it later. We don't write out
130 * the new status stuff, though. These should all die soon, as the
131 * old status.xml was created before the new status system's design
132 * was created.
133 * 131 *
134 * -- ChipX86 132 * The changes to status.xml caused by the new status API
133 * are fully backward compatible. The new status API just
134 * adds the optional sub-statuses to the XML file.
135 */ 135 */
136 typedef struct 136 struct _GaimStatusSaved
137 { 137 {
138 char *name; 138 char *name;
139 char *state; 139 GaimStatusType *type;
140 char *message; 140 char *message;
141 141
142 } GaimStatusV1Info; 142 GList *individual; /**< A list of GaimStatusSavedSub's. */
143 143 };
144 static GList *v1_statuses = NULL; 144
145 #endif 145 struct _GaimStatusSavedSub
146 146 {
147 GaimAccount *account;
148 GaimStatusType *type;
149 char *message;
150 };
147 151
148 static int primitive_scores[] = 152 static int primitive_scores[] =
149 { 153 {
150 0, /* unset */ 154 0, /* unset */
151 -500, /* offline */ 155 -500, /* offline */
158 -10, /* idle, special case. */ 162 -10, /* idle, special case. */
159 -5 /* idle time, special case. */ 163 -5 /* idle time, special case. */
160 }; 164 };
161 165
162 static GHashTable *buddy_presences = NULL; 166 static GHashTable *buddy_presences = NULL;
167 static GList *saved_statuses = NULL;
163 168
164 #define SCORE_IDLE 5 169 #define SCORE_IDLE 5
165 #define SCORE_IDLE_TIME 6 170 #define SCORE_IDLE_TIME 6
166 171
167 /************************************************************************** 172 /**************************************************************************
1643 else 1648 else
1644 return FALSE; 1649 return FALSE;
1645 } 1650 }
1646 1651
1647 const GList * 1652 const GList *
1648 gaim_statuses_get_stored(void) 1653 gaim_statuses_get_saved(void)
1654 {
1655 return saved_statuses;
1656 }
1657
1658 GaimStatusSaved *
1659 gaim_statuses_find_saved(const GaimStatusType *status_type, const char *id)
1649 { 1660 {
1650 return NULL; 1661 return NULL;
1651 } 1662 }
1652 1663
1653 GaimStatus * 1664 const char *
1654 gaim_statuses_find_stored(const GaimStatusType *status_type, const char *id) 1665 gaim_statuses_saved_get_name(const GaimStatusSaved *saved_status)
1655 { 1666 {
1656 return NULL; 1667 return saved_status->name;
1657 } 1668 }
1658 1669
1659 void * 1670 void *
1660 gaim_statuses_get_handle() { 1671 gaim_statuses_get_handle() {
1661 static int handle; 1672 static int handle;
1721 void 1732 void
1722 gaim_statuses_sync(void) 1733 gaim_statuses_sync(void)
1723 { 1734 {
1724 } 1735 }
1725 1736
1737 /**
1738 * Parse a saved status and add it to the saved_statuses linked list.
1739 *
1740 * Here's an example of the XML for a saved status:
1741 * <status name="Girls">
1742 * <state>away</state>
1743 * <message>I like the way that they walk
1744 * And it's chill to hear them talk
1745 * And I can always make them smile
1746 * From White Castle to the Nile</message>
1747 * </status>
1748 *
1749 * I know. Moving, huh?
1750 *
1751 * TODO: Make sure the name is unique before adding it to the linked list.
1752 */
1753 static void
1754 gaim_statuses_read_parse_status(xmlnode *status)
1755 {
1756 xmlnode *node;
1757 const char *name, *state, *message;
1758 GaimStatusSaved *new;
1759
1760 name = xmlnode_get_attrib(status, "name");
1761 if (name == NULL)
1762 name = "TODO: Make up something unique";
1763
1764 node = xmlnode_get_child(status, "state");
1765 if (node != NULL) {
1766 state = xmlnode_get_data(node);
1767 }
1768
1769 node = xmlnode_get_child(status, "message");
1770 if (node != NULL) {
1771 message = xmlnode_get_data(node);
1772 }
1773
1774 /* TODO: Need to read in substatuses here */
1775
1776 new = g_new0(GaimStatusSaved, 1);
1777
1778 new->name = g_strdup(name);
1779 /* TODO: Need to set type based on "state" */
1780 new->type = NULL;
1781 if (message != NULL)
1782 new->message = g_strdup(message);
1783
1784 saved_statuses = g_list_append(saved_statuses, new);
1785 }
1786
1787 /**
1788 * @return TRUE on success, FALSE on failure (if the file can not
1789 * be opened, or if it contains invalid XML).
1790 */
1791 gboolean
1792 gaim_statuses_read(const char *filename)
1793 {
1794 GError *error;
1795 gchar *contents = NULL;
1796 gsize length;
1797 xmlnode *statuses, *status;
1798
1799 gaim_debug_info("status", "Reading %s\n", filename);
1800
1801 if (!g_file_get_contents(filename, &contents, &length, &error)) {
1802 gaim_debug_error("status", "Error reading status.xml: %s\n",
1803 error->message);
1804 g_error_free(error);
1805 return FALSE;
1806 }
1807
1808 statuses = xmlnode_from_str(contents, length);
1809
1810 if (statuses == NULL) {
1811 FILE *backup;
1812 gchar *name;
1813 gaim_debug_error("status", "Error parsing status.xml\n");
1814 name = g_build_filename(gaim_user_dir(), "status.xml~", NULL);
1815 if ((backup = fopen(name, "w"))) {
1816 fwrite(contents, length, 1, backup);
1817 fclose(backup);
1818 chmod(name, S_IRUSR | S_IWUSR);
1819 } else {
1820 gaim_debug_error("status", "Unable to write backup %s\n", name);
1821 }
1822 g_free(name);
1823 g_free(contents);
1824 return FALSE;
1825 }
1826
1827 g_free(contents);
1828
1829 for (status = xmlnode_get_child(statuses, "status"); status != NULL;
1830 status = xmlnode_get_next_twin(status)) {
1831 gaim_statuses_read_parse_status(status);
1832 }
1833
1834 gaim_debug_info("status", "Finished reading status.xml\n");
1835
1836 xmlnode_free(statuses);
1837
1838 return TRUE;
1839 }
1840
1726 void 1841 void
1727 gaim_statuses_load(void) 1842 gaim_statuses_load(void)
1728 { 1843 {
1729 } 1844 const char *user_dir = gaim_user_dir();
1845 gchar *filename;
1846 gchar *msg;
1847
1848 if (user_dir == NULL)
1849 return;
1850
1851 filename = g_build_filename(user_dir, "status.xml", NULL);
1852
1853 if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
1854 if (!gaim_statuses_read(filename)) {
1855 msg = g_strdup_printf(_("An error was encountered parsing the "
1856 "file containing your saved statuses (%s). They "
1857 "have not been loaded, and the old file has been "
1858 "renamed to status.xml~."), filename);
1859 gaim_notify_error(NULL, NULL, _("Saved Statuses Error"), msg);
1860 g_free(msg);
1861 }
1862 }
1863
1864 g_free(filename);
1865 }