Alice

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        - UI additions (join button, etc)
        - Use Fliggy and websocket-js for Firefox
        - Use noembed.com for embedded content
          (tweets, video, etc.)

0.19  Tue 31 Aug 2010
        - Added a dark theme
        - Made preferences and connections windows
          into popup divs instead of real windows
        - Redis message store improvements
        - Improved debug output
        - Workarounds for weird android browser
          quirks
        - Much better mobile style
        - Improved reconnect behavior
        - Nick tab completion in private messages
        - Use browser's timezone for timestamps
        - Faster page loads

0.18  Tue 10 Aug 2010
        - Shortcuts work on Linux and Windows

lib/Alice.pm  view on Meta::CPAN


  map  {$_->[1]}
  sort {$a->[0] cmp $b->[0]}
  map  {[($o{$_->id} || $o{$_->title} || $prefix.$_->sort_name), $_]}
       $self->windows;
}

sub close_window {
  my ($self, $window) = @_;

  AE::log debug => "sending a request to close a tab: " . $window->title;
  $self->broadcast($window->close_action);

  if ($window->is_channel) {
    my $irc = $self->get_irc($window->network);
    my $config = $self->config->servers->{$window->network};
    $config->{channels} = [grep {$_ ne $window->title} @{$config->{channels}}];
    $self->config->write;
  }

  $self->remove_window($window->id) if $window->type ne "info";

lib/Alice.pm  view on Meta::CPAN

        line   => $line,
      );

      $self->irc_command($input);
    }
  }
}

sub purge_disconnects {
  my ($self) = @_;
  AE::log debug => "removing broken streams";
  $self->streams([grep {!$_->closed} @{$self->streams}]);
}

sub render {
  my ($self, $template, @data) = @_;
  $self->template->render_file("$template.html", $self, @data)->as_string;
}

sub is_highlight {
  my ($self, $own_nick, $body) = @_;

lib/Alice/Config.pm  view on Meta::CPAN

    }
  }
  else {
    say STDERR "No config found, writing a few config to ".$self->fullpath;
    $self->write($loaded);
  }
}

sub read_commandline_args {
  my $self = shift;
  my ($port, $debug, $address, $log);
  GetOptions("port=i" => \$port, "debug=s" => \$debug, "log=s" => \$log, "address=s" => \$address);
  $self->commandline->{port} = $port if $port and $port =~ /\d+/;
  $self->commandline->{address} = $address if $address;

  $AnyEvent::Log::FILTER->level($debug || "info");

  if ($log) {
    $AnyEvent::Log::COLLECT->attach(AnyEvent::Log::Ctx->new(
      level => ($debug || "info"),
      log_to_file => $log
    ));
  }
}

sub http_port {
  my $self = shift;
  if ($self->commandline->{port}) {
    return $self->commandline->{port};
  }

lib/Alice/HTTP/Server.pm  view on Meta::CPAN

    $req->env->{"psgix.session.options"}{expire} = 1;
    $res->redirect("/login");
  }
  $res->send;
}

sub setup_xhr_stream {
  my ($self, $req, $res) = @_;
  my $app = $self->app;

  AE::log debug => "opening new stream";

  $res->headers([@Alice::HTTP::Stream::XHR::headers]);
  my $stream = Alice::HTTP::Stream::XHR->new(
    writer     => $res->writer,
    start_time => $req->param('t'),
    # android requires 4K updates to trigger loading event
    min_bytes  => $req->user_agent =~ /android/i ? 4096 : 0,
    on_error => sub { $app->purge_disconnects },
  );

  $stream->send([$app->connect_actions]);
  $app->add_stream($stream);
}

