package WebGUI::Workflow::Activity::WccAutoVote; 

use strict;
use base 'WebGUI::Workflow::Activity';
use WWW::Mechanize;
    
=head1 NAME

Package WebGUI::Workflow::Activity::WccAutoVote

=head1 DESCRIPTION

Whoa! Last day to enter the "Best Workflow Activity that Integrates with an External Service" contest and nobody has submitted anything!

Ok, here's something fun..

Let's choose someone else's WebGUI site as the External Service to integrate with. For example.. a Poll on somebody else's site... say... the community contest poll on webgui.org/wcc?  

:evil-grin:

Install this workflow on your own wG site to:
* Connect to an external wG site of your choosing (customisable in the options as "Site URL", say.. www.webgui.org) 
* Register a new user on that site. The workflow starts by trying to register "autoVoter0" and then increments the index until it finds an unregistered name, eg. autoVoter1, autoVoter2, ..
* Login to the site as the new user and pull up the poll page (customisable in the options as "Poll URL", say.. www.webgui.org/wcc)
* Vote for the poll answer of your choosing! (customisable in the options as "Answer", say.. whichever entry you want flood in some votes for)

If you decided to run the workflow every minute or so off your own site... well you might be able to influence the votes slightly..
(and if you wanted to be really evil you could put your URLs through an anonymiser so that each vote would come from a unique IP)

The Deets
* The code depends on WWW::Mechanize (which you will need to install via cpan with the command "install WWW::Mechanize")
* We're basically site-scraping here so the code is dependent on the wG templates being used. I tested on the default wG tempaltes.
* We're also dependent on "Allow Anonymous Registration" being turned on and Capcha turned off (both of which happen to be the case on webgui.org....)
* Everything is logged to the wG errorHandler so you can see exactly what the workflow is doing step-by-step (and the reasons for any breakages)  

Sample Output
INFO Log::Log4perl::Appender::log[182] Running with settings:
INFO Log::Log4perl::Appender::log[182] Site URL: http://mysite.com
INFO Log::Log4perl::Appender::log[182] Poll URL: http://mysite.com/mypoll
INFO Log::Log4perl::Appender::log[182] Answer: a1
INFO Log::Log4perl::Appender::log[182] Try to create an new user called: autoVoter0
INFO Log::Log4perl::Appender::log[182] Opened Create Account page
INFO Log::Log4perl::Appender::log[182] Found first form on page
INFO Log::Log4perl::Appender::log[182] Set username field
INFO Log::Log4perl::Appender::log[182] Set pasword field
INFO Log::Log4perl::Appender::log[182] Set pasword confirm field
INFO Log::Log4perl::Appender::log[182] Set pasword email field
INFO Log::Log4perl::Appender::log[182] Submitted form
INFO Log::Log4perl::Appender::log[182] Username already in use, try again!
INFO Log::Log4perl::Appender::log[182] Try to create an new user called: autoVoter1
INFO Log::Log4perl::Appender::log[182] Opened Create Account page
INFO Log::Log4perl::Appender::log[182] Found first form on page
INFO Log::Log4perl::Appender::log[182] Set username field
INFO Log::Log4perl::Appender::log[182] Set pasword field
INFO Log::Log4perl::Appender::log[182] Set pasword confirm field
INFO Log::Log4perl::Appender::log[182] Set pasword email field
INFO Log::Log4perl::Appender::log[182] Submitted form
INFO Log::Log4perl::Appender::log[182] Username already in use, try again!
INFO Log::Log4perl::Appender::log[182] Try to create an new user called: autoVoter2
INFO Log::Log4perl::Appender::log[182] Opened Create Account page
INFO Log::Log4perl::Appender::log[182] Found first form on page
INFO Log::Log4perl::Appender::log[182] Set username field
INFO Log::Log4perl::Appender::log[182] Set pasword field
INFO Log::Log4perl::Appender::log[182] Set pasword confirm field
INFO Log::Log4perl::Appender::log[182] Set pasword email field
INFO Log::Log4perl::Appender::log[182] Submitted form
INFO Log::Log4perl::Appender::log[182] Opened polling page
INFO Log::Log4perl::Appender::log[182] Ticked vote option
INFO Log::Log4perl::Appender::log[182] Submitted voting form
INFO Log::Log4perl::Appender::log[182] Voting seemed to succeed!
INFO Log::Log4perl::Appender::log[182] Finished.

=head1 SYNOPSIS

See WebGUI::Workflow::Activity for details on how to use any activity.

