Youtube: Add support for adaptive video formats (split video/audio)
[videosite.git] / videosite / FileGetter.pm
1 # (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # A getter which will download the media to a local file storage
5 #
6
7 package videosite::FileGetter;
8
9 use videosite::GetterBase;
10 @ISA = qw(videosite::GetterBase);
11
12 use strict;
13 use File::Basename;
14
15 sub new {
16     my $class = shift;
17     my $self = $class->SUPER::new(
18         NAME => 'filegetter',
19         _PARAMS => {
20             MINFREE => ['500000', 'The amount of space that needs to be available on the filesystem before the video is downloaded (in kilobytes)'],
21             FILEPATTERN => ['/tmp/%s - %s - %s.flv', "The file name to save the file under. This is a string which is passed to a sprintf call later on. The parameters passed to that sprintf call, in order, are:\n- The site the video is from\n- The ID of the video\n- The title of the video\n- The URL of the video file itself\n- The URL of the site the video was taken from\nAll parameters are encoded (space and / replaced by _)"]
22         },
23         @_,
24     );
25
26     return bless($self, $class);
27 }
28
29 sub get {
30     my $self = shift;
31     my $video = shift;
32     my $dlfile;
33     my $dirname;
34     my $ua;
35     my $res;
36
37     $dlfile = sprintf($self->_getval('FILEPATTERN'),
38         $self->_encode($video->{'SOURCE'}),
39         $self->_encode($video->{'ID'}),
40         $self->_encode($video->{'TITLE'}),
41         $self->_encode($video->{'DLURL'}),
42         $self->_encode($video)->{'URL'});
43
44     $dirname = dirname($dlfile);
45     if ($self->_diskfree($dirname) < $self->_getval('MINFREE')) {
46         $self->error("Not enough free space to download");
47         return 0;
48     }
49
50     if (exists($video->{'CONNECTOR'})) {
51         $self->selectconn($video->{'CONNECTOR'});
52     }
53     $ua = $self->ua();
54
55     $self->debug('Going to download %s to %s', $video->{'DLURL'}, $dlfile);
56
57     $res = $ua->mirror($video->{'DLURL'}, $dlfile);
58     if (!$res->is_success()) {
59         $self->error('Could not download %s to %s (%s)', $video->{'DLURL'}, $dlfile, $res->code());
60         return 0;
61     }
62
63     if (exists($video->{'DLURL_AUDIO'})) {
64         $dlfile = $dlfile . ".audio";
65         $self->debug('Going to download %s to %s', $video->{'DLURL_AUDIO'}, $dlfile);
66
67         $res = $ua->mirror($video->{'DLURL_AUDIO'}, $dlfile);
68         if (!$res->is_success()) {
69             $self->error('Could not download %s to %s (%s)', $video->{'DLURL_AUDIO'}, $dlfile, $res->code());
70             return 0;
71         }
72     }
73
74     return 1;
75 }
76
77
78 sub _encode {
79     my $self = shift;
80     my $s = shift;
81
82     $s =~ s|[/ ]|_|g;
83
84     return $s;
85 }
86
87 sub _diskfree {
88
89     # poor man's df
90     # if you want it portable, use Filesys::Statvfs
91
92     my $self = shift;
93     my $dir = shift;
94     my $size;
95
96     open DF, "df -P $dir|" or return 0;
97     my $line = <DF>; # skip header
98
99     if ( $line = <DF> ) {
100         if ($line =~ /\s(\d+)\s+\d{1,3}% (\/.*)$/) {
101             $size = $1;
102         }
103     } else {
104         $size = -1; #some error occurred
105     }
106
107     close DF;
108     return $size;
109 }