2 # @(#)$Header: /home/mythtv/mythtvrep/scripts/twit.tv.pl,v 1.32 2010/07/24 23:28:11 mythtv Exp $
3 # Auric 2010/01/10 http://web.aanet.com.au/auric/
5 # MythNetvision Grabber Script for TWiT.tv site.
7 # If you want to alter any of the default settings.
8 # Create/Change $HOME/.mythtv/MythNetvision/userGrabberPrefs/twit.tv.cfg
11 # playerargs=-fs -zoom %MEDIAURL%
13 # Some settings you can have in this are
14 # Print info/progress message: 0 - off, 1 - low ,2 - high
16 # Info messages go to: 0 = stderr, filename = filename
18 # External player to use
20 # Args to external player %MEDIAURL% will be replaced with content url
22 # External download to use
24 # Args to external download %MEDIAURL% will be replaced with content url
26 # A network player like a flash or html5 html. TODO 0.24 May not be approved
30 # Seconds to cache results Default 72000
33 ################################################################################
38 use HTML::TreeBuilder;
47 use FindBin
'$Bin',
'$Script';
48 use
lib "$Bin/nv_perl_libs";
51 #################################### Settings #################################
52 # Load from config file. May overwrite above.
55 #################################### Globals ##################################
56 my $version =
'$Revision: 1.32 $'; $version =~ s/\D*([\d\.]+)\D*/$1/; # rcs tag populated
61 my $baseicon =
'http://twit.tv/sites/all/themes/twit/img/logo.gif';
62 my $store =
"/tmp/.${site}.diritemsref.store";
63 our ($opt_v, $opt_T, $opt_p, $opt_S);
66 #################################### Site Specific Subs ##########################
67 # Build all vid items for all directories
68 # input hash ref to { "directory name" => [array of anonymous hash's] }
70 # 'dirthumbnail' => $icon,
72 # 'mythtv:subtitle' => "",
73 # 'author' => $author,
74 # 'pubDate' => $pubDate,
75 # 'description' => $description,
77 # 'player' => $player,
78 # 'playerargs' => $playerargs,
79 # 'download' => $download,
80 # 'downloadargs' => $downloadargs,
81 # 'media:thumbnailurl' => "",
82 # 'media:contenturl' => $contenturl,
83 # 'media:contentlength' => $length,
84 # 'media:contentduration' => "",
85 # 'media:contentwidth' => "",
86 # 'media:contentheight' => "",
87 # 'media:contentlanguage' => $language,
89 # 'mythtv:country' => ""
90 # 'mythtv:season' => ""
91 # 'mythtv:episode' => ""
92 # 'mythtv:customhtml' => ""
94 # Basically this hash ref is what you need to build.
99 my $baseurl = shift @
_;
101 my $dirurlsref = builddirurls($baseurl);
102 my $vidurlsref = buildvidurls($dirurlsref);
104 foreach my $dir (keys(%$vidurlsref)) {
105 my $diritemsfound = 0;
106 for (
my $c = 0; $c <= $#{$vidurlsref->{
$dir}}; $c++) {
107 my $found = builditems($diritemsref,
$dir, ${$vidurlsref->{
$dir}}[$c]);
108 $itemsfound += $found;
109 $diritemsfound += $found;
110 # Skip rest as nothing found so far. (To speed things up)
111 if ($c > 0 && $diritemsfound == 0) {
112 mnvinfomsg(2,
"Skipping rest of $dir as nothing found so far");
116 mnvinfomsg(1,
"$dir Items found $diritemsfound");
121 # Collect url's of all the podcasts
123 # return hash ref to { "directory name" => "url" }
129 mnvinfomsg(1,
"Getting $baseurl");
132 die "Could not retrieve $baseurl";
134 my $tree = HTML::TreeBuilder->new;
135 eval { $tree->parse($content); };
137 die "$baseurl parse failed, $@";
142 my $tmp = $tree->look_down(
'class',
'leaf first');
143 ($tmp) and push(@ptrs, $tmp);
144 my @
tmp = $tree->look_down(
'class',
'leaf');
145 (@
tmp) and push(@ptrs, @tmp);
146 foreach my $ptr (@ptrs) {
147 my @as = $ptr->find_by_tag_name(
'a');
148 foreach my $a (@as) {
149 my $dir = $a->as_trimmed_text();
150 $dirurls{$dir} = mnvcleantext($baseurl.$a->attr(
'href'));
153 #print STDERR Dumper(%dirurls);
159 # Collect url's to all vids
160 # input hash ref to { "directory name" => "url" }
161 # return hash ref to { "directory name" => [url] }
163 my $dirurls = shift @
_;
167 foreach my $dir (sort(keys(%$dirurls))) {
168 mnvinfomsg(1,
"Getting $dir $dirurls->{$dir}");
169 my $content =
get($dirurls->{
$dir});
171 warn
"Could not retrieve $dirurls->{$dir}";
174 my $tree = HTML::TreeBuilder->new;
175 eval { $tree->parse($content); };
177 warn
"$dirurls->{$dir} parse failed, $@";
184 #my $ptr = $tree->look_down('class', 'podcast-description');
185 #($ptr) and $dirdesc = $ptr->as_trimmed_text();
188 my $tmp = $tree->look_down(
'class',
'podcast-number current');
189 ($tmp) and push(@ptrs, $tmp);
190 my @tmp = $tree->look_down(
'class',
'podcast-number');
191 (@
tmp) and push(@ptrs, @tmp);
192 foreach my $urlp (@ptrs) {
193 push(@{$vidurls{
$dir}}, mnvcleantext($baseurl.$urlp->attr(
'href')));
196 #print STDERR Dumper(%vidurls);
201 # input hash ref to { "directory name" => [array of anonymous hash's] }
202 # input "directory name"
204 # output number of items added
210 mnvinfomsg(2,
"Getting $dir Episode $url");
213 warn
"Could not retrieve $url";
216 my $tree = HTML::TreeBuilder->new;
217 eval { $tree->parse($content); };
219 warn
"$url parse failed, $@";
225 my @as = $tree->find_by_tag_name(
'a');
226 foreach my $a (@as) {
227 $a->as_trimmed_text() =~ /Download
Video/ or
next;
228 $a->attr(
'href') =~ /^
http:.*video.*mp4$/ and push(@links, mnvcleantext($a->attr(
'href')));
230 (@links) or
return 0;
234 my $tmp = $tree->look_down(
'class',
'podcast-number current');
235 ($tmp) and push(@ptrs, $tmp);
236 my @tmp = $tree->look_down(
'class',
'podcast-number');
237 (@
tmp) and push(@ptrs, @tmp);
239 foreach my $tmp (@ptrs) {
240 my $testurl = $tmp->attr(
'href');
241 $url =~ /
http:.*${testurl}/ and $ptr = $tmp and
last;
244 $title = mnvcleantext($ptr->attr(
'title'));
245 $ptr = $ptr->parent();
246 my $ptr2 = $ptr->look_down(
'class',
'podcast-date');
248 my $time = str2time($ptr2->as_trimmed_text());
249 $pubDate = time2str(
"%a, %d %b %Y 00:00:00 GMT", $time);
250 $pubDate = mnvcleantext($pubDate);
252 $ptr2 = $ptr->find_by_tag_name(
'p');
253 ($ptr2) and $desc = mnvcleantext($ptr2->as_trimmed_text());
255 ($title) or
return 0;
258 $ptr = $tree->look_down(
'class',
'imagecache imagecache-coverart');
259 ($ptr) and $icon = mnvcleantext($ptr->attr(
'src'));
262 $ptr = $tree->look_down(
'class',
'running-time');
263 ($ptr) and
my $tmpdur = $ptr->as_trimmed_text();
264 if ($tmpdur =~ s/Running time:
265 my $hours = 0;
my $mins = 0;
my $secs = 0;
268 ($mins, $secs) = split(
':', $tmpdur);
269 }
elsif ($count == 2) {
270 ($hours, $mins, $secs) = split(
':', $tmpdur);
274 $tmpdur = ($hours * 60 * 60) + ($mins * 60) + $secs;
275 ($tmpdur > 0) and $duration = mnvcleantext($tmpdur);
283 my ($width, $height, $titleresolution);
289 if (mnvgetconfig(
'resolution')) {
290 $titleresolution = $title;
291 if ((mnvgetconfig(
'resolution') eq
"high") && ($width < 750)) {
292 mnvinfomsg(1,
"Skipping $contenturl due to wrong resolution");
295 if ((mnvgetconfig(
'resolution') eq
"low") && ($width >= 750)) {
296 mnvinfomsg(1,
"Skipping $contenturl due to wrong resolution");
300 $titleresolution =
"$title (${width}x${height})";
303 if ((mnvgetconfig(
'netplayer')) && (
$contenturl)) {
304 if (mnvistype(mnvgetconfig(
'netplayertype'),
$contenturl)) {
305 my $encodedtitle = decode_entities($title);
306 $encodedtitle = mnvURLEncode($encodedtitle);
307 $link = mnvcleantext(mnvgetconfig(
'netplayer').
"?title=${encodedtitle}&videofile=").$contenturl;
309 mnvinfomsg(1,
"Not ".mnvgetconfig(
'netplayertype').
" $contenturl");
312 push(@{$diritemsref->{$dir}}, {
313 'dirthumbnail' =>
$icon,
314 'title' => $titleresolution,
315 'mythtv:subtitle' =>
"",
316 'author' =>
"twit.tv",
317 'pubDate' => $pubDate,
318 'description' =>
$desc,
320 'player' => mnvgetconfig(
'player'),
321 'playerargs' => mnvgetconfig(
'playerargs'),
322 'download' => mnvgetconfig(
'download'),
323 'downloadargs' => mnvgetconfig(
'downloadargs'),
324 'media:thumbnailurl' =>
$icon,
326 'media:contentlength' =>
"",
327 'media:contentduration' => $duration,
328 'media:contentwidth' => $width,
329 'media:contentheight' => $height,
330 'media:contentlanguage' =>
"",
332 'mythtv:country' => $country,
333 'mythtv:season' =>
"",
334 'mythtv:episode' =>
"",
335 'mythtv:customhtml' =>
"no"
338 mnvinfomsg(2,
"Added $title");
344 #################################### Main #####################################
345 # If you copy this for another site, hopefully these won't need to changed
349 ($mnvcommonsubs::netvisionver == 23) and
print "$site|TS\n";
360 ($opt_p) and $page = $opt_p;
362 print STDERR
"Must have -T or -S option\n";
374 if (($ss) && (time() - $ss->mtime) < mnvgetconfig(
'cachetime')) {
375 eval { $diritemsref = retrieve($store); };
377 die "Could not load store, $@";
379 $totalitems = mnvnumresults($diritemsref);
380 mnvinfomsg(1,
"Using previous run data");
382 $totalitems = builddiritems($diritemsref, $baseurl);
383 eval { store($diritemsref, $store); };
385 warn
"Could not save store, $@";
391 <title>'.$site.
'</title>
392 <link>'.$baseurl.
'</link>
394 if ($type eq
"search") {
395 $filtereditems = mnvfilter($diritemsref, $search);
396 mnvprintsearch($diritemsref, $page);
397 mnvinfomsg(1,
"Total Items match $filtereditems of $totalitems");
399 mnvprinttree($diritemsref, 4);
400 mnvinfomsg(1,
"Total Items found $totalitems");
402 print "</channel>\n";