=head1 METHODS

These methods are available from this class:

=cut


#-------------------------------------------------------------------

=head2 definition ( session, definition )

See WebGUI::Workflow::Activity::defintion() for details.

=cut 

sub definition {
	my $class = shift;
	my $session = shift;
	my $definition = shift;
	my $i18n = WebGUI::International->new($session, "Activity_WccAutoVote");
	push(@{$definition}, {
		name=>"WccAutoVote",
		properties=> {
			siteUrl =>
			{
				fieldType       => 'url',
				label           => $i18n->echo('Site URL'),
				defaultValue    => "http://mysite.com",
				hoverHelp       => $i18n->echo("URL of an external WebGUI site to connect to")
			},
			pollUrl =>
			{
				fieldType       => 'url',
				label           => $i18n->echo('Poll URL'),
				defaultValue    => "http://mysite.com/mypoll",
				hoverHelp       => $i18n->echo("URL of a page on the external WebGUI site containing the poll you want to vote in")
			},
			answer =>
			{
				fieldType       => 'text',
				label           => $i18n->echo('Answer'),
				defaultValue    => "a1",
				hoverHelp       => $i18n->echo("The poll answer you want to vote for (it will be something like 'a1', or 'a2' etc.. - check out the HTML source on the poll voting page")
			},
		},
	});
	return $class->SUPER::definition($session,$definition);
}


#-------------------------------------------------------------------

=head2 execute ( [ object ] )

See WebGUI::Workflow::Activity::execute() for details.

=cut

sub execute {
	my $self = shift;
    my $mode = shift;
	my $session = $self->session;
	my $eh = $self->session->errorHandler;
	
	# Create our Mechanize object
    my $m = new WWW::Mechanize;
	$self->{m} = $m;
	
	# Settings
	$eh->info("Running with settings:");
    my $siteUrl = $self->get("siteUrl");
    my $pollUrl = $self->get("pollUrl");
    my $answer = $self->get("answer");
    $eh->info("Site URL: $siteUrl");
    $eh->info("Poll URL: $pollUrl");
    $eh->info("Answer: $answer");
	
	# Keep trying to create a new user until we find a unique username
	my $i = 0;
   	$self->createAccount("autoVoter" . $i++);
   	while ($self->getBody =~ /That account name is already in use/) {
   		$eh->info("Username already in use, try again!");
   		$self->createAccount("autoVoter" . $i++);
   	}
   	# Die on any other account creation errors (we're not trying to be too fancy here..)
   	if ($self->getBody =~ /Create Account/) {
		die("Account Creation failed: " . $self->getBody);
   	}
	
	# Vote!
	$m->get($pollUrl);
	$self->report("Opened polling page");
	$m->field(answer => $answer);
	$self->report("Ticked vote option");
	$m->submit;
	$self->report("Submitted voting form");
	if ($self->getBody =~ /pollColor/) {
		$eh->info("Voting seemed to succeed!")
   	} else {
   		$eh->info("Voting failed :(")
   	}
	$eh->info("Finished.");
	return $self->COMPLETE;
}

#-------------------------------------------------------------------
sub report {
	my $self = shift;
	my $msg = shift;
	$self->session->errorHandler->error("Failed on: $msg") unless $self->{m}->success;
	$self->session->errorHandler->info($msg);
}

#-------------------------------------------------------------------
sub createAccount {
	my $self = shift;
	my $username = shift;
	my $m = $self->{m};
	$self->session->errorHandler->info("Try to create an new user called: $username");
	my $siteUrl = $self->get("siteUrl");
	$m->get("$siteUrl?op=auth;method=createAccount");
    $self->report("Opened Create Account page");
	$m->form_number(0);
	$self->report("Found first form on page");
	$m->field("authWebGUI.username" => $username);
	$self->report("Set username field");
	$m->field("authWebGUI.identifier" => "bob");
	$self->report("Set pasword field");
	$m->field("authWebGUI.identifierConfirm" => "bob");
	$self->report("Set pasword confirm field");
	$m->field("email" => "$username\@mailinator.com");
	$self->report("Set pasword email field");
	$m->submit;
	$self->report("Submitted form");
	
}

#-------------------------------------------------------------------
sub getBody {
	my $self    = shift;
	my $c = $self->{m}->content;
	$c =~ s/^.*\<body\>/\<body\>/si;
	$c =~ s/\<\/body\>.*/\<\/body\>/si;
	return $c;
}

1;