#!/usr/bin/perl -w
# :set tabstop=4

use diagnostics;
use strict;

#
# Cliente de "https://gestiona.unizar.es/aparcamiento/"
#
# Actualmente pide plaza en Campus Pza. S. Francisco.
#
# OJO: Es imprescindible ajustar las opciones entre OPT begin/end
# OJO: La opcion "--file" se deberia usar solamente con "named pipes"
# en conjuncion con un agente de gestion de passwords en memoria.
# Es mala idea almacenar passwords en texto claro en el disco duro.
#
# Requiere: wget, display, X11 / jp2a (captcha)
# Requiere: tesseract (captcha)
#

our $current_date = makedate(time());

our $serverproto = "https";
our $servername = "gestiona.unizar.es";
our $serverpath = "aparcamiento";

#
# Options
#

#### OPT begin
#### Cambiar estas lineas para ajustar las opciones
our $marca="Seat";
our $modelo="600";
our $color="Rosa";
our $matricula="6969XXX";

our $home = $ENV{'HOME'};
our $cookies="$home/.cookies.txt";
#our $cookies=File::HomeDir->my_home . "/.cookies.txt"
our $image="$home/.captcha.jpg";

use Getopt::Long;
my $DEF_FILE =	"";
my $DEF_FLOG =	"";
my $DEF_LOG =	"";
my $DEF_PASS =	"Foo";
my $DEF_NIP =	"696969";
my $DEF_DATE =	$current_date;

#### OPT end

our $opt_version;
our $opt_file;
our $opt_log;
our $opt_nip;
our $opt_pass;
our $opt_date;
our $opt_help;
our $opt_auto;
our $opt_verbose;


my $VERSION = "0.0.4, Mar 2017";

sub usage
{
print STDERR "$current_date\n";

	warn "$0: @_\n" if @_;
	print <<EOF;
usage: $0 [options] code
Options are:
  --file=string         (read nip and password from file, default no file)
  --log=string          (log answer from server to this file (STDOUT))
  --nip=your_nip        (NIP, default $DEF_NIP)
  --pass=your_pass      (password, default $DEF_PASS)
  --date=date           (date, default $DEF_DATE)
  --auto                (auto captcha decode)
  --version             (print version)
  --verbose             (verbose)
  -h                    (this help)

park.pl version $VERSION by SPDsoft
EOF

	exit(0);
}

my $uok = GetOptions( qw(
file=s
log=s
nip=i
pass=s
date=s
version
verbose
auto
help));

usage("Usage error!") unless $uok;
usage() if $opt_help;


if ( $opt_version )
{
	print STDERR "park.pl v. $VERSION\n";
	exit(0);
}

my $file = $opt_file || $DEF_FILE;
my $log = $opt_log || $DEF_LOG;
my $pass = $opt_pass || $DEF_PASS;
my $nip = $opt_nip || $DEF_NIP;
my $date = $opt_date || $DEF_DATE;

if ( $file ne "" )
{
	open(F , "<$file" ) || die "Can't open $file: $!";
	$_ = <F>;
	($nip,$pass) = split();
	close (F);
}

if ( $log ne "" )
{
	open(STDOUT , ">$log" ) || die "Can't open $log: $!";
}


#my $x = int(rand(103));
#my $y = int(rand(59));

my $postargs="txtNIP=$nip&txtPassword=$pass&metodo=Entrar";
my $cl=length($postargs);
#print STDERR "POSTARGS: $postargs ($cl)\n" if $opt_verbose;

####
#### jsessionid
####


my $in_headers=1;
my $jsessionid="";


#print STDERR "#### $postargs\n" if  $opt_verbose;
print STDERR "#### $serverproto://$servername/$serverpath/\n" if  $opt_verbose;
open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies $serverproto://$servername/$serverpath/|" );

while(<CMD>)
{
	if( /(.*form.*AccesoBean.*action=.*jsessionid=)([A-F0-9]*)(">.*)/ )
	{
		$jsessionid=$2;
		print STDERR "#### Found: $jsessionid\n";
	}
}
close(CMD);

print STDERR "#### jsessionid: \"$jsessionid\"\n" if $opt_verbose;

if ( $jsessionid eq "" )
{
print STDERR "######################### ERROR: jsessionid failed\n";
exit (1);
}

####
#### Permisos de un dia
####

$in_headers=1;
my $url="";
my $captcha="";
my $autocaptcha="";
my $captchaurl="";


#print STDERR "#### $postargs\n" if  $opt_verbose;
open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies  --post-data=\"$postargs\" \"$serverproto://$servername/$serverpath/acceso.do;jsessionid=$jsessionid\"|" );

while(<CMD>)
{
	if( /(.*a href=\")(listadoPermisosDia[^\"]*)(" class.*)/ )
	{
		$url=$2;
	}
	if( /([ ]*)(No se ha podido acceder al sistema.*)/ )
	{
		print STDERR "#### ERROR: \"$2\"\n";
	}
}
close(CMD);

print STDERR "#### URL: \"$url\"\n" if $opt_verbose;

if ( $url eq "" )
{
	print STDERR "######################### ERROR: url failed\n";
	exit (1);
}

####
#### Listar
####

$in_headers=1;
$postargs="";
my $solicitar="";

open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies  \"$serverproto://$servername/$serverpath/$url\"|" );

while(<CMD>)
{
	if( /(.*form.*ListaPermisoDiaBean.*action=\")([^\"]*)(">.*)/ )
	{
		$solicitar=$2;
		$postargs="metodo=Solicitar"
	}
}	
close(CMD);


print STDERR "#### URL: \"$solicitar\"\n" if $opt_verbose;

