| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package BusyBird::Main::PSGI; |
|
2
|
5
|
|
|
5
|
|
4722
|
use strict; |
|
|
5
|
|
|
|
|
6
|
|
|
|
5
|
|
|
|
|
175
|
|
|
3
|
5
|
|
|
5
|
|
26
|
use warnings; |
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
156
|
|
|
4
|
5
|
|
|
5
|
|
21
|
use BusyBird::Util qw(set_param future_of); |
|
|
5
|
|
|
|
|
6
|
|
|
|
5
|
|
|
|
|
260
|
|
|
5
|
5
|
|
|
5
|
|
2016
|
use BusyBird::Main::PSGI::View; |
|
|
5
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
180
|
|
|
6
|
5
|
|
|
5
|
|
2436
|
use Router::Simple; |
|
|
5
|
|
|
|
|
13374
|
|
|
|
5
|
|
|
|
|
130
|
|
|
7
|
5
|
|
|
5
|
|
2273
|
use Plack::Request; |
|
|
5
|
|
|
|
|
181498
|
|
|
|
5
|
|
|
|
|
162
|
|
|
8
|
5
|
|
|
5
|
|
2367
|
use Plack::Builder (); |
|
|
5
|
|
|
|
|
23845
|
|
|
|
5
|
|
|
|
|
107
|
|
|
9
|
5
|
|
|
5
|
|
2051
|
use Plack::App::File; |
|
|
5
|
|
|
|
|
28091
|
|
|
|
5
|
|
|
|
|
152
|
|
|
10
|
5
|
|
|
5
|
|
32
|
use Try::Tiny; |
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
299
|
|
|
11
|
5
|
|
|
5
|
|
21
|
use JSON qw(decode_json); |
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
38
|
|
|
12
|
5
|
|
|
5
|
|
643
|
use Scalar::Util qw(looks_like_number); |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
206
|
|
|
13
|
5
|
|
|
5
|
|
21
|
use List::Util qw(min); |
|
|
5
|
|
|
|
|
12
|
|
|
|
5
|
|
|
|
|
260
|
|
|
14
|
5
|
|
|
5
|
|
20
|
use Carp; |
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
282
|
|
|
15
|
5
|
|
|
5
|
|
39
|
use Exporter qw(import); |
|
|
5
|
|
|
|
|
6
|
|
|
|
5
|
|
|
|
|
152
|
|
|
16
|
5
|
|
|
5
|
|
18
|
use URI::Escape qw(uri_unescape); |
|
|
5
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
197
|
|
|
17
|
5
|
|
|
5
|
|
21
|
use Encode qw(decode_utf8); |
|
|
5
|
|
|
|
|
6
|
|
|
|
5
|
|
|
|
|
334
|
|
|
18
|
5
|
|
|
5
|
|
33
|
use Future::Q; |
|
|
5
|
|
|
|
|
8
|
|
|
|
5
|
|
|
|
|
121
|
|
|
19
|
5
|
|
|
5
|
|
19
|
use POSIX qw(ceil); |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
76
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our @EXPORT_OK = qw(create_psgi_app); |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub create_psgi_app { |
|
25
|
45
|
|
|
45
|
1
|
1030
|
my ($main_obj) = @_; |
|
26
|
45
|
|
|
|
|
263
|
my $self = __PACKAGE__->_new(main_obj => $main_obj); |
|
27
|
45
|
|
|
|
|
161
|
return $self->_to_app; |
|
28
|
|
|
|
|
|
|
} |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub _new { |
|
31
|
45
|
|
|
45
|
|
157
|
my ($class, %params) = @_; |
|
32
|
45
|
|
|
|
|
347
|
my $self = bless { |
|
33
|
|
|
|
|
|
|
router => Router::Simple->new, |
|
34
|
|
|
|
|
|
|
view => undef, ## lazy build |
|
35
|
|
|
|
|
|
|
}, $class; |
|
36
|
45
|
|
|
|
|
480
|
$self->set_param(\%params, "main_obj", undef, 1); |
|
37
|
45
|
|
|
|
|
159
|
$self->_build_routes(); |
|
38
|
45
|
|
|
|
|
1929
|
return $self; |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub _to_app { |
|
42
|
45
|
|
|
45
|
|
86
|
my $self = shift; |
|
43
|
45
|
|
|
|
|
177
|
my $sharedir = $self->{main_obj}->get_config("sharedir_path"); |
|
44
|
45
|
|
|
|
|
235
|
$sharedir =~ s{/+$}{}; |
|
45
|
|
|
|
|
|
|
return Plack::Builder::builder { |
|
46
|
45
|
|
|
45
|
|
1843
|
Plack::Builder::enable 'ContentLength'; |
|
47
|
45
|
|
|
|
|
6377
|
Plack::Builder::mount '/static' => Plack::App::File->new( |
|
48
|
|
|
|
|
|
|
root => File::Spec->catdir($sharedir, 'www', 'static') |
|
49
|
|
|
|
|
|
|
)->to_app; |
|
50
|
45
|
|
|
|
|
2821
|
Plack::Builder::mount '/' => $self->_my_app; |
|
51
|
45
|
|
|
|
|
383
|
}; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _my_app { |
|
55
|
45
|
|
|
45
|
|
67
|
my ($self) = @_; |
|
56
|
|
|
|
|
|
|
return sub { |
|
57
|
185
|
|
|
185
|
|
839037
|
my ($env) = @_; |
|
58
|
185
|
|
66
|
|
|
1065
|
$self->{view} ||= BusyBird::Main::PSGI::View->new(main_obj => $self->{main_obj}, script_name => $env->{SCRIPT_NAME}); |
|
59
|
185
|
100
|
|
|
|
822
|
if(my $dest = $self->{router}->match($env)) { |
|
60
|
179
|
|
|
|
|
14493
|
my $req = Plack::Request->new($env); |
|
61
|
179
|
|
|
|
|
1417
|
my $code = $dest->{code}; |
|
62
|
179
|
|
|
|
|
317
|
my $method = $dest->{method}; |
|
63
|
179
|
50
|
|
|
|
786
|
return defined($code) ? $code->($self, $req, $dest) : $self->$method($req, $dest); |
|
64
|
|
|
|
|
|
|
}else { |
|
65
|
6
|
|
|
|
|
578
|
return $self->{view}->response_notfound(); |
|
66
|
|
|
|
|
|
|
} |
|
67
|
45
|
|
|
|
|
254
|
}; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub _build_routes { |
|
71
|
45
|
|
|
45
|
|
56
|
my ($self) = @_; |
|
72
|
45
|
|
|
|
|
192
|
my $tl_mapper = $self->{router}->submapper( |
|
73
|
|
|
|
|
|
|
'/timelines/{timeline}', {} |
|
74
|
|
|
|
|
|
|
); |
|
75
|
45
|
|
|
|
|
1226
|
$tl_mapper->connect('/statuses.{format}', |
|
76
|
|
|
|
|
|
|
{method => '_handle_tl_get_statuses'}, {method => 'GET'}); |
|
77
|
45
|
|
|
|
|
5527
|
$tl_mapper->connect('/statuses.json', |
|
78
|
|
|
|
|
|
|
{method => '_handle_tl_post_statuses'}, {method => 'POST'}); |
|
79
|
45
|
|
|
|
|
3700
|
$tl_mapper->connect('/ack.json', |
|
80
|
|
|
|
|
|
|
{method => '_handle_tl_ack'}, {method => 'POST'}); |
|
81
|
45
|
|
|
|
|
3189
|
$tl_mapper->connect('/updates/unacked_counts.json', |
|
82
|
|
|
|
|
|
|
{method => '_handle_tl_get_unacked_counts'}, {method => 'GET'}); |
|
83
|
45
|
|
|
|
|
3567
|
$tl_mapper->connect($_, {method => '_handle_tl_index'}) foreach "", qw(/ /index.html /index.htm); |
|
84
|
45
|
|
|
|
|
10933
|
$self->{router}->connect('/updates/unacked_counts.json', |
|
85
|
|
|
|
|
|
|
{method => '_handle_get_unacked_counts'}, {method => 'GET'}); |
|
86
|
45
|
|
|
|
|
2008
|
foreach my $path ("/", "/index.html") { |
|
87
|
90
|
|
|
|
|
2207
|
$self->{router}->connect($path, {method => '_handle_get_timeline_list'}, {method => 'GET'}); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub _get_timeline_name { |
|
92
|
152
|
|
|
152
|
|
261
|
my ($dest) = @_; |
|
93
|
152
|
|
|
|
|
235
|
my $name = $dest->{timeline}; |
|
94
|
152
|
50
|
|
|
|
340
|
$name = "" if not defined($name); |
|
95
|
152
|
|
|
|
|
278
|
$name =~ s/\+/ /g; |
|
96
|
152
|
|
|
|
|
368
|
return decode_utf8(uri_unescape($name)); |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _get_timeline { |
|
100
|
135
|
|
|
135
|
|
201
|
my ($self, $dest) = @_; |
|
101
|
135
|
|
|
|
|
284
|
my $name = _get_timeline_name($dest); |
|
102
|
135
|
|
|
|
|
3947
|
my $timeline = $self->{main_obj}->get_timeline($name); |
|
103
|
135
|
100
|
|
|
|
1220
|
if(!defined($timeline)) { |
|
104
|
4
|
|
|
|
|
35
|
die qq{No timeline named $name}; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
131
|
|
|
|
|
249
|
return $timeline; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _handle_tl_get_statuses { |
|
110
|
70
|
|
|
70
|
|
137
|
my ($self, $req, $dest) = @_; |
|
111
|
|
|
|
|
|
|
return sub { |
|
112
|
70
|
|
|
70
|
|
3378
|
my $responder = shift; |
|
113
|
70
|
|
|
|
|
91
|
my $timeline; |
|
114
|
70
|
|
|
|
|
234
|
my $only_statuses = !!($req->query_parameters->{only_statuses}); |
|
115
|
70
|
100
|
100
|
|
|
5960
|
my $format = !defined($dest->{format}) ? "" |
|
|
|
50
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
: (lc($dest->{format}) eq "json" && $only_statuses) ? "json_only_statuses" |
|
117
|
|
|
|
|
|
|
: $dest->{format}; |
|
118
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
119
|
70
|
|
|
|
|
2534
|
$timeline = $self->_get_timeline($dest); |
|
120
|
69
|
|
100
|
|
|
173
|
my $count = $req->query_parameters->{count} || 20; |
|
121
|
69
|
50
|
33
|
|
|
865
|
if(!looks_like_number($count) || int($count) != $count) { |
|
122
|
0
|
|
|
|
|
0
|
die "count parameter must be an integer\n"; |
|
123
|
|
|
|
|
|
|
} |
|
124
|
69
|
|
100
|
|
|
159
|
my $ack_state = $req->query_parameters->{ack_state} || 'any'; |
|
125
|
69
|
|
|
|
|
493
|
my $max_id = decode_utf8($req->query_parameters->{max_id}); |
|
126
|
69
|
|
|
|
|
799
|
return future_of($timeline, "get_statuses", |
|
127
|
|
|
|
|
|
|
count => $count, ack_state => $ack_state, max_id => $max_id); |
|
128
|
|
|
|
|
|
|
})->then(sub { |
|
129
|
65
|
|
|
|
|
11179
|
my $statuses = shift; |
|
130
|
65
|
|
|
|
|
325
|
$responder->($self->{view}->response_statuses( |
|
131
|
|
|
|
|
|
|
statuses => $statuses, http_code => 200, format => $format, |
|
132
|
|
|
|
|
|
|
timeline_name => $timeline->name |
|
133
|
|
|
|
|
|
|
)); |
|
134
|
|
|
|
|
|
|
})->catch(sub { |
|
135
|
5
|
|
|
|
|
1584
|
my ($error, $is_normal_error) = @_; |
|
136
|
5
|
100
|
|
|
|
40
|
$responder->($self->{view}->response_statuses( |
|
|
|
100
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
error => "$error", http_code => ($is_normal_error ? 500 : 400), format => $format, |
|
138
|
|
|
|
|
|
|
($timeline ? (timeline_name => $timeline->name) : ()) |
|
139
|
|
|
|
|
|
|
)); |
|
140
|
70
|
|
|
|
|
558
|
}); |
|
141
|
70
|
|
|
|
|
670
|
}; |
|
142
|
|
|
|
|
|
|
} |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub _handle_tl_post_statuses { |
|
145
|
31
|
|
|
31
|
|
63
|
my ($self, $req, $dest) = @_; |
|
146
|
|
|
|
|
|
|
return sub { |
|
147
|
31
|
|
|
31
|
|
1632
|
my $responder = shift; |
|
148
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
149
|
31
|
|
|
|
|
1216
|
my $timeline = $self->_get_timeline($dest); |
|
150
|
30
|
|
|
|
|
137
|
my $posted_obj = decode_json($req->content); |
|
151
|
29
|
100
|
|
|
|
26065
|
if(ref($posted_obj) ne 'ARRAY') { |
|
152
|
5
|
|
|
|
|
11
|
$posted_obj = [$posted_obj]; |
|
153
|
|
|
|
|
|
|
} |
|
154
|
29
|
|
|
|
|
121
|
return future_of($timeline, "add_statuses", statuses => $posted_obj); |
|
155
|
|
|
|
|
|
|
})->then(sub { |
|
156
|
27
|
|
|
|
|
5475
|
my $added_num = shift; |
|
157
|
27
|
|
|
|
|
247
|
$responder->($self->{view}->response_json(200, {count => $added_num + 0})); |
|
158
|
|
|
|
|
|
|
})->catch(sub { |
|
159
|
4
|
|
|
|
|
1400
|
my ($e, $is_normal_error) = @_; |
|
160
|
4
|
100
|
|
|
|
30
|
$responder->($self->{view}->response_json(($is_normal_error ? 500 : 400), {error => "$e"})); |
|
161
|
31
|
|
|
|
|
314
|
}); |
|
162
|
31
|
|
|
|
|
342
|
}; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub _handle_tl_ack { |
|
166
|
28
|
|
|
28
|
|
58
|
my ($self, $req, $dest) = @_; |
|
167
|
|
|
|
|
|
|
return sub { |
|
168
|
28
|
|
|
28
|
|
1364
|
my $responder = shift; |
|
169
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
170
|
28
|
|
|
|
|
1027
|
my $timeline = $self->_get_timeline($dest); |
|
171
|
27
|
|
|
|
|
43
|
my $max_id = undef; |
|
172
|
27
|
|
|
|
|
42
|
my $ids = undef; |
|
173
|
27
|
100
|
|
|
|
115
|
if($req->content) { |
|
174
|
23
|
|
|
|
|
18927
|
my $body_obj = decode_json($req->content); |
|
175
|
23
|
50
|
|
|
|
564
|
if(ref($body_obj) ne 'HASH') { |
|
176
|
0
|
|
|
|
|
0
|
die "Response body must be an object.\n"; |
|
177
|
|
|
|
|
|
|
} |
|
178
|
23
|
|
|
|
|
66
|
$max_id = $body_obj->{max_id}; |
|
179
|
23
|
|
|
|
|
47
|
$ids = $body_obj->{ids}; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
27
|
|
|
|
|
390
|
return future_of($timeline, "ack_statuses", max_id => $max_id, ids => $ids); |
|
182
|
|
|
|
|
|
|
})->then(sub { |
|
183
|
25
|
|
|
|
|
3713
|
my $acked_num = shift; |
|
184
|
25
|
|
|
|
|
166
|
$responder->($self->{view}->response_json(200, {count => $acked_num + 0})); |
|
185
|
|
|
|
|
|
|
})->catch(sub { |
|
186
|
3
|
|
|
|
|
962
|
my ($e, $is_normal_error) = @_; |
|
187
|
3
|
100
|
|
|
|
29
|
$responder->($self->{view}->response_json(($is_normal_error ? 500 : 400), {error => "$e"})); |
|
188
|
28
|
|
|
|
|
233
|
}); |
|
189
|
28
|
|
|
|
|
297
|
}; |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub _handle_tl_get_unacked_counts { |
|
193
|
6
|
|
|
6
|
|
10
|
my ($self, $req, $dest) = @_; |
|
194
|
|
|
|
|
|
|
return sub { |
|
195
|
6
|
|
|
6
|
|
279
|
my $responder = shift; |
|
196
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
197
|
6
|
|
|
|
|
361
|
my $timeline = $self->_get_timeline($dest); |
|
198
|
5
|
|
|
|
|
17
|
my $query_params = $req->query_parameters; |
|
199
|
5
|
|
|
|
|
365
|
my %assumed = (); |
|
200
|
5
|
100
|
|
|
|
17
|
if(defined $query_params->{total}) { |
|
201
|
3
|
|
|
|
|
9
|
$assumed{total} = delete $query_params->{total}; |
|
202
|
|
|
|
|
|
|
} |
|
203
|
5
|
|
|
|
|
16
|
foreach my $query_key (keys %$query_params) { |
|
204
|
5
|
50
|
|
|
|
19
|
next if !looks_like_number($query_key); |
|
205
|
5
|
50
|
|
|
|
14
|
next if int($query_key) != $query_key; |
|
206
|
5
|
|
|
|
|
10
|
$assumed{$query_key} = $query_params->{$query_key}; |
|
207
|
|
|
|
|
|
|
} |
|
208
|
5
|
|
|
|
|
20
|
my $ret_future = Future::Q->new; |
|
209
|
|
|
|
|
|
|
$timeline->watch_unacked_counts(assumed => \%assumed, callback => sub { |
|
210
|
5
|
|
|
|
|
8
|
my ($error, $w, $unacked_counts) = @_; |
|
211
|
5
|
|
|
|
|
18
|
$w->cancel(); ## immediately cancel the watcher to prevent multiple callbacks |
|
212
|
5
|
50
|
|
|
|
52
|
if($error) { |
|
213
|
0
|
|
|
|
|
0
|
$ret_future->reject($error, 1); |
|
214
|
|
|
|
|
|
|
}else { |
|
215
|
5
|
|
|
|
|
16
|
$ret_future->fulfill($unacked_counts); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
5
|
|
|
|
|
88
|
}); |
|
218
|
5
|
|
|
|
|
26
|
return $ret_future; |
|
219
|
|
|
|
|
|
|
})->then(sub { |
|
220
|
5
|
|
|
|
|
566
|
my ($unacked_counts) = @_; |
|
221
|
5
|
|
|
|
|
23
|
$responder->($self->{view}->response_json(200, {unacked_counts => $unacked_counts})); |
|
222
|
|
|
|
|
|
|
})->catch(sub { |
|
223
|
1
|
|
|
|
|
255
|
my ($e, $is_normal_error) = @_; |
|
224
|
1
|
50
|
|
|
|
8
|
$responder->($self->{view}->response_json(($is_normal_error ? 500 : 400), {error => "$e"})); |
|
225
|
6
|
|
|
|
|
40
|
}); |
|
226
|
6
|
|
|
|
|
51
|
}; |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub _handle_get_unacked_counts { |
|
230
|
17
|
|
|
17
|
|
29
|
my ($self, $req, $dest) = @_; |
|
231
|
|
|
|
|
|
|
return sub { |
|
232
|
17
|
|
|
17
|
|
803
|
my $responder = shift; |
|
233
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
234
|
17
|
|
|
|
|
594
|
my $query_params = $req->query_parameters; |
|
235
|
17
|
|
|
|
|
1950
|
my $level = $query_params->{level}; |
|
236
|
17
|
100
|
33
|
|
|
112
|
if(not defined($level)) { |
|
|
|
50
|
66
|
|
|
|
|
|
237
|
3
|
|
|
|
|
6
|
$level = "total"; |
|
238
|
|
|
|
|
|
|
}elsif($level ne 'total' && (!looks_like_number($level) || int($level) != $level)) { |
|
239
|
0
|
|
|
|
|
0
|
die "level parameter must be an integer\n"; |
|
240
|
|
|
|
|
|
|
} |
|
241
|
17
|
|
|
|
|
26
|
my %assumed = (); |
|
242
|
17
|
|
|
|
|
54
|
foreach my $query_key (keys %$query_params) { |
|
243
|
62
|
100
|
|
|
|
609
|
next if substr($query_key, 0, 3) ne 'tl_'; |
|
244
|
46
|
|
|
|
|
116
|
$assumed{decode_utf8(substr($query_key, 3))} = $query_params->{$query_key}; |
|
245
|
|
|
|
|
|
|
} |
|
246
|
17
|
|
|
|
|
207
|
my $ret_future = Future::Q->new; |
|
247
|
|
|
|
|
|
|
$self->{main_obj}->watch_unacked_counts( |
|
248
|
|
|
|
|
|
|
level => $level, assumed => \%assumed, callback => sub { |
|
249
|
15
|
|
|
|
|
18
|
my ($error, $w, $tl_unacked_counts) = @_; |
|
250
|
15
|
|
|
|
|
41
|
$w->cancel(); ## immediately cancel the watcher to prevent multiple callbacks |
|
251
|
15
|
50
|
|
|
|
361
|
if($error) { |
|
252
|
0
|
|
|
|
|
0
|
$ret_future->reject($error, 1); |
|
253
|
|
|
|
|
|
|
}else { |
|
254
|
15
|
|
|
|
|
43
|
$ret_future->fulfill($tl_unacked_counts); |
|
255
|
|
|
|
|
|
|
} |
|
256
|
|
|
|
|
|
|
} |
|
257
|
17
|
|
|
|
|
331
|
); |
|
258
|
15
|
|
|
|
|
81
|
return $ret_future; |
|
259
|
|
|
|
|
|
|
})->then(sub { |
|
260
|
15
|
|
|
|
|
1850
|
my ($tl_unacked_counts) = @_; |
|
261
|
15
|
|
|
|
|
66
|
$responder->($self->{view}->response_json(200, {unacked_counts => $tl_unacked_counts})); |
|
262
|
|
|
|
|
|
|
})->catch(sub { |
|
263
|
2
|
|
|
|
|
906
|
my ($e, $is_normal_error) = @_; |
|
264
|
2
|
50
|
|
|
|
16
|
$responder->($self->{view}->response_json(($is_normal_error ? 500 : 400), {error => "$e"})); |
|
265
|
17
|
|
|
|
|
141
|
}); |
|
266
|
17
|
|
|
|
|
151
|
}; |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub _handle_tl_index { |
|
270
|
17
|
|
|
17
|
|
26
|
my ($self, $req, $dest) = @_; |
|
271
|
17
|
|
|
|
|
48
|
return $self->{view}->response_timeline(_get_timeline_name($dest)); |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub _handle_get_timeline_list { |
|
275
|
10
|
|
|
10
|
|
16
|
my ($self, $req, $dest) = @_; |
|
276
|
|
|
|
|
|
|
return sub { |
|
277
|
10
|
|
|
10
|
|
529
|
my $responder = shift; |
|
278
|
|
|
|
|
|
|
Future::Q->try(sub { |
|
279
|
10
|
|
|
|
|
378
|
my $num_per_page = $self->{main_obj}->get_config('timeline_list_per_page'); |
|
280
|
112
|
|
|
|
|
994
|
my @timelines = grep { |
|
281
|
10
|
|
|
|
|
45
|
!$self->{main_obj}->get_timeline_config($_->name, "hidden") |
|
282
|
|
|
|
|
|
|
} $self->{main_obj}->get_all_timelines(); |
|
283
|
10
|
50
|
|
|
|
58
|
if(@timelines == 0) { |
|
284
|
0
|
|
|
|
|
0
|
die "No visible timeline. Probably you must configure config.psgi to create a timeline."; |
|
285
|
|
|
|
|
|
|
} |
|
286
|
10
|
|
|
|
|
56
|
my $page_num = ceil(scalar(@timelines) / $num_per_page); |
|
287
|
10
|
|
|
|
|
16
|
my $cur_page = 0; |
|
288
|
10
|
|
|
|
|
34
|
my $query = $req->query_parameters; |
|
289
|
10
|
100
|
|
|
|
640
|
if(defined $query->{page}) { |
|
290
|
7
|
100
|
100
|
|
|
72
|
if(!looks_like_number($query->{page}) || $query->{page} < 0 || $query->{page} >= $page_num) { |
|
|
|
|
100
|
|
|
|
|
|
291
|
4
|
|
|
|
|
22
|
die "Invalid page parameter\n"; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
3
|
|
|
|
|
8
|
$cur_page = $query->{page}; |
|
294
|
|
|
|
|
|
|
} |
|
295
|
6
|
|
|
|
|
72
|
my @target_timelines = @timelines[($cur_page * $num_per_page) .. min(($cur_page+1) * $num_per_page - 1, $#timelines)]; |
|
296
|
24
|
|
|
|
|
447
|
return Future::Q->needs_all(map { future_of($_, "get_unacked_counts") } @target_timelines)->then(sub { |
|
297
|
6
|
|
|
|
|
1622
|
my (@unacked_counts_list) = @_; |
|
298
|
24
|
|
|
|
|
42
|
my @timeline_unacked_counts = map { |
|
299
|
6
|
|
|
|
|
19
|
+{ name => $target_timelines[$_]->name, counts => $unacked_counts_list[$_] } |
|
300
|
|
|
|
|
|
|
} 0 .. $#target_timelines; |
|
301
|
6
|
|
|
|
|
67
|
$responder->( $self->{view}->response_timeline_list( |
|
302
|
|
|
|
|
|
|
timeline_unacked_counts => \@timeline_unacked_counts, |
|
303
|
|
|
|
|
|
|
total_page_num => $page_num, |
|
304
|
|
|
|
|
|
|
cur_page => $cur_page |
|
305
|
|
|
|
|
|
|
) ); |
|
306
|
6
|
|
|
|
|
12
|
}); |
|
307
|
|
|
|
|
|
|
})->catch(sub { |
|
308
|
4
|
|
|
|
|
576
|
my ($error, $is_normal_error) = @_; |
|
309
|
4
|
50
|
|
|
|
18
|
$responder->($self->{view}->response_error_html( |
|
310
|
|
|
|
|
|
|
($is_normal_error ? 500 : 400), $error |
|
311
|
|
|
|
|
|
|
)); |
|
312
|
10
|
|
|
|
|
99
|
}); |
|
313
|
10
|
|
|
|
|
89
|
}; |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
1; |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
__END__ |