File Coverage

blib/lib/MediaWiki/Bot/Plugin/Admin.pm
Criterion Covered Total %
statement 15 198 7.5
branch 0 66 0.0
condition 0 36 0.0
subroutine 5 18 27.7
pod 13 13 100.0
total 33 331 9.9


line stmt bran cond sub pod time code
1             package MediaWiki::Bot::Plugin::Admin;
2             # ABSTRACT: A plugin to MediaWiki::Bot providing admin functions
3              
4 6     6   1178488 use strict;
  6         16  
  6         243  
5 6     6   36 use warnings;
  6         24  
  6         183  
6             #use diagnostics;
7 6     6   28 use Carp;
  6         12  
  6         496  
8 6     6   8478 use List::Compare;
  6         182869  
  6         373  
9              
10             our $VERSION = '3.004000'; # VERSION
11              
12              
13 6     6   77 use Exporter qw(import);
  6         12  
  6         14632  
14             our @EXPORT = qw(
15             rollback
16             delete undelete delete_archived_image
17             block unblock
18             protect unprotect
19             transwiki_import xml_import
20             set_usergroups add_usergroups remove_usergroups
21             );
22              
23              
24             sub rollback {
25 0     0 1   my $self = shift;
26 0           my $page = shift;
27 0           my $user = shift;
28 0           my $summary = shift;
29 0           my $markbot = shift;
30              
31 0           my $res = $self->{api}->edit({
32             action => 'rollback',
33             title => $page,
34             user => $user,
35             summary => $summary,
36             markbot => $markbot,
37             });
38 0 0         return $self->_handle_api_error() unless $res;
39              
40 0           return $res;
41             }
42              
43              
44             sub delete {
45 0     0 1   my $self = shift;
46 0           my $page = shift;
47 0   0       my $summary = shift || 'BOT: deleted page by command';
48              
49 0           my $res = $self->{api}->api({
50             action => 'query',
51             titles => $page,
52             prop => 'info|revisions',
53             intoken => 'delete'
54             });
55 0           my $data = [ %{ $res->{query}->{pages} } ]->[1];
  0            
56 0           my $edittoken = $data->{deletetoken};
57              
58 0           $res = $self->{api}->api({
59             action => 'delete',
60             title => $page,
61             token => $edittoken,
62             reason => $summary
63             });
64 0 0         return $self->_handle_api_error() unless $res;
65              
66 0           return $res;
67             }
68              
69              
70             sub undelete {
71 0     0 1   my $self = shift;
72 0           my $page = shift;
73 0   0       my $summary = shift || 'BOT: undeleting page by command';
74              
75             # http://meta.wikimedia.org/w/api.php?action=query&list=deletedrevs&titles=User:Mike.lifeguard/sandbox&drprop=token&drlimit=1
76 0           my $token_results = $self->{api}->api({
77             action => 'query',
78             list => 'deletedrevs',
79             titles => $page,
80             drlimit => 1,
81             drprop => 'token',
82             });
83 0           my $token = $token_results->{query}->{deletedrevs}->[0]->{token};
84              
85 0           my $res = $self->{api}->api({
86             action => 'undelete',
87             title => $page,
88             reason => $summary,
89             token => $token,
90             });
91 0 0         return $self->_handle_api_error() unless $res;
92              
93 0           return $res;
94             }
95              
96              
97             sub delete_archived_image {
98 0     0 1   my $self = shift;
99 0           my $archive = shift;
100 0   0       my $summary = shift || 'BOT: deleting old version of image by command';
101              
102 0           my $file = [ split m/!/, $archive ]->[1];
103              
104 0           my ($token) = $self->_get_edittoken($file);
105              
106 0           my $res = $self->{api}->api({
107             action => 'delete',
108             title => "File:$file",
109             token => $token,
110             reason => $summary,
111             oldimage => $archive,
112             });
113 0 0         return $self->_handle_api_error() unless $res;
114              
115 0           return $res;
116              
117             }
118              
119              
120             sub block {
121 0     0 1   my $self = shift;
122 0           my $user;
123             my $length;
124 0           my $summary;
125 0           my $anononly;
126 0           my $autoblock;
127 0           my $blockac;
128 0           my $blockemail;
129 0           my $blocktalk;
130 0 0         if (ref $_[0] eq 'HASH') {
131 0           $user = $_[0]->{user};
132 0           $length = $_[0]->{length};
133 0           $summary = $_[0]->{summary};
134 0           $anononly = $_[0]->{anononly};
135 0           $autoblock = $_[0]->{autoblock};
136 0           $blockac = $_[0]->{blockac};
137 0           $blockemail = $_[0]->{blockemail};
138 0           $blocktalk = $_[0]->{blocktalk};
139             }
140             else {
141 0           $user = shift;
142 0           $length = shift;
143 0           $summary = shift;
144 0           $anononly = shift;
145 0           $autoblock = shift;
146 0           $blockac = shift;
147 0           $blockemail = shift;
148 0           $blocktalk = shift;
149             }
150              
151 0           my $res;
152             my $edittoken;
153              
154 0 0         if ($self->{blocktoken}) {
155 0           $edittoken = $self->{blocktoken};
156             }
157             else {
158 0           $res = $self->{api}->api({
159             action => 'query',
160             titles => 'Main_Page',
161             prop => 'info|revisions',
162             intoken => 'block'
163             });
164 0           my $data = [ %{ $res->{query}->{pages} } ]->[1];
  0            
165 0           $edittoken = $data->{blocktoken};
166 0           $self->{blocktoken} = $edittoken;
167             }
168 0           my $hash = {
169             action => 'block',
170             user => $user,
171             token => $edittoken,
172             expiry => $length,
173             reason => $summary
174             };
175 0 0         $hash->{anononly} = $anononly if ($anononly);
176 0 0         $hash->{autoblock} = $autoblock if ($autoblock);
177 0 0         $hash->{nocreate} = $blockac if ($blockac);
178 0 0         $hash->{noemail} = $blockemail if ($blockemail);
179 0 0         $hash->{allowusertalk} = 1 if (!$blocktalk);
180              
181 0           $res = $self->{api}->api($hash);
182 0 0         if (!$res) {
183 0           return $self->_handle_api_error();
184             }
185              
186 0           return $res;
187             }
188              
189              
190             sub unblock {
191 0     0 1   my $self = shift;
192 0           my $user = shift;
193 0           my $summary = shift;
194              
195 0           my $res;
196             my $edittoken;
197 0 0         if ($self->{unblocktoken}) {
198 0           $edittoken = $self->{unblocktoken};
199             }
200             else {
201 0           $res = $self->{api}->api({
202             action => 'query',
203             titles => 'Main_Page',
204             prop => 'info|revisions',
205             intoken => 'unblock',
206             });
207 0           my $data = [ %{ $res->{query}->{pages} } ]->[1];
  0            
208 0           $edittoken = $data->{unblocktoken};
209 0           $self->{unblocktoken} = $edittoken;
210             }
211              
212 0           my $hash = {
213             action => 'unblock',
214             user => $user,
215             token => $edittoken,
216             reason => $summary,
217             };
218 0           $res = $self->{api}->api($hash);
219 0 0         return $self->_handle_api_error() unless $res;
220              
221 0           return $res;
222             }
223              
224              
225             sub unprotect { # A convenience function
226 0     0 1   my $self = shift;
227 0           my $page = shift;
228 0           my $reason = shift;
229              
230 0           return $self->protect($page, $reason, 'all', 'all');
231             }
232              
233              
234             sub protect {
235 0     0 1   my $self = shift;
236 0           my $page = shift;
237 0           my $reason = shift;
238 0 0         my $editlvl = defined($_[0]) ? shift : 'sysop';
239 0 0         my $movelvl = defined($_[0]) ? shift : 'sysop';
240 0   0       my $time = shift || 'infinite';
241 0           my $cascade = shift;
242              
243 0 0         $editlvl = 'all' if $editlvl eq '';
244 0 0         $movelvl = 'all' if $movelvl eq '';
245              
246 0 0 0       if ($cascade and ($editlvl ne 'sysop' or $movelvl ne 'sysop')) {
      0        
247 0 0         carp "Can't set cascading unless both editlvl and movelvl are sysop." if $self->{debug};
248             }
249 0           my $res = $self->{api}->api({
250             action => 'query',
251             titles => $page,
252             prop => 'info|revisions',
253             intoken => 'protect'
254             });
255              
256 0           my $data = [ %{ $res->{query}->{pages} } ]->[1];
  0            
257 0           my $edittoken = $data->{protecttoken};
258              
259 0           $res = $self->{api}->api({
260             action => 'protect',
261             title => $page,
262             token => $edittoken,
263             reason => $reason,
264             protections => "edit=$editlvl|move=$movelvl",
265             expiry => $time,
266             cascade => $cascade,
267             });
268 0 0         return $self->_handle_api_error() unless $res;
269              
270 0           return $res;
271             }
272              
273             sub transwiki_import {
274 0     0 1   my $self = shift;
275 0   0       my $prefix = $_[0]->{prefix} || 'w';
276 0           my $page = $_[0]->{page};
277 0   0       my $namespace = $_[0]->{ns} || 0;
278 0 0         my $history = defined($_[0]->{history}) ? $_[0]->{history} : 1;
279 0 0         my $templates = defined($_[0]->{templates}) ? $_[0]->{templates} : 0;
280              
281 0           my $res = $self->{api}->api({
282             action => 'query',
283             prop => 'info',
284             titles => 'Main Page',
285             intoken => 'import',
286             });
287 0 0         return $self->_handle_api_error() unless $res;
288              
289 0           my $data = [ %{ $res->{query}->{pages} } ]->[1];
  0            
290 0           my $importtoken = $data->{importtoken};
291              
292 0           $res = $self->{api}->api({
293             action => 'import',
294             token => $importtoken,
295             interwikisource => $prefix,
296             interwikipage => $page,
297             fullhistory => $history,
298             namespace => $namespace,
299             templates => $templates,
300             });
301 0 0         return $self->_handle_api_error() unless $res;
302              
303 0           return $res;
304             }
305              
306              
307             sub xml_import {
308 0     0 1   my $self = shift;
309 0 0         my $filename = shift or die 'No filename given';
310              
311 0           my $success = $self->{api}->edit({
312             action => 'import',
313             xml => [ $filename ],
314             });
315 0 0         return $self->_handle_api_error() unless $success;
316 0           return $success;
317             }
318              
319              
320             sub set_usergroups {
321 0     0 1   my $self = shift;
322 0           my $user = shift;
323 0           my $rights = shift;
324 0           my $summary = shift;
325              
326 0           $user =~ s/^User://;
327              
328 0 0 0       unless (
      0        
329             exists $self->{userrightscache}
330             and $self->{userrightscache}
331             and $self->{userrightscache}->{user} eq $user
332             ) {
333 0           $self->usergroups($user);
334             }
335 0           my $compare = List::Compare->new({
336             lists => [ $self->{userrightscache}->{groups}, $rights ],
337             unsorted => 1,
338             });
339 0           my %add = map { $_ => 1 } $compare->get_complement;
  0            
340 0           my %remove = map { $_ => 1 } $compare->get_unique;
  0            
341 0           delete $add{ $_ } for qw(* user autoconfirmed);
342 0           delete $remove{ $_ } for qw(* user autoconfirmed);
343              
344 0           my $hash = {
345             action => 'userrights',
346             user => $user,
347             add => join('|', keys %add),
348             remove => join('|', keys %remove),
349             reason => $summary,
350             token => $self->{userrightscache}->{token},
351             };
352 0           my $res = $self->{api}->api($hash);
353 0 0         return $self->_handle_api_error() unless $res;
354              
355 0           my %new_usergroups = map { $_ => 1 } @{ $self->{userrightscache}->{groups} };
  0            
  0            
356 0           delete $new_usergroups{ $_ } for @{ $res->{userrights}->{removed} };
  0            
357 0           $new_usergroups{ $_ } = 1 for @{ $res->{userrights}->{added} };
  0            
358 0           delete $self->{userrightscache};
359 0           return keys %new_usergroups;
360             }
361              
362              
363             sub add_usergroups {
364 0     0 1   my $self = shift;
365 0           my $user = shift;
366 0           my $rights = shift;
367 0           my $summary = shift;
368              
369 0           $user =~ s/^User://;
370              
371 0 0 0       unless (
      0        
372             exists $self->{userrightscache}
373             and exists $self->{userrightscache}->{user}
374             and $self->{userrightscache}->{user} eq $user
375             ) {
376 0           $self->usergroups($user);
377             }
378              
379 0           my $res = $self->{api}->api({
380             action => 'userrights',
381             user => $user,
382             add => @$rights,
383             reason => $summary,
384             token => $self->{userrightscache}->{token},
385             });
386 0 0         return $self->_handle_api_error() unless $res;
387              
388 0           delete $self->{userrightscache};
389 0           return @{ $res->{userrights}->{added} };
  0            
390             }
391              
392              
393              
394             sub remove_usergroups {
395 0     0 1   my $self = shift;
396 0           my $user = shift;
397 0           my $rights = shift;
398 0           my $summary = shift;
399              
400 0           $user =~ s/^User://;
401              
402 0 0 0       unless (
      0        
403             exists $self->{userrightscache}
404             and exists $self->{userrightscache}->{user}
405             and $self->{userrightscache}->{user} eq $user
406             ) {
407 0           $self->usergroups($user);
408             }
409              
410 0           my $res = $self->{api}->api({
411             action => 'userrights',
412             user => $user,
413             remove => @$rights,
414             reason => $summary,
415             token => $self->{userrightscache}->{token},
416             });
417 0 0         return $self->_handle_api_error() unless $res;
418              
419 0           delete $self->{userrightscache};
420 0           return @{ $res->{userrights}->{removed} };
  0            
421             }
422              
423             1;
424              
425             __END__