| 1 | #!/usr/local/bin/perl |
|---|
| 2 | |
|---|
| 3 | # 2007-07-22 v0.01 |
|---|
| 4 | # License : Same as Perl |
|---|
| 5 | # Sample : http://blog.bulkneets.net/misc/ustream/channel2json.pl |
|---|
| 6 | |
|---|
| 7 | use lib qw(lib); |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | use CGI; |
|---|
| 11 | use LWP::UserAgent; |
|---|
| 12 | use Cache::FileCache; |
|---|
| 13 | use URI::Fetch; |
|---|
| 14 | use JSON::Syck; |
|---|
| 15 | |
|---|
| 16 | my $channels_limit = 70; |
|---|
| 17 | |
|---|
| 18 | my $q = CGI->new; |
|---|
| 19 | |
|---|
| 20 | my $cache = Cache::FileCache->new({ |
|---|
| 21 | 'cache_root' => '.cache', |
|---|
| 22 | 'namespace' => 'ustream2json', |
|---|
| 23 | 'default_expires_in' => 3600 |
|---|
| 24 | }); |
|---|
| 25 | |
|---|
| 26 | my %scraper = ( |
|---|
| 27 | 'usc' => qr{src="http://ustream\.tv/([^"]*?)\.usc"}o, |
|---|
| 28 | 'irc' => qr{name="channel" value="(\#[^,]*?)"}o, |
|---|
| 29 | ); |
|---|
| 30 | |
|---|
| 31 | my $mode = $q->param("mode") || 'usc'; |
|---|
| 32 | my $channel_name = $q->param("channel_name"); |
|---|
| 33 | my @channels = split(/,/, $channel_name); |
|---|
| 34 | |
|---|
| 35 | if (scalar @channels > $channels_limit){ |
|---|
| 36 | output_json($q, "too large"); |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | my %result = map { |
|---|
| 40 | $_ => channel2any($_, $mode) |
|---|
| 41 | } map { |
|---|
| 42 | $_ =~ s{http://(?:www\.)?ustream.tv/channel/}{}; $_ |
|---|
| 43 | } @channels; |
|---|
| 44 | |
|---|
| 45 | output_json($q, \%result); |
|---|
| 46 | |
|---|
| 47 | sub channel2any { |
|---|
| 48 | my ($channel, $mode) = @_; |
|---|
| 49 | my $content = channel_fetch($channel); |
|---|
| 50 | $content =~ $scraper{$mode}; |
|---|
| 51 | return $1 ? $1 : undef; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | sub channel_fetch { |
|---|
| 55 | my $channel = shift; |
|---|
| 56 | my $url = "http://www.ustream.tv/channel/" . $channel; |
|---|
| 57 | my $ua = LWP::UserAgent->new; |
|---|
| 58 | $ua->agent('ustream2json/0.01'); |
|---|
| 59 | |
|---|
| 60 | my $res = URI::Fetch->fetch( |
|---|
| 61 | $url, |
|---|
| 62 | UserAgent => $ua, |
|---|
| 63 | Cache => $cache, |
|---|
| 64 | NoNetwork => 3600 |
|---|
| 65 | ); |
|---|
| 66 | |
|---|
| 67 | return $res->is_success ? $res->content : undef; |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | sub output_json { |
|---|
| 71 | my ($q, $obj) = @_; |
|---|
| 72 | print $q->header( |
|---|
| 73 | "-type" => "text/javascript", |
|---|
| 74 | "-charset" => 'utf-8' |
|---|
| 75 | ); |
|---|
| 76 | my $json = JSON::Syck::Dump($obj); |
|---|
| 77 | if(defined (my $p = $q->param('callback'))){ |
|---|
| 78 | $json = "$p($json);" if($p =~ /[a-zA-Z0-9\.\_\[\]]/); |
|---|
| 79 | } |
|---|
| 80 | print $json; |
|---|
| 81 | } |
|---|