#!/usr/bin/perl

require ("/var/www/aikido/BasePage.pm");
use CGI qw(:standard);
use POSIX qw(strftime);
use XML::RSS;
use Date::Parse;
use strict;
use warnings;

my $conn = BasePage::get_connection();
my $session = BasePage::get_session($conn);

my @passwords = ('Ashi', 'Ashikubi', 'Atemi', 'Awase', 'Ayamochi',
		'Bokken', 'Bokuto', 'Bukiwaza', 'Chudan', 'Seidan',
		'Dogi', 'Dojo', 'Erimochi', 'Fumikomi', 'Gaesi',
		'Ganmen', 'Gyaku', 'Hakama', 'Hasso', 'Hojodosa',
		'Ikkyu', 'Irimi', 'Jodan', 'Kaiten', 'Ken', 
		'Katamochi', 'Kihon', 'Kohai', 'Kokyu', 'Kokai',
		'Kote', 'Kotegaeshi', 'Metsuke', 'Mokuso', 'Mune',
		'Munemochi', 'Nage', 'Nikyu', 'Omote', 'Osae',
		'Rei', 'Renshu', 'Sabaki', 'Seiza', 'Sempai', 'Sensei',
		'Shikko', 'Shime', 'Shitsumon', 'Shomen', 'Shomenuchi',
		'Suwari', 'Tachi', 'Tanto', 'Tatami', 'Tekubi', 'Tenkai',
		'Tsuki', 'Uchi', 'Ukemi', 'Ura', 'Ushiro', 'Waza', 'Yame',
		'Yoke');

# XXX use the spam harvester thingie here
# XXX move to base class and use in calendar too
sub escape($) {
	my $text = shift;
	$text =~ s/&/&amp;/g;
	$text =~ s/--/&ndash;/g;
	$text =~ s/</&lt;/g;
	$text =~ s/>/&gt;/g;
	$text =~ s/ü/&uuml;/g;
	$text =~ s/ö/&ouml;/g;
	$text =~ s/ä/&auml;/g;
	$text =~ s/Ü/&Uuml;/g;
	$text =~ s/Ö/&Ouml;/g;
	$text =~ s/Ä/&Auml;/g;
	$text =~ s/ß/&szlig;/g;
	$text =~ s/\*([^*]+)\*/<b>$1<\/b>/g;
	$text =~ s/(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)/<a href="mailto:$1">$1<\/a>/g;
	$text =~ s/([a-z]{3,9}:\/\/[-a-zA-Z0-9_.,;\/?=]*)/<a href="$1">$1<\/a>/g;
	$text =~ s/file:([-a-zA-Z0-9._]+):([-a-zA-Z0-9._]+)/<a href="files\/$1">$2<\/a>/g;
	$text =~ s/file:([-a-zA-Z0-9._]+)/<a href="files\/$1">$1<\/a>/g;
	$text =~ s/[\n\r]{2}/<br\/>/g;
	return $text;
}

sub unescape($) {
	my $text = shift;
	$text =~ s/<br\/>/\r\n/g;
	$text =~ s/<a href="files\/([^"]+)">([^<]+)<\/a>/file:$1:$2/g;
	$text =~ s/<a href="mailto:([^"]*)">[^<]*<\/a>/$1/g;
	$text =~ s/<a href="([^"]*)">[^<]*<\/a>/$1/g;
	$text =~ s/<b>([^<]+)<\/b>/*$1*/g;
	$text =~ s/&uuml;/ü/g;
	$text =~ s/&ouml;/ö/g;
	$text =~ s/&auml;/ä/g;
	$text =~ s/&Uuml;/Ü/g;
	$text =~ s/&Ouml;/Ö/g;
	$text =~ s/&Auml;/Ä/g;
	$text =~ s/&szlig;/ß/g;
	$text =~ s/&lt;/</g;
	$text =~ s/&gt;/>/g;
	$text =~ s/&ndash;/--/g;
	$text =~ s/&amp;/&/g;
	return $text;
}

my %caps = ();

