view Lib/DOM/Providers/Headlines.pm @ 35:f25d021780b3

DOM::Navigator::Builder working version
author Sergey
date Tue, 17 Nov 2009 17:46:24 +0300
parents 03e58a454b20
children 16ada169ca75
line wrap: on
line source

package DOM::Providers::Headlines::Headline;
use Common;
use Time::Local;
our @ISA = qw(Object);

BEGIN {
    DeclareProperty(Id => ACCESS_READ);
    DeclareProperty(DateModify => ACCESS_READ);
    DeclareProperty(DateExpire => ACCESS_READ);
    DeclareProperty(URL => ACCESS_READ);
    DeclareProperty(Text => ACCESS_READ);
    DeclareProperty(Channel => ACCESS_READ);
}

sub str2time {
    my $str = shift;
    
    if ($str =~ /^(\d{4})-(\d{2})-(\d{2})(?:\s(\d{2}):(\d{2}):(\d{2}))?$/) {
        my ($year,$month,$day,$hh,$mm,$ss) = ($1,$2-1,$3,(defined $4 ? $4 : 0),(defined $5 ? $5 : 0),(defined $6 ? $6 : 0));
        return timelocal($ss,$mm,$hh,$day,$month,$year);
    } else {
        die new Exception("A string '$str' isn't an ISO standard time");
    }
}

sub IsActive {
    my ($this) = @_;
    my $timeExpire = str2time($this->{$DateExpire});

    return ($timeExpire > time());
}

package DOM::Providers::Headlines::Collection;
use Common;
our @ISA = qw (Object);

BEGIN {
    DeclareProperty(Items => ACCESS_READ);
}

sub CTOR {
    my ($this,%args) = @_;

    foreach my $headline (@{$args{'Items'}}) {
        $this->{$Items}->{$headline->Id()} = $headline if ($headline->IsActive)
    }
}

sub as_list {
    my $this = shift;

    return [ map { $this->{$Items}->{$_} } sort keys %{$this->{$Items}} ];
}

sub GenerateRandomSequence {
    my ($count,$max) = @_;

    my %hash;
    $hash{rand()} = $_ foreach (0 .. $max - 1);
    my @sequence = map { $hash{$_} } sort keys %hash;
    return splice @sequence,0,$count;
}

sub Random {
    my ($this,$count) = @_;

    my $list = $this->as_list();
    
    return [map { $list->[$_] } GenerateRandomSequence($count,scalar(@$list))];
}

sub Recent {
    my ($this,$count) = @_;
    
    my @result = sort { $b->DateModify() cmp $a->DateModify() } values %{$this->{$Items}};
    splice @result,$count;
    
    return \@result;
}

sub AddItem {
    my ($this,$newItem) = @_;
    
    $this->{$Items}->{$newItem->Id()} = $newItem;
}

package DOM::Providers::Headlines;
use Common;
use ObjectStore::Headlines;

our $DBPath;
our $Encoding;

my %Channels;

eval {
    LoadHeadlines();
};

if ($@) {
    my $err = $@;
    if (ref $err eq 'Exception') {
        die $err->ToString();
    } else {
        die $err;
    }
}


sub GetProviderInfo {
    return {
        Name => 'Headlines',
        Host => 'DOM::Site',
        Objects => \%Channels
    }
}

sub LoadHeadlines {
    my $dsHeadlines = new ObjectStore::Headlines(DBPath => $DBPath, HeadlineClass => 'DOM::Providers::Headlines::Headline', Encoding => $Encoding);
    
    foreach my $headline (@{$dsHeadlines->Search(Filter => sub { return $_[0]->IsActive(); } )}) {
        my $channel = $headline->Channel() || 'main';
        $Channels{$channel} = new DOM::Providers::Headlines::Collection() if not exists $Channels{$channel};
        $Channels{$channel}->AddItem($headline);
    }
}

1;