/index.fcgi
#!/usr/bin/perl
use CGI::Fast qw/:standard/;
use CGI::Session;
#use CGI::Carp qw/fatalsToBrowser/;
use Vector::Config qw/$webroot/;
use Vector::Util qw/url_encode/;
use Vector::Channel;
use Vector::Post;
use Vector::Auth qw/authbox/;
use Vector::Paginator;
use Vector::File;
use Vector::Notify;
use Vector::Error;
use Vector::Template;
use strict;
our ($login_id, $login_user);
my ($type, $object, $subobject, @extra);
my ($pobject, $plink, $head);
sub page_setup {
my ($session) = @_;
if ($type eq 'channel') {
$pobject = "#$object";
$plink = "${webroot}channel/$object";
if (defined $subobject) {
$head = qq{<link rel="alternate" type="application/rss+xml" title="Thread $subobject in #$object [RSS]" href="${webroot}rss/$object/$subobject">};
} else {
$head = qq{<link rel="alternate" type="application/rss+xml" title="All posts in #$object [RSS]" href="${webroot}rss/$object">};
}
if ($login_id) {
if (param('Reply')) {
my $channel_id = Vector::Channel::id($object);
my $replyto = param('replyto');
my $file = Vector::File::store;
my $post = new Vector::Post($login_id, $channel_id, param('data'), $file, $replyto);
$post->save;
print redirect($post->post_uri);
next REQUEST;
} elsif (param('Start Thread')) {
my $channel_id = Vector::Channel::id($object);
unless ($channel_id) {
$channel_id = Vector::Channel::create($object);
}
my $file = Vector::File::store;
my $post = new Vector::Post($login_id, $channel_id, param('data'), $file);
$post->save;
print redirect($post->thread_uri);
next REQUEST;
} elsif (url_param('watch')) {
my $channel_id = Vector::Channel::id($object);
if (url_param('watch') eq 'on') {
Vector::Notify::set($login_id, $channel_id, $subobject);
} else {
Vector::Notify::clear($login_id, $channel_id, $subobject);
}
print redirect("${webroot}channel/$object" . (defined $subobject ? "/$subobject" : ''));
next REQUEST;
}
}
} elsif ($type eq 'user') {
$plink = "${webroot}user/$object/" . join('/', @extra);
$object = $object . '://' . @extra[0] . '/' . join('/', splice(@extra, 1));
$pobject = "~$object";
if ($login_user->{username} eq $object) {
if (param('Save')) {
$login_user->{email} = param('email');
$login_user->save;
print redirect($login_user->user_url);
next REQUEST;
}
}
} else {
$pobject = 'Home';
$plink = $webroot;
$head = qq{<link rel="alternate" type="application/rss+xml" title="Channel List [RSS]" href="${webroot}rss">};
if (param('Join Channel')) {
my $channel = param('channel');
$channel =~ s/^#//;
print redirect($webroot . 'channel/' . url_encode($channel));
next REQUEST;
}
}
Delete('data');
}
sub page_display {
my ($session) = @_;
print $session->header,
start_html(
-title => "Vector: $pobject",
-style => "${webroot}static/style.css",
-head => <<HEAD
<link rel="icon" type="image/png" href="${webroot}static/favicon.png">
<script type="text/javascript" src="${webroot}static/ui.js"></script>
$head
HEAD
);
print h1(a({href => $plink}, $pobject));
authbox($session);
if ($login_id) {
print div({style => 'text-align: right'}, a({href => $login_user->user_url}, 'Preferences'));
}
if ($type eq 'channel') {
my $channel_id = Vector::Channel::id($object);
if (defined $subobject) {
my $head = load Vector::Post($subobject);
if ($login_id) {
print p, Vector::Notify::widget($login_id, $channel_id, $subobject);
}
print '<ul class="posts">';
$head->print;
print '</ul>';
} else {
my $paginator = new Vector::Paginator("$webroot$type/$object", param('page') || 0, reverse Vector::Channel::list($object));
my $navigator = $paginator->navigator;
my @heads = map { load Vector::Post($_) } $paginator->page_items;
if ($login_id) {
print p, Vector::Notify::widget($login_id, $channel_id);
}
if (@heads) {
print p, $navigator;
print '<ul class="posts">';
foreach my $h (@heads) {
$h->print(10);
}
print '</ul>';
print p, $navigator;
} else {
print p, "Channel is empty.";
}
if ($login_id) {
print h2('Start Thread');
print start_form,
textarea('data', '', 5, 60), br,
filefield(-name => 'file'), br,
submit('Start Thread'),
end_form;
}
}
} elsif ($type eq 'user') {
if ($login_id) {
if ($object eq $login_user->{username}) {
print start_form,
'Email: ', textfield('email', $login_user->{email}, 40),
p, submit('Save'),
end_form;
}
}
} else {
my %env;
unless ($login_id) {
$env{GETSTARTED} = "After you log in, you can create a channel by joining a nonexistent channel and then posting.";
}
$env{GETSTARTED} .= p . start_form .
textfield('channel', '', 20) .
submit('Join Channel') .
end_form;
Vector::Template::process('home', \%env);
}
print end_html;
}
REQUEST:
while (my $q = new CGI::Fast) {
my $session = new CGI::Session($q);
$login_id = $session->param('id');
if ($login_id) {
$login_user = Vector::User->fetch_by_id($login_id);
} else {
$login_user = undef;
}
(undef, $type, $object, @extra) = split(m'/', $ENV{PATH_INFO});
$subobject = $extra[0];
eval { page_setup($session) };
if ($@) {
Vector::Error::error_page;
next REQUEST;
}
eval { page_display($session) };
if ($@) {
print "Kaboom: $@";
}
}