File Coverage

blib/lib/App/Toolforge/MixNMatch.pm
Criterion Covered Total %
statement 39 124 31.4
branch 0 26 0.0
condition 0 15 0.0
subroutine 13 21 61.9
pod 2 2 100.0
total 54 188 28.7


line stmt bran cond sub pod time code
1             package App::Toolforge::MixNMatch;
2              
3 2     2   66290 use strict;
  2         8  
  2         48  
4 2     2   8 use warnings;
  2         3  
  2         45  
5              
6 2     2   917 use Error::Pure qw(err);
  2         20902  
  2         41  
7 2     2   3412 use Getopt::Std;
  2         84  
  2         93  
8 2     2   804 use IO::Barf qw(barf);
  2         979  
  2         23  
9 2     2   1214 use JSON::XS;
  2         10762  
  2         111  
10 2     2   842 use LWP::Simple qw(get);
  2         114524  
  2         16  
11 2     2   1165 use Perl6::Slurp qw(slurp);
  2         2509  
  2         10  
12 2     2   66 use Readonly;
  2         4  
  2         119  
13 2     2   815 use Toolforge::MixNMatch::Diff;
  2         14115  
  2         50  
14 2     2   784 use Toolforge::MixNMatch::Print::Catalog;
  2         31514  
  2         51  
15 2     2   777 use Toolforge::MixNMatch::Struct::Catalog;
  2         3119  
  2         52  
16 2     2   781 use Unicode::UTF8 qw(encode_utf8);
  2         719  
  2         1944  
