view scan.pl @ 254:1e4922d9a671

fixed for saving island data.
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Mon, 17 Nov 2008 13:01:10 +0800
parents d75f26fc1c69
children b01560b95779
line wrap: on
line source

#!/usr/bin/perl
use strict;
use Data::Dumper;
use Carp;
use Ikariam;
use Parallel::ForkManager;

package main;

package Ikariam::Scanner;
use strict;
use Carp;
use Ikariam;
use Data::Dumper;
use Parallel::ForkManager;

sub new {
    my($class, $i) = @_;
    warn("new scanner");
    my $self = {
        ikariam => $i,
    };

    return bless $self, $class;
}

sub saveCities
{
    my ($self, $island, @cities) = @_;

    if ($#cities == -1) {
        warn ("empty cities list.\n");
        return;
    }

    foreach my $h_city (@cities) {
        # Carp::carp(sprintf("checking %s\n", $h_city->{'cityname'}));
        print(STDERR sprintf("checking cityname %s\n", $h_city->{'cityname'}));
        $h_city->{island} = $island;
        $h_city->{'time'} = time;
        my $c = Ikariam::Cities->retrieve($h_city->{cityId});
        if(defined($c)) {
            foreach (keys(%$h_city)) { 
                $c->set($_ => $h_city->{$_}); 
            }
        } else {
            $c = Ikariam::Cities->insert($h_city);
        }
        $c->update();

        my $user = Ikariam::User->retrieve($h_city->{'user'});
        next if (defined($user) && defined($user->time) && $user->time gt (time - 30*60));

        $self->saveUser($h_city->{owner});
    }
}

sub saveUser
{
    my $self = shift;
    my $userName = shift;
    my $users;

    foreach my $x (qw/score army_score_main trader_score_secondary/) {
        my $i = $self->{ikariam}->clone();
        $users = $i->viewScore($x, $userName, 0);

        foreach my $h_user (values(%{$users})) {
            # Carp::carp(sprintf("Saving user %s\n", $h_user->{'name'}));
            $h_user->{'time'} = time;
            my $user = Ikariam::User->retrieve($h_user->{'id'});
            if(defined($user)) {
                # check if the arm score is down
                foreach (keys(%$h_user)) { $user->set($_ => $h_user->{$_}); }
            } else {
                $user = Ikariam::User->insert($h_user);
            }
            $user->update();
            $self->saveAlly($h_user->{allyId});
        }
    }
}

sub saveAlly
{
    my $self = shift;
    my $allyId = shift;
    return unless (defined($allyId) && $allyId ne '0');

    # Save for member of ally 
    my $ally = Ikariam::Ally->retrieve($allyId);
    if(!defined($ally) || $ally->time le (time - 30*60*1)) {
        my $i = $self->{ikariam}->clone();
        my $h_ally = $i->viewAlly($allyId);
        $h_ally->{'time'} = time;
        if(defined($ally)) {
            foreach (keys(%$h_ally)) { $ally->set($_ => $h_ally->{$_}); }
        } else {
            $ally = Ikariam::Ally->insert($h_ally);
        }
        $ally->update();
    }
}

sub saveIslands {
    my ($self, @islands) = @_;

    my $pm = new Parallel::ForkManager(10);

    foreach my $h_island (@islands)
    {
        my $pid = $pm->start and next;
        
        printf("checking island %d\n", $h_island->{id});
        my $island;
        if($island = Ikariam::Island->retrieve($h_island->{id})) {
            foreach my $i (keys(%$h_island)) {
                $island->set($i => $h_island->{$i});
            }
        } else {
            $island = Ikariam::Island->insert($h_island);
        }

        # scanning the island
        # 10 minutes cache.
        if($island->time le (time - 60*10)) {
            my $i = $self->{ikariam}->clone();
            my @cities = 
                $i->viewIsland($h_island->{id});
            $island->set('time', time);
        }
        $island->update();

        $self->saveCities($h_island->{id}, @cities);
        $pm->finish;
    }
    $pm->wait_all_children;
}

1;

package main;

# local $SIG{ALRM} = sub { die "timeout\n" };
# alarm 3;
our $i = new Ikariam($::server, $::user, $::pass);

$i->login;
if($#ARGV == 1) {
    my @islands = $i->viewWorldMap($ARGV[0], $ARGV[1]);
    # my $s = new Ikariam::Scanner($i);
    # $s->saveIslands(@islands);
    new Ikariam::Scanner($i)->saveIslands(@islands);
} elsif($#ARGV == 0) {
    my $island = $ARGV[0];
    my @cities = $i->viewIsland($island);
    new Ikariam::Scanner($i)->saveCities($island, @cities);
} elsif($#ARGV == -1) {
    my $cities = $i->check;
    # random
    foreach my $cityId (keys(%$cities)) {
        my @islands = $i->viewWorldMap( $cities->{$cityId}->{island}->{x},  $cities->{$cityId}->{island}->{y});
        new Ikariam::Scanner($i)->saveIslands(@islands);
    }
} else {
    die("Usage: $0\nUsage: $0 x y\n");
}
$i->logout;