Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml (revision d4efddfb7d34a8409cf78dd337f3933e0ed11d08)
+++ doc/user-guide/commands.xml (revision 3e5766022e8103765d62343956cf1aeba34b4d82)
@@ -839,4 +839,19 @@
+
+ local
+ local, utc, gmt, timezone-spec
+
+
+
+ If message timestamps are available for offline messages or chatroom backlogs, BitlBee will display them as part of the message. By default it will use the local timezone. If you're not in the same timezone as the BitlBee server, you can adjust the timestamps using this setting.
+
+
+
+ Values local/utc/gmt should be self-explanatory. timezone-spec is a time offset in hours:minutes, for example: -8 for Pacific Standard Time, +2 for Central European Summer Time, +5:30 for Indian Standard Time.
+
+
+
+
try
Index: irc.c
===================================================================
--- irc.c (revision d4efddfb7d34a8409cf78dd337f3933e0ed11d08)
+++ irc.c (revision 3e5766022e8103765d62343956cf1aeba34b4d82)
@@ -199,4 +199,5 @@
s->flags |= SET_NULL_OK;
s = set_add( &irc->set, "strip_html", "true", NULL, irc );
+ s = set_add( &irc->set, "timezone", "local", set_eval_timezone, irc );
s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c (revision d4efddfb7d34a8409cf78dd337f3933e0ed11d08)
+++ protocols/nogaim.c (revision 3e5766022e8103765d62343956cf1aeba34b4d82)
@@ -39,4 +39,5 @@
static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );
+static char *format_timestamp( irc_t *irc, time_t msg_ts );
GSList *connections;
@@ -718,5 +719,5 @@
{
irc_t *irc = ic->irc;
- char *wrapped;
+ char *wrapped, *ts;
user_t *u;
@@ -760,8 +761,16 @@
( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
strip_html( msg );
-
+
+ if( ( ts = format_timestamp( irc, sent_at ) ) )
+ {
+ char *new = g_strconcat( ts, msg, NULL );
+ g_free( ts );
+ ts = msg = new;
+ }
+
wrapped = word_wrap( msg, 425 );
irc_msgfrom( irc, u->nick, wrapped );
g_free( wrapped );
+ g_free( ts );
}
@@ -867,5 +876,7 @@
if( c && u )
{
- irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, "", wrapped );
+ char *ts = format_timestamp( ic->irc, sent_at );
+ irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped );
+ g_free( ts );
}
else
@@ -1061,6 +1072,92 @@
}
-
-
+char *set_eval_timezone( set_t *set, char *value )
+{
+ char *s;
+
+ if( strcmp( value, "local" ) == 0 ||
+ strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 )
+ return value;
+
+ /* Otherwise: +/- at the beginning optional, then one or more numbers,
+ possibly followed by a colon and more numbers. Don't bother bound-
+ checking them since users are free to shoot themselves in the foot. */
+ s = value;
+ if( *s == '+' || *s == '-' )
+ s ++;
+
+ /* \d+ */
+ if( !isdigit( *s ) )
+ return SET_INVALID;
+ while( *s && isdigit( *s ) ) s ++;
+
+ /* EOS? */
+ if( *s == '\0' )
+ return value;
+
+ /* Otherwise, colon */
+ if( *s != ':' )
+ return SET_INVALID;
+ s ++;
+
+ /* \d+ */
+ if( !isdigit( *s ) )
+ return SET_INVALID;
+ while( *s && isdigit( *s ) ) s ++;
+
+ /* EOS */
+ return *s == '\0' ? value : SET_INVALID;
+}
+
+static char *format_timestamp( irc_t *irc, time_t msg_ts )
+{
+ time_t now_ts = time( NULL );
+ struct tm now, msg;
+ char *set;
+
+ /* If the timestamp is <= 0 or less than a minute ago, discard it as
+ it doesn't seem to add to much useful info and/or might be noise. */
+ if( msg_ts <= 0 || msg_ts > now_ts - 60 )
+ return NULL;
+
+ set = set_getstr( &irc->set, "timezone" );
+ if( strcmp( set, "local" ) == 0 )
+ {
+ localtime_r( &now_ts, &now );
+ localtime_r( &msg_ts, &msg );
+ }
+ else
+ {
+ int hr, min = 0, sign = 60;
+
+ if( set[0] == '-' )
+ {
+ sign *= -1;
+ set ++;
+ }
+ else if( set[0] == '+' )
+ {
+ set ++;
+ }
+
+ if( sscanf( set, "%d:%d", &hr, &min ) >= 1 )
+ {
+ msg_ts += sign * ( hr * 60 + min );
+ now_ts += sign * ( hr * 60 + min );
+ }
+
+ gmtime_r( &now_ts, &now );
+ gmtime_r( &msg_ts, &msg );
+ }
+
+ if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday )
+ return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ",
+ msg.tm_hour, msg.tm_min, msg.tm_sec );
+ else
+ return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "
+ "%02d:%02d:%02d\x02]\x02 ",
+ msg.tm_year + 1900, msg.tm_mon, msg.tm_mday,
+ msg.tm_hour, msg.tm_min, msg.tm_sec );
+}
/* The plan is to not allow straight calls to prpl functions anymore, but do
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h (revision d4efddfb7d34a8409cf78dd337f3933e0ed11d08)
+++ protocols/nogaim.h (revision 3e5766022e8103765d62343956cf1aeba34b4d82)
@@ -324,4 +324,5 @@
/* Misc. stuff */
+char *set_eval_timezone( set_t *set, char *value );
char *set_eval_away_devoice( set_t *set, char *value );
gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );