source: trunk/wiki.cgi @ 1227

Last change on this file since 1227 was 1227, checked in by nick, 13 years ago

Start to support metadata discovery stuff

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