Rewrite from_arg using "switch"
[umph.git] / bin / umph
blob5f15715ae1631d255b48983eb6176f9f238859bd
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', 'switch';
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.1");
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 = $@ ? "" : " with Umph::Prompt version $Umph::Prompt::VERSION";
41 say "umph version $VERSION$p";
42 exit 0;
45 sub print_help
47 require Pod::Usage;
48 Pod::Usage::pod2usage(-exitstatus => 0, -verbose => 1);
51 use constant MAX_RESULTS_LIMIT => 50; # Refer to http://is.gd/OcSjwU
52 my %config;
54 sub check_max_results_value
56 if ($config{max_results} > MAX_RESULTS_LIMIT)
58 say STDERR
59 "WARNING --max-results exceeds max. accepted value, using "
60 . MAX_RESULTS_LIMIT
61 . " instead";
62 $config{max_results} = MAX_RESULTS_LIMIT;
66 sub check_umph_prompt
68 if ($config{'interactive'} and not eval 'require Umph::Prompt')
70 say STDERR
71 qq/WARNING Umph::Prompt not found, ignoring --interactive option/;
72 $config{interactive} = 0;
76 sub init
78 GetOptions(
79 \%config,
80 'type|t=s',
81 'start_index|start-index|s=i',
82 'max_results|max-results|m=i',
83 'interactive|i',
84 'all|a',
85 'json',
86 'csv',
87 'proxy=s',
88 'no_proxy|no-proxy',
89 'quiet|q',
90 'version' => \&print_version,
91 'help' => \&print_help,
92 ) or exit 1;
94 print_help if scalar @ARGV == 0;
96 $config{type} ||= 'p'; # Default to "playlist".
97 $config{start_index} ||= 1; # Default to 1.
98 $config{max_results} ||= 25; # Default 25.
100 check_max_results_value;
101 check_umph_prompt;
104 sub spew_qe {print STDERR @_ unless $config{quiet}}
106 my @items;
108 sub main
110 init;
111 spew_qe "Checking ... ";
113 require LWP;
114 my $a = new LWP::UserAgent;
115 $a->env_proxy; # http://search.cpan.org/perldoc?LWP::UserAgent
116 $a->proxy('http', $config{proxy}) if $config{proxy};
117 $a->no_proxy('') if $config{no_proxy};
119 require XML::DOM;
120 my $p = new XML::DOM::Parser(LWP_UserAgent => $a);
121 my $s = $config{start_index};
122 my $m = $config{all} ? MAX_RESULTS_LIMIT : $config{max_results};
124 while (1)
126 my $doc = $p->parsefile(from_arg($ARGV[0], $s, $m));
127 my $root = $doc->getDocumentElement;
128 my $n = 0;
129 for my $entry ($root->getElementsByTagName("entry"))
131 my $t = to_item($entry, "title")->getFirstChild->getNodeValue;
132 my $l =
133 to_item($entry, "link")->getAttributeNode("href")->getValue;
134 my %data = (title => $t, url => $l, selected => 1);
135 push @items, \%data;
136 spew_qe((++$n % 5 == 0) ? " " : ".");
137 ++$s;
139 $doc->dispose;
141 last if $n == 0 or not $config{all};
144 spew_qe "done.\n";
146 croak "error: nothing found\n" if scalar @items == 0;
148 open_prompt() if $config{interactive};
150 say qq/{\n "video": [/ if $config{json};
152 my $i = 0;
154 foreach (@items)
156 if ($_->{selected} or not $config{interactive})
158 ++$i;
160 my $t = $_->{title} || "";
161 $t =~ s/"/\\"/g;
163 if ($config{json})
165 say "," if $i > 1;
166 say " {";
167 say qq/ "title": "$t",/;
168 say qq/ "url": "$_->{url}"/;
169 print " }";
171 elsif ($config{csv}) {say qq/"$t","$_->{url}"/}
172 else {say "$_->{url}"}
176 say "\n ]\n}" if $config{json};
180 use constant GURL => "http://gdata.youtube.com/feeds/api";
182 sub from_arg
184 my ($arg0, $s, $m) = @_;
185 my $u;
187 given ($config{type})
189 when (/^u/)
191 $u = GURL . "/users/$arg0/uploads";
193 when (/^f/)
195 $u = GURL . "/users/$arg0/favorites";
197 default
199 $arg0 =~ s/^PL//;
200 $u = GURL . "/playlists/$arg0";
204 $u .= "?v=2";
205 $u .= "&start-index=$s";
206 $u .= "&max-results=$m";
209 sub to_item
211 my ($entry, $name) = @_;
212 $entry->getElementsByTagName($name)->item(0);
215 sub open_prompt
217 my $p = new Umph::Prompt(
219 # Commands.
220 commands => {
221 q => sub {
222 my ($p, $args) = @_;
223 $p->exit(\@items, $args);
225 d => sub {
226 my ($p, $args) = @_;
227 $p->display(\@items, $args);
229 m => sub {
230 my ($p, $args) = @_;
231 $p->max_shown_items(@{$args});
233 s => sub {
234 my ($p, $args) = @_;
235 $p->select(\@items, $args);
237 h => sub {
238 my ($p, $args) = @_;
239 my @a;
240 push @a,
241 {cmd => 'normal', desc => 'print results in default format'};
242 push @a, {cmd => 'json', desc => 'print results in json'};
243 push @a, {cmd => 'csv', desc => 'print results in csv'};
244 $p->help(\@a);
246 n => sub {
247 $config{json} = 0;
248 $config{csv} = 0;
249 say STDERR "=> print in default format";
251 j => sub {
252 $config{json} = 1;
253 $config{csv} = 0;
254 say STDERR "=> print in json";
256 c => sub {
257 $config{json} = 0;
258 $config{csv} = 1;
259 say STDERR "=> print in csv";
263 # Callbacks. All of these are optional.
264 ontoggle => sub {
265 my ($p, $args) = @_;
266 $p->toggle(\@items, $args);
268 onitems => sub {return \@items},
269 onloaded => sub {
270 my ($p, $args) = @_;
271 $p->display(\@items, $args);
274 # Other (required) settings
275 total_items => scalar @items,
276 prompt_msg => 'umph',
277 max_shown_items => 20
280 say STDERR qq/Enter prompt. Type "help" to get a list of commands./;
281 $p->exec;
284 __END__
286 =head1 SYNOPSIS
288 umph [-q] [-i] [--csv | --json] [--type=E<lt>valueE<gt>]
289 [[--all | [--start-index=E<lt>valueE<gt>] [--max-results=E<lt>valueE<gt>]]
290 [--proxy=E<lt>addrE<gt> | --no-proxy] [--help]
291 E<lt>playlist_idE<gt> | E<lt>usernameE<gt>
293 =head2 OPTIONS
295 --help Print help and exit
296 --version Print version and exit
297 -q, --quiet Be quiet
298 -i, --interactive Run in interactive mode
299 -t, --type arg (=p) Get feed type
300 -s, --start-index arg (=1) Index of first matching result
301 -m, --max-results arg (=25) Max number of results included
302 -a, --all Get all items
303 --json Print details in JSON
304 --csv Print details in CSV
305 --proxy arg (=http_proxy) Use proxy for HTTP connections
306 --no-proxy Disable use of HTTP proxy
308 =cut
310 # vim: set ts=2 sw=2 tw=72 expandtab: