Avoid Monotonous Tasks With WWW::Mechanize
Hi everyone,
A SourceHosting.net client recently asked to create a large number of users in a custom installation of phpDeadlock that he uses to manage access to his Subversion repository here. Since phpDeadlock doesn’t have a user management API, this sounded like a monotonous, error-prone task. After entering 10-15 users, the chances of misspelling a name or email address or clicking the wrong button in the UI will likely increase dramatically.
I briefly investigated adding records directly to the backend MySQL database, but since various other actions are fired by user creation, including email notifications to the new user and the system administrator, using the application’s UI was the safest choice.
I had run across the WWW::Mechanize Perl module a while back, but hadn’t used it yet. I knew it could be used to automate interaction with a web site, and after reading through the rich list of methods, I promptly began hacking a script together to parse a list of email addresses supplied by the client and use it to drive the user creation UI.
The module implements a headless web browser, including cookie jar, history, form submission and other behaviors that you would expect, except it doesn’t parse and execute Javascript. That was a non-issue for me.
phpDeadlock has an administrator login prompt that requests a password before any privileged pages are accessed. Logging in to the application was a no-brainer in WWW::Mechanize:
use WWW::Mechanize; use String::Random; use Text::Capitalize; my $mech = WWW::Mechanize->new(); $mech->get('https://phpdeadlock.mydomain.com/admin/'); $mech->set_visible('ItsASecret'); $mech->submit_form();
That was too easy! All further page requests will be authenticated. Next, the script enters a loop to process email addresses presented on STDIN, one per line, and populate the required fields:
for my $email (<STDIN>) { chomp $email; my @fields = split /\@/, $email; my $finitial = substr($fields[0], 0, 1); my $lname = substr($fields[0], 1); my $pw = new String::Random->randpattern("ssssssss"); $mech->get('https://phpdeadlock.mydomain.com/admin/newuser.php'); $mech->submit_form( fields => { firstname => capitalize($finitial), lastname => capitalize($lname), email => $email, username => $fields[0], password => $pw, password2 => $pw } ); print "Added new user for $finitial $lname\n"; }
If the user’s full name had been supplied, I could have easily parsed that and set the firstname and lastname fields appropriately.
The possibilities for using this module are endless, and I encourage you to try it out, especially when you’re dreading a repetitive web application UI task. Make sure to check the list of other Perl modules that are based on WWW::Mechanize, too!