changeset 6065:3a40666c08b4

[gaim-migrate @ 6515] These be away messages. They don't do nothing that the old away messages ain't done, but they save themselves in ~/.gaim/status.xml instead of ~/.gaimrc. Astute CVS watchers will have noticed a bit of a trend like that. So in the future status.xml will have all sorts of cool stuff (I have big plans) but it's kinda boring for now. Also, I should've done this weeks ago. I should stop being busy. I'd like to give a shoutout to my boy Rob Flynn, keepin' it real in Atlanta. You know you my boy, Dawg. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 08 Jul 2003 23:48:10 +0000
parents ed3c3c38e182
children c99959f1bb73
files src/Makefile.am src/dialogs.c src/gaimrc.c src/main.c src/status.c src/status.h
diffstat 6 files changed, 330 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Tue Jul 08 23:07:13 2003 +0000
+++ b/src/Makefile.am	Tue Jul 08 23:48:10 2003 +0000
@@ -40,6 +40,8 @@
 	request.h \
 	server.c \
 	server.h \
+	status.c \
+	status.h \
 	sound.c \
 	sound.h \
 	util.c \
--- a/src/dialogs.c	Tue Jul 08 23:07:13 2003 +0000
+++ b/src/dialogs.c	Tue Jul 08 23:48:10 2003 +0000
@@ -28,6 +28,7 @@
 #include "privacy.h"
 #include "prpl.h"
 #include "request.h"
+#include "status.h"
 #include "util.h"
 
 #include "gtkblist.h"
@@ -3276,6 +3277,7 @@
 	}
 
 	do_away_menu(NULL);
+	gaim_status_sync();
 
 	return am;
 }
--- a/src/gaimrc.c	Tue Jul 08 23:07:13 2003 +0000
+++ b/src/gaimrc.c	Tue Jul 08 23:48:10 2003 +0000
@@ -337,8 +337,10 @@
 		if (!fgets(buf, sizeof(buf), f))
 			return;
 
-		if (buf[0] == '}')
+		if (buf[0] == '}') {
+			gaim_status_sync();
 			return;
+		}
 
 		p = parse_line(buf, &parse_buffer);
 		if (!strcmp(p->option, "message")) {
@@ -361,6 +363,7 @@
 		g_snprintf(a->message, sizeof(a->message), "%s", BORING_DEFAULT_AWAY_MSG);
 		away_messages = g_slist_append(away_messages, a);
 	}
+	gaim_status_sync();
 }
 
 /*
--- a/src/main.c	Tue Jul 08 23:07:13 2003 +0000
+++ b/src/main.c	Tue Jul 08 23:48:10 2003 +0000
@@ -893,6 +893,7 @@
 	gaim_plugins_load_saved("/gaim/gtk/plugins/loaded");
 
 	gaim_pounces_load();
+	gaim_status_load();
 
 #ifdef _WIN32
 	/* Various win32 initializations */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/status.c	Tue Jul 08 23:48:10 2003 +0000
