source: trunk/wiki.cgi @ 587

Last change on this file since 587 was 587, checked in by kake, 17 years ago

Encapsulate config data in OpenGuides::Config.

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