1 # -*- coding: ascii -*-
2 ###########################################################################
3 # clive, command line video extraction utility.
4 # Copyright 2007, 2008, 2009 Toni Gundogdu.
6 # This file is part of clive.
8 # clive is free software: you can redistribute it and/or modify it under
9 # the terms of the GNU General Public License as published by the Free
10 # Software Foundation, either version 3 of the License, or (at your option)
13 # clive is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 # You should have received a copy of the GNU General Public License along
19 # with this program. If not, see <http://www.gnu.org/licenses/>.
20 ###########################################################################
26 use base
'Class::Singleton';
36 return bless( {}, $class );
42 clive
::Config
->instance->init;
43 clive
::Curl
->instance->init;
44 clive
::Log
->instance->init;
45 clive
::Cache
->instance->init;
46 clive
::Exec
->instance->init;
50 exit(clive
::Log
->instance->errorOccurred);
58 my $config = clive
::Config
->instance->config;
60 # Read from recall file.
61 if ( $config->{recall
} and -e
$config->{recall_file
} ) {
62 if ( open( my $fh, "<", $config->{recall_file
} ) ) {
63 _parseLine
( $self, $_ ) while (<$fh>);
67 clive
::Log
->instance->errn("$config->{recall_file}: $!");
72 if ( $config->{cache_grep
} ) {
73 my $cache = clive
::Cache
->instance;
74 foreach ( @
{ $cache->grepQueue } ) {
75 push( @
{ $self->{queue
} }, $_ );
80 _parseLine
( $self, $_ ) foreach (@ARGV);
83 if ( scalar( @
{ $self->{queue
} } ) == 0
84 && scalar( @ARGV == 0 ) )
86 _parseLine
( $self, $_ ) while (<STDIN
>);
89 my $cache = clive
::Cache
->instance;
90 my $curl = clive
::Curl
->instance;
91 my $log = clive
::Log
->instance;
93 require clive
::HostFactory
;
96 foreach ( @
{ $self->{queue
} } ) {
97 my $host = clive
::HostFactory
->new($_);
99 my $props = clive
::Video
->new;
100 $props->page_link($_);
105 if ( $cache->enabled() && $config->{cache_read
} ) {
106 $rc = $cache->read( \
$props );
107 if ( $rc == 1 && $props->video_format() ne $config->{format
} )
110 # Cache: video format != requested format -> re-fetch.
115 # Cache failed or record did not exist. Fetch the video page.
119 $rc = $curl->fetchToMem( $props->page_link, \
$content );
123 $props->page_title( \
$content );
124 $rc = $host->parsePage( \
$content, \
$props );
127 $rc = $curl->queryFileLength( \
$props );
129 $props->video_format( $config->{format
} );
130 $cache->write( \
$props );
136 # Cache record found.
138 $log->out("cache $_ ...done\n");
142 # If everything went OK so far, proceed to extract etc.
145 push( @
{ $self->{passed_queue
} }, $_ );
147 $props->formatOutputFilename;
149 if ( $props->nothing_todo ) {
151 "file is already fully retrieved; nothing to do");
152 clive
::Exec
->instance->queue( \
$props );
156 if ( $config->{no_extract
} ) {
159 elsif ( $config->{emit_csv
} ) {
163 if ( $curl->fetchToFile( \
$props ) == 0 ) {
164 clive
::Exec
->instance->queue( \
$self, \
$props );
170 $log->err("no support: $_");
174 clive
::Exec
->instance->runExec;
176 # Update recall file.
177 if ( !$log->errorOccurred() ) {
178 if ( open( my $fh, ">", $config->{recall_file
} ) ) {
179 print( $fh "$_\n" ) foreach ( @
{ $self->{passed_queue
} } );
183 $log->errn("$config->{recall_file}: $!");
189 my ( $self, $ln ) = @_;
191 return if $ln =~ /^$/;
192 return if $ln =~ /^#/;
197 if $ln !~ m{^http://}i;
199 # Youtube: youtube-nocookie.com -> youtube.com.
200 $ln =~ s/-nocookie//;
202 # Translate host specific embedded link to video page link.
203 $ln =~ s!/v/!/watch?v=!i; # youtube
204 $ln =~ s!googleplayer.swf!videoplay!i; # googlevideo
205 $ln =~ s!/pl/!/videos/!i; # sevenload
206 $ln =~ s!/e/!/view?i=!i; # liveleak
208 # Lastfm demystifier.
209 if ( $ln =~ /last\.fm/ ) {
212 clive
::Log
->instance->errn("no support: $ln");
215 $ln = "http://youtube.com/watch?v=$1";
218 push( @
{ $self->{queue
} }, $ln );
222 require clive
::HostFactory
;
223 clive
::HostFactory
->dumpHosts();
229 # I am the man who walks alone.