App-Alice
view release on metacpan or search on metacpan
lib/App/Alice/HTTPD.pm view on Meta::CPAN
sub setup_stream {
my ($self, $req) = @_;
$self->app->log(info => "opening new stream");
my $min = $req->param('msgid') || 0;
return sub {
my $respond = shift;
my $stream = App::Alice::Stream->new(
queue => [ map({$_->join_action} $self->app->windows) ],
writer => $respond,
start_time => $req->param('t'),
# android requires 4K updates to trigger loading event
min_bytes => $req->user_agent =~ /android/i ? 4096 : 0,
);
$self->add_stream($stream);
$self->app->with_messages(sub {
return unless @_;
$stream->enqueue(
map {$_->{buffered} = 1; $_}
grep {$_->{msgid} > $min}
@_
);
$stream->send;
});
}
}
sub purge_disconnects {
my ($self) = @_;
$self->app->log(debug => "removing broken streams");
$self->streams([grep {!$_->closed} $self->streams]);
}
sub handle_message {
my ($self, $req) = @_;
my $msg = $req->param('msg');
my $is_html = $req->param('html');
utf8::decode($msg) unless utf8::is_utf8($msg);
$msg = html_to_irc($msg) if $is_html;
my $source = $req->param('source');
my $window = $self->app->get_window($source);
if ($window) {
for (split /\n/, $msg) {
try {
$self->app->handle_command($_, $window) if length $_
} catch {
$self->app->log(info => $_);
}
}
}
my $res = $req->new_response(200);
$res->content_type('text/plain');
$res->content_length(2);
$res->body('ok');
return $res->finalize;
}
sub send_index {
my ($self, $req) = @_;
return sub {
my $respond = shift;
my $writer = $respond->([200, ["Content-type" => "text/html; charset=utf-8"]]);
my @windows = $self->app->sorted_windows;
@windows > 1 ? $windows[1]->{active} = 1 : $windows[0]->{active} = 1;
$writer->write(encode_utf8 $self->app->render('index_head', @windows));
$self->send_windows($writer, sub {
$writer->write(encode_utf8 $self->app->render('index_footer', @windows));
$writer->close;
delete $_->{active} for @windows;
}, @windows);
}
}
sub send_windows {
my ($self, $writer, $cb, @windows) = @_;
if (!@windows) {
$cb->();
}
else {
my $window = pop @windows;
$writer->write(encode_utf8 $self->app->render('window_head', $window));
$window->buffer->with_messages(sub {
my @messages = @_;
$writer->write(encode_utf8 $_->{html}) for @messages;
}, 0, sub {
$writer->write(encode_utf8 $self->app->render('window_footer', $window));
$self->send_windows($writer, $cb, @windows);
});
}
}
sub send_logs {
my ($self, $req) = @_;
my $output = $self->app->render('logs');
my $res = $req->new_response(200);
$res->body(encode_utf8 $output);
return $res->finalize;
}
sub send_search {
my ($self, $req) = @_;
return sub {
my $respond = shift;
$self->app->history->search(
user => $self->app->user, %{$req->parameters}, sub {
my $rows = shift;
my $content = $self->app->render('results', $rows);
my $res = $req->new_response(200);
$res->body(encode_utf8 $content);
$respond->($res->finalize);
});
}
}
sub send_range {
my ($self, $req) = @_;
return sub {
my $respond = shift;
$self->app->history->range(
$self->app->user, $req->param('channel'), $req->param('id'), sub {
my ($before, $after) = @_;
$before = $self->app->render('range', $before, 'before');
( run in 0.585 second using v1.01-cache-2.11-cpan-39bf76dae61 )