if ( $solicitar eq "" )
{
	print STDERR "######################### ERROR: solicitar failed\n";
	exit (1);
}


####
#### Solicitar
####

$in_headers=1;

#print STDERR "#### $postargs\n" if  $opt_verbose;

open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies --post-data=\"$postargs\" \"$serverproto://$servername$solicitar\"|" );

$postargs="";

while(<CMD>)
{
	if( /.*input.*chkAceptarCondiciones.*/ )
	{
		$postargs="chkAceptarCondiciones=Si&metodo=Continuar";
	}
}	
close(CMD);


#print STDERR "#### PA: \"$postargs\"\n" if $opt_verbose;

if ( $postargs eq "" )
{
	print STDERR "######################### ERROR: PA failed\n";
	exit (1);
}


####
#### Selecionar
####

$in_headers=1;
$url="";
$captcha="";

#print STDERR "#### $postargs\n" if  $opt_verbose;

open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies --post-data=\"$postargs\" \"$serverproto://$servername$solicitar\"|" );

$postargs="metodo=Solicitar";

while(<CMD>)
{
	if( /(.*form.*PermisoDiaBean.*action=\")([^"]*)(">.*)/ )
		{ $url=$2; }

	if( /(.*input.*txtEmail.*value=\")([^"]*)(">.*)/ )
		{ $postargs = "$postargs&txtEmail=$2"; }

	if( /(.*input.*txtTfno.*value=\")([^"]*)(">.*)/ )
		{ $postargs = "$postargs&txtTfno=$2"; }

	if( /(.*select.*lstModalidades.*value=\")([^"]*)(">.*)/ )
		{ $postargs = "$postargs&lstModalidades=$2"; }

	if( /(.*img.*id.*imgCaptcha.*src=\")([^"]*)(".*)/ )
	{
		$captcha = "$2";
		$captchaurl="$serverproto://$servername$solicitar";
		$captchaurl =~ s/\/[^\/]*$/\//g;
		$captchaurl = "$captchaurl$captcha";
		print STDERR "#### CAPTCHA $captchaurl\n" if  $opt_verbose;

		system ( "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies \"$captchaurl\" > $image");
		system ("convert -contrast-stretch \"20%,100%\" $image $image.jpg; mv $image.jpg $image; jp2a -i $image");

		$autocaptcha=`tesseract $image stdout -7 2>/dev/null | grep ...`;
		chomp($autocaptcha);

		if ( $opt_auto )
		{
			$captcha=$autocaptcha;
		}
		else
		{
			system ("display $image &");
			print "#### CAPTCHA ($autocaptcha) ? ";
			$captcha=<STDIN>;
			chomp($captcha);
		}
		print STDERR "#### CAPTCHA $captcha\n" if  $opt_verbose;
		$postargs = "$postargs&txtCodigoCaptcha=$captcha";
	}
}	


$postargs = "$postargs&txtFecha=$date";
$postargs = "$postargs&txtMarca=$marca";
$postargs = "$postargs&txtModelo=$modelo";
$postargs = "$postargs&txtColor=$color";
$postargs = "$postargs&txtMatricula=$matricula";

close(CMD);


print STDERR "#### SA: \"$url\"\n" if $opt_verbose;

if ( $url eq "" )
{
	print STDERR "######################### ERROR: SA failed\n";
	exit (1);
}


####
#### OK
####

$in_headers=1;

my $resultado="OK";

print STDERR "#### $serverproto://$servername$url\n" if  $opt_verbose;
print STDERR "#### $postargs\n" if  $opt_verbose;

open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies --post-data=\"$postargs\" \"$serverproto://$servername$url\" |" );


$url="";

while(<CMD>)
{
	if( /.*digo introducido en el campo.*Captcha.*/ )
		{ $resultado="#### ERROR: Eres un robot"; }

	if( /.*Solo puede seleccionar.*/ )
		{ $resultado="#### ERROR: Te has pasado de fecha"; }

	if( /.*No quedan plazas disponibles.*/ )
		{ $resultado="#### ERROR: Esta petao"; }

	if( /(.*form.*PermisoDiaBean.*action=\")([^"]*SiSolicitar)(">.*)/ )
		{ $url=$2; }

	if( /(.*input.*metodo.*value=\")(S[^"]*)(">.*)/ )
		{ $postargs = "metodo=$2"; }

}	

close(CMD);


if ( $resultado ne "OK" )
{
	print "$resultado\n";
	exit (1);
}
print STDERR "#### Si: \"$url\"\n" if $opt_verbose;

if ( $url eq "" )
{
	print STDERR "######################### ERROR: Solicitar failed\n";
	exit (1);
}



####
#### Si
####

$in_headers=1;

$resultado="#### Error: algo ha ido mal";

#print STDERR "#### $postargs\n" if  $opt_verbose;

open( CMD, "wget --no-check-certificate -O - --quiet --keep-session-cookies --save-cookies $cookies --load-cookies $cookies --post-data=\"$postargs\" \"$serverproto://$servername$url\"|" );


while(<CMD>)
{
	if( /.*procesada correctamente.*/ )
	{
		$resultado="OK";
	}
}	

close(CMD);


print "$resultado\n";

if ( $resultado ne "OK" )
{
	exit (1);
}

exit (0);

###########################################################################

sub makedate {
	my $secs = shift;
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($secs);
	my $mname = (qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec})[$mon];
	my $dname = (qw{Sun Mon Tue Wed Thu Fri Sat})[$wday];
	$mon = $mon + 1;
	$year = $year + 1900;
	return sprintf("%02d/%02d/%04d",$mday,$mon,$year);
}

###########################################################################