17              
18             # Constants
19             Readonly::Scalar our $URI_BASE => 'https://mix-n-match.toolforge.org/';
20             Readonly::Scalar our $URI_CATALOG_DETAIL => $URI_BASE.'api.php?query=catalog_details&catalog=%s';
21              
22             our $VERSION = 0.04;
23              
24             # Constructor.
25             sub new {
26 0     0 1   my ($class, @params) = @_;
27              
28             # Create object.
29 0           my $self = bless {}, $class;
30              
31             # Object.
32 0           return $self;
33             }
34              
35             sub _catalog_json_file_to_obj {
36 0     0     my $json_file = shift;
37              
38 0           my $json = slurp($json_file);
39 0           my $struct_hr = decode_json($json);
40 0           my $obj = Toolforge::MixNMatch::Struct::Catalog::struct2obj($struct_hr->{'data'});
41              
42 0           return $obj;
43             }
44              
45             sub _command_diff {
46 0     0     my ($json_file1, $json_file2, $print_options) = @_;
47              
48 0 0 0       if (! defined $json_file1 || ! -r $json_file1) {
49 0           return (1, "Doesn't exist JSON file #1 for diff.");
50             }
51 0 0 0       if (! defined $json_file2 || ! -r $json_file2) {
52 0           return (1, "Doesn't exist JSON file #2 for diff.");
53             }
54              
55 0           my $opts_hr = _process_print_options($print_options);
56              
57 0           my $obj1 = _catalog_json_file_to_obj($json_file1);
58 0           my $obj2 = _catalog_json_file_to_obj($json_file2);
59              
60 0           my $diff = Toolforge::MixNMatch::Diff::diff($obj1, $obj2);
61              
62 0           my $ret = Toolforge::MixNMatch::Print::Catalog::print($diff, $opts_hr);
63 0           print encode_utf8($ret)."\n";
64              
65 0           return (0, undef);
66             }
67              
68             sub _command_download {
69 0     0     my ($catalog_id, $output_file) = @_;
70              
71 0 0 0       if (! defined $catalog_id || $catalog_id !~ m/^\d+$/ms) {
72 0           return (1, 'Missing or bad catalog ID.');
73             }
74 0 0         if (! defined $output_file) {
75 0           $output_file = $catalog_id.'.json';
76             }
77              
78 0           my $json = _download_catalog_detail($catalog_id);
79 0           barf($output_file, $json);
80              
81 0           print "Catalog with '$catalog_id' ID was saved to '$output_file'.\n";
82              
83 0           return (0, undef);
84             }
85              
86             sub _command_print {
87 0     0     my ($json_file_or_catalog_id, $print_options) = @_;
88              
89 0           my $json;
90 0 0         if (-r $json_file_or_catalog_id) {
    0          
91 0           $json = slurp($json_file_or_catalog_id);
92             } elsif ($json_file_or_catalog_id =~ m/^\d+$/ms) {
93 0           $json = _download_catalog_detail($json_file_or_catalog_id);
94             } else {
95 0           return (1, "Doesn't exist JSON file or catalog ID for print.");
96             }
97              
98 0           my $opts_hr = _process_print_options($print_options);
99              
100 0           my $struct_hr = decode_json($json);
101 0           my $obj = Toolforge::MixNMatch::Struct::Catalog::struct2obj($struct_hr->{'data'});
102 0           my $ret = Toolforge::MixNMatch::Print::Catalog::print($obj, $opts_hr);
103 0           print encode_utf8($ret)."\n";
104              
105 0           return (0, undef);
106             }
107              
108             sub _download_catalog_detail {
109 0     0     my $catalog_id = shift;
110              
111 0           my $uri = sprintf $URI_CATALOG_DETAIL, $catalog_id;
112 0           my $json = get($uri);
113 0 0         if (! defined $json) {
114 0           err "Cannot download '$uri'.";
115             }
116              
117 0           return $json;
118             }
119              
120             sub _process_print_options {
121 0     0     my $print_options = shift;
122              
123 0 0         if (! defined $print_options) {
124 0           return;
125             }
126              
127              
128 0           my $opts_hr = {};
129 0           foreach my $print_option (split m/,/, $print_options) {
130 0           $opts_hr->{$print_option} = 1;
131             }
132              
133 0           return $opts_hr;
134             }
135              
136             # Run script.
137             sub run {
138 0     0 1   my $self = shift;
139              
140             # Process arguments.
141 0           $self->{'_opts'} = {
142             'h' => 0,
143             };
144 0 0 0       if (! getopts('h', $self->{'_opts'}) || $self->{'_opts'}->{'h'}
      0        
145             || @ARGV < 1) {
146              
147 0           print STDERR "Usage: $0 [-h] [--version] [command] [command_args ..]\n";
148 0           print STDERR "\t-h\t\tPrint help.\n";
149 0           print STDERR "\t--version\tPrint version.\n";
150 0           print STDERR "\tcommand\t\tCommand (diff, download, print).\n\n";
151 0           print STDERR "\tcommand 'diff' arguments:\n";
152 0           print STDERR "\t\tjson_file1 - JSON file #1\n";
153 0           print STDERR "\t\tjson_file2 - JSON file #2\n";
154 0           print STDERR "\t\t[print_options] - Print options (type, count, year_months, users)\n";
155 0           print STDERR "\tcommand 'download' arguments:\n";
156 0           print STDERR "\t\tcatalog_id - Catalog ID\n";
157 0           print STDERR "\t\t[output_file] - Output file (default is catalog_id.json)\n";
158 0           print STDERR "\tcommand 'print' arguments:\n";
159 0           print STDERR "\t\tjson_file or catalog_id - Catalog ID or JSON file\n";
160 0           print STDERR "\t\t[print_options] - Print options (type, count, year_months, users)\n";
161 0           return 1;
162             }
163 0           my $command = shift @ARGV;
164 0           my @command_args = @ARGV;
165              
166 0           my ($return, $error);
167 0 0         if ($command eq 'diff') {
    0          
    0          
168 0           ($return, $error) = _command_diff(@command_args);
169             } elsif ($command eq 'download') {
170 0           ($return, $error) = _command_download(@command_args);
171             } elsif ($command eq 'print') {
172 0           ($return, $error) = _command_print(@command_args);
173             } else {
174 0           print STDERR "Command '$command' doesn't supported.\n";
175 0           return 1;
176             }
177 0 0         if ($return == 1) {
178 0           print STDERR $error."\n";
179 0           return 1;
180             }
181              
182 0           return 0;
183             }
184              
185             1;
186              
187             __END__
188              
189             =pod
190              
191             =encoding utf8
192              
193             =head1 NAME
194              
195             App::Toolforge::MixNMatch - Perl class for mix-n-match application.
196              
197             =head1 SYNOPSIS
198              
199             use App::Toolforge::MixNMatch;
200              
201             my $obj = App::Toolforge::MixNMatch->new;
202             $obj->run;
203              
204             =head1 METHODS
205              
206             =over 8
207              
208             =item C<new()>
209              
210             Constructor.
211              
212             =item C<run()>
213              
214             Run.
215              
216             =back
217              
218             =head1 ERRORS
219              
220             new():
221             From Class::Utils:
222             Unknown parameter '%s'.
223              
224             =head1 EXAMPLE
225              
226             use strict;
227             use warnings;
228              
229             use App::Toolforge::MixNMatch;
230              
231             # Run.
232             exit App::Toolforge::MixNMatch->new->run;
233              
234             # Output:
235             # Usage: ./examples/ex1.pl [-h] [--version] [command] [command_args ..]
236             # -h Print help.
237             # --version Print version.
238             # command Command (diff, download, print).
239             #
240             # command 'diff' arguments:
241             # json_file1 - JSON file #1
242             # json_file2 - JSON file #2
243             # [print_options] - Print options (type, count, year_months, users)
244             # command 'download' arguments:
245             # catalog_id - Catalog ID
246             # [output_file] - Output file (default is catalog_id.json)
247             # command 'print' arguments:
248             # json_file or catalog_id - Catalog ID or JSON file
249             # [print_options] - Print options (type, count, year_months, users)
250              
251             =head1 DEPENDENCIES
252              
253             L<Getopt::Std>.
254              
255             =head1 REPOSITORY
256              
257             L<https://github.com/tupinek/App-Toolforge-MixNMatch>.
258              
259             =head1 AUTHOR
260              
261             Michal Josef Špaček L<mailto:skim@cpan.org>
262              
263             L<http://skim.cz>
264              
265             =head1 LICENSE AND COPYRIGHT
266              
267             © 2020 Michal Josef Špaček
268              
269             BSD 2-Clause License
270              
271             =head1 VERSION
272              
273             0.04
274              
275             =cut