source: trunk/wiki.cgi @ 1027

Last change on this file since 1027 was 1027, checked in by kake, 14 years ago

Added category and locale parameters to action=random and made a new macro to go with it.

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