Add use 5.010001 to bin
[umph.git] / bin / umph
blobb182b1f6d9253e8d457aae1646fad44499a1a83c
1 #!/usr/bin/perl
3 # umph
4 # Copyright (C) 2010-2011 Toni Gundogdu <legatvs@cpan.org>
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/>.
20 use 5.010001;
21 use feature 'say';
23 use warnings;
24 use strict;
26 binmode STDOUT, ":utf8";
27 binmode STDERR, ":utf8";
29 use version 0.77 (); our $VERSION = version->declare("0.2.0");
31 use Getopt::ArgvFile(home => 1, startupFilename => [qw(.umphrc)]);
32 use Getopt::Long qw(:config bundling);
33 use Carp qw(croak);
35 exit main();
37 sub print_version
39 eval "require Umph::Prompt";
40 my $p = $@ ? "" : ", Umph::Prompt version $Umph::Prompt::VERSION";
41 say "umph version $VERSION$p
42 Copyright (C) 2010-2011 Toni Gundogdu
43 This is free software; see the source for copying conditions. There is NO
44 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.";
45 exit 0;
48 sub print_help
50 require Pod::Usage;
51 Pod::Usage::pod2usage(-exitstatus => 0, -verbose => 1);
54 use constant MAX_RESULTS_LIMIT => 50; # Refer to http://is.gd/OcSjwU
55 my %config;
57 sub check_max_results_value
59 if ($config{max_results} > MAX_RESULTS_LIMIT)
61 say STDERR
62 "WARNING --max-results exceeds max. accepted value, using "
63 . MAX_RESULTS_LIMIT
64 . " instead";
65 $config{max_results} = MAX_RESULTS_LIMIT;
69 sub check_umph_prompt
71 if ($config{'interactive'} and not eval 'require Umph::Prompt')
73 say STDERR
74 qq/WARNING Umph::Prompt not found, ignoring --interactive option/;
75 $config{interactive} = 0;
79 sub init
81 GetOptions(
82 \%config,
83 'type|t=s',
84 'start_index|start-index|s=i',
85 'max_results|max-results|m=i',
86 'interactive|i',
87 'all|a',
88 'json',
89 'csv',
90 'proxy=s',
91 'no_proxy|no-proxy',
92 'quiet|q',
93 'version' => \&print_version,
94 'help' => \&print_help,
95 ) or exit 1;
97 print_help if scalar @ARGV == 0;
99 $config{type} ||= 'p'; # Default to "playlist".
100 $config{start_index} ||= 1; # Default to 1.
101 $config{max_results} ||= 25; # Default 25.
103 check_max_results_value;
104 check_umph_prompt;
107 sub spew_qe {print STDERR @_ unless $config{quiet}}
109 my @items;
111 sub main
113 init;
114 spew_qe "Checking ... ";
116 require LWP;
117 my $a = new LWP::UserAgent;
118 $a->env_proxy; # http://search.cpan.org/perldoc?LWP::UserAgent
119 $a->proxy('http', $config{proxy}) if $config{proxy};
120 $a->no_proxy('') if $config{no_proxy};
122 require XML::DOM;
123 my $p = new XML::DOM::Parser(LWP_UserAgent => $a);
124 my $s = $config{start_index};
125 my $m = $config{all} ? MAX_RESULTS_LIMIT : $config{max_results};
127 while (1)
129 my $doc = $p->parsefile(from_arg($ARGV[0], $s, $m));
130 my $root = $doc->getDocumentElement;
131 my $n = 0;
132 for my $entry ($root->getElementsByTagName("entry"))
134 my $t = to_item($entry, "title")->getFirstChild->getNodeValue;
135 my $l =
136 to_item($entry, "link")->getAttributeNode("href")->getValue;
137 my %data = (title => $t, url => $l, selected => 1);
138 push @items, \%data;
139 spew_qe((++$n % 5 == 0) ? " " : ".");
140 ++$s;
142 $doc->dispose;
144 last if $n == 0 or not $config{all};
147 spew_qe "done.\n";
149 croak "error: nothing found\n" if scalar @items == 0;
151 open_prompt() if $config{interactive};
153 say qq/{\n "video": [/ if $config{json};
155 my $i = 0;
157 foreach (@items)
159 if ($_->{selected} or not $config{interactive})
161 ++$i;
163 my $t = $_->{title} || "";
164 $t =~ s/"/\\"/g;
166 if ($config{json})
168 say "," if $i > 1;
169 say " {";
170 say qq/ "title": "$t",/;
171 say qq/ "url": "$_->{url}"/;
172 print " }";
174 elsif ($config{csv}) {say qq/"$t","$_->{url}"/}
175 else {say "$_->{url}"}
179 say "\n ]\n}" if $config{json};
183 use constant GURL => "http://gdata.youtube.com/feeds/api";
185 sub from_arg
187 my ($arg0, $s, $m) = @_;
189 my $u;
190 if ($config{type} eq "u" or $config{type} eq "uploads")
192 $u = GURL . "/users/$arg0/uploads?v=2";
194 elsif ($config{type} eq "f" or $config{type} eq "favorites")
196 $u = GURL . "/users/$arg0/favorites?v=2";
198 else
200 $u = GURL . "/playlists/$arg0?v=2";
203 $u .= "&start-index=$s";
204 $u .= "&max-results=$m";
207 sub to_item
209 my ($entry, $name) = @_;
210 $entry->getElementsByTagName($name)->item(0);
213 sub open_prompt
215 my $p = new Umph::Prompt(
217 # Commands.
218 commands => {
219 q => sub {
220 my ($p, $args) = @_;
221 $p->exit(\@items, $args);
223 d => sub {
224 my ($p, $args) = @_;
225 $p->display(\@items, $args);
227 m => sub {
228 my ($p, $args) = @_;
229 $p->max_shown_items(@{$args});
231 s => sub {
232 my ($p, $args) = @_;
233 $p->select(\@items, $args);
235 h => sub {
236 my ($p, $args) = @_;
237 my @a;
238 push @a,
239 {cmd => 'normal', desc => 'print results in default format'};
240 push @a, {cmd => 'json', desc => 'print results in json'};
241 push @a, {cmd => 'csv', desc => 'print results in csv'};
242 $p->help(\@a);
244 n => sub {
245 $config{json} = 0;
246 $config{csv} = 0;
247 say STDERR "=> print in default format";
249 j => sub {
250 $config{json} = 1;
251 $config{csv} = 0;
252 say STDERR "=> print in json";
254 c => sub {
255 $config{json} = 0;
256 $config{csv} = 1;
257 say STDERR "=> print in csv";
261 # Callbacks. All of these are optional.
262 ontoggle => sub {
263 my ($p, $args) = @_;
264 $p->toggle(\@items, $args);
266 onitems => sub {return \@items},
267 onloaded => sub {
268 my ($p, $args) = @_;
269 $p->display(\@items, $args);
272 # Other (required) settings
273 total_items => scalar @items,
274 prompt_msg => 'umph',
275 max_shown_items => 20
278 say STDERR qq/Enter prompt. Type "help" to get a list of commands./;
279 $p->exec;
282 __END__
284 =head1 SYNOPSIS
286 umph [-q] [-i] [-a] [--csv | --json] [-t E<lt>typeE<gt>]
287 [--proxy E<lt>addrE<gt> | --no-proxy]
288 [E<lt>playlist_idE<gt> | E<lt>usernameE<gt>]
290 =head2 OPTIONS
292 --help Print help and exit
293 --version Print version and exit
294 -q, --quiet Be quiet
295 -i, --interactive Run in interactive mode
296 -t, --type arg (=p) Get feed type
297 -s, --start-index arg (=1) Index of first matching result
298 -m, --max-results arg (=25) Max number of results included
299 -a, --all Get all items
300 --json Print details in JSON
301 --csv Print details in CSV
302 --proxy arg (=http_proxy) Use proxy for HTTP connections
303 --no-proxy Disable use of HTTP proxy
305 =cut
307 # vim: set ts=2 sw=2 tw=72 expandtab: