User:Tweakbot/Wikipedia/Page.pm

/Wikipedia.pm /Wikipedia/Page.pm /tweakbot.pl
package Wikipedia::Page;

use strict;
use warnings;

use constant LANGUAGE		=> 'en';
use constant SERVER		=> 'http://%s.wikipedia.org';

use constant EDIT		=> '/w/index.php?title=%s&action=edit';
use constant EDIT_FORM		=> 'editform';
use constant EDIT_FORM_WIKI	=> 'wpTextbox1';
use constant EDIT_FORM_SUMMARY	=> 'wpSummary';
use constant EDIT_FORM_MINOR	=> 'wpMinoredit';
#use constant EDIT_FORM_WATCH	=> 'wpWatchthis';
use constant EDIT_FORM_SAVE	=> 'wpSave';
# these actions are not supported yet
#use constant EDIT_FORM_PREVIEW	=> 'wpPreview';
#use constant EDIT_FORM_DIFF	=> 'wpDiff';

use HTML::Form			qw//;

=head1 NAME

Wikipedia::Page - Provides a layer of abstraction for automatic editing of
a single Wikipedia article.

=head1 DESCRIPTION

FIXME

=head1 SYNOPSIS

FIXME

=head1 SUBROUTINES

=cut

sub new {
	my $class = shift;

	my %opts = @_;

	my ($pagename, $user_agent, $server) =
		@opts{qw/ pagename user_agent server /};

	# TODO: handle these more gracefully
	defined $pagename or die "$class error: no page name defined";
	defined $user_agent or die "$class error: no user agent defined";

	unless (defined $server) {
		# no server name defined
		my $language = $opts{'language'};

		$language = LANGUAGE unless defined $language;

		$server = sprintf SERVER, $language;
	}

	bless {
		'pagename'	=> $pagename,
		'user_agent'	=> $user_agent,
		'server'	=> $server,
		'_edit_form'	=> undef,
	}, $class
}

=head2 contents

Returns the wiki source of the requested page.

	my $wiki_source = $page->contents;

=cut

sub contents {
	my $self = shift;

	my $edit_form = $self->_get_form
		or die "no suitable form for `$self->{'pagename'}'";

	$edit_form->value(EDIT_FORM_WIKI)
}

=head2 put_contents

Submits the changed page to Wikipedia.

	$page->put_contents($contents, [$edit_summary, $is_minor]);

=cut

sub put_contents {
	my $self = shift;

	my ($new_contents, $edit_summary, $is_minor) = @_;

	my $edit_form = $self->_get_form(1)
		or die "no suitable form for `$self->{'pagename'}'";

	my $old_contents = $edit_form->value(EDIT_FORM_WIKI);

	warn "no changes being made to page `$self->{'pagename'}'"
		if $new_contents eq $old_contents;

	$edit_form->value(EDIT_FORM_WIKI, $new_contents);
	$edit_form->value(EDIT_FORM_SUMMARY, $edit_summary);
	$edit_form->value(EDIT_FORM_MINOR, $is_minor);

	$self->{'user_agent'}->request($edit_form->click(EDIT_FORM_SAVE));
}

################

sub _get_form {
	my $self = shift;

	my $use_saved = shift || 0;

	return $self->{'_edit_form'}
		if $use_saved && defined $self->{'_edit_form'};

	my ($pagename, $user_agent, $server) =
		@{$self}{qw/ pagename user_agent server /};

	$self->{'_edit_form'} = (grep {$_->attr('id') eq EDIT_FORM}
		HTML::Form->parse(
			$user_agent->get($server.sprintf EDIT, $pagename)
		)
	)[0]
}

=head1 SEE ALSO

L<Wikipedia>

=head1 AUTHOR

	Part of project Tweakbot by Dan Church <amphetamachine@gmail.com>

=cut

1