Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 May 2012 18:28:10 +0000 (UTC)
From:      Dag-Erling Smorgrav <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r235729 - in user/des/fbce: . db lib lib/FBCE lib/FBCE/Controller lib/FBCE/Model lib/FBCE/Schema lib/FBCE/Schema/Result lib/FBCE/Script lib/FBCE/View root root/admin root/lib root/resul...
Message-ID:  <201205211828.q4LISAsb068123@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: des
Date: Mon May 21 18:28:09 2012
New Revision: 235729
URL: http://svn.freebsd.org/changeset/base/235729

Log:
  Dump the election server code, as promised two years ago :)

Added:
  user/des/fbce/
  user/des/fbce/Changes
  user/des/fbce/Makefile.PL
  user/des/fbce/README
  user/des/fbce/db/
  user/des/fbce/db/fbce.sql
  user/des/fbce/db/notes
  user/des/fbce/db/update.sh   (contents, props changed)
  user/des/fbce/fbce.conf
  user/des/fbce/lib/
  user/des/fbce/lib/FBCE/
  user/des/fbce/lib/FBCE.pm
  user/des/fbce/lib/FBCE/Controller/
  user/des/fbce/lib/FBCE/Controller.pm
  user/des/fbce/lib/FBCE/Controller/Admin.pm
  user/des/fbce/lib/FBCE/Controller/Result.pm
  user/des/fbce/lib/FBCE/Controller/Root.pm
  user/des/fbce/lib/FBCE/Controller/Run.pm
  user/des/fbce/lib/FBCE/Controller/See.pm
  user/des/fbce/lib/FBCE/Controller/Vote.pm
  user/des/fbce/lib/FBCE/Model/
  user/des/fbce/lib/FBCE/Model/FBCE.pm
  user/des/fbce/lib/FBCE/Model/Schedule.pm
  user/des/fbce/lib/FBCE/Schema/
  user/des/fbce/lib/FBCE/Schema.pm
  user/des/fbce/lib/FBCE/Schema/Result/
  user/des/fbce/lib/FBCE/Schema/Result/Person.pm
  user/des/fbce/lib/FBCE/Schema/Result/Result.pm
  user/des/fbce/lib/FBCE/Schema/Result/Statement.pm
  user/des/fbce/lib/FBCE/Schema/Result/Vote.pm
  user/des/fbce/lib/FBCE/Script/
  user/des/fbce/lib/FBCE/Script/User.pm
  user/des/fbce/lib/FBCE/View/
  user/des/fbce/lib/FBCE/View/HTML.pm
  user/des/fbce/root/
  user/des/fbce/root/admin/
  user/des/fbce/root/admin/index.tt
  user/des/fbce/root/bylaws.tt
  user/des/fbce/root/favicon.ico   (contents, props changed)
  user/des/fbce/root/index.tt
  user/des/fbce/root/lib/
  user/des/fbce/root/lib/bylaws
  user/des/fbce/root/lib/date
  user/des/fbce/root/lib/datetime
  user/des/fbce/root/lib/footer
  user/des/fbce/root/lib/header
  user/des/fbce/root/lib/html_bottom
  user/des/fbce/root/lib/html_top
  user/des/fbce/root/lib/loginout
  user/des/fbce/root/lib/main
  user/des/fbce/root/lib/navigation
  user/des/fbce/root/lib/schedule
  user/des/fbce/root/lib/time
  user/des/fbce/root/login.tt
  user/des/fbce/root/mission.tt
  user/des/fbce/root/result/
  user/des/fbce/root/result/index.tt
  user/des/fbce/root/run/
  user/des/fbce/root/run/closed.tt
  user/des/fbce/root/run/edit.tt
  user/des/fbce/root/run/index.tt
  user/des/fbce/root/run/register.tt
  user/des/fbce/root/run/when
  user/des/fbce/root/run/withdraw.tt
  user/des/fbce/root/see/
  user/des/fbce/root/see/candidate.tt
  user/des/fbce/root/see/index.tt
  user/des/fbce/root/static/
  user/des/fbce/root/static/2010/
  user/des/fbce/root/static/2010/fbce.css
  user/des/fbce/root/static/2010/index.html
  user/des/fbce/root/static/fbce.css
  user/des/fbce/root/static/images/
  user/des/fbce/root/static/images/btn_120x50_built.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_120x50_built_shadow.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_120x50_powered.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_120x50_powered_shadow.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_88x31_built.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_88x31_built_shadow.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_88x31_powered.png   (contents, props changed)
  user/des/fbce/root/static/images/btn_88x31_powered_shadow.png   (contents, props changed)
  user/des/fbce/root/static/images/catalyst_logo.png   (contents, props changed)
  user/des/fbce/root/static/images/lquotes.png   (contents, props changed)
  user/des/fbce/root/static/images/rquotes.png   (contents, props changed)
  user/des/fbce/root/vote/
  user/des/fbce/root/vote/index.tt
  user/des/fbce/root/vote/when
  user/des/fbce/root/x
  user/des/fbce/script/
  user/des/fbce/script/fbce_cgi.pl   (contents, props changed)
  user/des/fbce/script/fbce_create.pl   (contents, props changed)
  user/des/fbce/script/fbce_fastcgi.pl   (contents, props changed)
  user/des/fbce/script/fbce_server.pl   (contents, props changed)
  user/des/fbce/script/fbce_test.pl   (contents, props changed)
  user/des/fbce/script/fbce_user.pl   (contents, props changed)
  user/des/fbce/t/
  user/des/fbce/t/01app.t
  user/des/fbce/t/02pod.t
  user/des/fbce/t/03podcoverage.t
  user/des/fbce/t/controller_Admin.t
  user/des/fbce/t/controller_Result.t
  user/des/fbce/t/controller_Run.t
  user/des/fbce/t/controller_See.t
  user/des/fbce/t/controller_Vote.t
  user/des/fbce/t/model_FBCE.t
  user/des/fbce/t/view_HTML.t

