[ekg2-commit] r4036 - trunk/plugins/irc: trunk/plugins/irc/irc.c trunk/plugins/irc/irc.h trunk/plugins/irc/session-pl.txt

SVN commit svn w toxygen.net
Nie, 29 Cze 2008, 04:04:01 CEST


Author: wiechu
Date: 2008-06-29 04:03:59 +0200 (Sun, 29 Jun 2008)
New Revision: 4036

Modified:
   trunk/plugins/irc/irc.c
   trunk/plugins/irc/irc.h
   trunk/plugins/irc/session-pl.txt
Log:
    (draft) new irc session variable recode_list

Modified: trunk/plugins/irc/irc.c
===================================================================
--- trunk/plugins/irc/irc.c	2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/irc.c	2008-06-29 02:03:59 UTC (rev 4036)
@@ -466,6 +466,136 @@
 	LIST_DESTROY(oldlist, list_irc_resolver_free);
 }
 
+out_recodes_t *irc_find_out_recode(list_t rl, char *encname) {
+	out_recodes_t *recode;
+
+	if (!(encname && rl))
+		return NULL;
+
+	for ( ; rl; rl = rl->next) {
+		recode = (out_recodes_t *)(rl->data);
+		if ( recode->name && !xstrcasecmp(recode->name, encname) )
+			return recode;
+	}
+	return NULL;
+}
+
+recoded_channels_t *irc_find_recode_channel(list_t rcl, char *channame) {
+	recoded_channels_t *r_channel;
+
+	if (!(channame && rcl))
+		return NULL;
+
+	for ( ; rcl; rcl = rcl->next) {
+		r_channel = (recoded_channels_t *)(rcl->data);
+		if ( r_channel->name && !xstrcasecmp(r_channel->name, channame) )
+			return r_channel;
+	}
+	return NULL;
+}
+
+static char *irc_convert_out(irc_private_t *j, char *recipient, const char *line) {
+	char *recoded;
+	recoded_channels_t *r_channel;
+
+	if (!(j->recoded_channels)) {
+		/* channel/nick recode */
+		char *channame = (!xstrncasecmp(recipient, IRC4, 4)) ? recipient+4 : recipient;
+		if ((r_channel = irc_find_recode_channel(j->recoded_channels, channame))) {
+			if ((recoded = ekg_convert_string_p(line, r_channel->recode->conv_out)))
+				return recoded;
+		}
+	}
+
+	/* default recode */
+	if (j->conv_out == (void *) -1)
+		return NULL;
+
+	if (!(recoded = ekg_convert_string_p(line, j->conv_out)))
+		debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
+
+	return recoded;
+}
+
+static void irc_changed_recode_list(session_t *s, const char *var) {
+	const char *val;
+	irc_private_t *j;
+	char **list1, **list2, *nicks, *encoding;
+	void *conv_in, *conv_out;
+	int i,i2;
+	list_t rcl, rl;
+	out_recodes_t *recode;
+	recoded_channels_t *r_channel;
+
+	if (!s || !(j = s->priv))
+		return;
+
+	/* Clean old lists */
+	for (rcl = j->recoded_channels; rcl; ) {
+		r_channel = rcl->data;
+		rcl = rcl->next;
+		xfree(r_channel->name);
+		list_remove(&rcl, r_channel, 1);
+	}
+	for (rl = j->out_recodes; rl; ) {
+		recode = rl->data;
+		rl = rl->next;
+		xfree(recode->name);
+		ekg_convert_string_destroy(recode->conv_in);
+		ekg_convert_string_destroy(recode->conv_out);
+		list_remove(&rl, recode, 1);
+	}
+
+	if (!(val = session_get(s, var)) || !*val)
+		return;
+
+	/* Parse list */
+	// Syntax: encoding1:nick1,nick2,#chan1,nick3;encoding2:nick4,#chan5,chan6
+	list1 = array_make(val, ";", 0, 1, 0);
+	for (i=0; list1[i]; i++) {
+		if (!(nicks = xstrchr(list1[i], ':'))) {
+			debug_error("[irc] recode_list parse error: no colon. Skipped. '%s'\n", list1[i]);
+			continue;
+		}
+		*nicks++ = '\0';
+		encoding = list1[i];
+		if (!*nicks) {
+			debug_error("[irc] recode_list parse error: no nick or channel. Skipped. '%s:'\n", encoding);
+			continue;
+		}
+		if (!*encoding) {
+			debug_error("[irc] recode_list parse error: no encoding name. Skipped. ':%s'\n", nicks);
+			continue;
+		}
+
+		if (!(recode = irc_find_out_recode(j->out_recodes, encoding))) {
+			if (!(conv_in = ekg_convert_string_init(NULL, encoding, &(conv_out)))) {
+				debug_error("[irc] recode_list error: unknown encoding '%s'\n", encoding);
+				continue;
+			}
+			recode = xmalloc(sizeof(out_recodes_t));
+			recode->name = xstrdup(encoding);
+			recode->conv_in  = conv_in;
+			recode->conv_out = conv_out;
+			list_add(&(j->out_recodes), recode);
+		}
+
+		list2 = array_make(nicks, ",", 0, 1, 0);
+		for(i2=0; list2[i2]; i2++) {
+			if ((r_channel = irc_find_recode_channel(j->recoded_channels, list2[i2]))) {
+				debug_error("[irc] recode_list. Duplicated channel/nick '%s'. Skipped.'\n", list2[i2]);
+				continue;
+			}
+			r_channel = xmalloc(sizeof(recoded_channels_t));
+			r_channel->name = xstrdup(list2[i2]);
+			r_channel->recode = recode;
+			list_add(&(j->recoded_channels), r_channel);
+		}
+		xfree(list2);
+	}
+	array_free(list1);
+}
+
 static void irc_changed_recode(session_t *s, const char *var) {
 	const char *val;
 	irc_private_t *j;
@@ -507,9 +637,8 @@
 		list_remove(&el, e, 1);
 	}
 
