source: trunk/wiki.cgi @ 798

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

Allow feed version of list_all_versions if requested

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