File Coverage

blib/lib/Mojolicious/Command/snoodoc.pm
Criterion Covered Total %
statement 12 57 21.0
branch 0 8 0.0
condition n/a
subroutine 4 12 33.3
pod 1 1 100.0
total 17 78 21.7


line stmt bran cond sub pod time code
1             package Mojolicious::Command::snoodoc;
2              
3 1     1   722 use Mojo::Base 'Mojolicious::Command';
  1         1  
  1         9  
4              
5 1     1   92618 use Mojo::UserAgent;
  1         148906  
  1         12  
6 1     1   47 use Mojo::URL;
  1         1  
  1         4  
7              
8 1     1   809 use Getopt::Long qw(GetOptionsFromArray);
  1         9065  
  1         5  
9              
10             our $VERSION = '0.04';
11              
12             has description => 'Quick reference tool for the reddit API';
13              
14             has usage => <
15             Usage:
16              
17             mojo snoodoc
18             mojo snoodoc --all
19              
20             Options:
21              
22             --all, -a Print a list of endpoints available
23              
24             Example:
25              
26             mojo snoodoc /api/hide
27              
28             EOF
29              
30             has ua => sub { Mojo::UserAgent->new() };
31              
32             has url => 'http://www.reddit.com/dev/api';
33              
34             sub _print_all_endpoints {
35 0     0     my $self = shift;
36              
37             $self->ua->get($self->url)->res->dom->at('div.toc')->find('a.section')->each(
38             sub {
39              
40             # print section title
41 0     0     say $_->text;
42              
43             $_->following->first->find('li a')->each(
44             sub {
45              
46             # convert paceholder tags, e.g. /by_id/{names}
47 0           $_->find('em')->each(sub { $_->replace('{' . $_->text . '}') });
  0            
48              
49             # indent results
50 0           say ' ' . $_->text;
51             }
52 0           );
53             }
54 0           );
55             }
56              
57             sub _pretty_print {
58 0     0     my ($self, $scopes, $desc, $params) = @_;
59              
60 0           say "OAuth Scopes:\n\n$scopes\n";
61              
62 0           say "Description:\n\n$desc\n";
63              
64 0           say "Parameters:\n\n$params";
65             }
66              
67             sub _get_info {
68 0     0     my ($self, $container) = @_;
69              
70             my $scopes = $container->find('.api-badge\ oauth-scope')->map( #
71 0     0     sub { ' * ' . $_->text } # indentaion
72 0           )->join("\n\n");
73              
74             my $desc = $container->find('.md p')->map(
75             sub {
76 0 0   0     unless ($_->text =~ /\bSee also\b/) {
77 0           $_->find('*')->map('strip'); # get all text available
78 0           return ' ' . $_->text;
79             }
80              
81             # use strip() instead?
82             return 'See also: ', $_->find('a')->map(
83             sub {
84 0           my $attr = $_->attr('href');
85              
86             # remove leading #POST/GET
87 0           $attr =~ s/^#[A-Z]{3,4}_//;
88              
89             # look like URL
90 0           $attr =~ s@_@/@g;
91 0           $attr =~ s/%7B/{/g;
92 0           $attr =~ s/%7D/}/g;
93 0           " $attr"; # indentation
94             }
95 0           )->join("\n\n");
96             }
97 0           )->join("\n\n");
98              
99             my $params = $container->find('table.parameters tr')->map(
100             sub {
101 0     0     my $param = $_->at('th')->text;
102              
103             # some parameters don't have a description
104 0 0         if (my $param_desc = $_->at('td p')) {
105             ## strip code elements
106 0           $param_desc->children->map('strip');
107 0           $param .= ': ' . $param_desc->text;
108             }
109              
110             # indentation
111 0           " $param";
112             }
113 0           )->join("\n\n");
114              
115 0           $self->_pretty_print($scopes, $desc, $params);
116             }
117              
118             sub run {
119 0     0 1   my ($self, @args) = @_;
120              
121 0           GetOptionsFromArray(
122             \@args, #
123             'all|a' => \my $all,
124             );
125              
126 0 0         if ($all) {
127 0           $self->_print_all_endpoints();
128 0           return;
129             }
130              
131             # assuming only one endpoint was given
132 0           my $endpoint = shift @args;
133              
134             # do not continue without endpoint
135 0 0         unless ($endpoint) {
136 0           print $self->usage;
137 0           return;
138             }
139              
140 0           $endpoint =~ s@^/@@; # remove leading /
141 0           $endpoint =~ s@/@_@g; # look like URL fragment
142              
143 0           my $container = $self->ua->get($self->url)->res->dom->at('div[id$=' . $endpoint . ']');
144              
145 0           $self->_get_info($container);
146             }
147              
148             1;
149             __END__