OSDN Git Service

add index2/firehose related redirect settings
[newslash/newslash.git] / src / newslash_web / lib / Newslash / Web / Controller / Archive.pm
1 package Newslash::Web::Controller::Archive;
2 use Mojo::Base 'Mojolicious::Controller';
3 use Mojo::Util qw(dumper);
4 use Mojo::JSON qw(decode_json encode_json);
5 use Template;
6
7 use DateTime;
8 use DateTime::Format::MySQL;
9 use Newslash::Util::Items;
10
11 sub _check_params {
12     my ($c, $type, $unit) = @_;
13
14     my $year = $c->stash('year');
15     my $month = $c->stash('month');
16     my $day = $c->stash('day');
17     my $do_redirect = 0;
18     my $r_path = "";
19
20     # check year
21     if (!$year || $year !~ m/^\d{2}$/) {
22         $year = DateTime->now->year - 2000;
23         $month = DateTime->now->month;
24         $month = "0" . $month if ($month < 10);
25         $day = "01";
26         $do_redirect = 1;
27     }
28     # check month
29     if (!$month || $month !~ m/^\d{2}$/) {
30         $month = "01";
31         $day = "01";
32         if ($unit eq "month" || $unit eq "day") {
33             $do_redirect = 1;
34         }
35     }
36     # check day
37     if (!$day || $day !~ m/^\d{2}$/) {
38         $day = "01";
39         if ($unit eq "day") {
40             $do_redirect = 1;
41         }
42     }
43
44     if ($unit eq "year") {
45         $r_path = "/$type/$year/" if $do_redirect;
46         return ($year, $month, $day, $r_path);
47     }
48     if ($unit eq "month") {
49         $r_path = "/$type/$year/$month/" if $do_redirect;
50         return ($year, $month, $day, $r_path);
51     }
52     if ($unit eq "day") {
53         $r_path = "/$type/$year/$month/$day/" if $do_redirect;
54         return ($year, $month, $day, $r_path);
55     }
56
57     # invalid unit
58     $year = DateTime->now->year - 2000;
59     $month = DateTime->now->month;
60     $month = "0" . $month if ($month < 10);
61     $day = "01";
62     $r_path = "/$type/$year/$month/$day/";
63     return ($year, $month, $day, $r_path);
64 }
65
66 sub _render_archive {
67     my $c = shift;
68     my $params = {@_};
69
70     my $user = $c->stash('user');
71     my $model = $params->{model};
72     my $type = $params->{type};
73     my $unit = $params->{unit} || "day";
74
75     my ($year, $month, $day, $r_path) = _check_params($c, $type, $unit);
76
77     if ($r_path) {
78         $c->res->code(301);
79         $c->redirect_to($r_path);
80         return;
81     }
82
83     $year = $year + 2000;
84     my $offset_sec = $user->{config}->{ui}->{offset_sec} || 0;
85     my $q_params = { year => $year,
86                      month => $month,
87                      day => $day,
88                      offset_sec => $offset_sec,
89                      order_by => {create_time => "DESC"},
90                    };
91
92     my $unwanted_keys = [];
93     $unwanted_keys = [qw(month day)] if ($unit eq "year");
94     $unwanted_keys = [qw(day)] if ($unit eq "month");
95     for my $k (@$unwanted_keys) {
96         delete $q_params->{$k};
97     }
98
99     if (!$user->{author}) {
100         $q_params->{hide_future} = 1;
101         $q_params->{public_only} = 1;
102     }
103
104     my $items = $model->select(%$q_params);
105
106     delete $q_params->{$unit};
107     delete $q_params->{order_by};
108     my $counts = $model->count(%$q_params);
109
110     # get next/prev date
111     my $next;
112     my $prev;
113     my $dt = DateTime->new(year => $year,
114                            month => $month,
115                            day => $day);
116     my $prev_items = $model->select(until => $dt,
117                                     offset_sec => $offset_sec,
118                                     order_by => {create_time => "DESC"},
119                                     hide_future => $user->{author} ? 0 : 1,
120                                     public_only => $user->{author} ? 0 : 1,
121                                     limit => 1,
122                                    );
123
124     $dt->add(days => 1) if $unit eq "day";
125     $dt->add(months => 1) if $unit eq "month";
126     my $next_items = $model->select(since => $dt,
127                                     offset_sec => $offset_sec,
128                                     order_by => {create_time => "ASC"},
129                                     hide_future => $user->{author} ? 0 : 1,
130                                     public_only => $user->{author} ? 0 : 1,
131                                     limit => 1
132                                    );
133     if ($prev_items && @$prev_items) {
134         $prev = Newslash::Util::Items->get_date_string_from_item($prev_items->[0], $offset_sec, $unit);
135     }
136
137     if ($next_items && @$next_items) {
138         $next = Newslash::Util::Items->get_date_string_from_item($next_items->[0], $offset_sec, $unit);
139     }
140
141
142     # get prev month
143     $dt = DateTime->new(year => $year,
144                         month => $month,
145                         day => 1);
146     my ($prev_month, $prev_month_date);
147     $dt->add(days => -1);
148     $prev_items = $model->select(until => $dt,
149                                  offset_sec => $offset_sec,
150                                  order_by => {create_time => "DESC"},
151                                  hide_future => $user->{author} ? 0 : 1,
152                                  public_only => $user->{author} ? 0 : 1,
153                                  limit => 1
154                                 );
155     if ($prev_items && @$prev_items) {
156         $dt = $c->format_timestamp(mysql => $prev_items->[0]->{create_time},
157                                    format => "datetime",
158                                    offset_sec => 0,
159                                   );
160         $dt->set(day => 1, hour => 0, minute => 0, second => 0);
161         $prev_items = $model->select(since => $dt,
162                                      offset_sec => $offset_sec,
163                                      order_by => {create_time => "ASC"},
164                                      hide_future => $user->{author} ? 0 : 1,
165                                      public_only => $user->{author} ? 0 : 1,
166                                      limit => 1
167                                     );
168         if ($prev_items && @$prev_items) {
169             $prev_month_date = Newslash::Util::Items->get_date_string_from_item($prev_items->[0], $offset_sec, "day");
170             $prev_month_date =~ m/^\d+\/0?(\d+)/;
171             $prev_month = $1;
172         }
173     }
174
175     # get next month
176     $dt = DateTime->new(year => $year,
177                         month => $month,
178                         day => 1);
179     my ($next_month, $next_month_date);
180     $dt->add(months => 1);
181     $next_items = $model->select(since => $dt,
182                                  offset_sec => $offset_sec,
183                                  order_by => {create_time => "ASC"},
184                                  hide_future => $user->{author} ? 0 : 1,
185                                  public_only => $user->{author} ? 0 : 1,
186                                  limit => 1
187                                 );
188     if ($next_items && @$next_items) {
189         $next_month_date = Newslash::Util::Items->get_date_string_from_item($next_items->[0], $offset_sec, "day");
190         $next_month_date =~ m/^\d+\/0?(\d+)/;
191         $next_month = $1;
192     }
193
194     my $page = { content_type => $type,
195                  type => "archive",
196                  year => $year,
197                  month => $month,
198                  day => $day,
199                };
200
201     $c->render(template => 'archive/index',
202                items => $items,
203                counts => $counts,
204                page => $page,
205                prev => $prev,
206                next => $next,
207                prev_month => $prev_month,
208                next_month => $next_month,
209                prev_month_date => $prev_month_date,
210                next_month_date => $next_month_date,
211                no_ad => (@items == 0),
212               );
213
214     if (@$items == 0) {
215         $c->rendered(404);
216     }
217 }
218
219 sub story {
220     my $c = shift;
221     $c->_render_archive(model => $c->model("stories"),
222                         type => "story",
223                         title => "記事");
224 }
225
226 sub journal {
227     my $c = shift;
228     $c->_render_archive(model => $c->model("journals"),
229                         type => "journal",
230                         title => "日記");
231 }
232
233 sub comment {
234     my $c = shift;
235     $c->_render_archive(model => $c->model("comments"),
236                         type => "comment",
237                         title => "コメント");
238 }
239
240 sub submission {
241     my $c = shift;
242     $c->_render_archive(model => $c->model("submissions"),
243                         type => "submission",
244                         title => "タレコミ");
245 }
246
247 sub poll {
248     my $c = shift;
249     $c->_render_archive(model => $c->model("polls"),
250                         type => "poll",
251                         title => "国民投票",
252                         unit => "month");
253 }
254
255 1;