#!/usr/bin/perl
# -----------------------------------------------------------------------------
# bitlbee-html.pl -- encode to / decode from HTML as used by AOL IM
# Copyright (C) 2005 Fabian Pietsch <fabian-irssi@canvon.dyndns.org>
#
# Irssi interface usage taken from kenny.pl
# http://alfie.ist.org/projects/irssi/scripts/kenny.pl
# Copyright (C) 2002 Gerfried Fuchs <alfie@channel.debian.de>
#
# Based on zzzmorse.pl (Irssi version) 0.1.4
# Copyright (C) 2003, 2004 Fabian Pietsch <fabian-irssi@canvon.dyndns.org>
#
# Distributed under the GNU GPL (General Public Licence)
# bitlbee-html.pl 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.
#
# bitlbee-html.pl 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.
# -----------------------------------------------------------------------------
#
# Version 0.1.5 (2005-08-17)
#
# Setup:
# - Just load the script in Irssi: /script load [PATH/]bitlbee-html.pl
# - If necessary, adjust the masks for which bitlbee-html should HTML-encode
#   messages:
#     /set bitlbee-html_masks MASK1 MASK2 MASK3
#   Format of MASKn is the usual NICK!USER@HOST, but see limitations below.
# - If you have placed the bitlbee connection in its own chatnet, you can limit
#   bitlbee-html.pl to handle only queries on that chatnet:
#     /set bitlbee-html_net BITLBEENET
#   To set up Irssi's chatnet configuration, use /ircnet (see /help ircnet).
#   To unset chatnet limiting, use:
#     /set -clear bitlbee-html_net
# - If you want to change what characters will get HTML-encoded, use:
#     /set bitlbee-html_encode CHARS
#   The default for CHARS is: <>&
# - If you want incoming messages to be HTML-decoded as well, do:
#     /set bitlbee-html_in on
#   This is disabled by default as bitlbee has "set html strip" (I'm told).
#
# Usage:
# - Just query with your AOL IM contacts using bitlbee as usual. Characters
#   with special meaning in HTML will automatically be encoded as HTML entities
#   (i.e., "<" becomes "&lt;" etc.).
# - If you ever want to send HTML as-is,
#   prefix your message with "[HTML] " (case insensitive, but beware the space)
#
# Known bugs & limitations:
# - /msg-ing someone isn't handled by bitlbee-html at all; you'll have to
#   create a query and use that.
# - A match against bitlbee-html_masks is only possible after the target's
#   address is known, even with *!*@* or similar; address will be known as
#   soon as a message is received from that nick. A whois or who doesn't seem
#   to work. It seems to be possible to use NICK (not NICK!*@*) as mask
#   that matches immediately, though.
# - When HTML-encoding own messages, they will be displayed encoded in one's
#   own buffer, too.
#
# ChangeLog:
#  - 0.1.1:
#     * initial release
#  - 0.1.2:
#     * documentation: setup notes, source comments
#     * added setting bitlbee-html_in (boolean) for HTML entity decoding of
#       incoming messages; not done by default anymore
#     * don't HTML entity encode own messages starting with "[HTML] ";
#       only strip this prefix off them
#  - 0.1.3:
#     * fix encoding -- didn't work at all <hide>
#       now uses different Irssi signal, previous was for the UI only
#     * updated documentation
#  - 0.1.4:
#     * only show address-unknown warning if target nick didn't match any mask
#     * added setting bitlbee-html_net (string) for optionally limiting
#       bitlbee-html.pl (and its nick/address matching and related warnings)
#       to the user's bitlbee "chatnet"
#     * document bitlbee-html_net
#     * fix script download URL
#     * fix typo in comment
#  - 0.1.5:
#     * added setting bitlbee-html_encode (string) to entity-encode only
#       certain user-selected characters --
#       AOL IM doesn't seem to be able to handle named entities for at least
#       german Umlauts and sz, but handles them correctly as plain chars
#     * document bitlbee-html_encode
#     * fix typo in setup documentation
#

use Irssi qw(signal_add_first signal_add_last signal_continue settings_add_str settings_add_bool settings_get_str settings_get_bool);
use HTML::Entities;
use strict;
use vars qw($VERSION %IRSSI);

$VERSION = '0.1.5';

%IRSSI = (
	'authors'     => 'Fabian Pietsch',
	'contact'     => 'fabian-irssi@canvon.dyndns.org',
	'name'        => 'bitlbee-html',
	'description' => 'Encode bitlbee IM messages to AOL IM users as HTML.',
	'license'     => 'GPL',
	'url'         => 'http://zzz.arara.de/software/raw/script/irssi/bitlbee-html_pl',
	'changed'     => '2005-08-17'
);

settings_add_str ('bitlbee-html', 'bitlbee-html_net',    '');
settings_add_str ('bitlbee-html', 'bitlbee-html_masks',  '*!*@login.oscar.aol.com');
settings_add_str ('bitlbee-html', 'bitlbee-html_encode', '<>&');
settings_add_bool('bitlbee-html', 'bitlbee-html_in',     0);

sub sig_msg_in
{
	# only handle incoming messages if explicitly configured (see above)
	return unless settings_get_bool('bitlbee-html_in');

	my ($server, $msg, $nick, $address, $target) = @_;

	# only handle messages on bitlbee chatnet, if set by user
	my $netwanted = settings_get_str('bitlbee-html_net');
	return if ($netwanted && ($server->{chatnet} ne $netwanted));

	# only handle messages to user-set targets
	return unless $server->masks_match
	  (settings_get_str('bitlbee-html_masks'), $nick, $address);

	# decode HTML entities (i.e., "&lt;" becomes "<" etc.)
	$_[1] = decode_entities($msg);

	# continue signal handling with filtered message
	signal_continue(@_);
}
signal_add_first('message private', \&sig_msg_in);

sub sig_msg_out
{
	my ($line, $server, $witem) = @_;

	# only handle messages on bitlbee chatnet, if set by user
	my $netwanted = settings_get_str('bitlbee-html_net');
	return if ($netwanted && ($server->{chatnet} ne $netwanted));

	# only handle queries
	return unless ($witem && ($witem->{type} eq 'QUERY'));

	# only handle messages to user-set targets
	unless ($server->masks_match
	  (settings_get_str('bitlbee-html_masks'), $witem->{name}, $witem->{address}))
	{
		# warn if address unknown, as otherwise the target could have matched
		$witem->print
		  ("bitlbee-html: warning: can't get address of " . $witem->{name},
		   MSGLEVEL_CLIENTERROR)
		  unless ($witem->{address});

		return;
	}

	# don't HTML entity encode own messages beginning with "[HTML] ";
	# strip that prefix, instead
	if ($line =~ s/^\[HTML\] //i)
	{
		$_[0] = $line;
	}
	else
	{
		# escape chars with special meaning in HTML as HTML entities
		# (i.e., "<" becomes "&lt;" etc.)
		$_[0] = encode_entities
		  ($line, settings_get_str('bitlbee-html_encode'));
	}

	# continue signal handling with filtered message
	signal_continue(@_);
}
signal_add_first('send text', \&sig_msg_out);

