OSDN Git Service

implement filtering feature for timeline (currently works journal only)
[newslash/newslash.git] / src / newslash_web / lib / Newslash / Web / Controller / Timeline.pm
1 package Newslash::Web::Controller::Timeline;
2 use Mojo::Base 'Newslash::Web::Controller';
3
4 use DateTime;
5 use DateTime::Format::MySQL;
6 use Newslash::Util::Items;
7
8 use Data::Dumper;
9
10 use constant CACHE_SEC => 30;
11
12 sub _make_navitem {
13     my ($self, $item) = @_;
14     return if !$item;
15
16     # consider timezone
17     my $user = $self->stash('user');
18     my $offset_sec = $user->{config}->{ui}->{offset_sec} || 0;
19
20     my $unit = "day";
21     $unit = "month" if $item->{content_type} eq "poll";
22     my $date = Newslash::Util::Items->get_date_string_from_item($item, $offset_sec, $unit);
23
24     my $id;
25     if ($item->{content_type} eq "story") {
26         $id = $item->{stoid};
27     }
28     elsif ($item->{content_type} eq "journal") {
29         $id = $item->{id};
30     }
31
32     return {
33             date => $date,
34             id => $id,
35             type => $item->{content_type},
36            };
37 }
38
39 sub _get_config {
40     my ($self, $key, $default) = @_;
41     my $config = $self->app->config->{Timeline} || {};
42     return $config->{$key} || $default;
43 }
44
45 sub _render_timeline {
46     my $self = shift;
47     my $params = {@_};
48
49     my $limit = $params->{limit};
50     my $items = $params->{items};
51
52     # check if next page exists
53     my $prev;
54     if (@$items > $limit) {
55         my $prev_item = pop @$items;
56         $prev = $self->_make_navitem($prev_item);
57     }
58
59     my $page = { type => "timeline",
60                  content_type => $params->{content_type},
61                 };
62
63     if ($params->{content_type} eq "journal") {
64         $self->render("timeline/timeline2",
65                       items => $items,
66                       prev => $prev,
67                       page => $page,
68                      );
69         $self->stats->add_event_counter("timeline_view");
70         return;
71     }
72
73     $self->render("timeline/base",
74                   items => $items,
75                   prev => $prev,
76                   page => $page,
77                  );
78     $self->stats->add_event_counter("timeline_view");
79 }
80
81 sub stories {
82     my $c = shift;
83     my $user = $c->stash('user');
84     my $limit = $c->_get_config("item_per_page", 10);
85
86     my $stories;
87     if ($user->{is_login}) {
88         $stories = $c->model('stories');
89     }
90     else {
91         $stories = $c->ccache->model('stories');
92     }
93     my $items = $stories->select(hide_future => $user->{author} ? 0 : 1,
94                                  public_only => $user->{author} ? 0 : 1,
95                                  limit => $limit + 1,
96                                  order_by => {create_time => 'desc'},
97                                 );
98
99     $c->_render_timeline(items => $items,
100                          content_type => "story",
101                          limit => $limit);
102 }
103
104 sub recent {
105     my $c = shift;
106     my $user = $c->stash('user');
107     my $limit = $c->_get_config("item_per_page", 10);
108
109     my $timeline;
110     if ($user->{is_login}) {
111         $timeline = $c->model('timeline');
112     }
113     else {
114         $timeline = $c->ccache->model('timeline');
115     }
116     my $items = $timeline->select(limit => $limit);
117
118     $c->_render_timeline(items => $items,
119                          content_type => "recent",
120                          limit => $limit,
121                         );
122 };
123
124 sub popular {
125     my $c = shift;
126     my $user = $c->stash('user');
127     my $popular_period = $c->_get_config("popular_period");
128     my $limit = $c->_get_config("item_per_page", 10);
129
130     if (!$popular_period || ref($popular_period) ne "HASH") {
131         $popular_period = {days => 3};
132     }
133
134     for my $k (keys %$popular_period) {
135         if ($k !~ /^(minutes|hours|days|weeks|months|years)$/) {
136             delete $popular_period->{$k};
137         }
138     }
139
140     # fallback
141     if (keys %$popular_period == 0) {
142         $popular_period = {days => 3};
143     }
144
145     my $timeline;
146     if ($user->{is_login}) {
147         $timeline = $c->model('timeline');
148     }
149     else {
150         $timeline = $c->ccache->model('timeline');
151     }
152     my $items = $timeline->select(limit => $limit,
153                                   order_by => {popularity => "DESC"},
154                                   %$popular_period);
155
156     $c->_render_timeline(items => $items,
157                          content_type => "popular",
158                          limit => $limit,
159                         );
160 }
161
162 sub comments {
163     my $c = shift;
164     my $user = $c->stash('user');
165     my $limit = $c->_get_config("item_per_page", 10);
166
167     my $comments;
168     if ($user->{is_login}) {
169         $comments = $c->model('comments');
170     }
171     else {
172         $comments = $c->ccache->model('comments');
173     }
174     my $items = $comments->select(limit => $limit + 1,
175                                   order_by => {create_time => 'DESC'});
176
177     $c->_render_timeline(items => $items,
178                          limit => $limit,
179                          content_type => "comment",
180                         );
181 }
182
183
184 sub journals {
185     my $c = shift;
186     my $user = $c->stash('user');
187     my $limit = $c->_get_config("item_per_page", 10);
188
189     my $journals;
190     if ($user->{is_login}) {
191         $journals = $c->model('journals');
192     }
193     else {
194         $journals = $c->ccache->model('journals');
195     }
196     my $items = $journals->select(limit => $limit + 1,
197                                   order_by => {create_time => 'DESC'});
198
199     $c->_render_timeline(items => $items,
200                          limit => $limit,
201                          content_type => "journal",
202                         );
203 }
204
205 sub submissions {
206     my $c = shift;
207     my $user = $c->stash('user');
208     my $limit = $c->_get_config("item_per_page", 10);
209
210     my $submissions;
211     if ($user->{is_login}) {
212         $submissions = $c->model('submissions');
213     }
214     else {
215         $submissions = $c->ccache->model('submissions');
216     }
217     my $items = $submissions->select(limit => $limit + 1,
218                                      order_by => {create_time => 'DESC'});
219
220     $c->_render_timeline(items => $items,
221                          limit => $limit,
222                          content_type => "submission",
223                         );
224 }
225
226 sub polls {
227     my $c = shift;
228     my $user = $c->stash('user');
229     my $limit = $c->_get_config("item_per_page", 10);
230
231     my $polls;
232     if ($user->{is_login}) {
233         $polls = $c->model('polls');
234     }
235     else {
236         $polls = $c->ccache->model('polls');
237     }
238     my $items = $polls->select(limit => $limit + 1,
239                                order_by => {create_time => 'DESC'});
240
241     $c->_render_timeline(items => $items,
242                          limit => $limit,
243                          content_type => "poll",
244                         );
245 }
246
247 1;
248