#!/usr/bin/perl -w
use strict;
use EVEcommon;
use CGI qw/ :standard *table /;
$|=1;
use Time::HiRes qw ( time );
my $begin = time;
my $trust = $ENV{'HTTP_EVE.TRUSTED'} || 'undef';
my $debug = param("debug") || url_param("debug") || 0;
my $name = param("name");
#$quest ||= $ENV{'HTTP_EVE.SOLARSYSTEMNAME'};
$name ||= "";
print header,"\n",
start_html("POS fuel ... ".$name),"\n";
my $nlink = $name ? a({href=>self_url,},$name) : "";
print h1("POS Fuel ... ".$nlink),"\n";
use DBI;
use EVE::Db;
my $dbh = EVE::Db::dbh();
die "cant connect to db: ".DBI->errstr unless $dbh;
my $sth_alltowers = $dbh->prepare(qq{
select distinct
i.typeID,
i.typeName
from
dbo.invTypes i,
dbo.invControlTowerResources t
where
t.controlTowerTypeID = i.typeID
and i.published = 1
}) or die $dbh->errstr;
$sth_alltowers->execute() or die $sth_alltowers->errstr;
my $rows = $sth_alltowers->fetchall_arrayref();
$sth_alltowers->finish();
my %id_to_tower = ();
for (@$rows) {
my ($id, $name,) = @$_;
$id_to_tower{$id} = $name;
}
my $type = param("type");
$type = undef unless $type && $id_to_tower{$type};
my $cpu = param("cpu");
$cpu = undef unless defined $cpu && $cpu =~ /^\d+$/;
my $grid = param("grid");
$grid = undef unless defined $grid && $grid =~ /^\d+$/;
my @opt = param("opt");
my $have = param("have");
$have = undef unless defined $have && $have =~ /^[\s\dwdh]+$/;
my $havehours = defined $have ? &to_hours($have) : 0;
my $sov = param("sov");
$sov = 0 unless defined $sov && $sov =~ /^[012]$/;
my $sovfactor = {
0 => 1,
1 => 0.75,
2 => 0.7,
}->{$sov} || 1;
my %times = (
'1h' => 1,
'1d' => 24,
'1w' => 24*7,
'4w' => 24*7*4,
);
my $want = param("want");
$want = undef unless defined $want && $want =~ /^[\s\dwdh,km]+$/;
my %wantm3 = ();
if (defined $want) {
$want =~ s/\s+/,/g;
$want =~ s/,+/,/g;
$want =~ s/(^,|,$)//g;
for (split /,/, $want) {
if ($_ =~ /^(\d+)(k)?m3$/) {
my $m3 = $1;
$m3 *= 1000 if $2 && $2 eq "k";
$wantm3{$_} = $m3;
}
my $h = &to_hours($_);
if ($h) {
my $l = "WANT ".&prettytime($h*3600, undef, 0);
$times{$l} = $h;
}
}
}
my @ids_by_name = sort {
lc($id_to_tower{$a})
cmp
lc($id_to_tower{$b})
} keys %id_to_tower;
#print hr, br, start_form(-method=>'get');
print hr, "\n",
start_form,
start_table,"\n";
print Tr(td([
"TYPE: ",
popup_menu(-name => 'type',
-values => \@ids_by_name,
-default => $type,
-labels => \%id_to_tower,
),
],),), "\n";
unless ($type) {
print end_table,"\n";
}
my %hourlyfuel = ();
my $attr = {};
if ($type) {
print Tr(td([
"NAME: ",
textfield(-name => 'name',
-default => '',
-size => 30,
),
"optional, for ident purposes",
],),), "\n";
print Tr(td([
"HAVE: ",
textfield(-name => 'have',
-default => '',
-size => 20,
),
"(ex: 3d5h)",
],),), "\n";
print Tr(td([
"WANT: ",
textfield(-name => 'want',
-default => '',
-size => 20,
),
"(ex: 12w,24w)",
],),), "\n";
# print "type: $type",br,"\n";
my $sth_attr = $dbh->prepare(qq{
select
a.*,
t.*,
u.unitName
from
dbo.dgmTypeAttributes a,
dbo.dgmAttributeTypes t,
dbo.eveUnits u
where
a.typeID = ?
and a.attributeID = t.attributeID
and t.unitID = u.unitID
and t.displayName is not null
}) or die $dbh->errstr;
$sth_attr->execute($type) or die $sth_attr->errstr;
$attr = $sth_attr->fetchall_hashref('displayName');
$sth_attr->finish();
die "tower $type cycle not hour based and i am lazy" unless
$attr->{'Starbase Control Tower Period'}->{'valueInt'}
== 3600000 &&
$attr->{'Starbase Control Tower Period'}->{'unitName'}
eq 'Milliseconds';
my $typecpu = $attr->{'CPU Output'}->{'valueInt'};
my $cpuunit = $attr->{'CPU Output'}->{'unitName'};
die "eeek, tower $type without cpu" unless $typecpu;
$cpu = $typecpu unless defined $cpu;
my $cpuusage = $cpu/$typecpu;
print Tr(td([
"CPU: ",
textfield(-name => 'cpu',
-default => $typecpu,
-size => 10,),
sprintf("of %s %s == %i%%", $typecpu, $cpuunit, $cpuusage*100),
],),), "\n";
my $typegrid = $attr->{'powergrid Output'}->{'valueInt'};
my $gridunit = $attr->{'powergrid Output'}->{'unitName'};
die "eeek, tower $type without grid" unless $typegrid;
$grid = $typegrid unless defined $grid;
my $gridusage = $grid/$typegrid;
print Tr(td([
"GRID: ",
textfield(-name => 'grid',
-default => $typegrid,
-size => 10,),
sprintf("of %s %s == %i%%", $typegrid, $gridunit, $gridusage*100),
],),),"\n";
print Tr(td([
'SOV:',
join(br,
radio_group(
-name => 'sov',
-values => [0,1,2,],
-labels => {
0 => 'NONE (100%)',
1 => 'SYSTEM (75%)',
2 => 'CONSTELLATION (70%)',},
-default => 0,),),
])), "\n";
print end_table,"\n";
if ($debug) {
for (sort keys %$attr) {
printf "\n
\nouterkey: %s
\n", $_;
&hashprint($attr->{$_});
}
}
my $sth_type = $dbh->prepare(qq{
select
*
from
dbo.invTypes
where
typeID = ?
}) or die $dbh->errstr;
$sth_type->execute($type) or die $sth_type->errstr;
my $invtype = $sth_type->fetchrow_hashref();
$sth_type->finish();
my $typecapacity = $invtype->{'capacity'};
die "eeek, tower $type without capacity" unless $typecapacity;
if ($debug) {
&hashprint($invtype);
}
my $sth_fuel = $dbh->prepare(qq{
select
t.*,
p.*,
i.typeName,
i.portionSize,
i.volume,
i.basePrice,
i.typeID
from
dbo.invControlTowerResources t,
dbo.invControlTowerResourcePurposes p,
dbo.invTypes i
where
t.purpose = p.purpose
and t.resourceTypeID = i.typeID
and t.controltowertypeid = ?
}) or die $dbh->errstr;
$sth_fuel->execute($type) or die $sth_fuel->errstr;
my $rows = $sth_fuel->fetchall_hashref('resourceTypeID');
$sth_fuel->finish();
my @opts = ('prices',);
my %opts = ('prices' => 'Show Prices',);
my $hvol = 0;
for (keys %$rows) {
if ($debug) {
printf "\n
\nouterkey: %s
\n", $_;
&hashprint($rows->{$_});
}
my $t = $rows->{$_};
use POSIX qw(ceil);
my $quant = ceil($t->{quantity}*$sovfactor);
if ($t->{purposeText} eq 'CPU') {
$quant = ceil($quant * $cpuusage);
}
if ($t->{purposeText} eq 'Power') {
$quant = ceil($quant * $gridusage);
}
#my $vol = $t->{volume}*$quant / $t->{portionSize};
my $vol = $t->{volume}*$quant;
my $isk = $t->{basePrice} / $t->{portionSize};
my $tid = $t->{resourceTypeID};
my $tlink = a({href=>"showinfo:$tid",},
$t->{typeName});
if ($t->{purposeText} eq 'Reinforce' ||
$t->{minSecurityLevel}) {
push @opts, $tid;
$opts{$tid} = $t->{typeName};
next unless grep {/^$tid$/} @opt;
}
$hourlyfuel{$t->{typeName}} = [$quant, $vol, $tlink, $isk, $t->{typeID},];
$hvol += $vol;
}
print checkbox_group(
-name => 'opt',
-linebreak => 'sure',
-values => \@opts,
-labels => \%opts,
),"\n";
# print checkbox_group
my $label = "FULL ";
my $hours = int($typecapacity/$hvol);
$label .= sprintf("%id", $hours/24) if $hours > 24;
$label .= sprintf "%ih", $hours%24;
$times{$label} = $hours;
for (keys %wantm3) {
my $m3 = $wantm3{$_};
my $label = sprintf "WANT %s == ", $_;
my $hours = int($m3/$hvol);
$label .= sprintf("%id", $hours/24) if $hours > 24;
$label .= sprintf "%ih", $hours%24;
$times{$label} = $hours;
}
if ($havehours) {
$label = "HAVE ".&prettytime($havehours*3600, undef, 0);
$times{$label} = $havehours;
my $need = $hours - $havehours;
$label = "FULL-HAVE ".&prettytime($need*3600, undef, 0);
$times{$label} = $need;
}
# printf "MAX FILL: %.2f hours\n", $typecapacity/$hvol;
# print "\n
\n";
}
print submit, "\n";
my $market;
if (grep {/^prices$/} @opt) {
require EVE::Market;
$market = EVE::Market->new(
where => "connectedhighsec",
when => 30*24*60*60,
) or die "cant get market";
}
if ($type) {
print hr, "\n";
my %vols = ();
my %isks = ();
my @table = ();
my @times = sort {$times{$a} <=> $times{$b}} keys %times;
my @header = ('Type',);
push(@header, 'Price') if $market;
push(@header, @times);
my %cubes = ();
for my $fuel (sort keys %hourlyfuel) {
my ($quant, $vol, $tlink, $baseprice, $tid,) = @{$hourlyfuel{$fuel}};
my @row = ($tlink,);
my $price = 0;
if ($market) {
my $P = eval { $market->get_price(typeID => $tid) };
#printf STDERR "DEB: %i - %s\n", $tid, $P;
my $p = eval { $P->{avg} } || $baseprice;
$p = sprintf "%.2f", $p;
#my $p = eval { $market->get_price(typeID => $fuel)->{avg} } || $baseprice;
push @row, textfield(-name => "price$tid",
-default => $p,
-size => 6,);
$price = param("price$tid");
$price = $p unless defined $price;
}
my $percube = 0;
if ($tlink =~ /(Nitrogen|Hydrogen|Oxygen|Helium) Isotopes/) {
$percube = 300;
} elsif ($tlink =~ /Liquid Ozone/) {
$percube = 25;
} elsif ($tlink =~ /Heavy Water/) {
$percube = 50;
}
for my $time (@times) {
my $q = int(($quant*$times{$time})+0.5);
if ($percube) {
use POSIX qw(ceil);
my $cubes = ceil(($q/$percube)+1);
$q = span({style=>'color: green',title=>"$cubes empire cubes",}, $q);
if (($cubes{$time}||0)<$cubes) {
$cubes{$time} = $cubes;
}
}
push @row, $q;
$vols{$time} += int(($vol*$times{$time})+0.5);
$isks{$time} += int(($price*$quant*$times{$time})+0.5);
}
push @table, td({-align=>'right'},\@row);
}
my @foot2 = ("Total ISK",);
if ($market) {
for (sort {$times{$a} <=> $times{$b}} keys %isks) {
push @foot2, &prettyisk($isks{$_});
}
}
print start_table({-border=>1}),
Tr([
th(\@header),
@table,
]),"\n";
my @foot = (th('Total m3'),);
if ($market) {
@foot = (th({colspan=>2},'Total m3'),);
}
for (sort {$times{$a} <=> $times{$b}} keys %vols) {
push @foot, th($vols{$_});
}
print Tr(@foot),"\n";
if (%cubes) {
@foot = (th('Empire Cubes'),);
if ($market) {
@foot = (th({colspan=>2},'Empire Cubes'),);
}
for (sort {$times{$a} <=> $times{$b}} keys %cubes) {
push @foot, th($cubes{$_});
}
print Tr(@foot),"\n";
}
if ($market) {
my @foot2 = (th({colspan=>2},"Total ISK"),);
for (sort {$times{$a} <=> $times{$b}} keys %isks) {
push @foot2, th(&shortprettyisk($isks{$_}));
}
print Tr(@foot2),"\n";
}
print end_table, "\n";
}
print end_form, "\n";
if ($debug) {
print hr,"\n",
"TRUST: $trust",br,"\n";
if ($trust eq 'yes') {
print "SERVER: ",$ENV{'HTTP_EVE.SERVERIP'},br,"\n";
print "CHAR: ",$ENV{'HTTP_EVE.CHARID'}," - ",$ENV{'HTTP_EVE.CHARNAME'},br,"\n";
print "LOCATION: ",$ENV{'HTTP_EVE.REGIONNAME'}," / ",
$ENV{'HTTP_EVE.CONSTELLATIONNAME'}," / ",
$ENV{'HTTP_EVE.SOLARSYSTEMNAME'}," / ",
$ENV{'HTTP_EVE.STATIONNAME'},br,"\n";
}
}
if ($debug) {
print hr,"\n";
for (sort keys %ENV) {
printf "%s: %s%s\n", $_, $ENV{$_}, br;
}
}
my $runtime = time - $begin;
print hr,
$runtime ? sprintf "Completed in %.3f sec.", $runtime : "",
end_html,"\n";
exit 0;
## TODO: libzify
##########
sub to_hours ($) {
my $s = shift;
return 0 unless $s =~ /^[\s\dwdh]+$/;
$s =~ s/\s//g;
my $h = 0;
while ($s =~ s/(\d+)w//) {
$h += $1*24*7;
}
while ($s =~ s/(\d+)d//) {
$h += $1*24;
}
while ($s =~ s/(\d+)h//) {
$h += $1;
}
if ($s =~ /^(\d+)$/) {
$h += $1;
}
return $h;
}
sub hashprint($) {
my $h = shift;
print hr,"\n";
for (keys %$h) {
printf "HP -- '%s': '%s'%s\n", $_, (defined $h->{$_} ? $h->{$_} : "UNDEF"), br;
}
print hr,"\n";
}