App-Termcast
view release on metacpan or search on metacpan
lib/App/Termcast.pm view on Meta::CPAN
package App::Termcast;
BEGIN {
$App::Termcast::AUTHORITY = 'cpan:DOY';
}
$App::Termcast::VERSION = '0.13';
use Moose;
# ABSTRACT: broadcast your terminal sessions for remote viewing
with 'MooseX::Getopt::Dashes';
use IO::Select;
use IO::Socket::INET;
use JSON;
use Scalar::Util 'weaken';
use Term::Filter::Callback;
use Term::ReadKey;
use Try::Tiny;
has host => (
is => 'rw',
isa => 'Str',
default => 'noway.ratry.ru',
documentation => 'Hostname of the termcast server to connect to',
);
has port => (
is => 'rw',
isa => 'Int',
default => 31337,
documentation => 'Port to connect to on the termcast server',
);
has user => (
is => 'rw',
isa => 'Str',
default => sub { $ENV{USER} },
documentation => 'Username for the termcast server',
);
has password => (
is => 'rw',
isa => 'Str',
default => 'asdf', # really unimportant
documentation => "Password for the termcast server\n"
. " (mostly unimportant)",
);
has bell_on_watcher => (
is => 'rw',
isa => 'Bool',
default => 0,
documentation => "Send a terminal bell when a watcher connects\n"
. " or disconnects",
);
has timeout => (
is => 'rw',
isa => 'Int',
default => 5,
documentation => "Timeout length for the connection to the termcast server",
);
has establishment_message => (
traits => ['NoGetopt'],
is => 'ro',
isa => 'Str',
lib/App/Termcast.pm view on Meta::CPAN
if ($fh == $socket) {
ReadMode(0, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
Carp::croak("Invalid password");
}
}
for my $fh (@$r) {
if ($fh == $socket) {
my $buf;
$socket->recv($buf, 4096);
if (!defined $buf || length $buf == 0) {
ReadMode(0, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
Carp::croak("Invalid password");
}
elsif ($buf ne ('hello, ' . $self->user . "\n")) {
ReadMode(0, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
Carp::carp("Unknown login response from server: $buf");
ReadMode(5, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
}
}
}
}
ReadMode(5, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
return $socket;
}
before clear_socket => sub {
my $self = shift;
Carp::carp("Lost connection to server ($!), reconnecting...");
$self->socket->close;
ReadMode(0, $self->input)
if $self->_has_term && $self->_term->_raw_mode;
};
sub _new_socket {
my $self = shift;
$self->_term->remove_input_handle($self->socket);
$self->clear_socket;
$self->_term->add_input_handle($self->socket);
}
has _needs_termsize_update => (
traits => ['NoGetopt'],
is => 'rw',
isa => 'Bool',
default => 0,
);
has _term => (
is => 'ro',
does => 'Term::Filter',
lazy => 1,
predicate => '_has_term',
default => sub {
my $_self = shift;
weaken(my $self = $_self);
# XXX using ::Callback for now because we need to be able to
# instantiate App::Termcast objects without initializing the terminal
# (in case of just calling write_to_termcast). This should
# eventually be deprecated in favor of moving the termcast interaction
# code out to an App::Termcast::Writer module or something, and
# this module should be a simple wrapper that combines that module
# with Term::Filter.
Term::Filter::Callback->new(
callbacks => {
setup => sub {
my ($term) = @_;
$term->add_input_handle($self->socket);
},
winch => sub {
# for the sake of sending a clear to the client anyway
syswrite $self->output, "\e[H\e[2J";
$self->_needs_termsize_update(1);
},
read_error => sub {
my ($term, $fh) = @_;
if ($fh == $self->socket) {
$self->_new_socket;
}
},
read => sub {
my ($term, $fh) = @_;
if ($fh == $self->socket) {
my $got = $term->_read_from_handle(
$self->socket, "socket"
);
$self->_new_socket unless defined $got;
if ($self->bell_on_watcher) {
# something better to do here?
syswrite $self->output, "\a";
}
}
},
munge_output => sub {
my ($term, $buf) = @_;
$self->write_to_termcast($buf);
$buf;
},
},
);
},
handles => [ 'run', 'input', 'output' ],
);
sub write_to_termcast {
my $self = shift;
my ($buf) = @_;
my $socket = $self->socket;
my $select = IO::Select->new($socket);
my (undef, $w, $e) = IO::Select->select(
undef, $select, $select, $self->timeout,
);
( run in 2.878 seconds using v1.01-cache-2.11-cpan-d8267643d1d )