2 # -*- coding: ascii -*-
5 # Copyright (C) 2010,2011 Toni Gundogdu <legatvs@gmail.com>
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 use version
0.77 (); our $VERSION = version
->declare("0.0.7");
26 binmode STDOUT
, ":utf8";
27 binmode STDERR
, ":utf8";
29 use Getopt
::ArgvFile
( home
=> 1, startupFilename
=> [qw(.grakerc)] );
30 use Getopt
::Long
qw(:config bundling);
46 'version' => \
&print_version
,
47 'license' => \
&print_license
,
48 'help' => \
&print_help
,
51 $config{title
} ||= $config{json
};
52 $config{title
} ||= $config{csv
};
56 print "grake version $VERSION\n";
61 print "# Copyright (C) 2010,2011 Toni Gundogdu.
63 # This program is free software: you can redistribute it and/or modify
64 # it under the terms of the GNU General Public License as published by
65 # the Free Software Foundation, either version 3 of the License, or
66 # (at your option) any later version.
68 # This program is distributed in the hope that it will be useful,
69 # but WITHOUT ANY WARRANTY; without even the implied warranty of
70 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71 # GNU General Public License for more details.
73 # You should have received a copy of the GNU General Public License
74 # along with this program. If not, see <http://www.gnu.org/licenses/>.
81 Pod
::Usage
::pod2usage
( -exitstatus
=> 0, -verbose
=> 1 );
91 print_help
() unless scalar @ARGV;
93 print STDERR
"Checking ..." unless $config{quiet
};
97 my $a = new LWP
::UserAgent
;
99 $a->env_proxy; # http://search.cpan.org/perldoc?LWP::UserAgent
101 $a->proxy( 'http', $config{proxy
} ) if $config{proxy
};
102 $a->no_proxy('') if $config{no_proxy
};
106 my $q = qr{v[=/]((?>[-_\w]{11}))};
112 unless ( $r->is_success ) {
113 printf STDERR
"\nerror: $_: %s\n", $r->status_line;
117 my $d = URI
::Escape
::uri_unescape
( $r->content );
118 @ids = uniq2
( ( @ids, $d =~ /$q/g ) );
120 print STDERR
"." unless $config{quiet
};
123 unless ( scalar @ids ) {
124 print STDERR
"error: nothing found.\n";
127 else { print STDERR
"done.\n" unless $config{quiet
}; }
129 if ( $config{title
} ) {
130 print STDERR
":: Getting video title ..." unless $config{quiet
};
133 foreach my $id (@ids) {
137 url
=> "http://youtube.com/watch?v=$id",
138 gvi
=> "http://www.youtube.com/get_video_info?&video_id=$id"
139 . "&el=detailpage&ps=default&eurl=&gl=US&hl=en",
144 $tmp{title
} = get_title
( $a, \
%tmp ) if $config{title
};
149 if ( $config{title
} ) {
150 print STDERR
"done.\n" unless $config{quiet
};
153 prompt
() if $config{interactive
};
155 if ( $config{json
} ) { print qq/{\n "video": [\n/; }
161 if ( $_->{selected
} or not $config{interactive
} ) {
165 my $t = $_->{title
} || "";
168 if ( $config{json
} ) {
170 print ",\n" if $i > 1;
173 . qq/ "title": "$t",\n/
174 . qq/ "url": "$_->{url}"\n/ . " }",
178 elsif ( $config{csv
} ) { print qq/"$t","$_->{url}"\n/; }
180 else { print "$_->{url}\n"; }
186 if ( $config{json
} ) { print "\n ]\n}\n"; }
193 my ( $a, $video ) = @_;
195 my $r = $a->get( $$video{gvi
} );
197 unless ( $r->is_success ) {
198 printf STDERR
"\nerror: $$video{url}: %s\n", $r->status_line;
204 my $q = CGI
->new( $r->content );
208 if ( $q->param('reason') ) {
209 printf STDERR
"\nerror: %s: %s (errorcode: %d)\n",
210 $$video{url
}, trim
( $q->param("reason") ),
211 $q->param("errorcode");
215 $title = trim
( Encode
::decode_utf8
( $q->param('title') ) );
216 print STDERR
"." unless $config{quiet
};
230 sub uniq2
{ # http://is.gd/g8jQU
234 unless ( $seen{$a} ) {
251 'n' => \
&select_none
,
252 'i' => \
&invert_selection
,
257 "Enter prompt. Type \"help\" to get a list of commands.\n";
262 while ( not $done ) {
271 if ( $ln =~ /(\d+)/ ) { toggle_caption
($1); }
274 next unless $ln =~ /(\w)/;
275 $cmds{$1}() if defined $cmds{$1};
283 print STDERR
"Commands:
285 list .. display found links (> indicates selected for download)
288 invert .. invert selection
289 (number) .. toggle caption
290 dump .. dump selected links and exit
291 quit .. quit without dumping links\n"
292 . qq/Command name abbreviations are allowed, e.g. "h" instead of "help"\n/;
300 printf STDERR
"%2s%02d: %s\n", $_->{selected
}
304 $_->{title
} || $_->{url
};
309 $_->{selected
} = 1 foreach @links;
314 $_->{selected
} = 0 foreach @links;
318 sub invert_selection
{
319 $_->{selected
} = not $_->{selected
} foreach @links;
323 sub dump { $done = 1; }
327 if ( $i >= 0 && exists $links[$i] ) {
328 $links[$i]->{selected
} = not $links[$i]->{selected
};
331 else { print STDERR
"error: out of range\n"; }
338 grake [-q] [-i] [-t] [--csv | --json] [--proxy E<lt>addrE<gt> | --no-proxy]
343 --help Print help and exit
344 --version Print version and exit
345 --license Print license and exit
347 -i, --interactive Run in interactive mode
348 -t, --title Get title for video link
349 --json Print details in json, implies -t
350 --csv Print details in csv, implies -t
351 --proxy arg (=http_proxy) Use proxy for HTTP connections
352 --no-proxy Disable use of HTTP proxy
356 # vim: set ts=4 sw=4 tw=72 expandtab: