Alice

 view release on metacpan or  search on metacpan

inc/Module/Install.pm  view on Meta::CPAN

	# all of the following checks should be included in import(),
	# to allow "eval 'require Module::Install; 1' to test
	# installation of Module::Install. (RT #51267)
	#-------------------------------------------------------------

	# Whether or not inc::Module::Install is actually loaded, the
	# $INC{inc/Module/Install.pm} is what will still get set as long as
	# the caller loaded module this in the documented manner.
	# If not set, the caller may NOT have loaded the bundled version, and thus
	# they may not have a MI version that works with the Makefile.PL. This would
	# result in false errors or unexpected behaviour. And we don't want that.
	my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
	unless ( $INC{$file} ) { die <<"END_DIE" }

Please invoke ${\__PACKAGE__} with:

	use inc::${\__PACKAGE__};

not:

	use ${\__PACKAGE__};

inc/Module/Install.pm  view on Meta::CPAN

	# is unreliable on some platforms and requires write permissions)
	# for now we should catch this and refuse to run.
	if ( -f $0 ) {
		my $s = (stat($0))[9];

		# If the modification time is only slightly in the future,
		# sleep briefly to remove the problem.
		my $a = $s - time;
		if ( $a > 0 and $a < 5 ) { sleep 5 }

		# Too far in the future, throw an error.
		my $t = time;
		if ( $s > $t ) { die <<"END_DIE" }

Your installer $0 has a modification time in the future ($s > $t).

This is known to create infinite loops in make.

Please correct this, then run $0 again.

END_DIE

inc/Module/Install.pm  view on Meta::CPAN

			goto &$code unless $cwd eq $pwd;
		}
		unless ($$sym =~ s/([^:]+)$//) {
			# XXX: it looks like we can't retrieve the missing function
			# via $$sym (usually $main::AUTOLOAD) in this case.
			# I'm still wondering if we should slurp Makefile.PL to
			# get some context or not ...
			my ($package, $file, $line) = caller;
			die <<"EOT";
Unknown function is found at $file line $line.
Execution of $file aborted due to runtime errors.

If you're a contributor to a project, you may need to install
some Module::Install extensions from CPAN (or other repository).
If you're a user of a module, please contact the author.
EOT
		}
		my $method = $1;
		if ( uc($method) eq $method ) {
			# Do nothing
			return;

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

    my $body;
    aio_load $self->fullpath, $body, sub {
      $config = eval $body;

      # upgrade ignore to new format
      if ($config->{ignore} and ref $config->{ignore} eq "ARRAY") {
        $config->{ignore} = {msg => $config->{ignore}};
      }

      if ($@) {
        warn "error loading config: $@\n";
      }
      $loaded->();
    }
  }
  else {
    say STDERR "No config found, writing a few config to ".$self->fullpath;
    $self->write($loaded);
  }
}

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

  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,
    );

    $stream->send([$app->connect_actions]);
    $app->add_stream($stream);
  }
  else {
    my $code = $req->env->{'websocket.impl'}->error_code;
    $res->send([$code, ["Content-Type", "text/plain"], ["something broke"]]);
  }
}

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

  my $msg = $req->param('msg');
  my $html = $req->param('html');
  my $source = $req->param('source');

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


our $NEXT_ID = 1;

use Any::Moose;

has closed => (
  is => 'rw',
  default => 0,
);

has on_error => (
  is => 'ro',
  required => 1,
);

has is_xhr => (
  is => 'ro',
  default => 1,
);

