49
|
1 package DOM::Providers::Headlines::Headline;
|
|
2 use Common;
|
|
3 use Time::Local;
|
|
4 our @ISA = qw(Object);
|
|
5
|
|
6 BEGIN {
|
|
7 DeclareProperty(Id => ACCESS_READ);
|
|
8 DeclareProperty(DateModify => ACCESS_READ);
|
|
9 DeclareProperty(DateExpire => ACCESS_READ);
|
|
10 DeclareProperty(URL => ACCESS_READ);
|
|
11 DeclareProperty(Text => ACCESS_READ);
|
|
12 DeclareProperty(Channel => ACCESS_READ);
|
|
13 }
|
|
14
|
|
15 sub str2time {
|
|
16 my $str = shift;
|
|
17
|
|
18 if ($str =~ /^(\d{4})-(\d{2})-(\d{2})(?:\s(\d{2}):(\d{2}):(\d{2}))?$/) {
|
|
19 my ($year,$month,$day,$hh,$mm,$ss) = ($1,$2-1,$3,(defined $4 ? $4 : 0),(defined $5 ? $5 : 0),(defined $6 ? $6 : 0));
|
|
20 return timelocal($ss,$mm,$hh,$day,$month,$year);
|
|
21 } else {
|
|
22 die new Exception("A string '$str' isn't an ISO standard time");
|
|
23 }
|
|
24 }
|
|
25
|
|
26 sub IsActive {
|
|
27 my ($this) = @_;
|
|
28 my $timeExpire = str2time($this->{$DateExpire});
|
|
29
|
|
30 return ($timeExpire > time());
|
|
31 }
|
|
32
|
|
33 package DOM::Providers::Headlines::Collection;
|
|
34 use Common;
|
|
35 our @ISA = qw (Object);
|
|
36
|
|
37 BEGIN {
|
|
38 DeclareProperty(Items => ACCESS_READ);
|
|
39 }
|
|
40
|
|
41 sub CTOR {
|
|
42 my ($this,%args) = @_;
|
|
43
|
|
44 foreach my $headline (@{$args{'Items'}}) {
|
|
45 $this->{$Items}->{$headline->Id()} = $headline if ($headline->IsActive)
|
|
46 }
|
|
47 }
|
|
48
|
|
49 sub as_list {
|
|
50 my $this = shift;
|
|
51
|
|
52 return [ map { $this->{$Items}->{$_} } sort keys %{$this->{$Items}} ];
|
|
53 }
|
|
54
|
|
55 sub GenerateRandomSequence {
|
|
56 my ($count,$max) = @_;
|
|
57
|
|
58 my %hash;
|
|
59 $hash{rand()} = $_ foreach (0 .. $max - 1);
|
|
60 my @sequence = map { $hash{$_} } sort keys %hash;
|
|
61 return splice @sequence,0,$count;
|
|
62 }
|
|
63
|
|
64 sub Random {
|
|
65 my ($this,$count) = @_;
|
|
66
|
|
67 my $list = $this->as_list();
|
|
68
|
|
69 return [map { $list->[$_] } GenerateRandomSequence($count,scalar(@$list))];
|
|
70 }
|
|
71
|
|
72 sub Recent {
|
|
73 my ($this,$count) = @_;
|
|
74
|
|
75 my @result = sort { $b->DateModify() cmp $a->DateModify() } values %{$this->{$Items}};
|
|
76 splice @result,$count;
|
|
77
|
|
78 return \@result;
|
|
79 }
|
|
80
|
|
81 sub AddItem {
|
|
82 my ($this,$newItem) = @_;
|
|
83
|
|
84 $this->{$Items}->{$newItem->Id()} = $newItem;
|
|
85 }
|
|
86
|
|
87 package DOM::Providers::Headlines;
|
|
88 use Common;
|
|
89 use ObjectStore::Headlines;
|
|
90
|
|
91 our $DBPath;
|
|
92 our $Encoding;
|
|
93
|
|
94 my %Channels;
|
|
95
|
|
96 eval {
|
|
97 LoadHeadlines();
|
|
98 };
|
|
99
|
|
100 if ($@) {
|
|
101 my $err = $@;
|
|
102 if (ref $err eq 'Exception') {
|
|
103 die $err->ToString();
|
|
104 } else {
|
|
105 die $err;
|
|
106 }
|
|
107 }
|
|
108
|
|
109
|
|
110 sub GetProviderInfo {
|
|
111 return {
|
|
112 Name => 'Headlines',
|
|
113 Host => 'DOM::Site',
|
|
114 Objects => \%Channels
|
|
115 }
|
|
116 }
|
|
117
|
|
118 sub LoadHeadlines {
|
|
119 my $dsHeadlines = new ObjectStore::Headlines(DBPath => $DBPath, HeadlineClass => 'DOM::Providers::Headlines::Headline', Encoding => $Encoding);
|
|
120
|
|
121 foreach my $headline (@{$dsHeadlines->Search(Filter => sub { return $_[0]->IsActive(); } )}) {
|
|
122 my $channel = $headline->Channel() || 'main';
|
|
123 $Channels{$channel} = new DOM::Providers::Headlines::Collection() if not exists $Channels{$channel};
|
|
124 $Channels{$channel}->AddItem($headline);
|
|
125 }
|
|
126 }
|
|
127
|
|
128 1;
|