#!/usr/bin/perl
# mwpush.pl - Push page data to a Wikimedia server
# By WikiPedia:User:KeithTyler
# Portions largely taken or based on upload.pl by WikiPedia:User:Eloquence

# call requirements
use Getopt::Std;
use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
use HTTP::Cookies;
use JSON;
use Data::Dumper;
#use warnings;

getopts('l:p:w:t:he');

if ($opt_h) { die "Usage: mwpush.pl -w <wiki host/path> -t <wiki page name> -l <wiki login> -p <wiki password> [-e] [files ...]\n"; }

if (!$opt_l) { die "Provide Wiki login with -l"; }
if (!$opt_p) { die "Provide Wiki password with -p"; }
if (!$opt_w) { die "Provide Wiki hostname and path with -w"; }
if (!$opt_t) { die "Provide Wiki page name with -t"; }

my $username=$opt_l;
my $password=$opt_p;
my $WIKI_PATH=$opt_w;
my $WIKI_PAGE=$opt_t;

my $onlyifempty=$opt_e;

### Login to wiki

# Set up connection data
my $browser=LWP::UserAgent->new();
my @ns_headers = (
 'User-Agent' => 'MediaWiki Pusher 0.1 by KeithTyler',  #Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20041107 Firefox/1.0',
 'Accept' => 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*',
 'Accept-Charset' => 'iso-8859-1,*,utf-8',
 'Accept-Language' => 'en-US',
);

# Hold cookies
$browser->cookie_jar( {} );

# Make login request
$response=$browser->post("http://".$WIKI_PATH."/api.php?action=login&lgname=$username&lgpassword=$password&format=json",@ns_headers);

# After logging in, we should be redirected to another page. 
# If we aren't, something is wrong.
#
if($response->code!=200) {
        print 
"We weren't able to receive login token. see wikipush.out ...\n";
        open(DEBUG,">wikipush.debug.out") or die "Could not write file.\n";
        print DEBUG $response->as_string;
        close(DEBUG);
        exit 1;
}

### get json values
my $data = $response->content();
my $hashRef = decode_json($data);
my $login = $hashRef->{'login'};
my $result = $login->{'result'};
my $token = $login->{'token'};
print "token request result: $result\n";
print "token request data: $token\n";

$response=$browser->post("http://".$WIKI_PATH."/api.php?action=login&lgname=$username&lgpassword=$password&lgtoken=$token&format=json",@ns_headers);
if($response->code!=200) {
        print 
"We weren't able to login. see wikipush.out ...\n";
        open(DEBUG,">wikipush.out") or die "Could not write file.\n";
        print DEBUG $response->as_string;
        close(DEBUG);
        exit 1;
}

$data = $response->content();
$hashRef = decode_json($data);
$login = $hashRef->{'login'};
$result = $login->{'result'};
if($result != 'Success') {
        print 
"We weren't able to login - no Success. see wikipush.out ...\n";
        open(DEBUG,">wikipush.out") or die "Could not write file.\n";
        print DEBUG $response->as_string;
        close(DEBUG);
        exit 1;
}

my $userid = $login->{'lguserid'};
print "userid: $userid\n";

### Get a wpEditToken

# We need to load our target page first in edit mode to capture a
# wpEditToken.  Without this the submit page will not submit.

$response=$browser ->
  get("http://".$WIKI_PATH."/index.php?title=".$WIKI_PAGE."&action=edit",
      @ns_headers);

my $startTime;
my $editToken;
my $content;
$content = $response->as_string;

# Get EditToken
# Note: wpEditToken can contain "+" and "\"
($editToken) = ( $content =~ m/value\=\"([0-9a-f\+\\]*)\" name\=\"wpEditToken\"/ );
($editTime) = ( $content =~ m/value\=\"([0-9a-f]*)\" name\=\"wpEdittime\"/ );
($startTime) = ( $content =~ m/value\=\"([0-9a-f]*)\" name\=\"wpStarttime\"/ );

# Determine page existence state
# If we find "selected new" (a CSS class set), it is a new (empty) page
# This is preferable to depending on message text (which is changeable)

if ($onlyifempty) {
  if ( ! ($content =~ m/class=\"selected new\"/ )) {
    print "Existing page is not empty. Aborting due to -e.\n";
    exit 1;
  }
}


### Collect input data into string

my $INPUT_DATA;

# Read data
while (<>) {
  $INPUT_DATA.=$_;
}


### Post data to Wiki

$response=$browser -> 
   post("http://".$WIKI_PATH."/index.php?title=".$WIKI_PAGE."&action=submit",
        @ns_headers,
        Content_Type=>'application/x-www-form-urlencoded',Content=>
        [ wpTextbox1 => $INPUT_DATA,
          wpSummary => "Automated page entry using MWPush.pl",
          wpSave => "Save page",
          wpSection => "",
          wpStarttime => $startTime,
          wpEdittime => $editTime,
          wpEditToken => $editToken,
        ]);


### Evaluate response from Wiki

if($response->code!=302) {
    print "Upload failed! Response was:\n";
    print $response->as_string;
    exit 1;
  } else {
    print "Uploaded successfully.\n";
  }               

# Evaluate operation

print "Everything seems to be OK. Log will be written to mwpush.log.\n";
open(LOG,">mwpush.log") or die "Could not write file.\n";
print LOG $response->as_string;
close(LOG);

