File Coverage

blib/lib/Mojolicious/Command/snoodoc.pm
Criterion Covered Total %
statement 12 56 21.4
branch 0 8 0.0
condition n/a
subroutine 4 12 33.3
pod 1 1 100.0
total 17 77 22.0


line stmt bran cond sub pod time code
1             package Mojolicious::Command::snoodoc;
2              
3 1     1   742 use Mojo::Base 'Mojolicious::Command';
  1         2  
  1         10  
4              
5 1     1   93564 use Mojo::UserAgent;
  1         158695  
  1         46  
6 1     1   64 use Mojo::URL;
  1         1  
  1         5  
7              
8 1     1   1127 use Getopt::Long qw(GetOptionsFromArray);
  1         12381  
  1         8  
9              
10             our $VERSION = '0.03';
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 0           $param .= ': ' . $param_desc->text;
106             }
107              
108             # indentation
109 0           " $param";
110             }
111 0           )->join("\n\n");
112              
113 0           $self->_pretty_print($scopes, $desc, $params);
114             }
115              
116             sub run {
117 0     0 1   my ($self, @args) = @_;
118              
119 0           GetOptionsFromArray(
120             \@args, #
121             'all|a' => \my $all,
122             );
123              
124 0 0         if ($all) {
125 0           $self->_print_all_endpoints();
126 0           return;
127             }
128              
129             # assuming only one endpoint was given
130 0           my $endpoint = shift @args;
131              
132             # do not continue without endpoint
133 0 0         unless ($endpoint) {
134 0           print $self->usage;
135 0           return;
136             }
137              
138 0           $endpoint =~ s@^/@@; # remove leading /
139 0           $endpoint =~ s@/@_@g; # look like URL fragment
140              
141 0           my $container = $self->ua->get($self->url)->res->dom->at('div[id$=' . $endpoint . ']');
142              
143 0           $self->_get_info($container);
144             }
145              
146             1;
147             __END__