Skip to content

Instantly share code, notes, and snippets.

@miyagawa
Created July 24, 2009 10:29
Show Gist options
  • Save miyagawa/153955 to your computer and use it in GitHub Desktop.
Save miyagawa/153955 to your computer and use it in GitHub Desktop.
Works with jk.nicovideo.jp and live.nicovideo.jp chat http://www.flickr.com/photos/bulknews/3752075630/
#!/usr/bin/perl
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Socket;
use AnyEvent::Handle;
use WWW::Mechanize;
use URI;
use XML::LibXML::Simple;
# $ch = jk1, jk2 for Jikkyo, or lv12345 for Live
my($email, $password, $ch) = @ARGV;
my $status = login_check_status($email, $password, $ch || "jk1");
binmode STDOUT, ":utf8";
my $cv = AnyEvent->condvar;
my $wc = $status->{stream}{watch_count};
tcp_connect $status->{ms}{addr}, $status->{ms}{port}, sub {
my $fh = shift;
warn "Connected to $status->{stream}{id}. Watchers: $wc\n";
my $hdl; $hdl = AnyEvent::Handle->new(
fh => $fh,
on_error => sub {
warn "error $_[2]\n";
$_[0]->destroy;
$cv->send;
},
on_eof => sub {
$hdl->destroy;
$cv->send;
},
);
$hdl->push_write(qq(<thread thread="$status->{ms}{thread}" res_from="-10" version="20061206"/>\0));
my $reader; $reader = sub {
my($hdl, $xml) = @_;
chomp $xml; # \0
my $res = XML::LibXML::Simple->new->XMLin(\$xml);
if ($res->{content}) {
printf "%s %s\n", format_date($res->{date}), $res->{content};
} elsif ($res->{video}) {
if ($wc != $res->{video}) {
print "** Watchers: $res->{video}\n";
$wc = $res->{video};
}
}
$hdl->push_read(line => "\0", $reader);
};
$hdl->push_read(line => "\0", $reader);
};
$cv->recv;
sub format_date {
my @localtime = localtime shift;
sprintf "%02d:%02d:%02d", @localtime[2,1,0];
}
sub login_check_status {
my($email, $password, $ch) = @_;
my %host = (jk => "jk", lv => "live");
my $host = $host{substr $ch, 0, 2}
or die "Unknown channel format $ch";
my $mech = WWW::Mechanize->new;
$mech->get("http://$host.nicovideo.jp/login");
$mech->submit_form(
fields => {
mail => $email,
password => $password,
},
);
my $uri = URI->new("http://$host.nicovideo.jp/api/getplayerstatus");
$uri->query_form(v => $ch);
$mech->get($uri);
my $res = XML::LibXML::Simple->new->XMLin($mech->content);
if ($res->{status} ne 'ok') {
die "Login failed: ", $mech->content;
}
return $res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment