2 # @(#)$Header: /home/mythtv/mythtvrep/scripts/twit.tv.pl,v 1.34 2015/11/04 11:29:00 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;
49 use FindBin '$Bin', '$Script';
50 use lib "$Bin/nv_perl_libs";
53 #################################### Settings #################################
54 # Load from config file. May overwrite above.
55 mnvloadconfig(fileparse($Script, '.pl'), "notused");
57 #################################### Globals ##################################
58 my $version = '$Revision: 1.34 $'; $version =~ s/\D*([\d\.]+)\D*/$1/; # rcs tag populated
59 my $command = "twit.tv.pl"; my $commandthumbnail = "twit.tv.png"; my $author = "Auric (modififed by Neoh4x0r)";
61 my $description = 'Leo Laporte & Friends';
62 my $baseurl = 'http://wiki.twit.tv';
63 my $feedsurl = 'http://wiki.twit.tv/wiki/TWiT_Show_Feeds';
64 my $baseicon = 'http://wiki.twit.tv/w/images/twitipedialogo.png';
65 my $store = "/tmp/.${site}.diritemsref.store";
67 my $video_small = "_video_small.xml";
68 my $video_large = "_video_large.xml";
69 my $video_hd = "_video_hd.xml";
71 my $video_size = $video_large;
73 my $max_page_count = 1; # 0=disabled ; limit the number of pages parsed for episodes (there are 24 ep/page * num_pages)
74 our ($opt_v, $opt_T, $opt_p, $opt_S);
77 #################################### Site Specific Subs ##########################
78 # Build all vid items for all directories
79 # input hash ref to { "directory name" => [array of anonymous hash's] }
81 # 'dirthumbnail' => $icon,
83 # 'mythtv:subtitle' => "",
84 # 'author' => $author,
85 # 'pubDate' => $pubDate,
86 # 'description' => $description,
88 # 'player' => $player,
89 # 'playerargs' => $playerargs,
90 # 'download' => $download,
91 # 'downloadargs' => $downloadargs,
92 # 'media:thumbnailurl' => "",
93 # 'media:contenturl' => $contenturl,
94 # 'media:contentlength' => $length,
95 # 'media:contentduration' => "",
96 # 'media:contentwidth' => "",
97 # 'media:contentheight' => "",
98 # 'media:contentlanguage' => $language,
100 # 'mythtv:country' => ""
101 # 'mythtv:season' => ""
102 # 'mythtv:episode' => ""
103 # 'mythtv:customhtml' => ""
105 # Basically this hash ref is what you need to build.
109 printf "DEBUG:builddiritems called\n";
110 my $diritemsref = shift @_;
111 my $baseurl = shift @_;
113 my $dirurlsref = builddirurls($baseurl);
114 my $vidurlsref = buildvidurls($dirurlsref);
116 foreach my $dir (keys(%$vidurlsref)) {
117 my $diritemsfound = 0;
118 my $count = $#{$vidurlsref->{$dir}};
119 # printf "DEBUG:builddiritems:count = '%d'\n", $count;
120 for (my $c = 0; $c <= $count; $c++) {
121 my $found = builditems($diritemsref, $dir, ${$vidurlsref->{$dir}}[$c]);
122 $itemsfound += $found;
123 $diritemsfound += $found;
124 # Skip rest as nothing found so far. (To speed things up)
125 if ($c > 0 && $diritemsfound == 0) {
126 mnvinfomsg(2, "Skipping rest of $dir as nothing found so far");
130 mnvinfomsg(1, "$dir Items found $diritemsfound");
135 # Collect url's of all the podcasts
137 # return hash ref to { "directory name" => "url" }
139 printf "DEBUG:builddirurls called\n";
140 my $baseurl = shift@_;
144 printf "DEBUG:builddirurls:Getting %s\n", $baseurl;
145 mnvinfomsg(1, "Getting $baseurl");
146 # only grab active shows
147 my $content = get($baseurl);
149 die "Could not retrieve $baseurl";
151 my $tree = HTML::TreeBuilder->new;
152 eval { $tree->parse($content); };
154 die "$baseurl parse failed, $@";
160 my $bReadingActiveShows = 0;
162 # read the active show TOC
163 my @tmp = $tree->look_down('class', 'toclevel-1 tocsection-1');
164 (@tmp) and push(@ptrs, @tmp);
165 foreach my $ptr (@ptrs) {
166 #printf "DEBUG:builddirurls:ptr = '%s'\n", $ptr->as_trimmed_text();
167 my $ul = $ptr->find_by_tag_name('ul');
168 #printf "DEBUG:builddirurls:ul = '%s'\n", $ul->as_trimmed_text();
169 my @li = $ul->find_by_tag_name('li');
170 foreach my $tag (@li) {
171 #printf "DEBUG:builddirurls:li = '%s'\n", $tag->as_trimmed_text();
172 my @as = $tag->find_by_tag_name('a');
173 foreach my $a (@as) {
174 my $id = mnvcleantext($a->attr('href'));
176 #printf "DEBUG:builddirurls:id = '%s'\n", $id;
179 # locate the active show by id
180 my @tmp1 = $tree->look_down('class', 'mw-headline', 'id' , $id);
181 (@tmp1) and push(@ptrs1, @tmp1);
182 foreach my $ptr1 (@ptrs1) {
184 my $dir = $ptr1->as_trimmed_text();
185 #printf "DEBUG:builddirurls:dir = '%s'\n", $dir;
188 push(@show_dirs, $dir);
194 my $show_dirs_size = @show_dirs;
195 printf "DEBUG:builddirurls:found '%d' active shows\n", $show_dirs_size;
201 @tmp = $tree->look_down('class', 'external free');
202 (@tmp) and push(@ptrs, @tmp);
203 foreach my $ptr (@ptrs) {
204 my @as = $ptr->find_by_tag_name('a');
205 foreach my $a (@as) {
206 if ( ($url_count + 1) > $show_dirs_size)
210 my $url = mnvcleantext($a->attr('href'));
211 if ($url && $url =~ /$video_size$/)
213 my $dir = $show_dirs[$url_count];
214 printf "DEBUG:builddirurls:feed [%d] = '%s' -> '%s'\n", $url_count, $dir, $url;
215 $dirurls{$dir} = $url;
223 (keys(%dirurls)) or die "No urls found";
228 # Collect url's to all vids
229 # input hash ref to { "directory name" => "url" }
230 # return hash ref to { "directory name" => [url] }
232 printf "DEBUG:buildvidurls called\n";
233 my $dirurls = shift @_;
237 foreach my $dir (sort(keys(%$dirurls))) {
238 # this originally expected a streaming video on page, but we have a direct link to the feed
239 # just return the feed url
240 push(@{$vidurls{$dir}}, $dirurls->{$dir});
246 # input hash ref to { "directory name" => [array of anonymous hash's] }
247 # input "directory name"
249 # output number of items added
251 printf "DEBUG:buildvidurls called\n";
252 my $diritemsref = shift @_;
256 printf "DEBUG:builditems:%s -> %s\n", $dir, $url;
257 mnvinfomsg(2, "Getting $dir Episode $url");
258 my $content = get($url);
260 warn "Could not retrieve $url";
263 my $tree = XML::TreeBuilder->new;
264 eval { $tree->parse($content); };
266 warn "$url parse failed, $@";
275 my $thumbnail = $tree->find_by_tag_name('channel')->find_by_tag_name('image')->find_by_tag_name('url')->as_trimmed_text();;
278 my @tmp = $tree->find_by_tag_name('item');
279 (@tmp) and push(@ptrs, @tmp);
280 foreach my $ptr (@ptrs) {
281 #printf "DEBUG:builditems:ptr = %s\n", $ptr->as_trimmed_text();
282 my $title = HTML::Entities::encode($ptr->find_by_tag_name('title')->as_trimmed_text());
283 my $pubdate = $ptr->find_by_tag_name('pubDate')->as_trimmed_text();
284 my $description = HTML::Entities::encode($ptr->find_by_tag_name('description')->as_trimmed_text());
285 my $subtitle = HTML::Entities::encode($ptr->find_by_tag_name('itunes:subtitle')->as_trimmed_text());
286 my $contenturl = $ptr->find_by_tag_name('link')->as_trimmed_text();
287 my $duration = $ptr->find_by_tag_name('itunes:duration')->as_trimmed_text();
290 my $author = $ptr->find_by_tag_name('author')->as_trimmed_text();
292 my $raw_episode = $ptr->find_by_tag_name('comments')->as_trimmed_text();
293 my @words = split /\//, $raw_episode;
295 foreach my $part (@words)
300 my $epoch = str2time($pubdate);
301 my $dt = DateTime->from_epoch(epoch => $epoch);
302 my $format = '%Y/%m/%d';
303 my $timestamp = $dt->strftime($format);
304 $pubdate = $timestamp;
308 my ($width, $height);
309 my $tmp_contenturl = $contenturl;
310 $tmp_contenturl =~ /_(\d\d\d\d)x(\d\d\d)_/;
317 $tmp_contenturl = $contenturl;
318 $tmp_contenturl =~ /_(\d\d\d)x(\d\d\d)_/;
324 my $titleresolution = "$pubdate [EP#$episode] - $subtitle";
325 printf "DEBUG:builditems:ptr = [%s]\n", $titleresolution;
326 push(@{$diritemsref->{$dir}}, {
327 'dirthumbnail' => $thumbnail,
328 'title' => $titleresolution,
329 'mythtv:subtitle' => "",
331 'pubDate' => $pubdate,
332 'description' => $description,
333 'link' => $raw_episode,
334 'player' => mnvgetconfig('player'),
335 'playerargs' => mnvgetconfig('playerargs'),
336 'download' => mnvgetconfig('download'),
337 'downloadargs' => mnvgetconfig('downloadargs'),
338 'media:thumbnailurl' => $thumbnail,
339 'media:contenturl' => $contenturl,
340 'media:contentlength' => "",
341 'media:contentduration' => $duration,
342 'media:contentwidth' => $width,
343 'media:contentheight' => $height,
344 'media:contentlanguage' => "eng",
346 'mythtv:country' => "usa",
347 'mythtv:season' => "",
348 'mythtv:episode' => $episode,
349 'mythtv:customhtml' => "no"
356 #################################### Main #####################################
357 # If you copy this for another site, hopefully these won't need to changed
361 ($mnvcommonsubs::netvisionver == 23) and print "$site|TS\n";
362 ($mnvcommonsubs::netvisionver > 23) and mnvprintversion($site, $command, $author, $commandthumbnail, $version, $description);
366 my $type; my $page = 1; my $search = "";
372 ($opt_p) and $page = $opt_p;
374 print STDERR "Must have -T or -S option\n";
378 $SIG{'INT'} = \&mnvcleanexit;
379 $SIG{'HUP'} = \&mnvcleanexit;
380 $SIG{'TERM'} = \&mnvcleanexit;
381 $SIG{'QUIT'} = \&mnvcleanexit;
383 my $diritemsref = \%diritems;
384 my $totalitems = 0; my $filtereditems = 0;
385 my $ss = stat($store);
386 if (($ss) && (time() - $ss->mtime) < mnvgetconfig('cachetime')) {
387 eval { $diritemsref = retrieve($store); };
389 die "Could not load store, $@";
391 $totalitems = mnvnumresults($diritemsref);
392 mnvinfomsg(1, "Using previous run data");
394 printf "DEBUG: calling builddiritems\n";
395 $totalitems = builddiritems($diritemsref, $feedsurl);
396 printf "DEBUG: called builddiritems : totalitems = %d\n", $totalitems;
398 printf "DEBUG: storing items\n";
399 eval { store($diritemsref, $store); };
401 warn "Could not save store, $@";
403 printf "DEBUG: stored items\n";
408 <title>'.$site.'</title>
409 <link>'.$baseurl.'</link>
410 <description>'.$description.'</description>'."\n";
411 if ($type eq "search") {
412 $filtereditems = mnvfilter($diritemsref, $search);
413 mnvprintsearch($diritemsref, $page);
414 mnvinfomsg(1, "Total Items match $filtereditems of $totalitems");
416 mnvprinttree($diritemsref, 4);
417 mnvinfomsg(1, "Total Items found $totalitems");
419 print "</channel>\n";