sub print_news($$$) {
	my $session = shift;
	my $conn = shift;
	my $caps = shift;
	my $hlid = param('hl')||-1;
	my $sth = $conn->prepare_cached("select id,author,ctime,subject,text from news order by ctime desc");
	$sth->execute();
	while (my($id, $author, $ctime, $subject, $text) = $sth->fetchrow_array()) {
		$ctime =~ s/([0-9]{4})-([0-9]{2})-([0-9]{2}).*/$3.$2.$1/;
		my $links = "";
		if ($session->{username} and (($session->{username} eq $author)) 
			or ($caps->{'edit_news'})) {
#			$links = "[<a href='index.pl?action=edit&id=$id'>Bearbeiten</a>] [<a href='index.pl?action=delete&id=$id'>L&ouml;schen</a>]";
			$links = "<a href='index.pl?action=edit&id=$id'><img src='edit.gif' width='16' height='16' alt='Bearbeiten' title='Bearbeiten' border='0'></a><a href='index.pl?action=delete&id=$id'><img src='del.gif' width='16' height='16' alt='L&ouml;schen' title='L&ouml;schen' border='0'></a>";
		}
		if ($links) {
			print "<table><tr><td nowrap valign='top'>$links</td><td width='100%'>";
		}
		if ($hlid == $id) {
			print "<div class='hl'>\n";
		}
		print "<a name='$id'></a><h3 class='news'>$subject</h3>\n";
		# mailto links verschluesseln
		while ($text =~ /(<a href="mailto:[^"]*">[^<]*<\/a>)/) {
			my $origrep = $1;
			my $omail = $origrep;
			$omail =~ s/<a href="mailto:([^"]*)">[^<]*<\/a>/$1/;
			$omail = BasePage::jsobfusc($omail);
			$text =~ s/$origrep/$omail/;
		}
		print "<p class='news'>$text</p>\n";
		print "<p class='signature'>$author, $ctime</p>\n";
		if ($hlid == $id) {
			print "</div>\n";
		}
		if ($links) {
			print "</td></tr></table>";
		}
		print "<br/>"
	}
	$sth->finish();
}

my @links = ();
push(@links, "<a href='index.pl?action=subscribe' class='menu'>Abonnieren</a><br/>\n");
if ($session->{usercaps}) {
	%caps = %{$session->{usercaps}};
	if ($caps{'enter_news'}) {
		push(@links, "<a href='index.pl?action=new' class='menu'>Neu</a><br/>\n");
	}
}
$session->{pagelinks} = \@links;
		
my @header = ("<link rel='alternate' type='application/rss+xml' href='index.pl?type=rss' title='Aikido, Kendo und Iaido News'>\n",
'<META name="verify-v1" content="mEiQwO4fKZI8FnXcfFn/A0bmfPKkXWM1uDJc+ryEyOQ=" />'."\n");
		
$session->{pageheader} = \@header;

