line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package OpenGuides::Utils; |
2
|
|
|
|
|
|
|
|
3
|
95
|
|
|
95
|
|
1474
|
use strict; |
|
95
|
|
|
|
|
109
|
|
|
95
|
|
|
|
|
2486
|
|
4
|
95
|
|
|
95
|
|
321
|
use vars qw( $VERSION ); |
|
95
|
|
|
|
|
112
|
|
|
95
|
|
|
|
|
3590
|
|
5
|
|
|
|
|
|
|
$VERSION = '0.20'; |
6
|
|
|
|
|
|
|
|
7
|
95
|
|
|
95
|
|
293
|
use Carp qw( croak ); |
|
95
|
|
|
|
|
102
|
|
|
95
|
|
|
|
|
3356
|
|
8
|
95
|
|
|
95
|
|
42737
|
use Wiki::Toolkit; |
|
95
|
|
|
|
|
826031
|
|
|
95
|
|
|
|
|
2305
|
|
9
|
95
|
|
|
95
|
|
42756
|
use Wiki::Toolkit::Formatter::UseMod; |
|
95
|
|
|
|
|
1706970
|
|
|
95
|
|
|
|
|
2627
|
|
10
|
95
|
|
|
95
|
|
519
|
use URI::Escape; |
|
95
|
|
|
|
|
119
|
|
|
95
|
|
|
|
|
3998
|
|
11
|
95
|
|
|
95
|
|
63540
|
use MIME::Lite; |
|
95
|
|
|
|
|
2131553
|
|
|
95
|
|
|
|
|
2653
|
|
12
|
95
|
|
|
95
|
|
35113
|
use Net::Netmask; |
|
95
|
|
|
|
|
345906
|
|
|
95
|
|
|
|
|
6742
|
|
13
|
95
|
|
|
95
|
|
473
|
use List::Util qw( first ); |
|
95
|
|
|
|
|
111
|
|
|
95
|
|
|
|
|
4385
|
|
14
|
95
|
|
|
95
|
|
7833
|
use Data::Validate::URI qw( is_web_uri ); |
|
95
|
|
|
|
|
660187
|
|
|
95
|
|
|
|
|
222801
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
OpenGuides::Utils - General utility methods for OpenGuides scripts. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Provides general utility methods for OpenGuides scripts. Distributed |
23
|
|
|
|
|
|
|
and installed as part of the OpenGuides project, not intended for |
24
|
|
|
|
|
|
|
independent installation. This documentation is probably only useful |
25
|
|
|
|
|
|
|
to OpenGuides developers. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 SYNOPSIS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use OpenGuide::Config; |
30
|
|
|
|
|
|
|
use OpenGuides::Utils; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $config = OpenGuides::Config->new( file => "wiki.conf" ); |
33
|
|
|
|
|
|
|
my $wiki = OpenGuides::Utils->make_wiki_object( config => $config ); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 METHODS |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=over 4 |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=item B |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my $config = OpenGuides::Config->new( file => "wiki.conf" ); |
42
|
|
|
|
|
|
|
my $wiki = OpenGuides::Utils->make_wiki_object( config => $config ); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Croaks unless an C object is supplied. Returns a |
45
|
|
|
|
|
|
|
C object made from the given config file on success, |
46
|
|
|
|
|
|
|
croaks if any other error occurs. |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
The config file needs to define at least the following variables: |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=over |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=item * |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
dbtype - one of C, C and C |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item * |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
dbname |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=item * |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
indexing_directory - for the L, L, |
63
|
|
|
|
|
|
|
or C files to go in |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=back |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=cut |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub make_wiki_object { |
70
|
155
|
|
|
155
|
1
|
76664
|
my ($class, %args) = @_; |
71
|
155
|
100
|
|
|
|
757
|
my $config = $args{config} or croak "No config param supplied"; |
72
|
154
|
100
|
|
|
|
925
|
croak "config param isn't an OpenGuides::Config object" |
73
|
|
|
|
|
|
|
unless UNIVERSAL::isa( $config, "OpenGuides::Config" ); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Require in the right database module. |
76
|
153
|
|
|
|
|
650
|
my $dbtype = $config->dbtype; |
77
|
|
|
|
|
|
|
|
78
|
153
|
|
|
|
|
2571
|
my %wiki_toolkit_exts = ( |
79
|
|
|
|
|
|
|
postgres => "Pg", |
80
|
|
|
|
|
|
|
mysql => "MySQL", |
81
|
|
|
|
|
|
|
sqlite => "SQLite", |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
|
84
|
153
|
|
|
|
|
471
|
my $wiki_toolkit_module = "Wiki::Toolkit::Store::" . $wiki_toolkit_exts{$dbtype}; |
85
|
153
|
|
|
|
|
10284
|
eval "require $wiki_toolkit_module"; |
86
|
153
|
50
|
|
|
|
703033
|
croak "Can't 'require' $wiki_toolkit_module.\n" if $@; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Make store. |
89
|
153
|
|
|
|
|
794
|
my $store = $wiki_toolkit_module->new( |
90
|
|
|
|
|
|
|
dbname => $config->dbname, |
91
|
|
|
|
|
|
|
dbuser => $config->dbuser, |
92
|
|
|
|
|
|
|
dbpass => $config->dbpass, |
93
|
|
|
|
|
|
|
dbhost => $config->dbhost, |
94
|
|
|
|
|
|
|
dbport => $config->dbport, |
95
|
|
|
|
|
|
|
charset => $config->dbencoding, |
96
|
|
|
|
|
|
|
); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Make search. |
99
|
153
|
|
|
|
|
174971
|
my $search; |
100
|
153
|
50
|
33
|
|
|
721
|
if ( $config->use_lucy ) { |
|
|
50
|
33
|
|
|
|
|
101
|
0
|
|
|
|
|
0
|
$search = $class->make_lucy_searcher( config => $config ); |
102
|
|
|
|
|
|
|
} elsif ( $config->use_plucene |
103
|
|
|
|
|
|
|
&& ( lc($config->use_plucene) eq "y" |
104
|
|
|
|
|
|
|
|| $config->use_plucene == 1 ) |
105
|
|
|
|
|
|
|
) { |
106
|
153
|
|
|
|
|
10084
|
require Wiki::Toolkit::Search::Plucene; |
107
|
153
|
|
|
|
|
549916
|
my %plucene_args = ( path => $config->indexing_directory ); |
108
|
153
|
|
|
|
|
1586
|
my $munger = $config->search_content_munger_module; |
109
|
153
|
100
|
|
|
|
1129
|
if ( $munger ) { |
110
|
2
|
|
|
|
|
3
|
eval { |
111
|
2
|
|
|
|
|
88
|
eval "require $munger"; |
112
|
|
|
|
|
|
|
$plucene_args{content_munger} = sub { |
113
|
2
|
|
|
2
|
|
21348
|
my $content = shift; |
114
|
2
|
|
|
|
|
21
|
return $munger->search_content_munger( $content ); |
115
|
2
|
|
|
|
|
15
|
}; |
116
|
|
|
|
|
|
|
}; |
117
|
|
|
|
|
|
|
} |
118
|
153
|
|
|
|
|
1571
|
$search = Wiki::Toolkit::Search::Plucene->new( %plucene_args ); |
119
|
|
|
|
|
|
|
} else { |
120
|
0
|
|
|
|
|
0
|
require Wiki::Toolkit::Search::SII; |
121
|
0
|
|
|
|
|
0
|
require Search::InvertedIndex::DB::DB_File_SplitHash; |
122
|
0
|
|
|
|
|
0
|
my $indexdb = Search::InvertedIndex::DB::DB_File_SplitHash->new( |
123
|
|
|
|
|
|
|
-map_name => $config->indexing_directory, |
124
|
|
|
|
|
|
|
-lock_mode => "EX" |
125
|
|
|
|
|
|
|
); |
126
|
0
|
|
|
|
|
0
|
$search = Wiki::Toolkit::Search::SII->new( indexdb => $indexdb ); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Make formatter. |
130
|
153
|
|
|
|
|
3065
|
my $script_name = $config->script_name; |
131
|
153
|
|
|
|
|
1730
|
my $search_url = $config->script_url . "search.cgi"; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
my %macros = ( |
134
|
|
|
|
|
|
|
'@SEARCHBOX' => |
135
|
|
|
|
|
|
|
qq(), |
136
|
|
|
|
|
|
|
qr/\@INDEX_LINK\s+\[\[(Category|Locale)\s+([^\]|]+)\|?([^\]]+)?\]\]/ => |
137
|
|
|
|
|
|
|
sub { |
138
|
|
|
|
|
|
|
# We may be being called by Wiki::Toolkit::Plugin::Diff, |
139
|
|
|
|
|
|
|
# which doesn't know it has to pass us $wiki - and |
140
|
|
|
|
|
|
|
# we don't use it anyway. |
141
|
3
|
100
|
|
3
|
|
22825
|
if ( UNIVERSAL::isa( $_[0], "Wiki::Toolkit" ) ) { |
142
|
2
|
|
|
|
|
4
|
shift; # just throw it away |
143
|
|
|
|
|
|
|
} |
144
|
3
|
50
|
|
|
|
15
|
my $type = ( lc( $_[0] ) eq "category" ) ? "cat" : "loc"; |
145
|
3
|
|
66
|
|
|
16
|
my $link_title = $_[2] || "View all pages in $_[0] $_[1]"; |
146
|
3
|
|
|
|
|
20
|
return qq($link_title); |
147
|
|
|
|
|
|
|
}, |
148
|
|
|
|
|
|
|
qr/\@INDEX_LIST\s+\[\[(Category|Locale)\s+([^\]]+)]]/ => |
149
|
|
|
|
|
|
|
sub { |
150
|
7
|
|
|
7
|
|
4645
|
my ($wiki, $type, $value) = @_; |
151
|
7
|
|
|
|
|
57
|
return $class->do_index_list_macro( |
152
|
|
|
|
|
|
|
wiki => $wiki, type => $type, value => $value, |
153
|
|
|
|
|
|
|
include_prefix => 1 ); |
154
|
|
|
|
|
|
|
}, |
155
|
|
|
|
|
|
|
qr/\@INDEX_LIST_NO_PREFIX\s+\[\[(Category|Locale)\s+([^\]]+)]]/ => |
156
|
|
|
|
|
|
|
sub { |
157
|
4
|
|
|
4
|
|
1426
|
my ($wiki, $type, $value) = @_; |
158
|
4
|
|
|
|
|
29
|
return $class->do_index_list_macro( |
159
|
|
|
|
|
|
|
wiki => $wiki, type => $type, value => $value ); |
160
|
|
|
|
|
|
|
}, |
161
|
|
|
|
|
|
|
qr/\@NODE_COUNT\s+\[\[(Category|Locale)\s+([^\]]+)]]/ => |
162
|
|
|
|
|
|
|
sub { |
163
|
1
|
|
|
1
|
|
426
|
my ($wiki, $type, $value) = @_; |
164
|
1
|
|
|
|
|
11
|
return $class->do_node_count( |
165
|
|
|
|
|
|
|
wiki => $wiki, type => $type, value => $value ); |
166
|
|
|
|
|
|
|
}, |
167
|
|
|
|
|
|
|
qr/\@MAP_LINK\s+\[\[(Category|Locale)\s+([^\]|]+)\|?([^\]]+)?\]\]/ => |
168
|
|
|
|
|
|
|
sub { |
169
|
4
|
50
|
|
4
|
|
1464
|
if ( UNIVERSAL::isa( $_[0], "Wiki::Toolkit" ) ) { |
170
|
4
|
|
|
|
|
6
|
shift; # don't need $wiki |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
4
|
100
|
|
|
|
18
|
my $type = ( lc( $_[0] ) eq "category" ) ? "cat" : "loc"; |
174
|
4
|
|
66
|
|
|
17
|
my $link_title = $_[2] |
175
|
|
|
|
|
|
|
|| "View map of pages in $_[0] $_[1]"; |
176
|
4
|
|
|
|
|
27
|
return qq($link_title); |
177
|
|
|
|
|
|
|
}, |
178
|
|
|
|
|
|
|
qr/\@RANDOM_PAGE_LINK(?:\s+\[\[(Category|Locale)\s+([^\]|]+)\|?([^\]]+)?\]\])?/ => |
179
|
|
|
|
|
|
|
sub { |
180
|
5
|
50
|
|
5
|
|
2069
|
if ( UNIVERSAL::isa( $_[0], "Wiki::Toolkit" ) ) { |
181
|
5
|
|
|
|
|
9
|
shift; # don't need $wiki |
182
|
|
|
|
|
|
|
} |
183
|
5
|
|
|
|
|
18
|
my ( $type, $value, $link_title ) = @_; |
184
|
5
|
|
|
|
|
11
|
my $link = "$script_name?action=random"; |
185
|
|
|
|
|
|
|
|
186
|
5
|
100
|
66
|
|
|
32
|
if ( $type && $value ) { |
187
|
4
|
|
|
|
|
19
|
$link .= ";" . lc( uri_escape( $type ) ) . "=" |
188
|
|
|
|
|
|
|
. lc( uri_escape( $value ) ); |
189
|
4
|
|
66
|
|
|
88
|
$link_title ||= "View a random page in $type $value"; |
190
|
|
|
|
|
|
|
} else { |
191
|
1
|
|
50
|
|
|
5
|
$link_title ||= "View a random page on this guide"; |
192
|
|
|
|
|
|
|
} |
193
|
5
|
|
|
|
|
29
|
return qq($link_title); |
194
|
|
|
|
|
|
|
}, |
195
|
|
|
|
|
|
|
qr/\@INCLUDE_NODE\s+\[\[([^\]|]+)\]\]/ => |
196
|
|
|
|
|
|
|
sub { |
197
|
2
|
|
|
2
|
|
772
|
my ($wiki, $node) = @_; |
198
|
2
|
|
|
|
|
8
|
my %node_data = $wiki->retrieve_node( $node ); |
199
|
2
|
|
|
|
|
1994
|
return $node_data{content}; |
200
|
|
|
|
|
|
|
}, |
201
|
153
|
|
|
|
|
6348
|
); |
202
|
|
|
|
|
|
|
|
203
|
153
|
|
|
|
|
1056
|
my $custom_macro_module = $config->custom_macro_module; |
204
|
153
|
100
|
|
|
|
1384
|
if ( $custom_macro_module ) { |
205
|
2
|
|
|
|
|
3
|
eval { |
206
|
2
|
|
|
|
|
111
|
eval "require $custom_macro_module"; |
207
|
2
|
|
|
|
|
23
|
%macros = $custom_macro_module->custom_macros(macros => \%macros); |
208
|
|
|
|
|
|
|
}; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
153
|
|
|
|
|
2730
|
my $formatter = Wiki::Toolkit::Formatter::UseMod->new( |
212
|
|
|
|
|
|
|
extended_links => 1, |
213
|
|
|
|
|
|
|
implicit_links => 0, |
214
|
|
|
|
|
|
|
allowed_tags => [qw(a p b strong i em pre small img table td |
215
|
|
|
|
|
|
|
tr th br hr ul li center blockquote kbd |
216
|
|
|
|
|
|
|
div code span strike sub sup font dl dt dd |
217
|
|
|
|
|
|
|
)], |
218
|
|
|
|
|
|
|
macros => \%macros, |
219
|
|
|
|
|
|
|
pass_wiki_to_macros => 1, |
220
|
|
|
|
|
|
|
node_prefix => "$script_name?", |
221
|
|
|
|
|
|
|
edit_prefix => "$script_name?action=edit;id=", |
222
|
|
|
|
|
|
|
munge_urls => 1, |
223
|
|
|
|
|
|
|
external_link_class => "external", |
224
|
|
|
|
|
|
|
escape_url_commas => 0, |
225
|
|
|
|
|
|
|
); |
226
|
|
|
|
|
|
|
|
227
|
153
|
|
|
|
|
11147
|
my %conf = ( store => $store, |
228
|
|
|
|
|
|
|
search => $search, |
229
|
|
|
|
|
|
|
formatter => $formatter ); |
230
|
|
|
|
|
|
|
|
231
|
153
|
|
|
|
|
1074
|
my $wiki = Wiki::Toolkit->new( %conf ); |
232
|
153
|
|
|
|
|
5326
|
return $wiki; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub make_lucy_searcher { |
236
|
0
|
|
|
0
|
0
|
0
|
my ( $class, %args ) = @_; |
237
|
0
|
|
|
|
|
0
|
require Wiki::Toolkit::Search::Lucy; |
238
|
0
|
|
|
|
|
0
|
my $config = $args{config}; |
239
|
0
|
|
|
|
|
0
|
my %lucy_args = ( |
240
|
|
|
|
|
|
|
path => $config->indexing_directory, |
241
|
|
|
|
|
|
|
metadata_fields => [ qw( address category locale ) ], |
242
|
|
|
|
|
|
|
boost => { title => 10 }, # empirically determined (test t/306) |
243
|
|
|
|
|
|
|
); |
244
|
0
|
|
|
|
|
0
|
my $munger = $config->search_content_munger_module; |
245
|
0
|
0
|
|
|
|
0
|
if ( $munger ) { |
246
|
0
|
|
|
|
|
0
|
eval { |
247
|
0
|
|
|
|
|
0
|
eval "require $munger"; |
248
|
|
|
|
|
|
|
$lucy_args{content_munger} = sub { |
249
|
0
|
|
|
0
|
|
0
|
my $content = shift; |
250
|
0
|
|
|
|
|
0
|
return $munger->search_content_munger( $content ); |
251
|
0
|
|
|
|
|
0
|
}; |
252
|
|
|
|
|
|
|
}; |
253
|
|
|
|
|
|
|
} |
254
|
0
|
|
|
|
|
0
|
return Wiki::Toolkit::Search::Lucy->new( %lucy_args ); |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub do_index_list_macro { |
258
|
11
|
|
|
11
|
0
|
44
|
my ( $class, %args ) = @_; |
259
|
|
|
|
|
|
|
my ( $wiki, $type, $value, $include_prefix ) |
260
|
11
|
|
|
|
|
30
|
= @args{ qw( wiki type value include_prefix ) }; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# We may be being called by Wiki::Toolkit::Plugin::Diff, |
263
|
|
|
|
|
|
|
# which doesn't know it has to pass us $wiki |
264
|
11
|
100
|
|
|
|
54
|
if ( !UNIVERSAL::isa( $wiki, "Wiki::Toolkit" ) ) { |
265
|
1
|
50
|
|
|
|
7
|
if ( $args{include_prefix} ) { |
266
|
1
|
|
|
|
|
5
|
return "(unprocessed INDEX_LIST macro)"; |
267
|
|
|
|
|
|
|
} else { |
268
|
0
|
|
|
|
|
0
|
return "(unprocessed INDEX_LIST_NO_PREFIX macro)"; |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
10
|
|
|
|
|
46
|
my @nodes = sort $wiki->list_nodes_by_metadata( |
273
|
|
|
|
|
|
|
metadata_type => $type, |
274
|
|
|
|
|
|
|
metadata_value => $value, |
275
|
|
|
|
|
|
|
ignore_case => 1, |
276
|
|
|
|
|
|
|
); |
277
|
10
|
100
|
|
|
|
2460
|
unless ( scalar @nodes ) { |
278
|
4
|
|
|
|
|
37
|
return "\n* No pages currently in " . lc($type) . " $value\n"; |
279
|
|
|
|
|
|
|
} |
280
|
6
|
|
|
|
|
12
|
my $return = "\n"; |
281
|
6
|
|
|
|
|
13
|
foreach my $node ( @nodes ) { |
282
|
12
|
|
|
|
|
4622
|
my $title = $node; |
283
|
12
|
100
|
|
|
|
46
|
$title =~ s/^(Category|Locale) // unless $args{include_prefix}; |
284
|
12
|
|
|
|
|
42
|
$return .= "* " |
285
|
|
|
|
|
|
|
. $wiki->formatter->format_link( wiki => $wiki, |
286
|
|
|
|
|
|
|
link => "$node|$title" ) |
287
|
|
|
|
|
|
|
. "\n"; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
# URI::Escape escapes commas in URLs. This is annoying. |
290
|
6
|
|
|
|
|
4610
|
$return =~ s/%2C/,/gs; |
291
|
6
|
|
|
|
|
35
|
return $return; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
sub do_node_count { |
294
|
1
|
|
|
1
|
0
|
4
|
my ( $class, %args ) = @_; |
295
|
|
|
|
|
|
|
my ( $wiki, $type, $value ) |
296
|
1
|
|
|
|
|
4
|
= @args{ qw( wiki type value ) }; |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# We may be being called by Wiki::Toolkit::Plugin::Diff, |
299
|
|
|
|
|
|
|
# which doesn't know it has to pass us $wiki |
300
|
1
|
50
|
|
|
|
7
|
if ( !UNIVERSAL::isa( $wiki, "Wiki::Toolkit" ) ) { |
301
|
0
|
|
|
|
|
0
|
return "(unprocessed NODE_COUNT macro)"; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
1
|
|
|
|
|
6
|
my $num_nodes = scalar $wiki->list_nodes_by_metadata( |
305
|
|
|
|
|
|
|
metadata_type => $type, |
306
|
|
|
|
|
|
|
metadata_value => $value, |
307
|
|
|
|
|
|
|
ignore_case => 1, |
308
|
|
|
|
|
|
|
); |
309
|
1
|
|
|
|
|
288
|
return $num_nodes; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
=item B |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Returns coordinate data suitable for use with Google Maps (and other GIS |
314
|
|
|
|
|
|
|
systems that assume WGS-84 data). |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
my ($wgs84_long, $wgs84_lat) = OpenGuides::Utils->get_wgs84_coords( |
317
|
|
|
|
|
|
|
longitude => $longitude, |
318
|
|
|
|
|
|
|
latitude => $latitude, |
319
|
|
|
|
|
|
|
config => $config |
320
|
|
|
|
|
|
|
); |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=cut |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
sub get_wgs84_coords { |
325
|
189
|
|
|
189
|
0
|
7652
|
my ($self, %args) = @_; |
326
|
|
|
|
|
|
|
my ($longitude, $latitude, $config) = ($args{longitude}, $args{latitude}, |
327
|
|
|
|
|
|
|
$args{config}) |
328
|
189
|
50
|
|
|
|
790
|
or croak "No longitude supplied to get_wgs84_coords"; |
329
|
189
|
50
|
|
|
|
677
|
croak "geo_handler not defined!" unless $config->geo_handler; |
330
|
|
|
|
|
|
|
|
331
|
189
|
100
|
|
|
|
2055
|
if ($config->force_wgs84) { |
332
|
|
|
|
|
|
|
# Only as a rough approximation, good enough for large scale guides |
333
|
165
|
|
|
|
|
1333
|
return ($longitude, $latitude); |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
# If we don't have a lat and long, return undef right away |
337
|
24
|
50
|
66
|
|
|
233
|
unless($args{longitude} || $args{latitude}) { |
338
|
17
|
|
|
|
|
54
|
return undef; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
# Try to load a provider of Helmert Transforms |
342
|
7
|
|
|
|
|
11
|
my $helmert; |
343
|
|
|
|
|
|
|
# First up, try the MySociety Geo::HelmertTransform |
344
|
7
|
50
|
|
|
|
19
|
unless($helmert) { |
345
|
7
|
|
|
|
|
11
|
eval { |
346
|
7
|
|
|
|
|
950
|
require Geo::HelmertTransform; |
347
|
|
|
|
|
|
|
$helmert = sub($$$) { |
348
|
7
|
|
|
7
|
|
18
|
my ($datum,$oldlat,$oldlong) = @_; |
349
|
7
|
100
|
|
|
|
23
|
if ($datum eq 'Airy') { |
350
|
1
|
|
|
|
|
1
|
$datum = 'Airy1830'; |
351
|
|
|
|
|
|
|
} |
352
|
7
|
|
|
|
|
42
|
my $datum_helper = new Geo::HelmertTransform::Datum(Name=>$datum); |
353
|
7
|
|
|
|
|
7902
|
my $wgs84_helper = new Geo::HelmertTransform::Datum(Name=>'WGS84'); |
354
|
7
|
50
|
|
|
|
496
|
unless($datum_helper) { |
355
|
0
|
|
|
|
|
0
|
croak("No convertion helper for datum '$datum'"); |
356
|
0
|
|
|
|
|
0
|
return undef; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
7
|
|
|
|
|
30
|
my ($lat,$long,$h) = |
360
|
|
|
|
|
|
|
Geo::HelmertTransform::convert_datum($datum_helper,$wgs84_helper,$oldlat,$oldlong,0); |
361
|
7
|
|
|
|
|
4047
|
return ($long,$lat); |
362
|
7
|
|
|
|
|
5056
|
}; |
363
|
|
|
|
|
|
|
}; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
# Give up, return undef |
366
|
7
|
50
|
|
|
|
20
|
unless($helmert) { |
367
|
0
|
|
|
|
|
0
|
return undef; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
|
371
|
7
|
100
|
|
|
|
21
|
if ($config->geo_handler == 1) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
372
|
|
|
|
|
|
|
# Do conversion here |
373
|
6
|
|
|
|
|
53
|
return &$helmert('Airy1830',$latitude,$longitude); |
374
|
|
|
|
|
|
|
} elsif ($config->geo_handler == 2) { |
375
|
|
|
|
|
|
|
# Do conversion here |
376
|
0
|
|
|
|
|
0
|
return &$helmert('Airy1830Modified',$latitude,$longitude); |
377
|
|
|
|
|
|
|
} elsif ($config->geo_handler == 3) { |
378
|
1
|
50
|
|
|
|
23
|
if ($config->ellipsoid eq "WGS-84") { |
379
|
0
|
|
|
|
|
0
|
return ($longitude, $latitude); |
380
|
|
|
|
|
|
|
} else { |
381
|
|
|
|
|
|
|
# Do conversion here |
382
|
1
|
|
|
|
|
7
|
return &$helmert($config->ellipsoid,$latitude,$longitude); |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
} else { |
385
|
0
|
|
|
|
|
0
|
croak "Invalid geo_handler config option $config->geo_handler"; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item B |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Given a set of WGS84 coordinate data, returns the minimum, maximum, |
392
|
|
|
|
|
|
|
and centre latitude and longitude. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
%data = OpenGuides::Utils->get_wgs84_min_max( |
395
|
|
|
|
|
|
|
nodes => [ |
396
|
|
|
|
|
|
|
{ wgs84_lat => 51.1, wgs84_long => 1.1 }, |
397
|
|
|
|
|
|
|
{ wgs84_lat => 51.2, wgs84_long => 1.2 }, |
398
|
|
|
|
|
|
|
] |
399
|
|
|
|
|
|
|
); |
400
|
|
|
|
|
|
|
print "Top right-hand corner is $data{max_lat}, $data{max_long}"; |
401
|
|
|
|
|
|
|
print "Centre point is $data{centre_lat}, $data{centre_long}"; |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
The hashes in the C argument can include other key/value pairs; |
404
|
|
|
|
|
|
|
these will just be ignored. |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Returns false if it can't find any valid geodata in the nodes. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=cut |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub get_wgs84_min_max { |
411
|
15
|
|
|
15
|
1
|
606
|
my ( $self, %args ) = @_; |
412
|
15
|
|
|
|
|
22
|
my @nodes = @{$args{nodes}}; |
|
15
|
|
|
|
|
33
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
my @lats = sort |
415
|
39
|
100
|
|
|
|
193
|
grep { defined $_ && /^[-.\d]+$/ } |
416
|
15
|
|
|
|
|
27
|
map { $_->{wgs84_lat} } |
|
39
|
|
|
|
|
53
|
|
417
|
|
|
|
|
|
|
@nodes; |
418
|
|
|
|
|
|
|
my @longs = sort |
419
|
39
|
100
|
|
|
|
150
|
grep { defined $_ && /^[-.\d]+$/ } |
420
|
15
|
|
|
|
|
28
|
map { $_->{wgs84_long} } |
|
39
|
|
|
|
|
47
|
|
421
|
|
|
|
|
|
|
@nodes; |
422
|
|
|
|
|
|
|
|
423
|
15
|
100
|
66
|
|
|
71
|
if ( !scalar @lats || !scalar @longs ) { |
424
|
2
|
|
|
|
|
6
|
return; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
13
|
|
|
|
|
67
|
my %data = ( min_lat => $lats[0], max_lat => $lats[$#lats], |
428
|
|
|
|
|
|
|
min_long => $longs[0], max_long => $longs[$#longs] ); |
429
|
13
|
|
|
|
|
61
|
$data{centre_lat} = ( $data{min_lat} + $data{max_lat} ) / 2; |
430
|
13
|
|
|
|
|
34
|
$data{centre_long} = ( $data{min_long} + $data{max_long} ) / 2; |
431
|
13
|
|
|
|
|
84
|
return %data; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item B |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
$tt_vars{page_description} = |
437
|
|
|
|
|
|
|
OpenGuides::Utils->get_index_page_description( |
438
|
|
|
|
|
|
|
format => "map", |
439
|
|
|
|
|
|
|
criteria => [ type => "locale", value => "croydon" ], |
440
|
|
|
|
|
|
|
); |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
Returns a sentence that can be used as a summary of what's shown on an |
443
|
|
|
|
|
|
|
index page. |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
=cut |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
sub get_index_page_description { |
448
|
33
|
|
|
33
|
1
|
90
|
my ( $class, %args ) = @_; |
449
|
33
|
100
|
|
|
|
111
|
my $desc = ( $args{format} eq "map" ) ? "Map" : "List"; |
450
|
33
|
|
|
|
|
63
|
$desc .= " of all our pages"; |
451
|
|
|
|
|
|
|
|
452
|
33
|
|
|
|
|
36
|
my ( @cats, @locs ); |
453
|
33
|
|
|
|
|
46
|
foreach my $criterion ( @{$args{criteria}} ) { |
|
33
|
|
|
|
|
96
|
|
454
|
40
|
|
|
|
|
77
|
my ( $type, $name ) = ( $criterion->{type}, $criterion->{name} ); |
455
|
40
|
100
|
|
|
|
86
|
if ( $type eq "category" ) { |
456
|
17
|
|
|
|
|
54
|
$name =~ s/Category //; |
457
|
17
|
|
|
|
|
34
|
push @cats, $name; |
458
|
|
|
|
|
|
|
} else { |
459
|
23
|
|
|
|
|
63
|
$name =~ s/Locale //; |
460
|
23
|
|
|
|
|
52
|
push @locs, $name; |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
33
|
100
|
|
|
|
86
|
if ( scalar @cats ) { |
465
|
17
|
|
|
|
|
45
|
$desc .= " labelled with: " . join( ", ", @cats ); |
466
|
17
|
100
|
|
|
|
40
|
if ( scalar @locs ) { |
467
|
8
|
|
|
|
|
16
|
$desc .= ", and"; |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
} |
470
|
33
|
100
|
|
|
|
76
|
if ( scalar @locs ) { |
471
|
23
|
|
|
|
|
60
|
$desc .= " located in: " . join( ", ", @locs ); |
472
|
|
|
|
|
|
|
} |
473
|
33
|
|
|
|
|
54
|
$desc .= "."; |
474
|
33
|
|
|
|
|
111
|
return $desc; |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=item B |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
$redir = OpenGuides::Utils->detect_redirect( content => "foo" ); |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
Checks the content of a node to see if the node is a redirect to another |
482
|
|
|
|
|
|
|
node. If so, returns the name of the node that this one redirects to. If |
483
|
|
|
|
|
|
|
not, returns false. |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
(Also returns false if no content is provided.) |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=cut |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
sub detect_redirect { |
490
|
141
|
|
|
141
|
1
|
2194
|
my ( $self, %args ) = @_; |
491
|
141
|
100
|
|
|
|
415
|
return unless $args{content}; |
492
|
|
|
|
|
|
|
|
493
|
123
|
100
|
|
|
|
677
|
if ( $args{content} =~ /^#REDIRECT\s+(.+?)\s*$/ ) { |
494
|
9
|
|
|
|
|
20
|
my $redirect = $1; |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
# Strip off enclosing [[ ]] in case this is an extended link. |
497
|
9
|
|
|
|
|
32
|
$redirect =~ s/^\[\[//; |
498
|
9
|
|
|
|
|
36
|
$redirect =~ s/\]\]\s*$//; |
499
|
|
|
|
|
|
|
|
500
|
9
|
|
|
|
|
50
|
return $redirect; |
501
|
|
|
|
|
|
|
} |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=item B |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
my $fails = OpenGuides::Utils->validate_edit( |
507
|
|
|
|
|
|
|
id => $node, |
508
|
|
|
|
|
|
|
cgi_obj => $q |
509
|
|
|
|
|
|
|
); |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
Checks supplied content for general validity. If anything is invalid, |
512
|
|
|
|
|
|
|
returns an array ref of errors to report to the user. |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=cut |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub validate_edit { |
517
|
355
|
|
|
355
|
1
|
816
|
my ( $self, %args ) = @_; |
518
|
355
|
|
|
|
|
529
|
my $q = $args{cgi_obj}; |
519
|
355
|
|
|
|
|
385
|
my @fails; |
520
|
355
|
50
|
|
|
|
947
|
push @fails, "Content missing" unless $q; |
521
|
355
|
50
|
|
|
|
845
|
return \@fails if @fails; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
# Now do our real validation |
524
|
355
|
|
|
|
|
753
|
foreach my $var (qw(os_x os_y)) { |
525
|
710
|
100
|
100
|
|
|
7030
|
if ($q->param($var) and $q->param($var) !~ /^-?\d+$/) { |
526
|
1
|
|
|
|
|
51
|
push @fails, "$var must be integer, was: " . $q->param($var); |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
|
530
|
355
|
|
|
|
|
5442
|
foreach my $var (qw(latitude longitude)) { |
531
|
710
|
50
|
66
|
|
|
7224
|
if ($q->param($var) and $q->param($var) !~ /^-?\d+\.?(\d+)?$/) { |
532
|
0
|
|
|
|
|
0
|
push @fails, "$var must be numeric, was: " . $q->param($var); |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
|
536
|
355
|
100
|
66
|
|
|
6026
|
if ( $q->param('website') and $q->param('website') ne 'http://' ) { |
537
|
5
|
50
|
|
|
|
231
|
unless ( is_web_uri( scalar $q->param('website') ) ) { |
538
|
0
|
|
|
|
|
0
|
push @fails, $q->param('website') . ' is not a valid web URI'; |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
355
|
|
|
|
|
6508
|
return \@fails; |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
}; |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=item B |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
my $change_comment = parse_change_comment($string, $base_url); |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Given a base URL (for example, C), takes a string, |
551
|
|
|
|
|
|
|
replaces C<[[page]]> and C<[[page|titled link]]> with |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
page |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
and |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
titled link |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
respectively, and returns it. This is a limited subset of wiki markup suitable for |
560
|
|
|
|
|
|
|
use in page change comments. |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=cut |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
sub parse_change_comment { |
565
|
83
|
|
|
83
|
1
|
11337
|
my ($comment, $base_url) = @_; |
566
|
|
|
|
|
|
|
|
567
|
83
|
|
|
|
|
210
|
my @links = $comment =~ m{\[\[(.*?)\]\]}g; |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
# It's not all that great having to reinvent the wheel in this way, but |
570
|
|
|
|
|
|
|
# Text::WikiFormat won't let you specify the subset of wiki notation that |
571
|
|
|
|
|
|
|
# you're interested in. C'est la vie. |
572
|
83
|
|
|
|
|
160
|
foreach (@links) { |
573
|
2
|
100
|
|
|
|
9
|
if (/(.*?)\|(.*)/) { |
574
|
1
|
|
|
|
|
3
|
my ($page, $title) = ($1, $2); |
575
|
1
|
|
|
|
|
14
|
$comment =~ s{\[\[$page\|$title\]\]} |
576
|
|
|
|
|
|
|
{$title}; |
577
|
|
|
|
|
|
|
} else { |
578
|
1
|
|
|
|
|
3
|
my $page = $_; |
579
|
1
|
|
|
|
|
25
|
$comment =~ s{\[\[$page\]\]} |
580
|
|
|
|
|
|
|
{$page}; |
581
|
|
|
|
|
|
|
} |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
|
584
|
83
|
|
|
|
|
326
|
return $comment; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=item B |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
eval { OpenGuides::Utils->send_email( |
590
|
|
|
|
|
|
|
config => $config, |
591
|
|
|
|
|
|
|
subject => "Subject", |
592
|
|
|
|
|
|
|
body => "Test body", |
593
|
|
|
|
|
|
|
admin => 1, |
594
|
|
|
|
|
|
|
nobcc => 1, |
595
|
|
|
|
|
|
|
return_output => 1 |
596
|
|
|
|
|
|
|
) }; |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
if ($@) { |
599
|
|
|
|
|
|
|
print "Error mailing admin: $@\n"; |
600
|
|
|
|
|
|
|
} else { |
601
|
|
|
|
|
|
|
print "Mailed admin\n"; |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
Send out email. If C is true, the email will be sent to the site |
605
|
|
|
|
|
|
|
admin. If C is defined, email will be sent to addresses in that |
606
|
|
|
|
|
|
|
arrayref. If C is true, there will be no Bcc to the admin. |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
C and C are mandatory arguments. |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
Debugging: if C is true, the message will be returned as |
611
|
|
|
|
|
|
|
a string instead of being sent by email. |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
=cut |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
sub send_email { |
617
|
4
|
|
|
4
|
1
|
2350
|
my ( $self, %args ) = @_; |
618
|
4
|
50
|
|
|
|
13
|
my $config = $args{config} or die "config argument not supplied"; |
619
|
4
|
|
|
|
|
4
|
my @to; |
620
|
4
|
100
|
|
|
|
9
|
@to = @{$args{to}} if $args{to}; |
|
1
|
|
|
|
|
3
|
|
621
|
4
|
|
|
|
|
5
|
my @bcc; |
622
|
4
|
100
|
|
|
|
13
|
push @to, $config->contact_email if $args{admin}; |
623
|
4
|
100
|
|
|
|
28
|
die "No recipients specified" unless $to[0]; |
624
|
3
|
50
|
|
|
|
6
|
die "No subject specified" unless $args{subject}; |
625
|
3
|
50
|
|
|
|
6
|
die "No body specified" unless $args{body}; |
626
|
3
|
|
|
|
|
6
|
my $to_str = join ',', @to; |
627
|
3
|
50
|
|
|
|
9
|
push @bcc, $config->contact_email unless $args{nobcc}; |
628
|
3
|
|
|
|
|
22
|
my $bcc_str = join ',', @bcc; |
629
|
|
|
|
|
|
|
my $msg = MIME::Lite->new( |
630
|
|
|
|
|
|
|
From => $config->contact_email, |
631
|
|
|
|
|
|
|
To => $to_str, |
632
|
|
|
|
|
|
|
Bcc => $bcc_str, |
633
|
|
|
|
|
|
|
Subject => $args{subject}, |
634
|
|
|
|
|
|
|
Data => $args{body} |
635
|
3
|
|
|
|
|
7
|
); |
636
|
|
|
|
|
|
|
|
637
|
3
|
50
|
|
|
|
57608
|
if ( $args{return_output} ) { |
638
|
3
|
|
|
|
|
8
|
return $msg->as_string; |
639
|
|
|
|
|
|
|
} else { |
640
|
0
|
0
|
|
|
|
0
|
$msg->send or die "Couldn't send mail!"; |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
} |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=item B |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
if (OpenGuides::Utils->in_moderate_whitelist( '127.0.0.1' )) { |
647
|
|
|
|
|
|
|
# skip moderation and apply new verson to published site |
648
|
|
|
|
|
|
|
} |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Admins can supply a comma separated list of IP addresses or CIDR-notation |
651
|
|
|
|
|
|
|
subnets indicating the hosts which can bypass enforced moderation. Any |
652
|
|
|
|
|
|
|
values which cannot be parsed by C will be ignored. |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
=cut |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
sub in_moderate_whitelist { |
657
|
353
|
|
|
353
|
1
|
854
|
my ($self, $config, $ip) = @_; |
658
|
353
|
50
|
|
|
|
978
|
return undef if not defined $ip; |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
# create NetAddr::IP object of the test IP |
661
|
353
|
100
|
|
|
|
3050
|
my $addr = Net::Netmask->new2($ip) or return undef; |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
# load the configured whitelist |
664
|
|
|
|
|
|
|
my @whitelist |
665
|
352
|
|
|
|
|
31780
|
= split ',', $config->moderate_whitelist; |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
# test each entry in the whitelist |
668
|
352
|
|
|
|
|
3187
|
return eval{ |
669
|
2
|
|
|
2
|
|
6
|
first { Net::Netmask->new2($_)->match($addr->base) } @whitelist |
670
|
352
|
|
|
|
|
3398
|
}; |
671
|
|
|
|
|
|
|
} |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=back |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=head1 AUTHOR |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
The OpenGuides Project (openguides-dev@lists.openguides.org) |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
=head1 COPYRIGHT |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
Copyright (C) 2003-2013 The OpenGuides Project. All Rights Reserved. |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
684
|
|
|
|
|
|
|
under the same terms as Perl itself. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
=cut |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
1; |