Added: user/des/fbce/Changes
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/Changes	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,4 @@
+This file documents the revision history for Perl extension FBCE.
+
+0.01  2010-06-09 23:31:03
+        - initial revision, generated by Catalyst

Added: user/des/fbce/Makefile.PL
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/Makefile.PL	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,25 @@
+#!/usr/bin/env perl
+# IMPORTANT: if you delete this file your app will not work as
+# expected.  You have been warned.
+use inc::Module::Install;
+use Module::Install::Catalyst; # Complain loudly if you don't have
+                               # Catalyst::Devel installed or haven't said
+                               # 'make dist' to create a standalone tarball.
+
+name 'FBCE';
+all_from 'lib/FBCE.pm';
+
+requires 'Catalyst::Runtime' => '5.80024';
+requires 'Catalyst::Plugin::ConfigLoader';
+requires 'Catalyst::Plugin::Static::Simple';
+requires 'Catalyst::Action::RenderView';
+requires 'Moose';
+requires 'namespace::autoclean';
+requires 'Config::General'; # This should reflect the config file format you've chosen
+                 # See Catalyst::Plugin::ConfigLoader for supported formats
+test_requires 'Test::More' => '0.88';
+catalyst;
+
+install_script glob('script/*.pl');
+auto_install;
+WriteAll;

Added: user/des/fbce/README
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/README	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1 @@
+Run script/fbce_server.pl to test the application.