if ((param('action')||'') eq 'subscribe') {
		BasePage::page_header($session, '');
		print <<'EOF';
<h2>Abonnieren</h2>
EOF
	my $email = param('email');
	my $hash = "\U$email";
	$hash = crypt($hash, "ueshiba");
	my $num = 0;
	while ($hash) {
		$num += ord chop($hash);
		$num %= $#passwords+1;
	}
	my $password = $passwords[$num];
	my $doform = 1;
	if (param('code')) {
		my $code = param('code');
		if ("\U$code" ne "\U$password") {
			print <<'EOF';
<p class="error">Der Code passt nicht zur eingegebenen Email. Haben Sie 
diesen Code wirklich zugeschickt bekommen? Sind eventuell Tippfehler in
Code oder Email?</p>
EOF
		}
		else {
			if (param('sub')) {
				print <<EOF;
<p>Sie haben die aktuellen Nachrichten abonniert und werden diese von nun an
per email an $email zugeschickt bekommen. Wenn sie dies zu einem sp&auml;teren
Zeitpunkt wieder r&uuml;ckgängig machen wollen, so k&ouml;nnen Sie das 
ebenfalls &uuml;ber diese Seite tun.</p>
EOF
				my $sth = $conn->prepare_cached("insert into subscriber (email, name) values (?, ?)");
				$sth->execute($email, param('name'));
				$sth->finish();
			}
			elsif (param('unsub')) {
				my $sth = $conn->prepare_cached("delete from subscriber where email = ?");
				if ($sth->execute($email)) {
				print <<EOF;
<p>Ihr Abonnement wurde gek&uuml;ndigt, Sie werden keine weiteren Nachrichten 
per Email erhalten. Sie k&ouml;nnen das Abonnement zu einem sp&auml;teren 
Zeitpunkt auf dieser Seite wieder aufnehmen, falls Sie das w&uuml;nschen.</p>
EOF
				}
				else {
				print <<EOF;
<p>F&uuml;r diese Email-Addresse ist kein Abonnement vorhanden das 
gek&uuml;ndigt werden k&ouml;nnte. Eventuell haben Sie sich urspr&uuml;nglich 
unter einer anderen Addresse eingetragen?</p>
<p>Sollte es ihnen nicht gelingen ihr Abonnement zu l&ouml;schen, wenden Sie sich bitte an <a href="mailto:robertle\@semistable.com">robertle\@semistable.com</a>.</p>
EOF
				}
				$sth->finish();
			}
			$doform = 0;
		}
	}
	elsif (param('email')) {
		# actually send the mail
		my $sendmail = "/usr/sbin/sendmail -t";
		my $hostname = "aikido.semistable.com";
		my $from = "From: news\@$hostname\n";
		my $to = "To: $email\n";
		my $subject = "Subject: Bestätigungscode\n";
		my $body = 
"Sie haben versucht auf http://www.aikido-esv.de die aktuellen Nachrichten
zu abonnieren oder abzubestellen, benötigen dazu allerdings noch einen 
Bestätigungscode. Dieser lautet für Sie \"$password\". Bitte gehen Sie jetzt 
zurück auf http://www.aikido-esv.de/index.pl?subscribe, tragen Sie dort
erneut ihre Email und den Bestätigungscode ein.";
		my $spacer = "--";
		my $footer = "ESV München e.V\nMargarethe-Danzi-Str. 21\n80639 München\nTel: 089 12711020\nFax: 089 12711636\n1. Vorsitzender: Dr. Ansgar Ruggaber\nVereinsregister des Amtsgerichts München: VR 4386";
		my $mailer;
		open($mailer, "|$sendmail") or die "Cannot open $sendmail: $!";
		print $mailer $subject;
		print $mailer $to;
		print $mailer $from;
		print $mailer "Content-type: text/plain; charset=ISO-8859-15;\n\n";
		print $mailer "$body\n$spacer\n$footer";
		close($mailer);
		print <<EOF
<p>Es wurde eine Email mit dem Best&auml;tigungscode an <b>$email</b> versandt. Bitte warten Sie den empfang dieser Email ab und tragen sich dann hier erneut mit ihrer Email <b>und</b> dem Bestätigungscode ein.</p>
<p>Dies ist leider n&ouml;tig um sicherzustellen dass man nur sich selbst eintragen kann.</p>
EOF
	}
	else {
		print <<'EOF';
<p>&Uuml;ber dieses Formular k&ouml;nnen Sie die neuesten Nachrichten abonnieren und sich direkt als Email schicken lassen. Dazu m&uuml;ssen Sie lediglich ihren Namen (optional) und ihre Email-Addresse angeben. Sie erhalten dann einen Best&auml;tigungscode der sicherstellt dass sie auch der Inhaber der Email sind zugeschickt. Mit diesem Code können Sie dann ihr Abonnement abschließen. Zu einem Späteren Zeitpunkt k&ouml;nnen Sie nat&uuml;rlich ihr Abonnement wieder abbestellen. Ihre Email wird von uns nicht an Dritte weitergegeben.</p>
EOF
	}
	if ($doform == 1) {
		my $pname = param('name');
		my $pemail = param('email');
		my $pcode = param('code');
		print <<EOF;
<form action='index.pl' method='post' accept-charset='ISO-8859-1'>
<table>
<tr><th><label for='name'>Name:</label></th><td><input name='name' type='text' size='30' maxlength='128' value='$pname'/> (optional)</td></tr>
<tr><th><label for='email'>Email:</label></th><td><input name='email' type='text' size='30' maxlength='128' value='$pemail'/></td></tr>
<tr><th><label for='email'>Best&auml;tigungscode:</label></th><td><input name='code' type='text' size='30' maxlength='128' value='$pcode'/> (Wird ihnen in einer Email zugeschickt.)</td></tr>

<tr><th><input type='hidden' name='action' value='subscribe'/></th><td><input type='submit' name='sub' value=' Abonnieren '> &nbsp; <input type='submit' name='unsub' value=' Abbestellen '></td></tr>
</table>
</form>
EOF
	}
}
elsif (param('type') eq ('rss')) {
	my $rss = new XML::RSS (version => '1.0');
	$rss->channel(title   => 'Aikido, Kendo und Iaido News',
               link           => 'http://aikido-esv.de',
	       description    => 'Aktuelles aus der Aikido, Kendo und Iaido-Abteilung des ESV M&uuml;nchen',
               language       => 'de',
               );

	my $sth = $conn->prepare_cached("select id,ctime,subject,text from news order by ctime desc");
	$sth->execute();
	while (my($id, $ctime, $subject, $text) = $sth->fetchrow_array()) {
		# XXX hier gehört die echte zeitzone hin!
		my $time = strftime("%a, %d %b %Y %H:%M:%S GMT", strptime($ctime));
		$rss->add_item(title => $subject,
			guid => "aikido-esv.news.$id",
			pubDate => $time,
		        description => $text,
			link => "http://www.aikido-esv.de/index.pl?hl=$id#$id"
			);
	}
	$sth->finish();

	print "Content-type: application/rss+xml\n\n";
	print $rss->as_string;	
}
else {
	BasePage::page_header($session, '');
	print <<'EOF';
<h2>Aktuelles</h2>
EOF
	
	if (param('action') eq 'update') {
		my $id = param('id');
		my $text = escape(param('text'));
		my $title = escape(param('title'));
		
		$title = substr($title, 0 , 127);
		$text = substr($text, 0 , 1024);
		
		
		my $sth = $conn->prepare_cached("select author from news where id = ?");
		$sth->execute($id);
		my ($dbauthor) = $sth->fetchrow_array();
		$sth->finish();
		if ($dbauthor eq $session->{username}) {
			$sth = $conn->prepare_cached("update news set subject = ?, text = ?, mtime = now() where id = ? and author = ?");
			$sth->execute($title, $text, $id, $session->{username});
			$sth->finish();
		}
		elsif ($caps{'edit_news'}) {
			$sth = $conn->prepare_cached("update news set subject = ?, text = ?, mtime = now() where id = ?");
			$sth->execute($title, $text, $id);
			$sth->finish();
		}
		if (param('nomail') ne "true") {
			$sth = $conn->prepare_cached("update news set mailstatus = 2 where id = ? and mailstatus = 1");
			$sth->execute($id);
			$sth->finish();
		}
		print_news($session, $conn, \%caps);		
		
	}
	elsif (param('action') eq 'edit') {
		my $id = param('id');
		my $sth = $conn->prepare_cached("select id, author, ctime, subject, text from news where id = ?");
		$sth->execute($id);
		if (my($id, $author, $ctime, $subject, $text) = $sth->fetchrow_array()) {
			$subject = unescape($subject);
			$subject =~ s/"/'/g;
			$text = unescape($text);
			if (($author eq $session->{username}) or ($caps{'edit_news'})) {
				print <<EOF;
<p>Bitte geben Sie in diesem Formular Text und Titel des Eintrages an. Links und EMail-Addressen werden automatisch in Hyperlinks verwandelt, Wörter zwischen sternen (*) werden fett geschrieben. Mit den speziellen Tags "file:<i>filename</i>" und "file:<i>filename</i>:<i>linktext</i>" kann auf hochgeladene Dateien verwiesen werden. Bitte immer im Titel angeben für welche Sparte(n) der Eintrag relevant ist (also z.B. "Aikido: ......").</p>
<form action="index.pl" method="post" accept-charset="ISO-8859-1">
<table>
<tr><th><label for="title">Titel:</label></th><td><input name="title" type="text" size="75" maxlength="128" value="$subject"/></td></tr>
<tr><th><label for="text">Text:</label></th><td><textarea name="text" cols="75" rows="6">$text</textarea><input type="hidden" name="id" value="$id"/></td></tr>
<tr><th></th><td><input type="checkbox" name="nomail" value="true"> Keine Email an Abonnenten verschicken</td></tr>
<tr><th><input type="hidden" name="edit" value="true"><input type="hidden" name="action" value="update"/></th><td><input type="submit" value=" &Auml;ndern "></td></tr>
</table>
</form>
EOF
				
			}
			else {
			 # XXX not allowed
			}
		}
		else {
			# XXX news not found
		}
	}
	elsif (param('action') eq "delete") {
		my $id = param('id');
		if (param('delete') eq 'confirmed') {
			my $sth = $conn->prepare_cached("select author from news where id = ?");
			$sth->execute($id);
			my ($author) = $sth->fetchrow_array();
			if (($author eq $session->{username}) or ($caps{'edit_news'})) {
				my $sth2 = $conn->prepare_cached("delete from news where id = ?");
				$sth2->execute($id);
				$sth2->finish();
			}
			$sth->finish();
			print_news($session, $conn, \%caps);
			
		}
		else {
			print <<EOF
<p>Sind Sie sich sicher dass sie den Eintrag l&ouml;schen wollen?</p>
<form action="index.pl" method="post" accept-charset="ISO-8859-1">
<input type="hidden" name="action" value="delete"/>
<input type="hidden" name="id" value="$id"/>
<input type="hidden" name="delete" value="confirmed"/>
<input type="submit" value=" L&ouml;schen "/>
</form>
EOF
		}
	}
	elsif (param('title') and param('text')) {
		if ($caps{'enter_news'}) {
			# add news to the db
			my $text = escape(param('text'));
			my $title = escape(param('title'));
			
			$title = substr($title, 0 , 127);
			$text = substr($text, 0 , 1024);
			my $sth = $conn->prepare_cached("insert into news (id, author, ctime, mtime, subject, text, mailstatus) values (nextval('news_id'), ?, now(), now(), ?, ?, 0)");
			$sth->execute($session->{username}, $title, $text) or die ('Could not update DB!');
	#		my $sth2 = $conn->prepare_cached("select currval('news_id')");
	#		$sth2->execute();
	#		my ($id) = $sth2->fetchrow_array();
	#		$sth2->finish();
			$sth->finish();
			print_news($session, $conn, \%caps);		

		}
		else {
			print <<EOF;
<p class="error">Sie haben nicht die berechtigung Eintr&auml;ge zu verfassen.</p>
EOF
		}
	}
	elsif (param('action') eq 'new') {
		if ($caps{'enter_news'}) {
			print <<EOF;
<form action="index.pl" method="post" accept-charset="ISO-8859-1">
<p>Bitte geben Sie in diesem Formular Text und Titel des Eintrages an. Links und EMail-Addressen werden automatisch in Hyperlinks verwandelt, Wörter zwischen sternen (*) werden fett geschrieben. Mit den speziellen Tags "file:<i>filename</i>" und "file:<i>filename</i>:<i>linktext</i>" kann auf hochgeladene Dateien verwiesen werden. Bitte immer im Titel angeben für welche Sparte(n) der Eintrag relevant ist (also z.B. "Aikido: ......").</p>
<table>
<tr><th><label for="title">Titel:</label></th><td><input name="title" type="text" size="48" maxlength="128"/></td></tr>
<tr><th><label for="text">Text:</label></th><td><textarea name="text" cols="48" rows="6"></textarea></td></tr>
<tr><th></th><td><input type="submit" value=" Eintragen "></td></tr>
</table>
</form>
EOF
		}
		else {
			print <<EOF;
<p class="error">Sie haben nicht die berechtigung Eintr&auml;ge zu verfassen.</p>
EOF
		}
	}
	else {
		print_news($session, $conn, \%caps);
	}

	BasePage::page_footer();
}

