root/tags/rel0_58/wiki.cgi

Revision 920, 16.9 kB (checked in by dom, 2 years ago)

Version

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