package PgCommitFest::CommitFest; use strict; use warnings; sub delete { my ($r) = @_; $r->authenticate('require_login' => 1, 'require_administrator' => 1); $r->set_title('Delete CommitFest'); my $d; eval { $d = $r->db->select_one(<cgi_required_id); DELETE FROM commitfest WHERE id = ? RETURNING id EOM }; my $err = $@; if (! $err) { $r->error_exit('CommitFest not found.') if !defined $d; $r->db->commit; $r->redirect('/'); } if ($err =~ /commitfest_topic_commitfest_id_fkey/) { $r->error_exit(<error_exit("Internal error: $@"); } sub form { my ($r) = @_; $r->authenticate('require_login' => 1, 'require_administrator' => 1); # Decide whether this is a new commitfest or an edit of an existing # commitfest, and if editing reload data from database. my $d; my $id = $r->cgi_id(); if (defined $id) { $r->set_title('Edit CommitFest'); $d = $r->db->select_one(<error_exit('CommitFest not found.') if !defined $d; $r->redirect('/action/commitfest_view?id=' . $id) if $r->cgi('cancel'); } else { $r->set_title('New CommitFest'); $r->redirect('/') if $r->cgi('cancel'); } # Add controls. $r->add_control('name', 'text', 'Name', 'required' => 1); $r->add_control('commitfest_status', 'select', 'Status', 'required' => 1); $r->control('commitfest_status')->choice($r->db->select(<initialize_controls($d); # Handle commit. if ($r->cgi('go') && ! $r->is_error()) { if (defined $id) { $r->db->update('commitfest', { 'id' => $id }, \%value); } else { $id = $r->db->insert_returning_id('commitfest', \%value); } $r->db->commit; $r->redirect('/action/commitfest_view?id=' . $id); } # Display template. $r->render_template('commitfest_form', { 'id' => $id }); } sub search { my ($r) = @_; my $aa = $r->authenticate(); $r->set_title('CommitFest Index'); if (defined $aa && $aa->{'is_administrator'}) { $r->add_link('/action/commitfest_form', 'New CommitFest'); } my $list = $r->db->select(<render_template('commitfest_search', { 'list' => $list }); } sub view { my ($r, $extrapath) = @_; my $aa = $r->authenticate(); # Target commitfest can be specified either by ID, or we allow special # magic to fetch it by my $id = $r->cgi_id(); my $sqlbit; if (defined $id) { $sqlbit = "WHERE id = " . $r->db->quote($id); } elsif (defined $extrapath) { if ($extrapath eq 'open') { $sqlbit = "WHERE commitfest_status_id = 2 ORDER BY name DESC LIMIT 1"; } elsif ($extrapath eq 'inprogress') { $sqlbit = <error_exit("Unable to identify target CommitFest."); } # Fetch target commitfest from database. my $d = $r->db->select_one(<error_exit('CommitFest not found.') if !defined $d; $r->set_title('CommitFest %s (%s)', $d->{'name'}, $d->{'commitfest_status'}); # Load list of patches. my $previous_topic; my %patch_grouping; my %patch_index; my $patch_list = $r->db->select(<{'id'}); SELECT id, name, patch_status_id, patch_status, author, reviewers, commitfest_topic_id, commitfest_topic, commitfest_id, date_closed FROM patch_view WHERE commitfest_id = ? ORDER BY date_closed, commitfest_topic_sortorder, commitfest_topic, id EOM for my $p (@$patch_list) { if (grep { $_ eq $p->{'patch_status_id'} } qw(4 5 6)) { push @{$patch_grouping{$p->{'patch_status_id'}}}, $p; } else { if (!defined $previous_topic || $previous_topic ne $p->{'commitfest_topic'}) { push @{$patch_grouping{'p'}}, { 'topic_header' => 1, 'commitfest_topic' => $p->{'commitfest_topic'} }; $previous_topic = $p->{'commitfest_topic'}; } push @{$patch_grouping{'p'}}, $p; } $patch_index{$p->{'id'}} = $p; } # Load list of comments. my $comment_list = $r->db->select(<{'id'}); SELECT v.id, v.patch_id, v.patch_comment_type, v.message_id, v.content, v.creator, to_char(v.creation_time, 'YYYY-MM-DD') AS creation_time FROM most_recent_comments(?) v EOM for my $c (@$comment_list) { my $p = $patch_index{$c->{'patch_id'}}; unshift @{$p->{'comment_list'}}, $c; } # Add links and render template. $r->add_link('/action/patch_form?commitfest=' . $id, 'New Patch'); $r->add_link('/action/commitfest_topic_search?id=' . $id, 'CommitFest Topics'); if (defined $aa && $aa->{'is_administrator'}) { $r->add_link('/action/commitfest_form?id=' . $id, 'Edit CommitFest'); $r->add_link('/action/commitfest_delete?id=' . $id, 'Delete CommitFest', 'Are you sure you want to delete this CommitFest?'); } $r->render_template('commitfest_view', { 'd' => $d, 'patch_grouping' => [ { 'name' => 'Pending Patches', 'patch_list' => $patch_grouping{'p'}, 'closed' => 0 }, { 'name' => 'Committed Patches', 'patch_list' => $patch_grouping{'4'}, 'closed' => 1 }, { 'name' => 'Returned with Feedback', 'patch_list' => $patch_grouping{'5'}, 'closed' => 1 }, { 'name' => 'Rejected Patches', 'patch_list' => $patch_grouping{'6'}, 'closed' => 1 }, ]}); } 1;