source: trunk/wiki.cgi @ 821

Last change on this file since 821 was 821, checked in by nick, 15 years ago

Add the page to list nodes needing moderation

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1#!/usr/local/bin/perl
2
3use strict;
4use warnings;
5
6use vars qw( $VERSION );
7$VERSION = '0.56';
8
9use CGI qw/:standard/;
10use CGI::Carp qw(croak);
11use Wiki::Toolkit;
12use Geography::NationalGrid;
13use Geography::NationalGrid::GB;
14use OpenGuides;
15use OpenGuides::CGI;
16use OpenGuides::Config;
17use OpenGuides::RDF;
18use OpenGuides::Utils;
19use OpenGuides::Template;
20use Time::Piece;
21use URI::Escape;
22
23my $config_file = $ENV{OPENGUIDES_CONFIG_FILE} || "wiki.conf";
24my $config = OpenGuides::Config->new( file => $config_file );
25
26my $script_name = $config->script_name;
27my $script_url  = $config->script_url;
28
29my ($guide, $wiki, $formatter, $q);
30eval {
31    $guide = OpenGuides->new( config => $config );
32    $wiki = $guide->wiki;
33    $formatter = $wiki->formatter;
34
35    # Get CGI object, find out what to do.
36    $q = CGI->new;
37
38    # Note $q->param('keywords') gives you the entire param string.
39    # We need this to do URLs like foo.com/wiki.cgi?This_Page
40    my $node = $q->param('id') || $q->param('title') || $q->param('keywords') || "";
41    $node = $formatter->node_param_to_node_name( $node );
42
43    my $action       = $q->param('action')  || 'display';
44    my $commit       = $q->param('Save')    || 0;
45    my $preview      = $q->param('preview') || 0;
46    my $search_terms = $q->param('terms')   || $q->param('search') || '';
47    my $format       = $q->param('format')  || '';
48    my $oldid        = $q->param('oldid')   || '';
49
50    # Alternative method of calling search, supported by usemod.
51    $action = 'search' if $q->param("search");
52
53    if ($commit) {
54        $guide->commit_node(
55                             id      => $node,
56                             cgi_obj => $q,
57                           );
58    } elsif ($preview) {
59        preview_node($node);
60    } elsif ($action eq 'edit') {
61        edit_node($node);
62    } elsif ($action eq 'search') {
63        do_search($search_terms);
64    } elsif ($action eq 'show_backlinks') {
65        $guide->show_backlinks( id => $node );
66    } elsif ($action eq 'show_wanted_pages') {
67        show_wanted_pages();
68    } elsif ($action eq 'show_needing_moderation') {
69        show_needing_moderation();
70    } elsif ($action eq 'index') {
71        $guide->show_index(
72                            type   => $q->param("index_type") || "Full",
73                            value  => $q->param("index_value") || "",
74                            format => $format,
75                          );
76    } elsif ($action eq 'random') {
77        my @nodes = $wiki->list_all_nodes();
78        $node = $nodes[int(rand(scalar(@nodes) + 1)) + 1];
79        print $guide->redirect_to_node($node);
80    } elsif ($action eq 'find_within_distance') {
81        $guide->find_within_distance(
82                                      id => $node,
83                                      metres => $q->param("distance_in_metres")
84                                    );
85    } elsif ( $action eq 'admin' ) {
86        $guide->display_admin_interface();
87    } elsif ( $action eq 'set_moderation' ) {
88        $guide->set_node_moderation(
89                             id       => $node,
90                             password => $q->param("password") || "",
91                             moderation_flag => $q->param("moderation_flat") || "",
92                           );
93    } elsif ( $action eq 'moderate' ) {
94        $guide->moderate_node(
95                             id       => $node,
96                             version  => $q->param("version") || "",
97                             password => $q->param("password") || "",
98                           );
99    } elsif ( $action eq 'delete'
100              and ( lc($config->enable_page_deletion) eq "y"
101                    or $config->enable_page_deletion eq "1" )
102            ) {
103        $guide->delete_node(
104                             id       => $node,
105                             version  => $q->param("version") || "",
106                             password => $q->param("password") || "",
107                           );
108    } elsif ($action eq 'userstats') {
109        show_userstats(
110                        username => $q->param("username") || "",
111                        host     => $q->param("host") || "",
112                      );
113    } elsif ($action eq 'list_all_versions') {
114        if($format && ($format eq "rss" || $format eq "atom")) {
115            my %args = (
116                            feed_type    => $format,
117                            feed_listing => 'node_all_versions',
118                            name         => $node
119            );
120            $guide->display_feed( %args );
121        } else {
122            $guide->list_all_versions( id => $node );
123        }
124    } elsif ($action eq 'rc') {
125        if ($format && $format eq 'rss') {
126            my $feed = $q->param("feed");
127            if ( !defined $feed or $feed eq "recent_changes" ) {
128                my %args = map { $_ => ( $q->param($_) || "" ) }
129                           qw( feed items days ignore_minor_edits username
130                               category locale );
131                $args{feed_type} = 'rss';
132                $args{feed_listing} = 'recent_changes';
133                $guide->display_feed( %args );
134            } elsif ( $feed eq "chef_dan" ) {
135                display_node_rdf( node => $node );
136            } else {
137                croak "Unknown RSS feed type '$feed'";
138            }
139        } elsif ($format && $format eq 'atom') {
140            my %args = map { $_ => ( $q->param($_) || "" ) }
141                       qw( feed items days ignore_minor_edits username
142                           category locale );
143            $args{feed_type} = 'atom';
144            $args{feed_listing} = 'recent_changes';
145            $guide->display_feed( %args );
146        } else {
147            $guide->display_node( id => 'RecentChanges' );
148        }
149    } elsif ($action eq 'rss') {
150        my $redir_target = $script_url . $script_name . '?action=rc;format=rss';
151        my %args = map { $_ => ( $q->param($_) || "" ) }
152            qw( feed items days ignore_minor_edits username
153                category locale );
154        foreach my $arg (sort keys %args) {
155            if ($args{$arg} ne "") {
156                $redir_target .= ";$arg=$args{$arg}";
157            }
158        }
159        print $q->redirect( $redir_target );
160    } elsif ($action eq 'about') {
161        $guide->display_about(format => $format);
162    } else { # Default is to display a node.
163        if ( $format and $format eq "rdf" ) {
164            display_node_rdf( node => $node );
165        } elsif ( $format and $format eq 'raw' ) {
166            $guide->display_node(
167                                  id       => $node,
168                                  format   => 'raw',
169                                );
170        } else {
171            my $version = $q->param("version");
172            my $other_ver = $q->param("diffversion");
173            if ( $other_ver ) {
174                $guide->display_diffs(
175                                       id            => $node,
176                                       version       => $version,
177                                       other_version => $other_ver,
178                                     );
179            } else {
180                my $redirect;
181               
182                if ((defined $q->param("redirect")) && ($q->param("redirect") == 0)) {
183                  $redirect = 0;
184                } else {
185                  $redirect = 1;               
186                }
187               
188                $guide->display_node(
189                                      id       => $node,
190                                      version  => $version,
191                                      oldid    => $oldid,
192                                      redirect => $redirect,
193                                    );
194            }
195        }
196    }
197};
198
199if ($@) {
200    my $error = $@;
201    warn $error;
202    print $q->header;
203    my $contact_email = $config->contact_email;
204    print qq(<html><head><title>ERROR</title></head><body>
205             <p>Sorry!  Something went wrong.  Please contact the
206             Wiki administrator at
207             <a href="mailto:$contact_email">$contact_email</a> and quote
208             the following error message:</p><blockquote>)
209      . $q->escapeHTML($error)
210      . qq(</blockquote><p><a href="$script_name">Return to the Wiki home page</a>
211           </body></html>);
212}
213
214############################ subroutines ###################################
215
216sub show_userstats {
217    my %args = @_;
218    my ($username, $host) = @args{ qw( username host ) };
219    croak "No username or host supplied to show_userstats"
220        unless $username or $host;
221    my %criteria = ( last_n_changes => 5 );
222    $criteria{metadata_was} = $username ? { username => $username }
223                                        : { host     => $host };
224    my @nodes = $wiki->list_recent_changes( %criteria );
225    @nodes = map { {name          => $q->escapeHTML($_->{name}),
226            last_modified => $q->escapeHTML($_->{last_modified}),
227            comment       => $q->escapeHTML($_->{metadata}{comment}[0]),
228            url           => "$script_name?"
229          . $q->escape($formatter->node_name_to_node_param($_->{name})) }
230                       } @nodes;
231    my %tt_vars = ( last_five_nodes => \@nodes,
232            username        => $username,
233            username_param  => $wiki->formatter->node_name_to_node_param($username),
234                    host            => $host,
235                  );
236    process_template("userstats.tt", "", \%tt_vars);
237}
238
239sub preview_node {
240    my $node = shift;
241    my $content  = $q->param('content');
242    $content     =~ s/\r\n/\n/gs;
243    my $checksum = $q->param('checksum');
244
245    my %tt_metadata_vars = OpenGuides::Template->extract_metadata_vars(
246                                               wiki                 => $wiki,
247                           config               => $config,
248                           cgi_obj              => $q,
249                                               set_coord_field_vars => 1,
250    );
251    foreach my $var ( qw( username comment edit_type ) ) {
252        $tt_metadata_vars{$var} = $q->escapeHTML($q->param($var));
253    }
254
255    if ($wiki->verify_checksum($node, $checksum)) {
256        my %tt_vars = (
257            %tt_metadata_vars,
258            content                => $q->escapeHTML($content),
259            preview_html           => $wiki->format($content),
260            preview_above_edit_box => get_cookie( "preview_above_edit_box" ),
261            checksum               => $q->escapeHTML($checksum)
262    );
263        process_template("edit_form.tt", $node, \%tt_vars);
264    } else {
265        my %node_data = $wiki->retrieve_node($node);
266        my %tt_vars = ( checksum       => $node_data{checksum},
267                        new_content    => $content,
268                        stored_content => $node_data{content} );
269        foreach my $mdvar ( keys %tt_metadata_vars ) {
270            if ($mdvar eq "locales") {
271                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{locale};
272                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{locale};
273            } elsif ($mdvar eq "categories") {
274                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{category};
275                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{category};
276            } elsif ($mdvar eq "username" or $mdvar eq "comment"
277                      or $mdvar eq "edit_type" ) {
278                $tt_vars{$mdvar} = $tt_metadata_vars{$mdvar};
279            } else {
280                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{$mdvar}[0];
281                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{$mdvar};
282            }
283        }
284        process_template("edit_conflict.tt", $node, \%tt_vars);
285    }
286}
287
288sub edit_node {
289    my $node = shift;
290    my %node_data = $wiki->retrieve_node($node);
291    my ($content, $checksum) = @node_data{ qw( content checksum ) };
292    my $username = get_cookie( "username" );
293    my $edit_type = get_cookie( "default_edit_type" ) eq "normal" ?
294                        "Normal edit" : "Minor tidying";
295
296    my %metadata_vars = OpenGuides::Template->extract_metadata_vars(
297                             wiki     => $wiki,
298                             config   => $config,
299                 metadata => $node_data{metadata} );
300
301    $metadata_vars{website} ||= 'http://';
302
303    my %tt_vars = ( content         => $q->escapeHTML($content),
304                    checksum        => $q->escapeHTML($checksum),
305                    %metadata_vars,
306            username        => $username,
307                    edit_type       => $edit_type,
308                    deter_robots    => 1,
309    );
310
311    process_template("edit_form.tt", $node, \%tt_vars);
312}
313
314sub get_cookie {
315    my $pref_name = shift or return "";
316    my %cookie_data = OpenGuides::CGI->get_prefs_from_cookie(config=>$config);
317    return $cookie_data{$pref_name};
318}
319
320sub display_node_rdf {
321    my %args = @_;
322    my $rdf_writer = OpenGuides::RDF->new( wiki      => $wiki,
323                       config => $config );
324    print "Content-type: application/rdf+xml\n\n";
325    print $rdf_writer->emit_rdfxml( node => $args{node} );
326}
327
328sub process_template {
329    my ($template, $node, $vars, $conf, $omit_header) = @_;
330
331    my %output_conf = ( wiki     => $wiki,
332            config   => $config,
333                        node     => $node,
334            template => $template,
335            vars     => $vars
336    );
337    $output_conf{content_type} = "" if $omit_header; # defaults otherwise
338    print OpenGuides::Template->output( %output_conf );
339}
340
341
342sub do_search {
343    my $terms = shift;
344    my %finds = $wiki->search_nodes($terms);
345#    my @sorted = sort { $finds{$a} cmp $finds{$b} } keys %finds;
346    my @sorted = sort keys %finds;
347    my @results = map {
348        { url   => $q->escape($formatter->node_name_to_node_param($_)),
349      title => $q->escapeHTML($_)
350        }             } @sorted;
351    my %tt_vars = ( results      => \@results,
352                    num_results  => scalar @results,
353                    not_editable => 1,
354                    search_terms => $q->escapeHTML($terms) );
355    process_template("search_results.tt", "", \%tt_vars);
356}
357
358sub show_wanted_pages {
359    my @dangling = $wiki->list_dangling_links;
360    my @wanted;
361    my %backlinks_count;
362    foreach my $node_name (@dangling) {
363        $backlinks_count{$node_name} = scalar($wiki->list_backlinks( node => $node_name ));
364    }
365    foreach my $node_name (sort { $backlinks_count{$b} <=> $backlinks_count{$a} } @dangling) {
366        my $node_param =
367         uri_escape($formatter->node_name_to_node_param($node_name));
368        push @wanted, {
369            name          => $q->escapeHTML($node_name),
370            edit_link     => $script_url . uri_escape($script_name)
371                           . "?action=edit;id=$node_param",
372            backlink_link => $script_url . uri_escape($script_name)
373                    . "?action=show_backlinks;id=$node_param",
374            backlinks_count => $backlinks_count{$node_name}
375        };
376    }
377    process_template( "wanted_pages.tt",
378                      "",
379                      { not_editable  => 1,
380                        not_deletable => 1,
381                        deter_robots  => 1,
382                        wanted        => \@wanted } );
383}
384
385sub show_needing_moderation {
386    my @nodes = $wiki->list_unmoderated_nodes;
387
388    # Build the moderate link
389    foreach my $node (@nodes) {
390        my $node_param =
391            uri_escape($formatter->node_name_to_node_param($node->{'name'}));
392        $node->{'moderate_url'} = $script_url . "?action=moderate&id=".$node_param."&version=".$node->{'version'};
393        $node->{'diff_url'} = $script_url . "?id=".$node_param."&version=".$node->{'moderated_version'}."&diffversion=".$node->{'version'};
394    }
395
396    process_template( "needing_moderation.tt",
397                      "",
398                      { not_editable  => 1,
399                        not_deletable => 1,
400                        deter_robots  => 1,
401                        nodes        => \@nodes } );
402}
Note: See TracBrowser for help on using the repository browser.