@@ -0,0 +1,299 @@
+/*
+ * gaim
+ *
+ * Copyright (C) 2003 Jason Priestly
+ * Copyright (C) 2003 Luke Perry
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "status.h"
+#include "internal.h"
+#include "ui.h"
+#include "debug.h"
+#include "util.h"
+
+/* for people like myself who are too lazy to add an away msg :) */
+/* I don't know who "myself" is in this context.  The exclamation point
+ * makes it slightly less boring ;) */
+#define BORING_DEFAULT_AWAY_MSG _("Sorry, I ran out for a bit!")
+
+/* XML File Saving */
+
+/* All of this code is adapted from Nathan Walp's.  It's adapted all over the place
+ * for accounts, the buddy list, pounces, preferences, and the likes.  It would be
+ * neat if we could somehow make this more generic. */
+static gboolean status_loaded = FALSE;
+static guint    status_save_timer = 0;
+
+
+typedef enum
+{
+	TAG_NONE = 0,
+	TAG_STATUS,
+	TAG_STATE,
+	TAG_MESSAGE,
+
+} StatusParserTag;
+
+
+typedef struct
+{
+	StatusParserTag tag;
+	GString *buffer;
+	struct away_message *am;
+
+} StatusParserData;
+
+static void
+free_parser_data(gpointer user_data)
+{
+	StatusParserData *data = user_data;
+
+	if (data->buffer != NULL)
+		g_string_free(data->buffer, TRUE);
+
+	g_free(data);
+}
+
+static void gaim_status_write(FILE *fp, struct away_message *am)
+{
+	char *esc = NULL;
+	
+	esc = g_markup_escape_text(am->name, -1);
+	fprintf(fp, " <status name=\"%s\">\n", esc);
+	g_free(esc);
+	
+	fprintf(fp, "    <state>away</state>\n");
+	
+	esc = g_markup_escape_text(am->message, -1);
+	fprintf(fp, "    <message>%s</message>\n", esc);
+	g_free(esc);
+
+	fprintf(fp, " </status>\n");
+}
+
+static gboolean
+status_save_cb(gpointer unused)
+{
+	gaim_status_sync();
+	status_save_timer = 0;
+
+	return FALSE;
+}
+
+static void
+schedule_status_save()
+{
+	if (!status_save_timer)
+		status_save_timer = g_timeout_add(5000, status_save_cb, NULL);
+}
+
+static void
+start_element_handler(GMarkupParseContext *context,
+					  const gchar *element_name,
+					  const gchar **attribute_names,
+					  const gchar **attribute_values,
+					  gpointer user_data, GError **error)
+{
+	const char *value;
+	StatusParserData *data = user_data;
+	GHashTable *atts;
+	int i;
+
+	atts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+	for (i = 0; attribute_names[i] != NULL; i++) {
+		g_hash_table_insert(atts, g_strdup(attribute_names[i]),
+				    g_strdup(attribute_values[i]));
+	}
+
+	if (data->buffer != NULL) {
+		g_string_free(data->buffer, TRUE);
+		data->buffer = NULL;
+	}
+
+	if (!strcmp(element_name, "status")) {
+		data->tag = TAG_STATUS;
+		if ((value = g_hash_table_lookup(atts, "name")) != NULL) {
+			data->am = g_new0(struct away_message, 1);
+			g_snprintf(data->am->name, sizeof(data->am->name), "%s", value);
+			away_messages = g_slist_append(away_messages, data->am);
+		}
+	} else if (!strcmp(element_name, "message")) {
+		data->tag = TAG_MESSAGE;
+		
+	}
+}
+
+static void
+end_element_handler(GMarkupParseContext *context, const gchar *element_name,
+					gpointer user_data,  GError **error)
+{
+	StatusParserData *data = user_data;
+	gchar *buffer;
+
+	if (data->buffer == NULL)
+		return;
+
+	buffer = g_string_free(data->buffer, FALSE);
+	data->buffer = NULL;
+
+	if (data->tag == TAG_MESSAGE) {
+		if (*buffer != '\0')
+			g_snprintf(data->am->message, sizeof(data->am->message), "%s", buffer);
+	}
+
+	data->tag = TAG_NONE;
+
+	g_free(buffer);
+}
+
+static void
+text_handler(GMarkupParseContext *context, const gchar *text,
+			 gsize text_len, gpointer user_data, GError **error)
+{
+	StatusParserData *data = user_data;
+
+	if (data->buffer == NULL)
+		data->buffer = g_string_new_len(text, text_len);
+	else
+		g_string_append_len(data->buffer, text, text_len);
+}
+
+static GMarkupParser status_parser =
+{
+	start_element_handler,
+	end_element_handler,
+	text_handler,
+	NULL,
+	NULL
+};
+
+void gaim_status_sync()
+{
+	FILE *fp;
+	const char *user_dir = gaim_user_dir();
+	char *filename, *filename_real;
+
+	if (!status_loaded) {
+		gaim_debug(GAIM_DEBUG_WARNING, "status", "Writing status to disk.\n");
+		schedule_status_save();
+		return;
+	}
+
+	if (user_dir == NULL)
+		return;
+
+	gaim_debug(GAIM_DEBUG_INFO, "status", "Saving statuses to disk\n");
+
+	fp = fopen(user_dir, "r");
+
+	if (fp == NULL)
+		mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
+	else
+		fclose(fp);
+
+	filename = g_build_filename(user_dir, "status.xml.save", NULL);
+
+	if ((fp = fopen(filename, "w")) != NULL) {
+		GSList *l;
+
+		fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
+		fprintf(fp, "<statuses>\n");
+
+		for (l = away_messages; l != NULL; l = l->next)
+			gaim_status_write(fp, l->data);
+
+		fprintf(fp, "</statuses>\n");
+
+		fclose(fp);
+		chmod(filename, S_IRUSR | S_IWUSR);
+	}
+	else {
+		gaim_debug(GAIM_DEBUG_ERROR, "status", "Unable to write %s\n",
+				   filename);
+	}
+
+	filename_real = g_build_filename(user_dir, "status.xml", NULL);
+
+	if (rename(filename, filename_real) < 0) {
+		gaim_debug(GAIM_DEBUG_ERROR, "status", "Error renaming %s to %s\n",
+				   filename, filename_real);
+	}
+
+	g_free(filename);
+	g_free(filename_real);
+
+}
+
+void gaim_status_load()
+{
+	gchar *filename = g_build_filename(gaim_user_dir(), "status.xml", NULL);
+	gchar *contents = NULL;
+	gsize length;
+	GMarkupParseContext *context;
+	GError *error = NULL;
+	StatusParserData *parser_data;
+
+	if (filename == NULL) {
+		status_loaded = TRUE;
+		return;
+	}
+
+	if (!g_file_get_contents(filename, &contents, &length, &error)) {
+		gaim_debug(GAIM_DEBUG_ERROR, "status",
+				   "Error reading statuses: %s\n", error->message);
+		g_error_free(error);
+		g_free(filename);
+		status_loaded = TRUE;
+		if (!away_messages) {
+			struct away_message *a = g_new0(struct away_message, 1);
+			g_snprintf(a->name, sizeof(a->name), _("Slightly less boring default"));
+			g_snprintf(a->message, sizeof(a->message), "%s", BORING_DEFAULT_AWAY_MSG);
+			away_messages = g_slist_append(away_messages, a);
+		}
+		return;
+	}
+
+	parser_data = g_new0(StatusParserData, 1);
+
+	context = g_markup_parse_context_new(&status_parser, 0,
+					     parser_data, free_parser_data);
+
+	if (!g_markup_parse_context_parse(context, contents, length, NULL)) {
+		g_markup_parse_context_free(context);
+		g_free(contents);
+		g_free(filename);
+		status_loaded = TRUE;
+		return;
+	}
+
+	if (!g_markup_parse_context_end_parse(context, NULL)) {
+		gaim_debug(GAIM_DEBUG_ERROR, "status", "Error parsing %s\n",
+				   filename);
+		g_markup_parse_context_free(context);
+		g_free(contents);
+		g_free(filename);
+		status_loaded = TRUE;
+		return;
+	}
+
+	g_markup_parse_context_free(context);
+	g_free(contents);
+	g_free(filename);
+	status_loaded = TRUE;
+	return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/status.h	Tue Jul 08 23:48:10 2003 +0000
@@ -0,0 +1,22 @@
+/*
+ * gaim
+ *
+ * Copyright (C) 2003 Donald Rumsfeld
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+void gaim_status_sync();
+void gaim_status_load();