source: trunk/wiki.cgi @ 703

Last change on this file since 703 was 700, checked in by Earle Martin, 16 years ago

Change "action=rss" parameter to "action=rc;format=rss". Extract RecentChanges code in OpenGuides.pm to its own sub (display_recent_changes()). Fix references to old params in templates. Put redirect to URL with new parameters into wiki.cgi for old parameter.

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