File Coverage

blib/lib/MediaWiki/EditFramework.pm
Criterion Covered Total %
statement 28 43 65.1
branch 2 10 20.0
condition 0 3 0.0
subroutine 9 13 69.2
pod 6 6 100.0
total 45 75 60.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             MediaWiki::EditFramework - a framework for editing MediaWiki pages.
4              
5             =head1 SYNOPSIS
6              
7             use MediaWiki::EditFramework;
8              
9             my $wiki = MediaWiki::EditFramework->new('example.com', 'wiki');
10             my $page = $wiki->get_page('Main_Page');
11             my $text = $page->get_text;
12             $text =~ s/old thing/new update/g;
13             $page->edit($text, 'update page');
14              
15             =head2 DESCRIPTION
16              
17             This is a higher level framework for editing MediaWiki pages. It depends on
18             another module for lower level API access, and doesn't provide functionality
19             unrelated to editing. By using a higher-level abstraction layer in scripts,
20             it becomes simpler to change out backend modules as needed.
21              
22             This is the framework that I've been using for the past few years to run an
23             archiving bot. The main features that it has over lower-level frameworks
24             are:
25              
26             =over
27              
28             =item *
29              
30             Pages are represented as objects.
31              
32             This allows the page to store additional information, such as the last
33             updated timestamp when they were retrieved. The timestamp is then passed
34             back to the server when the page is edited, to allow it to properly detect
35             edit conflicts.
36              
37             =item *
38              
39             The module supports specified a write_prefix, which is appended to pages
40             titles when editing a page.
41              
42             This makes it easier to create a test mode for a bot script. By specifying
43             the write prefix in your own user space, the bot will retrieve the normal
44             pages, but the modifications will be written to user space so you can review
45             them without impacting others.
46              
47             =back
48              
49             =cut
50              
51             package MediaWiki::EditFramework;
52              
53 1     1   774 use strict;
  1         2  
  1         36  
54 1     1   5 use warnings;
  1         1  
  1         32  
55              
56 1     1   5 use Carp;
  1         11  
  1         73  
57 1     1   998 use MediaWiki::API;
  1         102732  
  1         35  
58 1     1   3295 use Data::Dumper;
  1         5827  
  1         70  
59 1     1   586 use MediaWiki::EditFramework::Page;
  1         2  
  1         25  
60 1     1   5 use strict;
  1         1  
  1         409  