Added: user/des/fbce/db/fbce.sql
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/db/fbce.sql	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,54 @@
+-- drop table if exists config cascade;
+-- create table config (
+--         key varchar not null primary key,
+--         value varchar not null,
+--         unique(key)
+-- );
+-- insert into config values('reg_open', '2010-06-09T00:00:00');
+-- insert into config values('reg_close', '2010-06-16T00:00:00');
+-- insert into config values('vote_open', '2010-06-17T00:00:00');
+-- insert into config values('vote_close', '2010-07-14T00:00:00');
+
+drop table if exists persons cascade;
+create table persons (
+        id serial primary key,
+        login varchar not null,
+        realname varchar null,
+        password varchar not null,
+        admin boolean not null default false,
+	active boolean not null default false,
+        incumbent boolean not null default false,
+	voted boolean not null default false,
+        votes integer not null default 0,
+        unique(login)
+);
+insert into persons(login, realname, password, admin)
+    values('des', 'Dag-Erling Smørgrav', '*', true);
+
+drop table if exists statements cascade;
+create table statements (
+        id serial primary key,
+        person integer not null,
+        short varchar(64) not null,
+        long text not null,
+        unique(person),
+        foreign key(person) references persons(id) on delete cascade on update cascade
+);
+
+drop table if exists votes cascade;
+create table votes (
+        id serial primary key,
+        voter integer not null,
+        candidate integer not null,
+        unique(voter, candidate),
+        foreign key(voter) references persons(id) on delete cascade on update cascade,
+        foreign key(candidate) references persons(id) on delete cascade on update cascade
+);
+
+drop view if exists results;
+create view results as
+    select persons.id, persons.login as login, persons.realname as realname, persons.incumbent, count(votes.*) as votes
+    from persons join votes on persons.id = votes.candidate
+    group by persons.id, persons.login, persons.realname, persons.incumbent;
+
+-- select * from results order by votes limit 9;

Added: user/des/fbce/db/notes
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/db/notes	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,7 @@
+% sudo /usr/local/etc/rc.d/postgresql initdb
+% sudo /usr/local/etc/rc.d/postgresql start
+% sudo -u pgsql createuser -s des
+% createuser -S -D -R fbce
+% createdb -E utf8 -O fbce fbce
+% psql -f db/fbce.sql fbce fbce 
+% ./db/update.sh

Added: user/des/fbce/db/update.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/db/update.sh	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+cd $(dirname $(realpath $0))
+
+../script/fbce_create.pl model \
+    FBCE DBIC::Schema FBCE::Schema \
+    create=static \
+    "dbi:Pg:dbname=fbce" fbce

Added: user/des/fbce/fbce.conf
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/fbce.conf	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,19 @@
+title = 2012 FreeBSD Core Team Election
+
+<Model::Schedule>
+  nominating_starts = 2012-05-23 00:00:00 UTC
+  nominating_ends = 2012-05-30 00:00:00 UTC
+  voting_starts = 2012-05-30 00:00:00 UTC
+  voting_ends = 2012-06-27 00:00:00 UTC
+  announcement = 2012-06-27 18:00:00 UTC
+  investiture = 2012-07-04
+  # XXX does not belong here
+  max_votes = 9
+</Model::Schedule>
+
+<Session>
+  expires = 1800
+  cookie_expires = 0
+  # cookie_secure = true
+  cache_size = 8m
+</Session>

Added: user/des/fbce/lib/FBCE.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,80 @@
+package FBCE;
+use Moose;
+use MooseX::Types::Common::Numeric qw(PositiveInt);
+use namespace::autoclean;
+
+use Catalyst::Runtime 5.80;
+
+use Catalyst qw/
+    ConfigLoader
+    Authentication
+    Authentication::Credential::Password
+    Session
+    Session::State::Cookie
+    Session::Store::FastMmap
+    Static::Simple
+    Unicode
+/;
+
+extends 'Catalyst';
+
+our $VERSION = '0.01';
+$VERSION = eval $VERSION;
+
+# Configure the application.
+
+__PACKAGE__->config(
+    name => 'FBCE',
+    view => 'HTML',
+    'Plugin::Static::Simple' => {
+	dirs => [ 'static' ],
+    },
+    'Plugin::Authentication' => {
+	default_realm => 'fbce',
+	fbce => {
+	    credential => {
+		class => 'Password',
+		password_field => 'password',
+		password_type  => 'salted_hash',
+	    },
+	    store => {
+		class => 'DBIx::Class',
+		user_model => 'FBCE::Person',
+	    },
+	},
+    },
+    # Disable deprecated behavior needed by old applications
+    disable_component_resolution_regex_fallback => 1,
+);
+
+# Start the application
+__PACKAGE__->setup();
+
+=head1 NAME
+
+FBCE - Catalyst based application
+
+=head1 SYNOPSIS
+
+    script/fbce_server.pl
+
+=head1 DESCRIPTION
+
+[enter your description here]
+
+=head1 SEE ALSO
+
+L<FBCE::Controller::Root>, L<Catalyst>
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;