has id => (

lib/Alice/HTTP/Stream/WebSocket.pm  view on Meta::CPAN

sub BUILD {
  my $self = shift;

  my $h = AnyEvent::Handle->new(
    fh => $self->fh,
    rbuf_max => 1024 * 10,
  );

  $h->{ws_version} = $self->ws_version;
  
  $h->on_error(sub {
    $self->close;
    undef $h;
    $self->on_error->();
  });

  $h->on_eof(sub {
    $self->close;
    undef $h;
    $self->on_error->();
  }); 

  $h->on_read(sub {
    $_[0]->push_read(
      'AnyEvent::Handle::Message::WebSocket',
      sub { $self->on_read->(from_json $_[1]) }
    );
  });
    
  $self->handle($h);

lib/Alice/HTTP/Stream/XHR.pm  view on Meta::CPAN

  $self->offset($local_time - $remote_time);

  # better way to get the AE handle?
  my $hdl = $self->writer->{handle};

  $hdl->{rbuf_max} = 1024 * 10;

  my $close = sub {
    $self->close;
    undef $hdl;
    $self->on_error->();
  };

  $hdl->on_eof($close);
  $hdl->on_error($close);

  $self->send([{type => "identify", id => $self->id}]);
}

sub send {
  my ($self, $messages) = @_;
  return if $self->closed;

  $messages = [$messages] if $messages and ref $messages ne "ARRAY";

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


sub call {
    my ($self, $env) = @_;

    $env->{'websocket.impl'} = Alice::HTTP::WebSocket::Impl->new($env);

    return $self->app->($env);
}

package Alice::HTTP::WebSocket::Impl;
use Plack::Util::Accessor qw(env error_code version);
use Scalar::Util qw(weaken);
use IO::Handle;
use Protocol::WebSocket::Handshake::Server;

sub new {
    my ($class, $env) = @_;
    my $self = bless { env => $env }, $class;
    weaken $self->{env};
    return $self;
}

sub handshake {
    my $self = shift;

    my $env = $self->env;

    my $hs = Protocol::WebSocket::Handshake::Server->new_from_psgi($env);

    my $fh = $env->{'psgix.io'};
    unless ($fh and $hs->parse($fh)) {
      $self->error_code(501);
      return;
    }

    if ($hs->is_done) {
      $fh->autoflush;
      print $fh $hs->to_string;
      $self->version($hs->version);
      return $fh;
    }

    $self->error_code(500);
}

package AnyEvent::Handle::Message::WebSocket;
use Protocol::WebSocket::Frame;

sub anyevent_write_type {
    my ($handle, @args) = @_;
    Protocol::WebSocket::Frame->new(
      version => $handle->{ws_version},
      buffer  => (join "", @args),

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


  builder {
      enable 'WebSocket';
      sub {
          my $env = shift;
          ...
          if (my $fh = $env->{'websocket.impl'}->handshake) {
              # interact via $fh
              ...
          } else {
              $res->code($env->{'websocket.impl'}->error_code);
          }
      };
  };


=head1 DESCRIPTION

Alice::HTTP::WebSocket provides WebSocket implementation through $env->{'websocket.impl'}.
Currently implements draft-ietf-hybi-thewebsocketprotocol-00 <http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00>.

=head1 METHODS

=over 4

=item my $fh = $env->{'websocket.impl'}->handshake;

Starts WebSocket handshake and returns filehandle on successful handshake.
If failed, $env->{'websocket.impl'}->error_code is set to an HTTP code.

=back

=head1 AUTHOR

motemen E<lt>motemen@gmail.comE<gt>

=head1 SEE ALSO

=head1 LICENSE

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


irc_event connect => sub {
  my ($self, $irc, $err) = @_;
  $irc->is_connecting(0);

  if ($irc->cl->{socket}) {
    $irc->cl->{socket}->rbuf_max(1024 * 10); # 10K max read buffer
  }

  if (defined $err) {
    $self->send_info($irc->name, "connect error: $err");
    $self->reconnect_irc($irc->name);
    return;
  }

  $self->send_info($irc->name, "connected");
  $irc->connect_time(time);

  $self->broadcast({
    type => "action",
    event => "connect",

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

		} else {
			checkSet = parts = [];
		}
	}

	if ( !checkSet ) {
		checkSet = set;
	}

	if ( !checkSet ) {
		throw "Syntax error, unrecognized expression: " + (cur || selector);
	}

	if ( toString.call(checkSet) === "[object Array]" ) {
		if ( !prune ) {
			results.push.apply( results, checkSet );
		} else if ( context && context.nodeType === 1 ) {
			for ( var i = 0; checkSet[i] != null; i++ ) {
				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
					results.push( set[i] );
				}

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

						return [];
					}

					break;
				}
			}
		}

		if ( expr == old ) {
			if ( anyFound == null ) {
				throw "Syntax error, unrecognized expression: " + expr;
			} else {
				break;
			}
		}

		old = expr;
	}

	return curLoop;
};

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


  function isRightClick(event)  { return _isButton(event, 2) }

  function element(event) {
    event = Event.extend(event);

    var node = event.target, type = event.type,
     currentTarget = event.currentTarget;

    if (currentTarget && currentTarget.tagName) {
      if (type === 'load' || type === 'error' ||
        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
          && currentTarget.type === 'radio'))
            node = currentTarget;
    }

    if (node.nodeType == Node.TEXT_NODE)
      node = node.parentNode;

    return Element.extend(node);
  }

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

