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 use version
0.77 (); our $VERSION = version
->declare("0.1.0");
27 binmode STDOUT
, ":utf8";
28 binmode STDERR
, ":utf8";
30 use Getopt
::ArgvFile
(home
=> 1, startupFilename
=> [qw(.grakerc)]);
31 use Getopt
::Long
qw(:config bundling);
48 'version' => \
&version
,
49 'help' => \
&print_help
,
52 $config{title
} ||= $config{json
};
53 $config{title
} ||= $config{csv
};
58 eval "require Umph::Prompt";
59 my $p = $@ ?
"" : ", Umph::Prompt version $Umph::Prompt::VERSION";
60 say "grake version $VERSION$p
61 Copyright (C) 2010-2011 Toni Gundogdu
62 This is free software; see the source for copying conditions. There is NO
63 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.";
70 Pod
::Usage
::pod2usage
(-exitstatus
=> 0, -verbose
=> 1);
80 print_help
() unless scalar @ARGV;
82 print STDERR
"Checking ..." unless $config{quiet
};
86 my $a = new LWP
::UserAgent
;
88 $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]+))};
105 unless ($r->is_success)
107 printf STDERR
"\nerror: $_: %s\n", $r->status_line;
111 my $d = URI
::Escape
::uri_unescape
($r->content);
112 @ids = weed
(uniq2
((@ids, $d =~ /$q/g)));
114 print STDERR
"." unless $config{quiet
};
119 print STDERR
"error: nothing found.\n";
122 else {print STDERR
"done.\n" unless $config{quiet
};}
126 print STDERR
":: Getting video title ..." unless $config{quiet
};
129 foreach my $id (@ids)
133 url
=> "http://youtube.com/watch?v=$id",
134 gvi
=> "http://www.youtube.com/get_video_info?&video_id=$id"
135 . "&el=detailpage&ps=default&eurl=&gl=US&hl=en",
140 $tmp{title
} = get_title
($a, \
%tmp) if $config{title
};
147 print STDERR
"done.\n" unless $config{quiet
};
150 prompt
() if $config{interactive
};
152 if ($config{json
}) {print qq/{\n "video": [\n/;}
158 if ($_->{selected
} or not $config{interactive
})
162 my $t = $_->{title
} || "";
167 print ",\n" if $i > 1;
170 . qq/ "title": "$t",\n/
171 . qq/ "url": "$_->{url}"\n/ . " }",
175 elsif ($config{csv
}) {print qq/"$t","$_->{url}"\n/;}
177 else {print "$_->{url}\n";}
181 if ($config{json
}) {print "\n ]\n}\n";}
188 my ($a, $video) = @_;
190 my $r = $a->get($$video{gvi
});
192 unless ($r->is_success)
194 printf STDERR
"\nerror: $$video{url}: %s\n", $r->status_line;
199 my $q = CGI
->new($r->content);
203 if ($q->param('reason'))
205 printf STDERR
"\nerror: %s: %s (errorcode: %d)\n",
206 $$video{url
}, trim
($q->param("reason")),
207 $q->param("errorcode");
212 $title = trim
(Encode
::decode_utf8
($q->param('title')));
213 print STDERR
"." unless $config{quiet
};
233 push @r, $_ if length $_ == 11;
239 { # http://is.gd/g8jQU
262 'n' => \
&select_none
,
263 'i' => \
&invert_selection
,
268 "Enter prompt. Type \"help\" to get a list of commands.\n";
282 if ($ln =~ /(\d+)/) {toggle_caption
($1);}
286 next unless $ln =~ /(\w)/;
287 $cmds{$1}() if defined $cmds{$1};
295 print STDERR
"Commands:
297 list .. display found links (> indicates selected for download)
300 invert .. invert selection
301 (number) .. toggle caption
302 dump .. dump selected links and exit
303 quit .. quit without dumping links\n"
304 . qq/Command name abbreviations are allowed, e.g. "h" instead of "help"\n/;
314 printf STDERR
"%2s%02d: %s\n", $_->{selected
}
318 $_->{title
} || $_->{url
};
324 $_->{selected
} = 1 foreach @links;
330 $_->{selected
} = 0 foreach @links;
336 $_->{selected
} = not $_->{selected
} foreach @links;
340 sub dump {$done = 1;}
345 if ($i >= 0 && exists $links[$i])
347 $links[$i]->{selected
} = not $links[$i]->{selected
};
350 else {print STDERR
"error: out of range\n";}
357 grake [-q] [-i] [-t] [--csv | --json] [--proxy E<lt>addrE<gt> | --no-proxy]
362 --help Print help and exit
363 --version Print version and exit
365 -i, --interactive Run in interactive mode
366 -t, --title Get title for video link
367 --json Print details in json, implies -t
368 --csv Print details in csv, implies -t
369 --proxy arg (=http_proxy) Use proxy for HTTP connections
370 --no-proxy Disable use of HTTP proxy
374 # vim: set ts=4 sw=4 tw=72 expandtab: