source: trunk/wiki.cgi @ 791

Last change on this file since 791 was 790, checked in by nick, 16 years ago

Pass the requested feed listing through all the feeds code, rather than just assuming it's recent_changes

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