*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,...

(function() {

  if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) return;

  var logger;
  if (window.WEB_SOCKET_LOGGER) {
    logger = WEB_SOCKET_LOGGER;
  } else if (window.console && window.console.log && window.console.error) {
    logger = window.console;
  } else {
    logger = {log: function(){ }, error: function(){ }};
  }

  if (swfobject.getFlashPlayerVersion().major < 10) {
    logger.error("Flash Player >= 10.0.0 is required.");
    return;
  }
  if (location.protocol == "file:") {
    logger.error(
      "WARNING: web-socket-js doesn't work in file:///... URL " +
      "unless you set Flash Security Settings properly. " +
      "Open the page via Web server i.e. http://...");
  }

  /**
   * This class represents a faux web socket.
   * @param {string} url
   * @param {array or string} protocols
   * @param {string} proxyHost

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

  WebSocket.prototype.__handleEvent = function(flashEvent) {

    if ("readyState" in flashEvent) {
      this.readyState = flashEvent.readyState;
    }
    if ("protocol" in flashEvent) {
      this.protocol = flashEvent.protocol;
    }

    var jsEvent;
    if (flashEvent.type == "open" || flashEvent.type == "error") {
      jsEvent = this.__createSimpleEvent(flashEvent.type);
    } else if (flashEvent.type == "close") {
      jsEvent = this.__createSimpleEvent("close");
      jsEvent.wasClean = flashEvent.wasClean ? true : false;
      jsEvent.code = flashEvent.code;
      jsEvent.reason = flashEvent.reason;
    } else if (flashEvent.type == "message") {
      var data = decodeURIComponent(flashEvent.message);
      jsEvent = this.__createMessageEvent("message", data);
    } else {

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

  /**
   * Loads WebSocketMain.swf and creates WebSocketMain object in Flash.
   */
  WebSocket.__initialize = function() {
    if (WebSocket.__flash) return;

    if (WebSocket.__swfLocation) {
      window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
    }
    if (!window.WEB_SOCKET_SWF_LOCATION) {
      logger.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
      return;
    }
    if (!window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR &&
        !WEB_SOCKET_SWF_LOCATION.match(/(^|\/)WebSocketMainInsecure\.swf(\?.*)?$/) &&
        WEB_SOCKET_SWF_LOCATION.match(/^\w+:\/\/([^\/]+)/)) {
      var swfHost = RegExp.$1;
      if (location.host != swfHost) {
        logger.error(
            "[WebSocket] You must host HTML and WebSocketMain.swf in the same host " +
            "('" + location.host + "' != '" + swfHost + "'). " +
            "See also 'How to host HTML file and SWF file in different domains' section " +
            "in README.md. If you use WebSocketMainInsecure.swf, you can suppress this message " +
            "by WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;");
      }
    }
    var container = document.createElement("div");
    container.id = "webSocketContainer";
    container.style.position = "absolute";

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

      "webSocketFlash",
      "1" /* width */,
      "1" /* height */,
      "10.0.0" /* SWF version */,
      null,
      null,
      {hasPriority: true, swliveconnect : true, allowScriptAccess: "always"},
      null,
      function(e) {
        if (!e.success) {
          logger.error("[WebSocket] swfobject.embedSWF failed");
        }
      });
  };

  /**
   * Called by Flash to notify JS that it's fully loaded and ready
   * for communication.
   */
  WebSocket.__onFlashInitialized = function() {
    setTimeout(function() {

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

   * Called by Flash to notify WebSockets events are fired.
   */
  WebSocket.__onFlashEvent = function() {
    setTimeout(function() {
      try {
        var events = WebSocket.__flash.receiveEvents();
        for (var i = 0; i < events.length; ++i) {
          WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
        }
      } catch (e) {
        logger.error(e);
      }
    }, 0);
    return true;
  };

  WebSocket.__log = function(message) {
    logger.log(decodeURIComponent(message));
  };

  WebSocket.__error = function(message) {
    logger.error(decodeURIComponent(message));
  };

  WebSocket.__addTask = function(task) {
    if (WebSocket.__flash) {
      task();
    } else {
      WebSocket.__tasks.push(task);
    }
  };

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

    $('connection_status').className = classname;
  },

  reconnect: function () {
    this.reconnecting = true;
    this.reconnect_count = 0;
    this.connect();
  },

  handleException: function(request, exception) {
    this.application.log("encountered an error with stream.");
    this.application.log(exception);
    this.connected = false;
    if (!this.aborting)
      setTimeout(this.connect.bind(this), 2000);
    else
      this.changeStatus("ok");
  },

  handleComplete: function(transport) {
    this.application.log("connection was closed cleanly.");

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

      tab: this.application.activeWindow().id
    });
    var protocol = (window.location.protocol.match(/^https/) ? "wss://" : "ws://");
    var url = protocol + window.location.host + "/wsstream?" + parameters;
    this.request = new WebSocket(url);
    this.request.onopen = function(){
      this.connected = true;
      setTimeout(cb, 100);
    }.bind(this);
    this.request.onmessage = this.handleUpdate.bind(this);
    this.request.onerror = this.handleException.bind(this);
    this.request.onclose = this.handleComplete.bind(this);
  },

  handleUpdate: function(e) {
    var data = e.data.evalJSON();
    this.processQueue(data);
  },

  sendMessage: function(form) {
    if (!this.connected) return false;

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

    this.aborting = true;
    if (this.request) this.request.close();
    this.aborting = false;
  },

  closeWindow: function(win) {
    this.sendMessage({source: win.id, msg: "/close"});
  },

  handleException: function(exception) {
    this.application.log("encountered an error with stream.");
    this.application.log(exception);
    this.connected = false;
    if (!this.aborting)
      setTimeout(this.connect.bind(this), 2000);
    else
      this.changeStatus("ok");
  },

  requestWindow: function(title, windowId, message) {
    this.sendMessage({source: windowId, msg: "/create " + title});

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

      params = form;
    }

    params['stream'] = this.id;

    new Ajax.Request('/say', {
      method: 'post',
      parameters: params,
      on401: this.gotoLogin,
      onException: function (request, exception) {
        alert("There was an error sending a message.");
      }
    });

    return true;
  },

  closeConnection: function() {
    this.aborting = true;
    if (this.request && this.request.transport)
      this.request.transport.abort();

share/templates/login.html  view on Meta::CPAN

? my ($app, $dest, $error) = @_;
<html>
  <head>
    <title>Use Alice Login</title>
    <link rel="shortcut icon" href="<?= $app->static_url("favicon.ico") ?>">
    <style type="text/css">
      body {
        text-align: center;
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        background: #eee;

share/templates/login.html  view on Meta::CPAN

        width: 150px;
      }
      input {
        margin-bottom: 15px;
      }
      input[type="submit"] {
        font-size: 16px;
        margin-bottom: 0;
        margin-top: 30px;
      }
      .error {
        color: #d00b0b;
        display: block;
        margin-top: 15px;
      }
    </style>
    <link rel="apple-touch-icon" href="<?= $app->static_url("image/alice.png") ?>" />
    <link rel="apple-touch-startup-image" href="<?= $app->static_url("image/alice.png") ?>" />
    <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">

share/templates/login.html  view on Meta::CPAN

    <form action="/login" method="post">
      <input type="hidden" name="dest" value="<?= $dest || "/" ?>" />

      <label for="username">User Name:</label>
      <input type="text" name="username" value="" id="username" />
      
      <label for="password">Password:</label>
      <input type="password" name="password" value="" id="password" />
      
      <input type="submit" value="Log in" />
      <? if ($error) { ?>
      <span class="error"><?= $error ?></span>
      <? } ?>
    </form>
  </body>
</html>



( run in 0.387 second using v1.01-cache-2.11-cpan-65fba6d93b7 )