#!/usr/bin/perl

# LICENSE
#
# gallery-uploader
# Copyright (C) 2007 Justin Watt
# justincwatt@gmail.com
# http://justinsomnia.org/
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Cookies;
use Getopt::Std;
use Term::ReadKey;
#use Data::Dumper;

# usage:
# gallery-uploader -l username -u http://example.com/gallery/main.php -a spring_break -f photos.txt -d

# flush output buffer immediately
$| = 1;

my %opts;
getopts('l:u:a:f:d', \%opts);

# first, check for photo file, read into an array for later
open (PHOTOS, $opts{f}) || die "Couldn't open " . $opts{f} . "\n";
my @photo_file_lines = <PHOTOS>;
close(PHOTOS);

# next, get gallery password for supplied user
print "Enter password: ";
ReadMode('noecho');
my $password = ReadLine(0);
chomp $password;
ReadMode(0);
print "\n";

# create user agent to send requests
my $ua = LWP::UserAgent->new;
$ua->agent("Gallery CLI Uploader/0.1");
$ua->cookie_jar(HTTP::Cookies->new(file => 'cookie_jar', autosave => 1));

# now let's try to send login request, establish session via cookie
my $response = $ua->request(POST $opts{u},
                            Content_Type =>'application/x-www-form-urlencoded',
                            Content => ['g2_controller'             => 'remote:GalleryRemote',
                                        'g2_form[cmd]'              => 'login',
                                        'g2_form[protocol_version]' => '2.2',
                                        'g2_form[uname]'            => $opts{l},
                                        'g2_form[password]'         => $password]
);

my %response = parse_response($response->content());

# check to see if password was accepted
if ($response{status} eq '0') {
  print "Login succeeded!\n"
} elsif ($response{status} eq '201') {
  die "Password Incorrect.\n";
} else {
  die $response->content() . "\n\n";
}

if ($opts{d}) {
  print $response->as_string . "\n";
}

# grab auth_token to send along with each subsequent request
my $auth_token = $response{auth_token};


# TODO: check to see if supplied album exists, if not, prompt to create


# get a list of all the files in the current working directory
opendir(DIR, ".");
my @files = readdir(DIR);
closedir(DIR);


# loop through all the photos in the text file and make sure they exist
# if not, see if anything matches
my @photos;
foreach my $line (@photo_file_lines) {
  chomp $line;
  next if ($line eq '' || substr($line, 0, 1) eq '#');
  
  # split on the first space
  my ($filename, $caption) = split(/ /, $line, 2);
  
  # if the filename as specified does not exist
  # look for a filename that matches
  if (!-s $filename) {
    my @matches = grep { /$filename/ } @files;
    if (@matches == 1) {
      $filename = $matches[0];
    } else {
      print @matches . " matches found for file '$filename', skipping...\n";
      next;
    }
  }
  
  push(@photos, {filename => $filename,
                 caption  => $caption});
}


# now loop through our validated array of filenames and upload!
my $i = 1;
foreach my $photo (@photos) {
  print "$i: Uploading " . $photo->{filename} . "...";
  $response = $ua->request(POST $opts{u},
                           Content_Type =>'form-data',
                           Content => ['g2_controller'          => 'remote:GalleryRemote',
                                       'g2_form[cmd]'           => 'add-item',
                                       'g2_form[set_albumPath]' => 'true',
                                       'g2_form[set_albumName]' => $opts{a},
                                       'g2_userfile'            => [$photo->{filename}],
                                       'g2_form[caption]'       => $photo->{caption},
                                       'g2_authToken'           => $auth_token]
  );

  %response = parse_response($response->content());
  
  if ($response{status} eq '0') {
    print "done.\n";

    if ($opts{d}) {
      print $response->as_string . "\n";
    }

  } else {
    print "failed: ";
    
    if ($response{status} eq '401') {
      print "you don't have permission to add photos to '" . $opts{a} . "'";
      
    } elsif ($response{status} eq '403') {
      print "album '" . $opts{a} . "' probably doesn't exist.";
    }
    print "\n";

    if ($opts{d}) {
      print $response->as_string . "\n";
    }

    exit;
  }
  $i++;
}



sub parse_response
{
  my $response = shift;
  my %fields;

  $response =~ s/.*\#__GR2PROTO__\n//s;
  my @lines = split('\n', $response);
  foreach (@lines) {
    my ($key, $value) = split('=', $_);
    if ($value ne '') {
      $fields{$key} = $value;
    }
  }

  return %fields;
}