-	if (!(val = session_get(s, var)) || !*val) {
+	if (!(val = session_get(s, var)) || !*val)
 		return;
-	}
 
 	char **args;
 	args = array_make(val, ",", 0, 1, 0);
@@ -1050,14 +1179,8 @@
  *
  * 	wo: Yes! We should use uncoded message for proper encoding in logs.
  */
-		if (j->conv_out != (void *) -1) {
-			__msg = ekg_convert_string_p(mline[1], j->conv_out);
 
-			if (!__msg)
-				debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
-		}
-
-		if (!__msg)
+		if (!(__msg = irc_convert_out(j, uid, mline[1])))
 			__msg = xstrdup((const char *)mline[1]);
 
 		coloured = irc_ircoldcolstr_to_ekgcolstr(session, head, 1);
@@ -1657,7 +1780,7 @@
 
 static COMMAND(irc_command_topic) {
 	irc_private_t	*j = irc_private(session);
-	char		**mp, *chan, *newtop;
+	char		**mp, *chan, *newtop, *recode;
 
 	if (!(chan=irc_getchan(session, params, name, 
 					&mp, 0, IRC_GC_CHAN))) 
@@ -1672,15 +1795,9 @@
 	else
 		newtop = saprintf("TOPIC %s\r\n", chan+4);
 
-	if (j->conv_out != (void *) -1) {
-		char *recode = ekg_convert_string_p(newtop, j->conv_out);
-
-		if (!recode)
-			debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
-		else {
-			xfree(newtop);
-			newtop = recode;
-		}
+	if ((recode = irc_convert_out(j, chan+4, newtop))) {
+		xfree(newtop);
+		newtop = recode;
 	}
 
 	watch_write(j->send_watch, newtop);
@@ -1959,14 +2076,7 @@
 
 	ischn = chantypes?!!xstrchr(chantypes, chan[4]):0;
 	
-	if (j->conv_out != (void *) -1) {
-		str = ekg_convert_string_p(*mp, j->conv_out);
-
-		if (!str)
-			debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
-	}
-
-	if (!str)
+	if (!(str = irc_convert_out(j, chan+4, *mp)))
 		str = xstrdup(*mp);
 
 	watch_write(irc_private(session)->send_watch, "PRIVMSG %s :\01ACTION %s\01\r\n",
@@ -2219,6 +2329,7 @@
 	PLUGIN_VAR_ADD("password",		VAR_STR, 0, 1, NULL),
 	PLUGIN_VAR_ADD("port",			VAR_INT, "6667", 0, NULL),
 	PLUGIN_VAR_ADD("realname",		VAR_STR, NULL, 0, NULL),		/* value will be inited @ irc_plugin_init() [pwd_entry->pw_gecos] */
+	PLUGIN_VAR_ADD("recode_list", VAR_STR, NULL, 0, irc_changed_recode_list),
 	PLUGIN_VAR_ADD("recode_out_default_charset", VAR_STR, NULL, 0, irc_changed_recode),		/* irssi-like-variable */
 	PLUGIN_VAR_ADD("server",		VAR_STR, 0, 0, irc_changed_resolve),
 

Modified: trunk/plugins/irc/irc.h
===================================================================
--- trunk/plugins/irc/irc.h	2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/irc.h	2008-06-29 02:03:59 UTC (rev 4036)
@@ -64,6 +64,8 @@
 	list_t awaylog;
 
 	list_t auto_guess_encoding;
+	list_t out_recodes;
+	list_t recoded_channels;
 
 	void *conv_in;
 	void *conv_out;
@@ -75,6 +77,19 @@
 	void *conv_out;
 } conv_in_out_t;
 
+/* data for private->out_recodes */
+typedef struct {
+	char *name;	/* encoding name */
+	void *conv_in;
+	void *conv_out;
+} out_recodes_t;
+
+/* data for private->recoded_channels */
+typedef struct {
+	char *name;	/* channel or nick */
+	out_recodes_t *recode;
+} recoded_channels_t;
+
 typedef struct _irc_awaylog_t {
 	char *channame;	/* channel name, (null if priv) */
 	char *uid;	/* nickname who wrote to us	*/

Modified: trunk/plugins/irc/session-pl.txt
===================================================================
--- trunk/plugins/irc/session-pl.txt	2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/session-pl.txt	2008-06-29 02:03:59 UTC (rev 4036)
@@ -125,6 +125,13 @@
 	odpowiedzi na /whois], by zmiany realname odniosły skutek należy się
 	ponownie połączyć
 
+recode_list
+	typ: text
+	domyślna wartość: brak
+	
+	Lista kodowań dla poszczególnych nicków lub/i kanałów
+	Syntax: encoding1:nick1,nick2,#chan1,nick3;encoding2:nick4,#chan5,chan6
+
 server
 	typ: tekst
 	domyślna wartość: brak



Więcej informacji o liście dyskusyjnej ekg2-commit