sub setup_ws_stream {
  my ($self, $req, $res) = @_;
  my $app = $self->app;

  AE::log debug => "opening new websocket stream";

  if (my $fh = $req->env->{'websocket.impl'}->handshake) {
    my $stream = Alice::HTTP::Stream::WebSocket->new(
      start_time => $req->param('t') || time,
      fh      => $fh,
      on_read => sub { $app->handle_message(@_) },
      on_error => sub { $app->purge_disconnects },
      ws_version => $req->env->{'websocket.impl'}->version,
    );

lib/Alice/HTTP/Server.pm  view on Meta::CPAN

    $res->notfound;
  }
  else {
    $res->send;
  }
}

sub save_tabsets {
  my ($self, $req, $res) = @_;

  AE::log debug => "saving tabsets";

  my $tabsets = {};

  for my $set ($req->param) {
    next if $set eq '_';
    my $wins = [$req->param($set)];
    $tabsets->{$set} = $wins->[0] eq 'empty' ? [] : $wins;
  }

  $self->app->config->tabsets($tabsets);
  $self->app->config->write;

  $res->body($self->render('tabset_menu'));
  $res->send;
}

sub server_config {
  my ($self, $req, $res) = @_;

  AE::log debug => "serving blank server config";
  
  my $name = $req->param('name');
  $name =~ s/\s+//g;
  my $config = $self->render('new_server', $name);
  my $listitem = $self->render('server_listitem', $name);
  
  $res->body(to_json({config => $config, listitem => $listitem}));
  $res->header("Cache-control" => "no-cache");
  $res->send;
}

#
# TODO separate methods for saving prefs and server configs
#

sub save_config {
  my ($self, $req, $res) = @_;

  AE::log debug => "saving config";
  
  my $new_config = {};
  if ($req->param('has_servers')) {
    $new_config->{servers} = {};
  }
  else {
    $new_config->{$_} = [$req->param($_)] for qw/highlights monospace_nicks/;
  }

  for my $name ($req->param) {

lib/Alice/HTTP/Server.pm  view on Meta::CPAN

  }

  $self->app->reload_config($new_config);
  $self->app->send_info("config", "saved");
  $res->ok;
}

sub tab_order  {
  my ($self, $req, $res) = @_;

  AE::log debug => "updating tab order";
  
  $self->app->tab_order([grep {defined $_} $req->param('tabs')]);
  $res->ok;
}

sub auth_enabled {
  my $self = shift;
  $self->app->auth_enabled;
}

lib/Alice/Readme.pod  view on Meta::CPAN

=head1 USAGE

Installation will add a new `alice` command to start the alice
server.  When the command is run it will start the daemon and print
the URL to load in your browser.

=head2 COMMANDLINE OPTIONS

=over 4

=item -d --debug

Print out additional debug information. Useful for development or
finding out if something is wrong.

=item -p --port

This will change the port that the HTTP server listens on. The
default port is 8080.

=item -a --address

This will change the IP address that the HTTP server listens on.

lib/Alice/Role/IRCEvents.pm  view on Meta::CPAN

    map {
      my $event = $_;
      $event => sub {
        my @args = @_; # we don't need the client
        shift @args;
        AE::log trace => "$event event for " . $irc->name;
        try {
          $EVENTS{$event}->($self, $irc, @args);
        }
        catch {
          AE::log debug => "Error in $event: $_";
          $self->send_info("Please report this bug! $_");
        }
      }
    } keys %EVENTS
  }
}

sub irc_event {
  my ($name, $code) = @_;

share/static/alice.js  view on Meta::CPAN


    }.bind(this));
  },

  log: function () {
    var win = this.activeWindow();
    for (var i=0; i < arguments.length; i++) {
      if (window.console && window.console.log) {
        console.log(arguments[i]);
      }
      if (this.options.debug == "true") {
        if (win) {
          win.addMessage({
            html: '<li class="message monospace"><div class="left">console</div><div class="msg">'+arguments[i].toString()+'</div></li>'
          });
        }
      }
    }
  },

  msgid: function() {



( run in 1.097 second using v1.01-cache-2.11-cpan-49f99fa48dc )