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/>.
25 binmode STDOUT
, ":utf8";
26 binmode STDERR
, ":utf8";
28 use version
0.77 (); our $VERSION = version
->declare("0.1.0");
30 use Getopt
::ArgvFile
(home
=> 1, startupFilename
=> [qw(.grakerc)]);
31 use Getopt
::Long
qw(:config bundling);
39 Pod
::Usage
::pod2usage
(-exitstatus
=> 0, -verbose
=> 1);
55 'version' => \
&version
,
59 help
if scalar @ARGV == 0;
61 $config{title
} ||= $config{json
};
62 $config{title
} ||= $config{csv
};
67 eval "require Umph::Prompt";
68 my $p = $@ ?
"" : ", Umph::Prompt version $Umph::Prompt::VERSION";
69 say "grake version $VERSION$p
70 Copyright (C) 2010-2011 Toni Gundogdu
71 This is free software; see the source for copying conditions. There is NO
72 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.";
76 sub spew_qe
{print STDERR
@_ unless $config{quiet
}}
85 spew_qe
"Checking ...";
88 my $a = new LWP
::UserAgent
;
89 $a->env_proxy; # http://search.cpan.org/perldoc?LWP::UserAgent
90 $a->proxy('http', $config{proxy
}) if $config{proxy
};
91 $a->no_proxy('') if $config{no_proxy
};
93 # Match: /watch?v=, /v/, /embed/
94 # (At least) Hulu uses the same "/embed/" which is why we no longer
95 # use the "(?>[-_\w]{11})".
97 my $q = qr{[?/](?:embed|v)[=/]((?>[-_\w]+))};
106 unless ($r->is_success)
108 printf STDERR
"\nerror: $_: %s\n", $r->status_line;
112 my $d = URI
::Escape
::uri_unescape
($r->content);
113 @ids = weed
(uniq2
((@ids, $d =~ /$q/g)));
115 spew_qe
((++$n % 5 == 0) ?
" " : ".");
118 if (scalar @ids == 0)
120 croak
"error: nothing found\n";
122 else {spew_qe
"done.\n"}
124 spew_qe
"Get video title ..." if $config{title
};
127 foreach my $id (@ids)
131 url
=> "http://youtube.com/watch?v=$id",
132 gvi
=> "http://www.youtube.com/get_video_info?&video_id=$id"
133 . "&el=detailpage&ps=default&eurl=&gl=US&hl=en",
138 $tmp{title
} = get_title
($a, \
%tmp, $n) if $config{title
};
143 spew_qe
"done.\n" if $config{title
};
145 prompt
() if $config{interactive
};
147 say qq/{\n "video": [/ if $config{json
};
153 if ($_->{selected
} or not $config{interactive
})
157 my $t = $_->{title
} || "";
164 say qq/ "title": "$t",/;
165 say qq/ "url": "$_->{url}"/;
169 elsif ($config{csv
}) {say qq/"$t","$_->{url}"/;}
171 else {say "$_->{url}";}
175 if ($config{json
}) {say "\n ]\n}";}
181 my ($a, $video, $n) = @_;
183 my $r = $a->get($$video{gvi
});
185 unless ($r->is_success)
187 printf STDERR
"\nerror: $$video{url}: %s\n", $r->status_line;
192 my $q = CGI
->new($r->content);
196 if ($q->param('reason'))
198 printf STDERR
"\nerror: %s: %s (errorcode: %d)\n",
199 $$video{url
}, trim
($q->param("reason")),
200 $q->param("errorcode");
205 $title = trim
(Encode
::decode_utf8
($q->param('title')));
206 spew_qe
(($n % 5 == 0) ?
" " : ".");
225 push @r, $_ if length $_ == 11;
231 { # http://is.gd/g8jQU
252 'd' => sub {$done=1},
254 'a' => \
&p_select_all
,
255 'n' => \
&p_select_none
,
256 'i' => \
&p_invert_selection
,
259 say STDERR
qq/Enter prompt. Type "help" to get a list of commands./;
273 if ($ln =~ /(\d+)/) {p_toggle
($1);}
277 next unless $ln =~ /(\w)/;
278 $cmds{$1}() if defined $cmds{$1};
286 say STDERR
qq/Commands
:
288 list
.. display found urls
(> indicates selected
for download
)
291 invert
.. invert selection
292 (number
) .. toggle caption
293 dump .. dump selected urls
and exit
294 quit
.. quit without dumping urls
295 Command name abbreviations are allowed
, e
.g
. "h" instead of
"help"/;
303 printf STDERR
"%2s%02d: %s\n", $_->{selected
}
307 $_->{title
} || $_->{url
};
313 $_->{selected
} = 1 foreach @urls;
319 $_->{selected
} = 0 foreach @urls;
323 sub p_invert_selection
325 $_->{selected
} = not $_->{selected
} foreach @urls;
332 if ($i >= 0 && exists $urls[$i])
334 $urls[$i]->{selected
} = not $urls[$i]->{selected
};
337 else {say STDERR
"error: out of range";}
344 grake [-q] [-i] [-t] [--csv | --json] [--proxy E<lt>addrE<gt> | --no-proxy]
349 --help Print help and exit
350 --version Print version and exit
352 -i, --interactive Run in interactive mode
353 -t, --title Get title for video link
354 --json Print details in json, implies -t
355 --csv Print details in csv, implies -t
356 --proxy arg (=http_proxy) Use proxy for HTTP connections
357 --no-proxy Disable use of HTTP proxy
361 # vim: set ts=2 sw=2 tw=72 expandtab: