view release on metacpan or search on metacpan
lib/App/Alice.pm view on Meta::CPAN
$self->alert("Alice server is shutting down");
if ($self->connected_ircs) {
print STDERR "\nDisconnecting, please wait\n" if $self->standalone;
$_->init_shutdown($msg) for $self->connected_ircs;
}
else {
print "\n";
$self->shutdown;
return;
}
$self->{shutdown_timer} = AnyEvent->timer(
after => 3,
cb => sub{$self->shutdown}
);
}
sub shutdown {
my $self = shift;
$self->_ircs([]);
$self->httpd->shutdown;
$_->buffer->clear for $self->windows;
delete $self->{shutdown_timer} if $self->{shutdown_timer};
$self->{on_shutdown}->() if $self->{on_shutdown};
$self->condvar->send if $self->condvar;
}
sub handle_command {
my ($self, $command, $window) = @_;
$self->commands->handle($command, $window);
}
sub reload_commands {
lib/App/Alice.pod view on Meta::CPAN
=item /connect <network>
Connect to a network. The network must be the name of a server from
the Connections window. If you are already connected to the network
it will do nothing.
=item /disconnect <network>
Disconnect from a network. The network must be the name of a server
from the Connections window. This command will also stop any reconnect
timers for that network.
=item /ignore <nick>
Ignore any nick that matches the one provided. B<This applies across
all networks.>
=item /ignores
List all active ignored nicks.
lib/App/Alice/HTTPD.pm view on Meta::CPAN
use Any::Moose;
use Try::Tiny;
has 'app' => (
is => 'ro',
isa => 'App::Alice',
required => 1,
);
has 'httpd' => (is => 'rw');
has 'ping_timer' => (is => 'rw');
has 'config' => (
is => 'ro',
isa => 'App::Alice::Config',
lazy => 1,
default => sub {shift->app->config},
);
my $url_handlers = [
[ qr{^/$} => \&send_index ],
lib/App/Alice/HTTPD.pm view on Meta::CPAN
} else {
$req->env->{"psgix.session"}{is_logged_in} = 0;
$req->env->{"psgix.session.options"}{expire} = 1;
$res->redirect("/login");
}
return $res->finalize;
}
sub ping {
my $self = shift;
$self->ping_timer(AnyEvent->timer(
after => 5,
interval => 10,
cb => sub {
$self->broadcast({
type => "action",
event => "ping",
});
}
));
}
sub shutdown {
my $self = shift;
$_->close for $self->streams;
$self->streams([]);
$self->ping_timer(undef);
$self->httpd(undef);
}
sub image_proxy {
my ($self, $req) = @_;
my $url = $req->request_uri;
$url =~ s/^\/get\///;
return sub {
my $respond = shift;
http_get $url, sub {
lib/App/Alice/IRC.pm view on Meta::CPAN
$_[0]->app->config->servers->{$_[0]->alias};
}
has 'app' => (
isa => 'App::Alice',
is => 'ro',
weak_ref => 1,
required => 1,
);
has 'reconnect_timer' => (
is => 'rw'
);
has [qw/reconnect_count connect_time/] => (
is => 'rw',
isa => 'Int',
default => 0,
);
sub increase_reconnect_count {$_[0]->reconnect_count($_[0]->reconnect_count + 1)}
lib/App/Alice/IRC.pm view on Meta::CPAN
my ($self, $time) = @_;
my $interval = time - $self->connect_time;
if ($interval < 15) {
$time = 15 - $interval;
$self->log(debug => "last attempt was within 15 seconds, delaying $time seconds")
}
if (!defined $time) {
# increase timer by 15 seconds each time, until it hits 5 minutes
$time = min 60 * 5, 15 * $self->reconnect_count;
}
$self->log(debug => "reconnecting in $time seconds");
$self->reconnect_timer(
AnyEvent->timer(after => $time, cb => sub {
$self->connect unless $self->is_connected;
})
);
}
sub cancel_reconnect {
my $self = shift;
$self->reconnect_timer(undef);
$self->reset_reconnect_count;
}
sub registered {
my $self = shift;
my @log;
$self->cl->enable_ping (300, sub {
$self->is_connected(0);
$self->log(debug => "ping timeout");
lib/App/Alice/IRC.pm view on Meta::CPAN
for (@channels) {
push @log, "joining $_";
$self->send_srv("JOIN", split /\s+/);
}
$self->log(debug => \@log);
};
sub disconnected {
my ($self, $cl, $reason) = @_;
delete $self->{disconnect_timer} if $self->{disconnect_timer};
$reason = "" unless $reason;
return if $reason eq "reconnect requested.";
$self->log(info => "disconnected: $reason");
$self->broadcast(map {
$_->format_event("disconnect", $self->nick, $reason),
} $self->windows);
$self->broadcast({
lib/App/Alice/IRC.pm view on Meta::CPAN
my ($self, $msg) = @_;
$self->disabled(1);
if (!$self->app->shutting_down) {
$self->app->remove_window($_) for $self->windows;
}
$msg ||= $self->app->config->quitmsg;
$self->log(debug => "disconnecting: $msg") if $msg;
$self->send_srv(QUIT => $msg);
$self->{disconnect_timer} = AnyEvent->timer(
after => 1,
cb => sub {
delete $self->{disconnect_timer};
$self->cl->disconnect($msg);
}
);
}
sub remove {
my $self = shift;
$self->removed(1);
$self->disconnect;
}
lib/App/Alice/Stream.pm view on Meta::CPAN
isa => 'Bool',
default => 0,
);
has 'seperator' => (
is => 'ro',
isa => 'Str',
default => 'xalicex',
);
has 'timer' => (
is => 'rw',
);
has 'writer' => (
is => 'rw',
required => 1,
);
has min_bytes => (
is => 'ro',
lib/App/Alice/Stream.pm view on Meta::CPAN
}
$self->writer->write( $self->to_string );
$self->flush;
}
sub close {
my $self = shift;
try {$self->writer->write($self->to_string)};
$self->flush;
$self->writer->close;
$self->timer(undef);
$self->closed(1);
}
sub flooded {
my $self = shift;
my $diff = time - $self->last_send;
if ($diff < 0.2) {
return 0.2 - $diff;
}
return 0;
}
sub delay {
my ($self, $delay) = @_;
$self->delayed(1);
$self->timer(AnyEvent->timer(
after => $delay,
cb => sub {
$self->delayed(0);
$self->timer(undef);
$self->_send;
},
));
}
sub flush {
my $self = shift;
$self->clear_queue;
$self->last_send(time);
}
share/commands.pl view on Meta::CPAN
name => 'disconnect',
re => qr{^/disconnect\s+(\S+)},
eg => "/DISCONNECT <server name>",
desc => "Disconnects from the specified server.",
code => sub {
my ($self, $window, $network) = @_;
my $irc = $self->app->get_irc($network);
if ($irc and $irc->is_connected) {
$irc->disconnect;
}
elsif ($irc->reconnect_timer) {
$irc->cancel_reconnect;
$irc->log(info => "canceled reconnect");
}
else {
$self->reply($window, "already disconnected");
}
},
},
{
name => 'connect',
share/static/alice.js view on Meta::CPAN
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.execute();
this.currentlyExecuting = false;
} catch(e) {
this.currentlyExecuting = false;
share/static/alice.js view on Meta::CPAN
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(response) {
if (this.options.decay) {
this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
function $(element) {
if (arguments.length > 1) {
share/static/alice.js view on Meta::CPAN
});
if (window.Event) Object.extend(window.Event, Event);
else window.Event = Event;
})();
(function() {
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
var timer;
function fireContentLoadedEvent() {
if (document.loaded) return;
if (timer) window.clearTimeout(timer);
document.loaded = true;
document.fire('dom:loaded');
}
function checkReadyState() {
if (document.readyState === 'complete') {
document.stopObserving('readystatechange', checkReadyState);
fireContentLoadedEvent();
}
}
function pollDoScroll() {
try { document.documentElement.doScroll('left'); }
catch(e) {
timer = pollDoScroll.defer();
return;
}
fireContentLoadedEvent();
}
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
} else {
document.observe('readystatechange', checkReadyState);
if (window == top)
timer = pollDoScroll.defer();
}
Event.observe(window, 'load', fireContentLoadedEvent);
})();
Element.addMethods();
/*------------------------------- DEPRECATED -------------------------------*/
Hash.toQueryString = Object.toQueryString;