root/tags/rel0_48/wiki.cgi

Revision 661, 11.9 kB (checked in by dom, 3 years ago)

Prepare for 0.48 release.

  • 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.48';
8
9use CGI qw/:standard/;
10use CGI::Carp qw(croak);
11use CGI::Wiki;
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        exit 0;
79    } elsif ($action eq 'find_within_distance') {
80        $guide->find_within_distance(
81                                      id => $node,
82                                      metres => $q->param("distance_in_metres")
83                                    );
84    } elsif ( $action eq 'delete'
85              and ( lc($config->enable_page_deletion) eq "y"
86                    or $config->enable_page_deletion eq "1" )
87            ) {
88        $guide->delete_node(
89                             id       => $node,
90                             version  => $q->param("version") || "",
91                             password => $q->param("password") || "",
92                           );
93    } elsif ($action eq 'userstats') {
94        show_userstats(
95                        username => $q->param("username") || "",
96                        host     => $q->param("host") || "",
97                      );
98    } elsif ($action eq 'list_all_versions') {
99        $guide->list_all_versions( id => $node );
100    } elsif ($action 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            $guide->display_rss( %args );
107        } elsif ( $feed eq "chef_dan" ) {
108            display_node_rdf( node => $node );
109        } else {
110            croak "Unknown RSS feed type '$feed'";
111        }
112    } else { # Default is to display a node.
113        if ( $format and $format eq "rdf" ) {
114            display_node_rdf( node => $node );
115        } else {
116            my $version = $q->param("version");
117            my $other_ver = $q->param("diffversion");
118            if ( $other_ver ) {
119                $guide->display_diffs(
120                                       id            => $node,
121                                       version       => $version,
122                                       other_version => $other_ver,
123                                     );
124            } else {
125                $guide->display_node(
126                                      id      => $node,
127                                      version => $version,
128                                      oldid   => $oldid,
129                );
130               
131            }
132        }
133    }
134};
135
136if ($@) {
137    my $error = $@;
138    warn $error;
139    print $q->header;
140    my $contact_email = $config->contact_email;
141    print qq(<html><head><title>ERROR</title></head><body>
142             <p>Sorry!  Something went wrong.  Please contact the
143             Wiki administrator at
144             <a href="mailto:$contact_email">$contact_email</a> and quote
145             the following error message:</p><blockquote>)
146      . $q->escapeHTML($error)
147      . qq(</blockquote><p><a href="$script_name">Return to the Wiki home page</a>
148           </body></html>);
149}
150exit 0;
151
152############################ subroutines ###################################
153
154sub show_userstats {
155    my %args = @_;
156    my ($username, $host) = @args{ qw( username host ) };
157    croak "No username or host supplied to show_userstats"
158        unless $username or $host;
159    my %criteria = ( last_n_changes => 5 );
160    $criteria{metadata_was} = $username ? { username => $username }
161                                        : { host     => $host };
162    my @nodes = $wiki->list_recent_changes( %criteria );
163    @nodes = map { {name          => $q->escapeHTML($_->{name}),
164                    last_modified => $q->escapeHTML($_->{last_modified}),
165                    comment       => $q->escapeHTML($_->{metadata}{comment}[0]),
166                    url           => "$script_name?"
167          . $q->escape($formatter->node_name_to_node_param($_->{name})) }
168                       } @nodes;
169    my %tt_vars = ( last_five_nodes => \@nodes,
170                    username        => $username,
171                    username_param  => $wiki->formatter->node_name_to_node_param($username),
172                    host            => $host,
173                  );
174    process_template("userstats.tt", "", \%tt_vars);
175}
176
177sub preview_node {
178    my $node = shift;
179    my $content  = $q->param('content');
180    $content     =~ s/\r\n/\n/gs;
181    my $checksum = $q->param('checksum');
182
183    my %tt_metadata_vars = OpenGuides::Template->extract_metadata_vars(
184                                               wiki                 => $wiki,
185                                               config               => $config,
186                                               cgi_obj              => $q,
187                                               set_coord_field_vars => 1,
188    );
189    foreach my $var ( qw( username comment edit_type ) ) {
190        $tt_metadata_vars{$var} = $q->escapeHTML($q->param($var));
191    }
192
193    if ($wiki->verify_checksum($node, $checksum)) {
194        my %tt_vars = (
195            %tt_metadata_vars,
196            content                => $q->escapeHTML($content),
197            preview_html           => $wiki->format($content),
198            preview_above_edit_box => get_cookie( "preview_above_edit_box" ),
199            checksum               => $q->escapeHTML($checksum)
200        );
201        process_template("edit_form.tt", $node, \%tt_vars);
202    } else {
203        my %node_data = $wiki->retrieve_node($node);
204        my %tt_vars = ( checksum       => $node_data{checksum},
205                        new_content    => $content,
206                        stored_content => $node_data{content} );
207        foreach my $mdvar ( keys %tt_metadata_vars ) {
208            if ($mdvar eq "locales") {
209                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{locale};
210                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{locale};
211            } elsif ($mdvar eq "categories") {
212                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{category};
213                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{category};
214            } elsif ($mdvar eq "username" or $mdvar eq "comment"
215                      or $mdvar eq "edit_type" ) {
216                $tt_vars{$mdvar} = $tt_metadata_vars{$mdvar};
217            } else {
218                $tt_vars{"stored_$mdvar"} = $node_data{metadata}{$mdvar}[0];
219                $tt_vars{"new_$mdvar"}    = $tt_metadata_vars{$mdvar};
220            }
221        }
222        process_template("edit_conflict.tt", $node, \%tt_vars);
223    }
224}
225
226sub edit_node {
227    my $node = shift;
228    my %node_data = $wiki->retrieve_node($node);
229    my ($content, $checksum) = @node_data{ qw( content checksum ) };
230    my $username = get_cookie( "username" );
231    my $edit_type = get_cookie( "default_edit_type" ) eq "normal" ?
232                        "Normal edit" : "Minor tidying";
233
234    my %metadata_vars = OpenGuides::Template->extract_metadata_vars(
235                             wiki     => $wiki,
236                             config   => $config,
237                             metadata => $node_data{metadata} );
238
239    my %tt_vars = ( content         => $q->escapeHTML($content),
240                    checksum        => $q->escapeHTML($checksum),
241                    %metadata_vars,
242                    username        => $username,
243                    edit_type       => $edit_type,
244                    deter_robots    => 1,
245    );
246
247    process_template("edit_form.tt", $node, \%tt_vars);
248}
249
250sub get_cookie {
251    my $pref_name = shift or return "";
252    my %cookie_data = OpenGuides::CGI->get_prefs_from_cookie(config=>$config);
253    return $cookie_data{$pref_name};
254}
255
256sub display_node_rdf {
257    my %args = @_;
258    my $rdf_writer = OpenGuides::RDF->new( wiki      => $wiki,
259                                           config => $config );
260    print "Content-type: text/plain\n\n";
261    print $rdf_writer->emit_rdfxml( node => $args{node} );
262    exit 0;
263}
264
265sub process_template {
266    my ($template, $node, $vars, $conf, $omit_header) = @_;
267
268    my %output_conf = ( wiki     => $wiki,
269                        config   => $config,
270                        node     => $node,
271                        template => $template,
272                        vars     => $vars
273    );
274    $output_conf{content_type} = "" if $omit_header; # defaults otherwise
275    print OpenGuides::Template->output( %output_conf );
276}
277
278
279sub do_search {
280    my $terms = shift;
281    my %finds = $wiki->search_nodes($terms);
282#    my @sorted = sort { $finds{$a} cmp $finds{$b} } keys %finds;
283    my @sorted = sort keys %finds;
284    my @results = map {
285        { url   => $q->escape($formatter->node_name_to_node_param($_)),
286          title => $q->escapeHTML($_)
287        }             } @sorted;
288    my %tt_vars = ( results      => \@results,
289                    num_results  => scalar @results,
290                    not_editable => 1,
291                    search_terms => $q->escapeHTML($terms) );
292    process_template("search_results.tt", "", \%tt_vars);
293}
294
295sub show_wanted_pages {
296    my @dangling = $wiki->list_dangling_links;
297    my @wanted;
298    my %backlinks_count;
299    foreach my $node_name (@dangling) {
300        $backlinks_count{$node_name} = scalar($wiki->list_backlinks( node => $node_name ));
301    }
302    foreach my $node_name (sort { $backlinks_count{$b} <=> $backlinks_count{$a} } @dangling) {
303        my $node_param =
304            uri_escape($formatter->node_name_to_node_param($node_name));
305        push @wanted, {
306            name          => $q->escapeHTML($node_name),
307            edit_link     => $script_url . uri_escape($script_name)
308                           . "?action=edit;id=$node_param",
309            backlink_link => $script_url . uri_escape($script_name)
310                           . "?action=show_backlinks;id=$node_param",
311            backlinks_count => $backlinks_count{$node_name}
312        };
313    }
314    process_template( "wanted_pages.tt",
315                      "",
316                      { not_editable  => 1,
317                        not_deletable => 1,
318                        deter_robots  => 1,
319                        wanted        => \@wanted } );
320}
Note: See TracBrowser for help on using the browser.