Added: user/des/fbce/lib/FBCE/Controller.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,57 @@
+package FBCE::Controller;
+use Moose;
+use DateTime;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+=head2 auto
+
+=cut
+
+sub auto :Private {
+    my ($self, $c) = @_;
+
+    $c->stash(title => FBCE->config->{'title'});
+    my $now = DateTime->now();
+    $c->stash(now => $now);
+    my $schedule = $c->comp('FBCE::Model::Schedule');
+    foreach my $phase ("nominating", "voting") {
+       foreach my $endpoint ("${phase}_starts", "${phase}_ends") {
+	   $c->stash($endpoint => $schedule->{$endpoint});
+       }
+    }
+    $c->stash('announcement' => $schedule->{'announcement'});
+    $c->stash('investiture' => $schedule->{'investiture'});
+    $c->stash(nominating => $schedule->nominating($now));
+    $c->stash(voting => $schedule->voting($now));
+    # XXX does not really belong in FBCE::Schedule
+    $c->stash(max_votes => $schedule->{'max_votes'});
+}
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/Admin.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/Admin.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,62 @@
+package FBCE::Controller::Admin;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller::Admin - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+
+=head2 index
+
+=cut
+
+sub index :Path :Args(0) {
+    my ( $self, $c ) = @_;
+
+    my $user = $c->user->get_object();
+    if (!$user->admin) {
+	$c->res->redirect($c->uri_for('/'));
+	$c->detach();
+    }
+    my $voters = $c->model('FBCE::Person')->
+	search(undef, { order_by => 'login' });
+    my $candidates = $c->model('FBCE::Statement')->
+	search_related('person', {}, { order_by => 'login' });
+    my $voted = $c->model('FBCE::Vote')->
+	search_related('voter', {}, { distinct => 1 });
+    my $votes = $c->model('FBCE::Vote');
+    my $results = $c->model('FBCE::Result')->
+	search(undef, { order_by => { -desc => 'votes' } });
+    $c->stash(voters => $voters);
+    $c->stash(candidates => $candidates);
+    $c->stash(voted => $voted);
+    $c->stash(votes => $votes);
+    $c->stash(results => $results);
+}
+
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/Result.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/Result.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,56 @@
+package FBCE::Controller::Result;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller::Result - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+
+=head2 index
+
+=cut
+
+sub index :Path :Args(0) {
+    my ($self, $c) = @_;
+
+    $c->stash(voters => $c->model('FBCE::Person')->
+	      search_rs(undef, { order_by => 'login' }));
+    $c->stash(candidates => $c->model('FBCE::Statement')->
+	      search_related('person', {}, { order_by => 'login' }));
+    if ($c->stash->{'announced'}) {
+	$c->stash(voted => $c->model('FBCE::Vote')->
+		  search_related('voter', {}, { distinct => 1 })->count);
+	$c->stash(votes => $c->model('FBCE::Vote')->count);
+	$c->stash(results => $c->model('FBCE::Result')->
+		  search_rs(undef, { order_by => { -desc => 'votes' } }));
+    } else {
+	$c->stash(voted => 0, votes => 0, results => undef);
+    }
+}
+
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/Root.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/Root.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,143 @@
+package FBCE::Controller::Root;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+#
+# Sets the actions in this controller to be registered with no prefix
+# so they function identically to actions created in MyApp.pm
+#
+__PACKAGE__->config(namespace => '');
+
+=head1 NAME
+
+FBCE::Controller::Root - Root Controller for FBCE
+
+=head1 DESCRIPTION
+
+[enter your description here]
+
+=head1 METHODS
+
+=head2 index
+
+The root page (/)
+
+=cut
+
+sub auto :Private {
+    my ($self, $c) = @_;
+
+    # Stash schedule information etc.
+    $c->stash(title => FBCE->config->{'title'});
+    my $now = DateTime->now();
+    $c->stash(now => $now);
+    my $schedule = $c->comp('FBCE::Model::Schedule');
+    foreach my $phase ("nominating", "voting") {
+	foreach my $endpoint ("${phase}_starts", "${phase}_ends") {
+	    $c->stash($endpoint => $schedule->{$endpoint});
+	}
+    }
+    $c->stash(announcement => $schedule->{'announcement'});
+    $c->stash(investiture => $schedule->{'investiture'});
+    $c->stash(nominating => $schedule->nominating($now));
+    $c->stash(voting => $schedule->voting($now));
+    $c->stash(announced => $schedule->announced($now));
+    # XXX does not really belong in FBCE::Schedule
+    $c->stash(max_votes => $schedule->{'max_votes'});
+
+    # Authentication
+    if ($c->request->path !~ m/^(login|logout|bylaws|mission|static\/.*)?$/) {
+	if (!$c->user_exists) {
+	    $c->stash(action => $c->uri_for());
+	    $c->stash(template => 'login.tt');
+	    return 0;
+	}
+    }
+    if ($c->user) {
+	$c->stash(user => $c->user->get_object());
+    }
+
+    return 1;
+}
+
+sub login :Local :Args(0) {
+    my ($self, $c) = @_;
+
+    my ($login, $password, $action) =
+	@{$c->request->params}{'login', 'password', 'action'};
+    if ($login && $password) {
+	$c->authenticate({
+	    login => $c->request->params->{'login'},
+	    password => $c->request->params->{'password'}
+	});
+    }
+    if ($c->user_exists) {
+	if ($action) {
+	    $c->response->redirect($action);
+	} else {
+	    $c->response->redirect($c->uri_for('/'));
+	}
+	return;
+    }
+    $c->stash(action => $action);
+}
+
+sub logout :Local :Args(0) {
+    my ($self, $c) = @_;
+
+    $c->logout();
+    $c->response->redirect($c->uri_for('/'));
+}
+
+sub index :Path :Args(0) {
+    my ($self, $c) = @_;
+
+}
+
+sub bylaws :Local :Args(0) {
+    my ($self, $c) = @_;
+
+}
+
+sub mission :Local :Args(0) {
+    my ($self, $c) = @_;
+
+}
+
+=head2 default
+
+Standard 404 error page
+
+=cut
+
+sub default :Path {
+    my ($self, $c) = @_;
+
+    $c->response->body('Page not found');
+    $c->response->status(404);
+}
+
+=head2 end
+
+Attempt to render a view, if needed.
+
+=cut
+
+sub end : ActionClass('RenderView') {}
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/Run.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/Run.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,133 @@
+package FBCE::Controller::Run;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller::Run - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+=head2 index
+
+=cut
+
+sub index :Path :Args(0) {
+    my ($self, $c) = @_;
+
+#    $c->authenticate();
+    my $user = $c->user->get_object();
+    $c->stash(user => $user);
+}
+
+sub register :Local :Args(0) {
+    my ($self, $c) = @_;
+
+#    $c->authenticate();
+    my $user = $c->user->get_object();
+    if ($c->stash->{'nominating'} != 0) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    $c->stash(user => $user);
+    if ($user->statement) {
+	$c->res->redirect($c->uri_for('/run/edit'));
+	$c->detach();
+    }
+    my $p = $c->req->params;
+    if ($p->{cancel}) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    if ($p->{submit}) {
+	my $stmt = $c->model('FBCE::Statement')->
+	    new({ person => $user, short => $p->{short}, long => $p->{long} });
+	$stmt->insert()
+	    or die("failed to register");
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    $c->stash(short => $p->{short});
+    $c->stash(long => $p->{long});
+}
+
+sub edit :Local :Args(0) {
+    my ($self, $c) = @_;
+
+#    $c->authenticate();
+    my $user = $c->user->get_object();
+    if ($c->stash->{'nominating'} != 0) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    $c->stash(user => $user);
+    if (!$user->statement) {
+	$c->res->redirect($c->uri_for('/run/register'));
+	$c->detach();
+    }
+    my $p = $c->req->params;
+    if ($p->{cancel}) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    my $statement = $user->statement;
+    if ($p->{submit}) {
+	$statement->update({ short => $p->{short}, long => $p->{long} })
+	    or die("failed to update");
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    $c->stash(short => $p->{short} // $statement->short);
+    $c->stash(long => $p->{long} // $statement->long);
+}
+
+sub withdraw :Local :Args(0) {
+    my ($self, $c) = @_;
+
+#    $c->authenticate();
+    my $user = $c->user->get_object();
+    if ($c->stash->{'nominating'} != 0) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    $c->stash(user => $user);
+    if (!$user->statement) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    my $p = $c->req->params;
+    if ($p->{cancel}) {
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+    my $statement = $user->statement;
+    if ($p->{submit}) {
+	$statement->delete()
+	    or die("failed to delete");
+	$c->res->redirect($c->uri_for('/run'));
+	$c->detach();
+    }
+}
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/See.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/See.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,60 @@
+package FBCE::Controller::See;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller::See - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+
+=head2 index
+
+=cut
+
+sub index :Path :Args(0) {
+    my ($self, $c) = @_;
+
+    my $user = $c->user->get_object();
+    $c->stash(user => $user);
+    my $candidates = $c->model('FBCE::Statement')->
+	search_related('person', {}, { order_by => 'login' });
+    $c->stash(candidates => $candidates);
+}
+
+sub candidate :Local :Args(1) {
+    my ($self, $c, $name) = @_;
+
+    my $user = $c->user->get_object();
+    $c->stash(user => $user);
+    my $candidate = $c->model('FBCE::Person')->find({ login => $name });
+    if (!$candidate || !$candidate->statement) {
+	$c->res->redirect($c->uri_for('/see'));
+	$c->detach();
+    }
+    $c->stash(candidate => $candidate);
+}
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Controller/Vote.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Controller/Vote.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,114 @@
+package FBCE::Controller::Vote;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+=head1 NAME
+
+FBCE::Controller::Vote - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+=head2 index
+
+=cut
+
+sub index :Path :Args(0) {
+    my ($self, $c) = @_;
+
+    my $user = $c->user->get_object();
+    $c->stash(user => $user);
+    if ($c->stash->{'phase'} != 0) {
+	return;
+    }
+    my $p = $c->req->params;
+    if ($p->{cancel}) {
+	$c->res->redirect($c->uri_for('/'));
+	$c->detach();
+    }
+    my $candidates = $c->model('FBCE::Statement')->
+	search_related('person', {}, { order_by => 'login' });
+    my %voted_for;
+    my $error;
+    if ($p->{vote}) {
+	my %vote_for;
+	while (my $candidate = $candidates->next) {
+	    if (exists $p->{"vote_for_" . $candidate->login}) {
+		$vote_for{$candidate->login} = $candidate;
+		$voted_for{$candidate->login} = 1;
+	    }
+	}
+	$candidates->reset;
+	if (scalar keys %vote_for > $c->stash->{'max_votes'}) {
+	    $error = "You can only vote for $c->stash->{'max_votes'} candidates.";
+	} else {
+	    my $schema = $user->result_source->schema;
+	    $schema->txn_do(sub {
+		$user->votes_voters->delete();
+		while (my ($login, $candidate) = each %vote_for) {
+		    $user->votes_voters->create({ candidate => $candidate });
+		}
+	    });
+	    if ($@) {
+		$error = "Database error!";
+	    } else {
+		$c->stash(vote_ok => 1);
+	    }
+	}
+    } else {
+	my $votes = $user->votes_voters;
+	while (my $vote = $votes->next) {
+	    $voted_for{$vote->candidate->login} = 1;
+	}
+    }
+    $c->stash(error => $error);
+    $c->stash(candidates => $candidates);
+    $c->stash(max_votes => $c->stash->{'max_votes'});
+    $c->stash(voted_for => \%voted_for);
+}
+
+# sub commit :Local :Args(0) {
+#     my ($self, $c) = @_;
+
+#     $c->authenticate();
+#     my $user = $c->user->get_object();
+#     if ($c->stash->{'phase'} != 0) {
+# 	$c->res->redirect($c->uri_for('/vote'));
+# 	$c->detach();
+#     }
+#     my $p = $c->req->params;
+#     if ($p->{cancel}) {
+# 	$c->res->redirect($c->uri_for('/vote'));
+# 	$c->detach();
+#     }
+#     if ($p->{commit}) {
+# 	$user->commit()
+# 	    or die("failed to commit");
+# 	$c->res->redirect($c->uri_for('/vote'));
+# 	$c->detach();
+#     }
+#     $c->stash(user => $user);
+# }
+
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: user/des/fbce/lib/FBCE/Model/FBCE.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Model/FBCE.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,43 @@
+package FBCE::Model::FBCE;
+
+use strict;
+use base 'Catalyst::Model::DBIC::Schema';
+
+__PACKAGE__->config(
+    schema_class => 'FBCE::Schema',
+    
+    connect_info => {
+        dsn => 'dbi:Pg:dbname=fbce',
+        user => 'fbce',
+        password => '',
+    }
+);
+
+=head1 NAME
+
+FBCE::Model::FBCE - Catalyst DBIC Schema Model
+
+=head1 SYNOPSIS
+
+See L<FBCE>
+
+=head1 DESCRIPTION
+
+L<Catalyst::Model::DBIC::Schema> Model using schema L<FBCE::Schema>
+
+=head1 GENERATED BY
+
+Catalyst::Helper::Model::DBIC::Schema - 0.59
+
+=head1 AUTHOR
+
+Dag-Erling Smørgrav
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;

Added: user/des/fbce/lib/FBCE/Model/Schedule.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/fbce/lib/FBCE/Model/Schedule.pm	Mon May 21 18:28:09 2012	(r235729)
@@ -0,0 +1,115 @@
+package FBCE::Model::Schedule;
+use Moose;
+use MooseX::Types::Common::Numeric qw(PositiveInt);
+use MooseX::Types::DateTime::MoreCoercions qw(DateTime);
+use DateTime;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Component' }
+
+=head1 NAME
+
+FBCE::Controller - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=cut
+
+has nominating_starts => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+has nominating_ends => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+has voting_starts => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+has voting_ends => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+has announcement => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+has investiture => (
+    isa => DateTime,
+    coerce => 1,
+    is => 'ro',
+    required => 1
+);
+
+# XXX does not belong here
+has max_votes => (
+    isa => PositiveInt,
+    is => 'ro',
+    required => 1
+);
+
+sub _phase($$$) {
+    my ($self, $phase, $now) = @_;
+
+    $now //= main::DateTime->now();
+    my ($starts, $ends) = ("${phase}_starts", "${phase}_ends");
+    my ($st, $et) = ($self->{$starts}, $self->{$ends});
+    if (main::DateTime->compare($now, $st) < 0) {
+	return -1;
+    } elsif (main::DateTime->compare($now, $et) < 0) {
+	return 0;
+    } else {
+	return 1;
+    }
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205211828.q4LISAsb068123>