MythTV  master
mnvcommonsubs.pm
Go to the documentation of this file.
1 # @(#)$Header: /home/mythtv/mythtvrep/scripts/nv_perl_libs/mnvcommonsubs.pm,v 1.10 2010/07/25 00:11:35 mythtv Exp $
2 # Auric 2010/01/10 http://web.aanet.com.au/auric/
3 #
4 # MythNetvision Grabber Script utility subs
5 #
6 #################################### Util Subs ############################################
7 
8 package mnvcommonsubs;
9 
10 use strict;
11 use warnings;
12 use HTML::Entities;
13 use Encode;
14 use LWP::Simple;
15 use File::stat;
16 use File::Basename;
17 use Sys::Hostname;
18 # mythbackend sets HOME and MYTHCONFDIR to /var/lib/mythtv.
19 # So have to hack it back to the real home for require MythTV to work.
20 $ENV{'HOME'} = (getpwuid $>)[7];
21 delete $ENV{'MYTHCONFDIR'};
22 require MythTV;
23 use Image::Magick;
24 use File::Copy;
25 
26 our(@ISA, @EXPORT, @EXPORT_OK, $VERSION);
27 $VERSION = '$Revision: 1.10 $'; $VERSION =~ s/\D*([\d\.]+)\D*/$1/; # rcs tag populated
28 
29 require Exporter;
30 @ISA = qw(Exporter);
31 @EXPORT = qw(mnvURLEncode mnvprintversion mnvcleanexit mnvinfomsg mnvcleantext mnvnumresults mnvfilter
32  mnvprinttree mnvprintsearch mnvrssitem2mnv mnvistype mnvgetsetting mnvgeticonDir mnvrssheader mnvrssfooter
33  mnvgetflashplayerurl mnvloadconfig mnvgetconfig mnvsetconfig);
34 @EXPORT_OK = qw(); # symbols to export on request
35 
36 my $mythobj;
37 eval { $mythobj = MythTV->new(); };
38 ($@) and die("Could not create MythTV-new() $@");
39 
40 # Netvision version access as $mnvcommonsubs::netvisionver
41 our $netvisionver = mnvgetnetvisionver();
42 
43 # Get a mnv configuration
44 # Default config values. These can be overridded by mnvsetconfig
45 our %config = (
46  'mnvinfo' => 0,
47  'mnvinfoop' => "",
48  'player' => "",
49  'playerargs' => "",
50  'download' => "",
51  'downloadargs' => "",
52  # A network player like a flash or html5 html. TODO 0.24 May not be approved
53  'netplayer' => "",
54  'netplayertype' => "",
55  # Seconds to cache results
56  'cachetime' => 72000,
57  'defaultautoplay' => 'autostart=1&autoplay=1'
58 );
59 
60 sub mnvgetconfig {
61  my $value = shift @_;
62 
63  return $config{$value};
64 }
65 
66 # Set a mnv configuration
67 sub mnvsetconfig {
68  my $value = shift @_;
69  my $data = shift @_;
70 
71  if (ref($config{$value}) eq "ARRAY") {
72  push(@{$config{$value}}, $data);
73  } else {
74  $config{$value} = $data;
75  }
76 }
77 
78 # Load a mnv configuration file
79 # $ENV{'HOME'}/.mythtv/MythNetvision/userGrabberPrefs/${configfile}.cfg
80 # INI Format
81 # # Default
82 # player=mplayer
83 # feedurl+url1 (Creates a array feedurl of all the entries)
84 # feedurl+url2
85 # # Section Specific
86 # [Section A]
87 # player=vlc
88 # [Section B]
89 # player=xine
90 sub mnvloadconfig {
91  my $configfile = shift @_;
92  my $section = shift @_;
93 
94  my $cfile = "/$ENV{'HOME'}/.mythtv/MythNetvision/userGrabberPrefs/${configfile}.cfg";
95  my $ss = stat($cfile);
96  if ($ss) {
97  open(CF, "<$cfile") or warn "Could not load $cfile";
98  my $in = 1; # In default section
99  while(<CF>) {
100  chomp;
101  /^\s*#/ and next;
102  s/\s*=\s*/=/g;
103  if ($in == 1 && /=/) {
104  my ($value, @data) = split('=', $_);
105  $config{$value} = join('=', @data);
106  next;
107  }
108  s/\s*\+\s*/\+/g;
109  if ($in == 1 && /\+/) {
110  my ($value, @data) = split('\+', $_);
111  push(@{$config{$value}}, join('+', @data));
112  next;
113  }
114  if (/^\s*\[(.*)\]\s*$/) {
115  if ($1 eq $section) {
116  $in = 1;
117  } else {
118  $in = 0;
119  }
120  }
121  }
122  close(CF);
123  }
124 }
125 
126 # Get a mythdb setting
127 sub mnvgetsetting {
128  my $setting = shift @_;
129  my $hostname = shift @_;
130 
131  my $data;
132  if ($hostname) {
133  $data = $mythobj->backend_setting($setting, $hostname);
134  } else {
135  $data = $mythobj->backend_setting($setting);
136  }
137 
138  return $data;
139 }
140 
141 # Find netvision version
142 sub mnvgetnetvisionver {
143 
144  my $netvisionver = "NA";
145  my $printerror = $mythobj->{'dbh'}->{'PrintError'};
146  my $printwarn = $mythobj->{'dbh'}->{'PrintWarn'};
147  $mythobj->{'dbh'}->{'PrintError'} = 0;
148  $mythobj->{'dbh'}->{'PrintWarn'} = 0;
149  eval { $mythobj->{'dbh'}->do("select count(*) from internetcontent where 1=0") };
150  unless ($mythobj->{'dbh'}->err) {
151  $netvisionver = "24";
152  } else {
153  eval { $mythobj->{'dbh'}->do("select count(*) from netvisiontreegrabbers where 1=0") };
154  unless ($mythobj->{'dbh'}->err) {
155  $netvisionver = "23";
156  }
157  }
158  $mythobj->{'dbh'}->{'PrintError'} = $printerror;
159  $mythobj->{'dbh'}->{'PrintWarn'} = $printwarn;
160 
161  return $netvisionver;
162 }
163 
164 # Find netvision icon directory
165 sub mnvgeticonDir {
166 
167  # 0.23 mythnetvision.iconDir. 0.24 %SHAREDIR%
168  my $icondir = mnvgetsetting('mythnetvision.iconDir', hostname());
169  ($icondir) and return $icondir;
170  return "%SHAREDIR%/mythnetvision/icons";
171 }
172 
173 # Encode a string
174 sub mnvURLEncode {
175  my $theURL = shift @_;
176 
177  $theURL =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
178  return $theURL;
179 }
180 
181 # print or return a typical <rss...> header
182 #
183 # in list context, return a list of lines with the header in it
184 # in scalar context, return as a string
185 # in void context, print the header to stdout
186 #
187 sub mnvrssheader {
188 
189  my $header='<?xml version="1.0" encoding="UTF-8"?>
190 <rss version="2.0"
191 xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
192 xmlns:content="http://purl.org/rss/1.0/modules/content/"
193 xmlns:cnettv="http://cnettv.com/mrss/"
194 xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
195 xmlns:media="http://search.yahoo.com/mrss/"
196 xmlns:atom="http://www.w3.org/2005/Atom"
197 xmlns:amp="http://www.adobe.com/amp/1.0"
198 xmlns:dc="http://purl.org/dc/elements/1.1/"
199 xmlns:mythtv="http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format">
200 ';
201 
202  if(wantarray()) {
203  return split(/\n/,$header);
204  } elsif(defined wantarray()) {
205  return $header;
206  } else {
207  print $header;
208  }
209 }
210 
211 # print or return a typical </rss> footer to close out an rss block
212 #
213 # in list context, return a list of lines with the footer in it
214 # in scalar context, return as a string
215 # in void context, print the header to stdout
216 sub mnvrssfooter {
217 
218  my $footer="</rss>\n";
219  if(wantarray()) {
220  return split(/\n/,$footer);
221  } elsif(defined wantarray()) {
222  return $footer;
223  } else {
224  print $footer;
225  }
226 }
227 
228 sub mnvprintversion {
229  my $site = shift @_;
230  my $command = shift @_;
231  my $author = shift @_;
232  my $commandthumbnail = shift @_;
233  my $version = shift @_;
234  my $description = shift @_;
235 
236  print '<grabber>'."\n";
237  print ' <name>'.$site.'</name>'."\n";
238  print ' <command>'.$command.'</command>'."\n";
239  print ' <author>'.$author.'</author>'."\n";
240  print ' <thumbnail>'.$commandthumbnail.'</thumbnail>'."\n";
241  print ' <type>video</type>'."\n";
242  print ' <description>'.$description.'</description>'."\n";
243  print ' <version>'.$version.'</version>'."\n";
244  print ' <search>true</search>'."\n";
245  print ' <tree>true</tree>'."\n";
246  print '</grabber>'."\n";
247 }
248 
249 # Download a icon from url
250 sub downloadicon {
251  my $url = shift @_;
252  my $name = shift @_;
253  my $icondir = shift @_;
254 
255  # Only works for 0.23
256  #my $icondir = mnvgeticonDir();
257 
258  my $ss = stat("${icondir}/${name}");
259  ($ss) and return "${icondir}/${name}";
260 
261  my @imgexts = ('jpg', 'jpeg', 'png', 'gif');
262  my $nameext = (fileparse($name, @imgexts))[2];
263  my $urlext = (fileparse($url, @imgexts))[2];
264 
265  mnvinfomsg(1, "Getting $url");
266  my $content = get($url);
267  unless ($content) {
268  die "Could not retrieve $url";
269  }
270 
271  open(IC, ">${icondir}/.tmp") or return 0;
272  print IC $content;
273  close(IC);
274 
275  if ($urlext eq $nameext) {
276  copy("${icondir}/.tmp", "${icondir}/${name}");
277  } else {
278  my $image=Image::Magick->new;
279  $image->Read(filename=>"${icondir}/.tmp");
280  $image->Write(filename=>"${icondir}/${name}");
281  }
282  unlink("${icondir}/.tmp");
283 
284  mnvinfomsg(1, "Saved icon ${icondir}/${name}");
285  return "${icondir}/${name}";
286 }
287 
288 sub mnvcleanexit {
289  my $esig = shift @_;
290 
291  fileno(FH) and close(FH);
292  if ($esig =~ /\D/) {
293  # called by signalhandler
294  exit 1;
295  } else {
296  exit $esig;
297  }
298 }
299 
300 # Debug/Info message
301 # $config{'mnvinfo'} specifies level of messages to print
302 # $config{'mnvinfoop'} specifies o/p file
303 sub mnvinfomsg {
304  my $level = shift @_;
305  my $mesg = shift @_;
306 
307  ($config{'mnvinfo'} < $level) and return;
308  $mesg = encode('utf8', $mesg);
309  if ($config{'mnvinfoop'} =~ /\D/) {
310  open(FH, ">$config{'mnvinfoop'}") unless fileno(FH);
311  my $t = localtime();
312  print FH "$t $level $mesg\n";
313  } else {
314  print STDERR "$mesg\n";
315  }
316 }
317 
318 # Clean and encode a string
319 sub mnvcleantext {
320  my $text = shift @_;
321 
322  ($text) or return;
323  $text =~ s/\n/ /g;
324  $text =~ s/^\s+|\s+$//g;
325  $text = encode_entities($text);
326  return $text;
327 }
328 
329 # Number of items found
330 sub mnvnumresults {
331  my $diritemsref = shift @_;
332 
333  my $nr = 0;
334  foreach my $dir (keys(%$diritemsref)) {
335  (@{$diritemsref->{$dir}}) or next;
336  foreach my $item (@{$diritemsref->{$dir}}) {
337  ($item) or next; # somewhere I get null references.
338  $nr += 1;
339  }
340  }
341  return $nr;
342 }
343 
344 # filter the items hash
345 # input hash ref produced by builditems
346 # output number of items
347 sub mnvfilter {
348  my $diritemsref = shift @_;
349  my $search = shift @_;
350 
351  my $filtereditems = 0;
352 
353  foreach my $dir (keys(%$diritemsref)) {
354  for (my $c = 0; $c <= $#{$diritemsref->{$dir}}; $c++) {
355  if (${$diritemsref->{$dir}}[$c]->{'title'} =~ /$search/i || ${$diritemsref->{$dir}}[$c]->{'author'} =~ /$search/i ||
356  ${$diritemsref->{$dir}}[$c]->{'description'} =~ /$search/i || ${$diritemsref->{$dir}}[$c]->{'link'} =~ /$search/i) {
357  $filtereditems++;
358  mnvinfomsg(2, "Saved $dir ".${$diritemsref->{$dir}}[$c]->{'title'});
359  } else {
360  mnvinfomsg(2, "Deleted $dir ".${$diritemsref->{$dir}}[$c]->{'title'});
361  delete(${$diritemsref->{$dir}}[$c]);
362  }
363  }
364  }
365  return $filtereditems;
366 }
367 
368 # Print a item
369 sub printitem {
370  my $item = shift @_;
371 
372  print " ".'<item>'."\n";
373  print " ".'<title>'.$item->{'title'}.'</title>'."\n";
374  print " ".'<mythtv:subtitle>'.$item->{'mythtv:subtitle'}.'</mythtv:subtitle>'."\n";
375  print " ".'<author>'.$item->{'author'}.'</author>'."\n";
376  print " ".'<pubDate>'.$item->{'pubDate'}.'</pubDate>'."\n";
377  print " ".'<description>'.$item->{'description'}.'</description>'."\n";
378  print " ".'<link>'.$item->{'link'}.'</link>'."\n";
379  print " ".'<player>'.$item->{'player'}.'</player>'."\n";
380  print " ".'<playerargs>'.$item->{'playerargs'}.'</playerargs>'."\n";
381  print " ".'<download>'.$item->{'download'}.'</download>'."\n";
382  print " ".'<downloadargs>'.$item->{'downloadargs'}.'</downloadargs>'."\n";
383  print " ".'<media:group>'."\n";
384  print " ".'<media:thumbnail url="'.$item->{'media:thumbnailurl'}.'"/>'."\n";
385  print " ".'<media:content url="'.$item->{'media:contenturl'}.'" length="'.$item->{'media:contentlength'}.'" duration="'.$item->{'media:contentduration'}.'" width="'.$item->{'media:contentwidth'}.'" height="'.$item->{'media:contentheight'}.'" lang="'.$item->{'media:contentlanguage'}.'"/>'."\n";
386  print " ".'</media:group>'."\n";
387  print " ".'<rating>'.$item->{'rating'}.'</rating>'."\n";
388  print " ".'<mythtv:country>'.$item->{'mythtv:country'}.'</mythtv:country>'."\n";
389  print " ".'<mythtv:season>'.$item->{'mythtv:season'}.'</mythtv:season>'."\n";
390  print " ".'<mythtv:episode>'.$item->{'mythtv:episode'}.'</mythtv:episode>'."\n";
391  print " ".'<mythtv:customhtml>'.$item->{'mythtv:customhtml'}.'</mythtv:customhtml>'."\n";
392  print " ".'</item>'."\n";
393  return 1;
394 }
395 
396 # print tree
397 # input hash ref produced by builditems
398 sub mnvprinttree {
399  my $diritemsref = shift @_;
400  my $mostrecentnumber = shift @_;
401 
402  my $icondir = mnvgeticonDir();
403 
404  foreach my $dir (sort(keys(%$diritemsref))) {
405  (@{$diritemsref->{$dir}}) or next;
406  my $dirprinted = 0;
407  if ($mostrecentnumber) {
408  my $printcount = 0;
409  foreach my $item (@{$diritemsref->{$dir}}) {
410  ($item) or next; # somewhere I get null references.
411  if ($dirprinted == 0) {
412  $dirprinted = 1;
413  # Need it here as don't have $item outside loop.
414  print " ".'<directory name="'.mnvcleantext($dir).'" thumbnail="'.$item->{'dirthumbnail'}.'">'."\n";
415  print " ".'<directory name="Most Recent" thumbnail="'.$icondir.'/directories/topics/most_recent.png">'."\n";
416  }
417  printitem($item);
418  $printcount++;
419  ($printcount >= $mostrecentnumber) and last;
420  }
421  print " ".'</directory>'."\n";
422  }
423  foreach my $item (@{$diritemsref->{$dir}}) {
424  ($item) or next; # somewhere I get null references.
425  if ($dirprinted == 0) {
426  $dirprinted = 1;
427  # Need it here as don't have $item outside loop.
428  print " ".'<directory name="'.mnvcleantext($dir).'" thumbnail="'.$item->{'dirthumbnail'}.'">'."\n";
429  }
430  printitem($item);
431  }
432  print " ".'</directory>'."\n";
433  }
434 }
435 
436 # print search
437 # input hash ref produced by builditems
438 sub mnvprintsearch {
439  my $diritemsref = shift @_;
440  my $page = shift @_;
441 
442  my $numresults = mnvnumresults($diritemsref);
443  if ($numresults < 1) {
444  print " ".'<numresults>0</numresults>'."\n";
445  print " ".'<returned>0</returned>'."\n";
446  print " ".'<startindex>0</startindex>'."\n";
447  return;
448  }
449  my $returned;
450  if ($page > 1) {
451  $returned = $numresults - (($page - 1) * 20);
452  } else {
453  $returned = $numresults;
454  }
455  ($returned > 20) and $returned = 20;
456  ($returned < 0) and $returned = 0;
457  my $startindex = ($page * 20) + 1;
458  ($startindex >= $numresults) and $startindex = 0;
459 
460  print " ".'<numresults>'.$numresults.'</numresults>'."\n";
461  print " ".'<returned>'.$returned.'</returned>'."\n";
462  print " ".'<startindex>'.$startindex.'</startindex>'."\n";
463 
464  my $scount = 0; my $ecount = 0;
465 L1: foreach my $dir (sort(keys(%$diritemsref))) {
466  (@{$diritemsref->{$dir}}) or next;
467  foreach my $item (@{$diritemsref->{$dir}}) {
468  ($item) or next; # somewhere I get null references.
469  if ($page > 1 && $scount < (($page - 1) * 20)) {
470  $scount++;
471  next;
472  }
473  $ecount++;
474  printitem($item);
475  ($ecount >= $returned) and last L1;
476  }
477  }
478 }
479 
480 # Parse a rss item.
481 # input default icon
482 # input rss->parse item
483 # output ref to %mnvitem
484 sub mnvrssitem2mnv {
485  my $icon = shift @_;
486  my $item = shift @_;
487 
488  my %mnvitem = (
489  'title' => "",
490  'weburl' => "",
491  'contenturl' => "",
492  'author' => "",
493  'pubDate' => "",
494  'thumbnail' => "",
495  'description' => "",
496  'length' => "",
497  'duration' => "",
498  'rating' => "",
499  'country' => ""
500  );
501 
502  #print Dumper($item);
503 
504  ($item->{'title'}) or return 0;
505  $mnvitem{'title'} = mnvcleantext($item->{'title'});
506 
507  ($item->{'link'}) and $mnvitem{'weburl'} = mnvcleantext($item->{'link'});
508  ($item->{'enclosure'}->{'url'}) and $mnvitem{'contenturl'} = mnvcleantext($item->{'enclosure'}->{'url'});
509  (($mnvitem{'weburl'}) || ($mnvitem{'contenturl'})) or return 0;
510  ($mnvitem{'contenturl'}) or $mnvitem{'contenturl'} = $mnvitem{'weburl'};
511 
512  if ($item->{'itunes'}->{'author'}) {
513  $mnvitem{'author'} = mnvcleantext($item->{'itunes'}->{'author'});
514  } elsif ($item->{'dc'}->{'creator'}) {
515  $mnvitem{'author'} = mnvcleantext($item->{'dc'}->{'creator'});
516  } elsif ($item->{'author'}) {
517  $mnvitem{'author'} = mnvcleantext($item->{'author'});
518  }
519 
520  ($item->{'pubDate'}) and $mnvitem{'pubDate'} = mnvcleantext($item->{'pubDate'});
521 
522  $mnvitem{'thumbnail'} = $icon;
523  if ($item->{'thumbnail'}) {
524  $mnvitem{'thumbnail'} = mnvcleantext($item->{'thumbnail'});
525  } elsif ($item->{'http://blip.tv/dtd/blip/1.0'}->{'smallThumbnail'}) {
526  $mnvitem{'thumbnail'} = mnvcleantext($item->{'http://blip.tv/dtd/blip/1.0'}->{'smallThumbnail'});
527  } elsif ($item->{'media'}->{'thumbnail'}) {
528  # To get this need to hack xml before $rss->parse with following
529  # $content =~ s/<media:thumbnail\s+url=\"([^\"]*)\"\s*\/>/<media:thumbnail>$1<\/media:thumbnail>/g;
530  $mnvitem{'thumbnail'} = mnvcleantext($item->{'media'}->{'thumbnail'});
531  } elsif ($item->{'description'}) {
532  # Sometimes hide thumbernail in description.
533  foreach my $line (split('\n', $item->{'description'})) {
534  $line =~ s/.*src=\"(http:.*\.[jpg][pni][gf])\".*/$1/i and $mnvitem{'thumbnail'} = $line and last;
535  }
536  }
537 
538  if ($item->{'media'}->{'description'}) {
539  $mnvitem{'description'} = $item->{'media'}->{'description'};
540  } elsif ($item->{'itunes'}->{'summary'}) {
541  $mnvitem{'description'} = $item->{'itunes'}->{'summary'};
542  } elsif ($item->{'description'}) {
543  $mnvitem{'description'} = $item->{'description'};
544  }
545  if ($mnvitem{'description'}) {
546  my $scrubber = HTML::Scrubber->new;
547  $scrubber->default(0);
548  $mnvitem{'description'} = $scrubber->scrub($mnvitem{'description'});
549  $mnvitem{'description'} = mnvcleantext($mnvitem{'description'});
550  ($mnvitem{'description'}) or $mnvitem{'description'} = "";
551  $mnvitem{'description'} =~ s/\&nbsp;/ /g;
552  }
553 
554  ($item->{'enclosure'}->{'length'}) and $mnvitem{'length'} = mnvcleantext($item->{'enclosure'}->{'length'});
555  if (($mnvitem{'length'}) && $mnvitem{'length'} < 5000) {
556  $mnvitem{'duration'} = $mnvitem{'length'};
557  $mnvitem{'length'} = "";
558  }
559  if ($item->{'itunes'}->{'duration'}) {
560  my $tmpdur = mnvcleantext($item->{'itunes'}->{'duration'});
561  my $count = $tmpdur =~ s/(:)/$1/g;
562  if ($count == 1) {
563  my ($mins, $secs) = split(':', $tmpdur);
564  (($mins =~ /^\d+$/) && ($secs =~ /^\d+$/)) and $tmpdur = ($mins * 60) + $secs;
565  } elsif ($count == 2) {
566  my ($hours, $mins, $secs) = split(':', $tmpdur);
567  (($hours =~ /^\d+$/) && ($mins =~ /^\d+$/) && ($secs =~ /^\d+$/)) and $tmpdur = ($hours * 60 * 60) + ($mins * 60) + $secs;
568  }
569  (($tmpdur =~ /^\d+$/) && $tmpdur > 0) and $mnvitem{'duration'} = $tmpdur;
570  }
571 
572  if ($item->{'media'}->{'restriction'}) {
573  $mnvitem{'country'} = mnvcleantext($item->{'media'}->{'restriction'});
574  }
575 
576  return \%mnvitem;
577 }
578 
579 # return media type (Not very accurate).
580 sub mnvistype {
581  my $type = shift @_;
582  my $file = shift @_;
583 
584  $file =~ s/redirect\.mp3//g;
585 
586  if ($type eq "flash") {
587  $file =~ /\.flv/i and return 1;
588  $file =~ /\.m[op4][34v]/i and return 1;
589  } elsif ($type eq "html5") {
590  $file =~ /\.m[op4][4v]/i and return 1;
591  $file =~ /\.ogm/i and return 1;
592  $file =~ /\.ogg/i and return 1;
593  } elsif ($type eq "mp4html5") {
594  $file =~ /\.m[op4][4v]/i and return 1;
595  } elsif ($type eq "ogghtml5") {
596  $file =~ /\.ogm/i and return 1;
597  $file =~ /\.ogg/i and return 1;
598  } elsif ($type eq "video") {
599  $file =~ /\.flv/i and return 1;
600  $file =~ /\.m[op4][4v]/i and return 1;
601  $file =~ /\.mpg/i and return 1;
602  $file =~ /\.mpeg/i and return 1;
603  $file =~ /\.mkv/i and return 1;
604  $file =~ /\.avi/i and return 1;
605  $file =~ /\.wmv/i and return 1;
606  $file =~ /\.as[xf]/i and return 1;
607  $file =~ /\.divx/i and return 1;
608  $file =~ /\.ogm/i and return 1;
609  } elsif ($type eq "audio") {
610  $file =~ /\.m4[ab]/i and return 1;
611  $file =~ /\.mp[23]/i and return 1;
612  $file =~ /\.og[ag]/i and return 1;
613  $file =~ /\.aac/i and return 1;
614  $file =~ /\.ram/i and return 1;
615  $file =~ /\.rm/i and return 1;
616  $file =~ /\.wav/i and return 1;
617  $file =~ /\.flac/i and return 1;
618  $file =~ /\.mka/i and return 1;
619  $file =~ /\.au/i and return 1;
620  }
621  return 0;
622 }
623 
624 1;