#!/usr/bin/perl

###############################################
# Copyright 2007 Jeremy Mooney
# http://jeremy.qux.net/projects/sm-fileupload/
# Last Modified 2007-07-31
###############################################

use strict;
use LWP::UserAgent;
use HTTP::Request;
use Digest::MD5;

# Parse input
my %parsedargs;
while($_ = shift @ARGV) {
   if ($_ eq '--email') {
      $parsedargs{'email'} = shift @ARGV;
   } elsif ($_ eq '--passwd') {
      $parsedargs{'passwd'} = shift @ARGV;
   } elsif ($_ eq '--passwdhash') {
      $parsedargs{'passwdhash'} = shift @ARGV;
   } elsif ($_ eq '--sessionid') {
      $parsedargs{'sessionid'} = shift @ARGV;
   } elsif ($_ eq '--caption') {
      $parsedargs{'caption'} = shift @ARGV;
   } elsif ($_ eq '--filename') {
      $parsedargs{'filename'} = shift @ARGV;
   } elsif ($_ eq '--albumid') {
      $parsedargs{'albumid'} = shift @ARGV;
   } elsif ($_ eq '--file') {
      $parsedargs{'file'} = shift @ARGV;
   } elsif ($_ eq '--getsession') {
      $parsedargs{'getsession'} = 1;
   } elsif ($_ eq '--logout') {
      $parsedargs{'logout'} = 1;
   } elsif ($_) {
      die "Expecting command at: $_\n";
   }
}

## Verify sane input before making calls
unless($parsedargs{'getsession'} || $parsedargs{'logout'}) { # If only dealing with session setup, don't need file data
   unless($parsedargs{'file'}) {
      die "Need to specify file to upload: use --file <filename>\n";
   }

   unless($parsedargs{'albumid'}) {
      die "Need to specify album id as destination: use --albumid <id>\n";
   }
}

my $ua = LWP::UserAgent->new;
$ua->agent('JeremysFileUpload/0.1');

unless ($parsedargs{'sessionid'}) {
   unless($parsedargs{'email'} && ($parsedargs{'passwd'} || $parsedargs{'passwdhash'})) {
      die "Need to specify either sessionid (--sessionid <id>) or email and password/hash (--email <email> --passwd[hash] <passwd>)\n";
   }
   my $request = HTTP::Request->new;
   $request->header('X-Smug-Version' => '1.1.1');
   $request->method('GET');

   $request->uri('https://api.smugmug.com/hack/rest/1.1.1/?APIKey=BoITI8ZKZ6btYeIunyRPbxA3a2a4gTG6'.
                   '&EmailAddress='.$parsedargs{'email'}.
                 ($parsedargs{'passwd'}?(
                   '&method=smugmug.login.withPassword'.
                   '&Password='.$parsedargs{'passwd'}
                 ):(
                   '&method=smugmug.login.withHash'.
                   '&PasswordHash='.$parsedargs{'passwdhash'}
                 ))
                );
   my $response = $ua->request($request);
   my $loginresp = $response->content;

   if ($loginresp =~ m/<SessionID>([^<]+)<\/SessionID>/) {
      $parsedargs{'sessionid'} = $1;
   } else {
      die "Could not receive session key - invalid login?\n".($loginresp);
   }
}
if ($parsedargs{'getsession'}) {
   print $parsedargs{'sessionid'};
   exit 0;
}

if ($parsedargs{'logout'}) {
   logout();
   exit;
}

my $request = HTTP::Request->new;
$request->header('X-Smug-Version' => '1.1.1');
$request->header('X-Smug-SessionID' => $parsedargs{'sessionid'});
$request->header('X-Smug-ResponseType' => 'REST');
$request->header('X-Smug-AlbumID' => $parsedargs{'albumid'});
if ($parsedargs{'filename'}) {
   $request->header('X-Smug-FileName' => $parsedargs{'filename'});
}
if ($parsedargs{'caption'}) {
   $request->header('X-Smug-Caption' => $parsedargs{'caption'});
}
   
my $md5hash = Digest::MD5->new;

open(FILE,$parsedargs{'file'}) || die "Could not open file $parsedargs{'file'}";
binmode FILE;
$md5hash->addfile(*FILE);
seek FILE,0,0;
my $filedata;
my $buffer;
while(read FILE,$buffer,1024) {
   $filedata .= $buffer;
}
close(FILE);
my $hashvalue = $md5hash->hexdigest();

$request->header('Content-MD5', $hashvalue);
$request->header('Content-Length',length($filedata));
$request->method('POST');
$request->uri('http://upload.smugmug.com/photos/xmlrawadd.mg');

$request->content($filedata);

my $response = $ua->request($request);

if ($response->is_success) {
   my $result = $response->content;
   if ($result =~ m/<ImageID>([^<]+)<\/ImageID>/) {
      print "$1";
      exit 0;
   } else {
      $result =~ m/<rsp stat="fail">\s*(.*)\s*<\/rsp>/s;
      die "Error uploading image: $1";
   }
} else {
   print $response->status_line;
   exit 1;
}

if ($parsedargs{'email'}) { # Should be only for currently-generated sessions
   logout();
   exit 0;
}

sub logout() {
   my $request = HTTP::Request->new;
   $request->header('X-Smug-Version' => '1.1.1');
   $request->method('GET');

   $request->uri('https://api.smugmug.com/hack/rest/1.1.1/?APIKey=BoITI8ZKZ6btYeIunyRPbxA3a2a4gTG6'.
                   '&method=smugmug.logout&SessionID='.$parsedargs{'sessionid'});
   my $response = $ua->request($request);
   if ($response->is_success) { # We don't care what the server says - if it was valid or not before, just that server saw logout request
      exit 0;
   } else {
      die "Error running logout: ".$response->status_line;
   } 
}

