#!/usr/bin/env perl use Getopt::Std; use IO::Socket; use Term::Prompt; use LWP::Simple; use LWP::UserAgent; use HTTP::Request::Common qw(POST); use XML::XPath; use XML::XPath::XMLParser; sub urldecode { my $str = shift; $str =~ s/%([A-Fa-f0-9]{2})/pack('C',hex($1))/seg; return $str; } sub findXPath { my ($xml,$xpath) = @_; my $tree = XML::XPath->new($xml); my $nodeset = $tree->find($xpath) or die "Cannot find xpath $xpath\n"; return $nodeset; } sub pageRequest { my ($ua, $url) = @_; if(@_ < 2) { print STDERR "not enough parameter in pageRequest\n"; return; } my $req = new HTTP::Request 'GET', $url; my $res = $ua->request($req)->decoded_content; die "Can't fetch url $url\n" unless defined $res; return $res; } sub login { my ($ua, $user, $pass) = @_; $ua->cookie_jar({ file => "$ENV{HOME}/.cookies.txt" }); my $req = POST 'http://www.gomtv.net/user/loginCheck.php', [cmd => 'login', returl => '', mb_username => $user, mb_password => $pass]; $res = $ua->request($req); if ($res->header('Set-Cookie') =~ /SES_memberno/) { return 1; } return 0; } sub help { print "usage: download [OPTIONS] [VIDEO_ID] [SET_ID] [FILE]\n"; } sub download { my ($ua, $id, $filename, $set) = @_; $page = pageRequest $ua, "http://www.gomtv.net/2010gslopens2/vod/$id"; $page =~ /setVQPlayer\(([0-9]+), ([0-9]+)\)/; die "Cant find setVQPlayer for $id\n" unless defined $1; my $league = $1; $page =~ /putBid\(([0-9]+), ([0-9]+), ([0-9]+), ([0-9]+), ([0-9]+), ([0-9]+)\)/; die "Cant find putBid\n" unless defined $1; my ($vidId, $vodSeq, $unoSeq) = ($1, $2, $3, $5); $vodSeq += $set - 1; my $content = pageRequest $ua, "http://www.gomtv.net/gox/flash_channel.php?intseq=$vidId&sets=$set&vodseq=$vodSeq&setvq=HQ&intCate=$league"; my $hrefs = findXPath($content, '//REF'); print STDERR "Cannot find the download url but got the secret page" unless defined $hrefs; my $dlurl = urldecode($hrefs->get_node(1)->getAttribute('href')); print STDERR "Cannot find the download url but got the secret page" unless defined $dlurl; $dlurl =~/uno=(\d+)/; print STDERR "Cannot find uno" unless defined $1; my $uno = $1; # okay this is the tricky part, we have to get a md5 key from the server # we hvae to simply establish a TCP connection and send a special string my $sock = new IO::Socket::INET(PeerPort => '63800', PeerAddr => '211.43.144.147', LocalPort => '58000', Proto => 'tcp', Reuse => 1 ) or die "ERROR in Socket Creation : $!\n"; print $sock "Login,0,$uno,$unoSeq,127.0.0.1\n"; my $recv = <$sock>; $recv =~ /([a-f0-9]{32})/; print STDERR "cannot find uno" unless defined $1; my $key = $1; close($sock); $dlurl.= "&key=$key"; if ($filename == "-") { return getprint($dlurl); } else { getstore($dlurl, $filename); } } getopts('qu:p:'); $username = ($opt_u) ? $opt_u : prompt('x', 'username:', '', 'your pass'); $password = ($opt_p) ? $opt_p : prompt('p', 'password:', '', ''); print "\n" unless $opt_q; $ua = new LWP::UserAgent; print "try to login..." unless $opt_q; login($ua, $username, $password) or die "Cannot login to gomtv\n"; print "successfull\n" unless $opt_q; print "find secret download site...\n" unless $opt_q; download($ua, $ARGV[0], $ARGV[2], $ARGV[1]); print "done\n" unless $opt_q;