61              
62             our $VERSION = '0.02';
63             our $ABSTRACT = 'framework for editing MediaWiki pages';
64              
65             =head2 CONSTRUCTOR
66              
67             =over
68              
69             =item B(I,I)
70              
71             Create a new instance pointing to the specified I and I (default
72             I). The underling API object points to http://I/I/api.php.
73              
74             =back
75              
76             =head2 METHODS
77              
78             =over
79              
80             =cut
81              
82             sub new ($;$$) {
83 1     1 1 453 my ($class,$site,$path)=@_;
84 1         7 my $mw = MediaWiki::API->new();
85 1 50       19065 if (defined $site) {
86 1 50       5 $path = 'w' unless defined $path;
87 1         8 $mw->{config}->{api_url} = "http://$site/$path/api.php";
88             }
89             #$mw->{ua}->cookie_jar({file=>"$ENV{HOME}/.cookies.txt", autosave=>1});
90 1         12 bless {0=>$mw, write_prefix=>''}, $class;
91             }
92              
93             =item B(I)
94              
95             Passes I to L's I method, to store cookies
96             for a persistent login.
97              
98             =cut
99              
100             sub cookie_jar( $$ ) {
101             #temporary method for persistent login.
102 0     0 1 0 my $self = shift;
103 0         0 my $file = shift;
104 0         0 $self->{0}{ua}->cookie_jar($file, autosave=>1);
105             }
106              
107             =item B(I,I)
108              
109             Log in the specified I.
110              
111             =cut
112              
113             sub login ($$$) {
114 0     0 1 0 my ($self,$user,$pass) = @_;
115 0         0 my $mw = $self->{0};
116              
117 0         0 my $state = $mw->api({ action=>'query', meta=>'userinfo', });
118            
119 0 0 0     0 if (
120             ! exists $state->{query}{userinfo}{anon}
121             and
122             $state->{query}{userinfo}{name} eq $user
123             ){
124 0         0 warn "already logged in as $user";
125             } else {
126 0 0       0 $mw->login( { lgname => $user, lgpassword => $pass } )
127             or confess $mw->{error}->{code} . ': ' .
128             Dumper($mw->{error}->{details});
129             }
130             }
131              
132              
133             =item B(I) </td> </tr> <tr> <td class="h" > <a name="134">134</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="135">135</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Get the wiki page with the specified I<TITLE>. Returns an instance of </td> </tr> <tr> <td class="h" > <a name="136">136</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> L<MediaWiki::EditFramework::Page>, which has methods to get/edit the page text. </td> </tr> <tr> <td class="h" > <a name="137">137</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="138">138</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="139">139</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="140">140</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub get_page( $$ ) { </td> </tr> <tr> <td class="h" > <a name="141">141</a> </td> <td class="c3" > 2 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#141-1"> 2 </a> </td> <td class="c3" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#141-1"> 1 </a> </td> <td > 19 </td> <td class="s"> MediaWiki::EditFramework::Page->new(@_); </td> </tr> <tr> <td class="h" > <a name="142">142</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> }; </td> </tr> <tr> <td class="h" > <a name="143">143</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="144">144</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item B<create_page>(I<TITLE>) </td> </tr> <tr> <td class="h" > <a name="145">145</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="146">146</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Get the wiki page with the specified I<TITLE>; then croak if it already </td> </tr> <tr> <td class="h" > <a name="147">147</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> exists. </td> </tr> <tr> <td class="h" > <a name="148">148</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="149">149</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="150">150</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="151">151</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub create_page( $$ ) { </td> </tr> <tr> <td class="h" > <a name="152">152</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td class="c0" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#152-1"> 0 </a> </td> <td class="c3" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#152-1"> 1 </a> </td> <td >   </td> <td class="s"> my $page = MediaWiki::EditFramework::Page->new(@_); </td> </tr> <tr> <td class="h" > <a name="153">153</a> </td> <td class="c0" > 0 </td> <td class="c0" > <a href="blib-lib-MediaWiki-EditFramework-pm--branch.html#153-1"> 0 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> croak "$_[1]: exists" if $page->exists; </td> </tr> <tr> <td class="h" > <a name="154">154</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return $page; </td> </tr> <tr> <td class="h" > <a name="155">155</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> }; </td> </tr> <tr> <td class="h" > <a name="156">156</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="157">157</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item B<write_prefix>(I<PREFIX>) </td> </tr> <tr> <td class="h" > <a name="158">158</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="159">159</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> When writing pages, prepend the specified I<PREFIX> to the page title. </td> </tr> <tr> <td class="h" > <a name="160">160</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="161">161</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This makes it easier to create a test mode for a bot script. By specifying </td> </tr> <tr> <td class="h" > <a name="162">162</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> the write prefix in your own user space, the bot will retrieve the normal </td> </tr> <tr> <td class="h" > <a name="163">163</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> pages, but the modifications will be written to user space so you can review </td> </tr> <tr> <td class="h" > <a name="164">164</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> them without impacting others. </td> </tr> <tr> <td class="h" > <a name="165">165</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="166">166</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="167">167</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="168">168</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub write_prefix { </td> </tr> <tr> <td class="h" > <a name="169">169</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td class="c0" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#169-1"> 0 </a> </td> <td class="c3" > <a href="blib-lib-MediaWiki-EditFramework-pm--subroutine.html#169-1"> 1 </a> </td> <td >   </td> <td class="s"> my $self = shift; </td> </tr> <tr> <td class="h" > <a name="170">170</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $prefix = shift; </td> </tr> <tr> <td class="h" > <a name="171">171</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> $self->{write_prefix} = $prefix; </td> </tr> <tr> <td class="h" > <a name="172">172</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="173">173</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="174">174</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =back </td> </tr> <tr> <td class="h" > <a name="175">175</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="176">176</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 SEE ALSO </td> </tr> <tr> <td class="h" > <a name="177">177</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="178">178</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> L<MediaWiki::API> </td> </tr> <tr> <td class="h" > <a name="179">179</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="180">180</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 COPYRIGHT </td> </tr> <tr> <td class="h" > <a name="181">181</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="182">182</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Copyright (C) 2012 by Steve Sanbeg </td> </tr> <tr> <td class="h" > <a name="183">183</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="184">184</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This library is free software; you can redistribute it and/or modify </td> </tr> <tr> <td class="h" > <a name="185">185</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> it under the same terms as Perl itself, either Perl version 5.10.1 or, </td> </tr> <tr> <td class="h" > <a name="186">186</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> at your option, any later version of Perl 5 you may have available. </td> </tr> <tr> <td class="h" > <a name="187">187</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="188">188</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="189">189</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="190">190</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 1; </td> </tr> </table> </body> </html>