my $r = $app->routes;
# index page
- $r->get('/')->to('index#root');
+ $r->get('/')->to('timeline#stories');
$r->get('/recent')->to('timeline#recent');
$r->get('/popular')->to('timeline#popular');
- $r->get('/journals')->to('index#journals');
- $r->get('/submissions')->to('index#submissions');
-
- # comment
- $r->get('/comments')->to('comment#index');
+ $r->get('/comments')->to('timeline#comments');
+ $r->get('/journals')->to('timeline#journals');
+ $r->get('/submissions')->to('timeline#submissions');
+ $r->get('/polls')->to('timeline#polls');
# Banned page
$r->get('/banned')->to('index#banned', noindex => 1);
$r->get('/story/:year/:month/')->to('archive#story');
$r->get('/story/:year/')->to('archive#story');
$r->get('/story/')->to('archive#story');
+
$r->get('/journal/:year/:month/:day/')->to('archive#journal');
$r->get('/journal/:year/:month/')->to('archive#journal');
$r->get('/journal/:year/')->to('archive#journal');
$r->get('/journal/')->to('archive#journal');
- $r->get('/journal/:year/:month/:day/' => [year => qr/[0-9]{2}/,
- month => qr/[0-9]{2}/,
- day => qr/[0-9]{2}/])->to('archive#journal');
-
- $r->get('/comment/:year/:month/:day/' => [year => qr/[0-9]{2}/,
- month => qr/[0-9]{2}/,
- day => qr/[0-9]{2}/])->to('archive#comment');
-
- $r->get('/submission/:year/:month/:day/' => [year => qr/[0-9]{2}/,
- month => qr/[0-9]{2}/,
- day => qr/[0-9]{2}/])->to('archive#submission');
-
+ $r->get('/submission/:year/:month/:day/')->to('archive#submission');
+ $r->get('/submission/:year/:month/')->to('archive#submission');
+ $r->get('/submission/:year/')->to('archive#submission');
+ $r->get('/submission/')->to('archive#submission');
# my page
$r->get('/my/settings')->to('user#settings', seclev => 1);
use DateTime;
use DateTime::Format::MySQL;
use Newslash::Util::Formatters;
+use Newslash::Util::Items;
sub _check_params {
my $c = shift;
return ($year, $month, $day, $do_redirect);
}
-sub story {
+sub _render_archive {
my $c = shift;
- my $user = $c->stash('user');
+ my $params = {@_};
+ my $user = $c->stash('user');
+ my $model = $params->{model};
+ my $type = $params->{type};
my ($year, $month, $day, $do_redirect) = _check_params($c);
if ($do_redirect) {
$c->res->code(301);
- $c->redirect_to("/story/$year/$month/$day/");
+ $c->redirect_to("/$type/$year/$month/$day/");
return 0;
}
month => $month,
day => $day,
type => 'archive',
- target => 'story',
+ target => $type,
};
- my $stories = $c->model('stories');
my $offset_sec = $user->{config}->{offset_sec} || 0;
- my $items = $stories->select(year => $year,
- month => $month,
- day => $day,
- offset_sec => $offset_sec,
- order_by => { time => "DESC" });
-
- my $counts = $stories->count(year => $year,
- month => $month,
- offset_sec => $offset_sec);
- #$c->app->log->debug(dumper($story_counts));
- #warn(dumper($prev_story));
- #warn(dumper($next_story));
+ my $items = $model->select(year => $year,
+ month => $month,
+ day => $day,
+ offset_sec => $offset_sec,
+ order_by => { create_time => "DESC" });
+
+ my $counts = $model->count(year => $year,
+ month => $month,
+ offset_sec => $offset_sec);
+
+ # get next/prev date
+ my $next;
+ my $prev;
+ my $dt = DateTime->new(year => $year,
+ month => $month,
+ day => $day);
+ my $prev_items = $model->select(until => $dt,
+ offset_sec => $offset_sec,
+ order_by => {create_time => "DESC"},
+ limit => 1);
+ $dt->add(days => 1);
+ my $next_items = $model->select(since => $dt,
+ offset_sec => $offset_sec,
+ order_by => {create_time => "ASC"},
+ limit => 1);
+ if ($prev_items && @$prev_items) {
+ $prev = Newslash::Util::Items->get_date_string_from_item($prev_items->[0], $offset_sec);
+ }
+
+ if ($next_items && @$next_items) {
+ $next = Newslash::Util::Items->get_date_string_from_item($next_items->[0], $offset_sec);
+ }
$c->render(template => 'archive/index',
items => $items,
counts => $counts,
page_property => $property,
+ prev => $prev,
+ next => $next,
+ archive_type => $type,
);
if (@$items == 0) {
}
}
-sub journal {
+sub story {
my $c = shift;
- my $user = $c->stash('user');
-
- my ($year, $month, $day, $do_redirect) = _check_params($c);
- if ($do_redirect) {
- $c->res->code(301);
- $c->redirect_to("/jorunal/$year/$month/$day/");
- return;
- }
- $year = $year + 2000;
- my $property = { year => $year,
- month => $month,
- day => $day,
- type => 'archive',
- target => 'journal',
- };
-
- my $journals = $c->model('journals');
- my $offset_sec = $user->{config}->{offset_sec} || 0;
-
- my $items = $journals->select(year => $year,
- month => $month,
- day => $day,
- offset_sec => $offset_sec,
- order_by => { date => "DESC" });
-
- my $counts = $journals->count(year => $year,
- month => $month,
- offset_sec => $offset_sec);
-
- #$c->app->log->debug(dumper($counts));
+ $c->_render_archive(model => $c->model("stories"),
+ type => "story",
+ title => "記事");
+}
- $c->render(template => 'archive/index',
- items => $items,
- counts => $counts,
- page_property => $property,
- );
+sub journal {
+ my $c = shift;
+ $c->_render_archive(model => $c->model("journals"),
+ type => "journal",
+ title => "日記");
+}
- if (@$items == 0) {
- $c->rendered(404);
- }
+sub comment {
+ my $c = shift;
+ $c->_render_archive(model => $c->model("comments"),
+ type => "comment",
+ title => "コメント");
}
+sub submission {
+ my $c = shift;
+ $c->_render_archive(model => $c->model("submissions"),
+ type => "submission",
+ title => "タレコミ");
+}
1;
sub index {
my $c = shift;
- my $comments = $c->model('comments')->select(limit => 10, order_by => {date => 'DESC'});
+ my $comments = $c->model('comments')->select(limit => 10, order_by => {create_time => 'DESC'});
$c->render(template => "timeline/base", items => $comments);
}
package Newslash::Web::Controller::Timeline;
use Mojo::Base 'Mojolicious::Controller';
-
use Mojo::Util qw(dumper);
-sub recent {
+use DateTime;
+use DateTime::Format::MySQL;
+use Newslash::Util::Formatters;
+
+sub _make_navitem {
+ my ($self, $item) = @_;
+ return if !$item;
+
+ my $dt = Newslash::Util::Formatters::parse_mysql_datetime($item->{create_time});
+ return if !$dt;
+
+ my $user = $self->stash('user');
+
+ # consider timezone
+ my $offset_sec = $user->{config}->{offset_sec} || 0;
+ $dt->add(seconds => -$offset_sec) if ($offset_sec != 0);
+
+ my ($yyyy, $mm, $dd) = ($dt->year, $dt->month, $dt->day);
+ my $yy = substr($yyyy, 2);
+ $mm = "0$mm" if $mm < 10;
+ $dd = "0$dd" if $dd < 10;
+
+ my $id;
+ if ($item->{content_type} eq "story") {
+ $id = $item->{stoid};
+ }
+ elsif ($item->{content_type} eq "journal") {
+ $id = $item->{id};
+ }
+
+ return {
+ date =>"$yy/$mm/$dd",
+ id => $id,
+ type => $item->{content_type},
+ };
+}
+
+sub _get_config {
+ my ($self, $key, $default) = @_;
+ my $config = $self->app->config->{Timeline} || {};
+ return $config->{$key} || $default;
+}
+
+sub _render_timeline {
+ my $self = shift;
+ my $params = {@_};
+
+ my $limit = $params->{limit};
+ my $items = $params->{items};
+ my $sub_title = $params->{title};
+
+ my $title = $self->config->{Site}->{name};
+
+ if (!$sub_title) {
+ my $description = $self->config->{Site}->{description} || "";
+ if ($description) {
+ $title = "$title -- $description";
+ }
+ }
+ else {
+ $title = "$sub_title | $title";
+ }
+
+ # check if next page exists
+ my $prev;
+ if (@$items > $limit) {
+ my $prev_item = pop @$items;
+ $prev = $self->_make_navitem($prev_item);
+ }
+
+ $self->render("timeline/base",
+ items => $items,
+ prev => $prev,
+ title => $title);
+}
+
+sub stories {
my $c = shift;
- my $config = $c->app->config->{Timeline} || {};
- my $limit = $config->{item_per_page} || 10;
+ my $user = $c->stash('user');
+ my $limit = $c->_get_config("item_per_page", 10);
+
+ my $show_future = $user->{is_admin} ? 1 : 0;
+ my $show_nonpublic = $user->{is_admin} ? 1 : 0;
+
+ my $items = $c->model('stories')->select(show_future => $show_future,
+ show_nonpublic => $show_nonpublic,
+ limit => $limit + 1,
+ order_by => {create_time => 'desc'},
+ );
+
+ $c->_render_timeline(items => $items,
+ limit => $limit);
+}
+sub recent {
+ my $c = shift;
+ my $limit = $c->_get_config("item_per_page", 10);
my $items = $c->model('timeline')->select(limit => $limit);
- $c->render(template => 'timeline/base', items => $items);
+
+ $c->_render_timeline(items => $items,
+ limit => $limit,
+ title => "最新");
};
sub popular {
my $c = shift;
- my $config = $c->app->config->{Timeline} || {};
- my $popular_period = $config->{popular_period};
- my $limit = $config->{item_per_page} || 10;
+ my $popular_period = $c->_get_config("popular_period");
+ my $limit = $c->_get_config("item_per_page", 10);
if (!$popular_period || ref($popular_period) ne "HASH") {
$popular_period = {days => 3};
}
my $items = $c->model('timeline')->select(limit => $limit,
- order_by => { popularity => "DESC" },
+ order_by => {popularity => "DESC"},
%$popular_period);
- $c->render(template => 'timeline/base', items => $items);
+ $c->_render_timeline(items => $items,
+ limit => $limit,
+ title => "人気");
+}
+
+sub comments {
+ my $c = shift;
+ my $limit = $c->_get_config("item_per_page", 10);
+ my $items = $c->model('comments')->select(limit => $limit + 1,
+ order_by => {create_time => 'DESC'});
+
+ $c->_render_timeline(items => $items,
+ limit => $limit,
+ title => "コメント");
+}
+
+
+sub journals {
+ my $c = shift;
+ my $limit = $c->_get_config("item_per_page", 10);
+ my $items = $c->model('journals')->select(limit => $limit + 1,
+ order_by => {create_time => 'DESC'});
+
+ $c->_render_timeline(items => $items,
+ limit => $limit,
+ title => "日記");
+}
+
+sub submissions {
+ my $c = shift;
+ my $limit = $c->_get_config("item_per_page", 10);
+ my $items = $c->model('submissions')->select(limit => $limit + 1,
+ order_by => {create_time => 'DESC'});
+
+ $c->_render_timeline(items => $items,
+ limit => $limit,
+ title => "タレコミ");
}
1;
[%- END -%]
</div><!-- .index -->
<div class="pager">
- [%- IF prev_page -%]
+ [%- IF prev -%]
<span class="prev">
- <a href="/story/[% prev_page.date %]/[% IF prev_page.sid %]#[% prev_page.sid %][% END %]">≪前の記事</a>
+ <a href="/[% archive_type %]/[% prev %]">≪前</a>
</span>
[%- END -%]
- [%- IF next_page -%]
+ [%- IF next -%]
<span class="next">
- <a href="/story/[% next_page.date %]/[% IF next_page.sid %]#[% next_page.sid %][% END %]">次の記事≫</a>
+ <a href="/[% archive_type %]/[% next %]">次≫</a>
</span>
[%- END -%]
</div>
<div class="type-selector">
<a href="/story/[% yy %]/[% mm %]/[% dd %]/">記事</a> /
<a href="/journal/[% yy %]/[% mm %]/[% dd %]/">日記</a> /
- <a href="/comment/[% yy %]/[% mm %]/[% dd %]/">コメント</a> /
<a href="/submission/[% yy %]/[% mm %]/[% dd %]/">タレコミ</a>
</div>
[%- INCLUDE common/article/article %]
[%- END -%]
</div><!-- .index -->
+
+ <div class="pager">
+ [%- IF prev -%]
+ <span class="prev">
+ <a href="/[% prev.type %]/[% prev.date %]/[% IF prev.id %]#[% prev.id %][% END %]">≪前の記事</a>
+ </span>
+ [%- END -%]
+ </div>
</div>
[%- INCLUDE common/sidebar -%]