2 # -*- coding: ascii -*-
4 # Copyright (C) 2010 Toni Gundogdu.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 use version
0.77 (); our $VERSION = version
->declare("2.3.1");
25 binmode STDOUT
, ":utf8";
26 binmode STDERR
, ":utf8";
28 use Getopt
::ArgvFile
qw(argvFile);
30 use Getopt
::Long
qw(:config bundling);
31 use Encode
qw(decode_utf8);
41 return process_queue
();
46 if ( grep { $_ eq "--config-file" } @ARGV ) {
47 argvFile
( fileOption
=> '--config-file' );
55 "@/usr/local/share/clive/cliverc",
56 "@/usr/share/clive/cliverc",
58 "@/etc/xdg/clive/clive.conf",
59 "@/etc/xdg/clive.conf"
67 '@' . "$ENV{HOME}/.cliverc",
68 '@' . "$ENV{HOME}/.clive/config",
69 '@' . "$ENV{HOME}/.config/clive/config"
74 push @ARGV, '@' . "$ENV{CLIVE_CONFIG}" if $ENV{CLIVE_CONFIG
};
82 'help' => \
&print_help
,
83 'version' => \
&print_version
,
84 'license' => \
&print_license
,
87 'output_file|output-file|O=s',
88 'no_download|no-download|n',
92 'get_with|get-with=s',
93 'filename_format|filename-format=s',
98 $config{format
} ||= 'default';
99 $config{filename_format
} ||= '%t.%s';
100 $config{regexp
} ||= '/(\\w|\\s)/g';
105 Carp
::croak
"error: specify path to quvi(1) command with --quvi"
106 unless $config{quvi
};
111 "error: specify path to a download command with --get-with\n"
112 unless $config{get_with
};
117 add_queue
($_) foreach @ARGV;
119 if ( scalar @queue == 0 ) { add_queue
($_) while <STDIN
>; }
121 @queue = uniq2
(@queue); # Remove duplicate URLs.
124 $| = 1; # Go unbuffered.
129 my $ln = trim
(shift);
132 return if $ln =~ /^$/;
133 return if $ln =~ /^#/;
135 $ln = "http://$ln" if $ln !~ m{^http://}i;
140 sub uniq2
{ # http://is.gd/g8jQU
144 unless ( $seen{$a} ) {
156 my $n = scalar @queue;
163 print_checking
( ++$i, $n );
165 my $q = $config{quvi
};
167 $q .= " -q" if $q !~ /-q/; # Force --quiet.
168 $q .= " -f $config{format}";
170 my $o = join '', qx/$q/;
176 $video = JSON
::XS
::decode_json
($o);
178 print "done.\n" unless $config{quiet
};
180 ( $r, $fpath ) = get_video
();
183 if ( $config{exec} ) { $r = invoke_exec
($fpath); }
192 return if $config{quiet
};
196 print "($i of $n) " if $n > 1;
197 print "Checking ...";
202 require File
::Basename
;
204 my $fpath = get_filename
();
205 my $fname = File
::Basename
::basename
($fpath);
207 if ( $config{no_download
} ) { print_video
($fname); return 0; }
209 write_video
( $fpath, $fname );
216 my $e = $config{exec};
217 $e =~ s/%f/"$fpath"/g;
224 sub to_mb
{ (shift) / ( 1024 * 1024 ); }
227 printf "%s %.2fM [%s]\n",
229 to_mb
( $video->{link}[0]->{length_bytes
} ),
230 $video->{link}[0]->{content_type
};
235 my ( $fpath, $fname ) = @_;
237 my $g = $config{get_with
};
238 $g =~ s/%u/"$video->{link}[0]->{url}"/g;
239 $g =~ s/%f/"$fpath"/g;
240 $g =~ s/%n/"$fname"/g;
251 if ( $config{output_file
} ) { $fpath = $config{output_file
}; }
252 else { $fpath = apply_output_path
( apply_filename_format
() ); }
257 sub apply_output_path
{
262 my $cwd = decode_utf8
(Cwd
::getcwd
);
265 require File
::Spec
::Functions
;
267 File
::Spec
::Functions
::catfile
( $cwd, $fname );
270 sub apply_filename_format
{
272 return $config{output_filename
}
273 if $config{output_filename
};
275 my $title = trim
( apply_regexp
( $video->{page_title
} ) );
276 my $fname = $config{filename_format
};
278 $fname =~ s/%s/$video->{link}[0]->{file_suffix}/g;
279 $fname =~ s/%h/$video->{host}/g if $video->{host
}; # quvi 0.2.8+
280 $fname =~ s/%i/$video->{id}/g;
281 $fname =~ s/%t/$title/g;
296 my ( $title, $rq ) = ( shift, qr
|^/(.*)/(.*)$| );
298 if ( $config{regexp
} =~ /$rq/ ) {
300 return unless $title; # Must be a syntax check.
302 $title = decode_utf8
($title); # Do not touch.
304 my ( $pat, $flags, $g, $i ) = ( $1, $2 );
307 $g = ( $flags =~ /g/ );
308 $i = ( $flags =~ /i/ );
311 $rq = $i ? qr
|$pat|i
: qr
|$pat|;
314 ?
join '', $title =~ /$rq/g
315 : join '', $title =~ /$rq/;
319 "invalid syntax (`$config{regexp}'), expected Perl like syntax "
320 . "`/pattern/flags', e.g. `/(\\w)/g'";
327 if ( $config{format
} eq "help" ) {
329 --format arg get format arg
330 --format list list websites and supported formats
331 --format list arg match arg to websites, list formats for matches
333 --format mp4_360p get format mp4_360p (youtube)
334 --format list youtube list youtube formats
335 --format list dailym list dailym(otion) formats
340 elsif ( $config{format
} eq "list" ) {
342 my $q = ( split /\s+/, $config{quvi
} )[0]; # Improve this.
345 foreach (qx/$q --support/) {
346 my ( $k, $v ) = split /\s+/, $_;
351 if ( scalar @ARGV > 0 ) {
353 foreach ( sort keys %h ) {
354 print "$_:\n $h{$_}\n" if $_ =~ /$ARGV[0]/;
362 print "$_:\n $h{$_}\n\n" foreach sort keys %h;
370 Pod
::Usage
::pod2usage
( -exitstatus
=> 0, -verbose
=> 1 );
374 print "clive version $VERSION\n";
379 print "# Copyright (C) 2010 Toni Gundogdu.
381 # This program is free software: you can redistribute it and/or modify
382 # it under the terms of the GNU General Public License as published by
383 # the Free Software Foundation, either version 3 of the License, or
384 # (at your option) any later version.
386 # This program is distributed in the hope that it will be useful,
387 # but WITHOUT ANY WARRANTY; without even the implied warranty of
388 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
389 # GNU General Public License for more details.
391 # You should have received a copy of the GNU General Public License
392 # along with this program. If not, see <http://www.gnu.org/licenses/>.
401 clive [E<lt>optionsE<gt>] [E<lt>urlE<gt> ...]
405 --help print help and exit
406 --version print version and exit
407 --license print license and exit
408 --quiet turn off all output excl. errors
409 -f, --format arg (=default) download video format
410 -O, --output-file arg write downloaded video to file
411 -n, --no-download do not download video, print info only
412 --config-file arg file to read clive arguments from
414 --quvi arg path to quvi(1) with additional args
415 --get-with arg path to download command with args
416 --filename-format arg (=%t.%s) output video filename format
417 --regexp arg (=/(\w|\s)/g) regexp to clean up video title
418 --exec arg invoke arg when download finishes
422 # vim: set ts=4 sw=4 tw=72 expandtab: