3 ###############################################################################
6 =item B<reporter> --analyst "Analyst Name" --report_title "Report Title"
8 Generates an asciidoc file in the git working directory that can be converted to
9 any appropriate format. The analyst and report parameters are required.
11 Optional parameters are :
13 --added_page_title and --added_page_file
15 If one is used both must be. The added page file can be plain text or asciidoc. This
16 adds an extra arbitrary page of notes to the report. Mig assumes the page file is in the mig git directory.
20 This will define a set of tags to use, if not set it will default to Circs,
21 Holds, Actors, Bibs, Assets & Money.
25 Gives more information about what is happening.
29 Allows you to override the default evergreen_staged_report.xml in the mig-xml folder.
31 --captions or --captions_off
33 Adds the captions tag to asciidoc header to turn off captions in generated output.
39 ###############################################################################
48 HOME PGHOST PGPORT PGUSER PGDATABASE MIGSCHEMA
49 MIGBASEWORKDIR MIGBASEGITDIR MIGGITDIR MIGWORKDIR
56 my $mig_bin = "$FindBin::Bin/";
57 use lib "$FindBin::Bin/";
59 use open ':encoding(utf8)';
61 pod2usage(-verbose => 2) if defined $ARGV[0] && $ARGV[0] eq '--help';
62 pod2usage(-verbose => 1) if ! $ARGV[1];
65 my $next_arg_is_analyst;
67 my $next_arg_is_report_title;
69 my $next_arg_is_reports_xml;
73 my $next_arg_is_added_page_title;
75 my $next_arg_is_added_page_file;
78 my $parser = XML::LibXML->new();
79 my $lines_per_page = 42;
84 foreach my $arg (@ARGV) {
85 if ($arg eq '--report_title') {
86 $next_arg_is_report_title = 1;
89 if ($next_arg_is_report_title) {
91 $next_arg_is_report_title = 0;
94 if ($arg eq '--analyst') {
95 $next_arg_is_analyst = 1;
98 if ($next_arg_is_analyst) {
100 $next_arg_is_analyst = 0;
103 if ($arg eq '--reports_xml') {
104 $next_arg_is_reports_xml = 1;
107 if ($next_arg_is_reports_xml) {
109 $next_arg_is_reports_xml = 0;
112 if ($arg eq '--tags') {
113 $next_arg_is_tags = 1;
116 if ($next_arg_is_tags) {
118 $next_arg_is_tags = 0;
121 if ($arg eq '--added_page_title') {
122 $next_arg_is_added_page_title = 1;
125 if ($next_arg_is_added_page_title) {
126 $added_page_title = $arg;
127 $next_arg_is_added_page_title = 0;
130 if ($arg eq '--added_page_file') {
131 $next_arg_is_added_page_file = 1;
134 if ($next_arg_is_added_page_file) {
135 $added_page_file = $arg;
136 $next_arg_is_added_page_file = 0;
139 if ($arg eq '--captions_off' or $arg eq '--captions') {
143 if ($arg eq '--debug') {
149 if (!defined $tags) {$tags = 'circs.holds.actors.bibs.assets.money.notices'};
150 if (!defined $report_title) { abort('--report_title must be supplied'); }
151 if (!defined $analyst) { abort('--analyst must be supplied'); }
153 my $mig_path = abs_path($0);
154 $mig_path =~ s|[^/]+$||;
155 $reports_xml = find_xml($reports_xml,$mig_path);
156 if (!defined $reports_xml) { abort("Can not find xml reports file."); }
157 my $dom = $parser->parse_file($reports_xml);
159 if (defined $added_page_file or defined $added_page_title) {
160 abort('must specify --added_page_file and --added_page_title') unless defined $added_page_file and defined $added_page_title;
162 if (defined $added_page_file) { $added_page_file = $MIGGITDIR . $added_page_file; }
164 my $dbh = Mig::db_connect();
165 my $report_file = create_report_name($report_title);
166 $report_file = $MIGGITDIR . $report_file;
168 open($fh, '>', $report_file) or abort("Could not open output file $report_file!");
169 write_title_page($report_title,$fh,$analyst,$captions_off);
171 if (defined $added_page_file and defined $added_page_title) {
173 print $fh "== $added_page_title\n";
174 print "$added_page_file\t$added_page_title\n";
175 open(my $an,'<:encoding(UTF-8)', $added_page_file) or abort("Could not open $added_page_file!");
176 while ( my $line = <$an> ) {
183 foreach my $func ($dom->findnodes('//function')) {
184 my $fdrop = $func->findvalue('./drop');
185 my $fcreate = $func->findvalue('./create');
186 my $fname = $func->findvalue('./name');
187 my $sdrop = $dbh->prepare($fdrop);
188 my $screate = $dbh->prepare($fcreate);
189 print "dropping function $fname ... ";
191 print "creating function $fname\n\n";
196 my @report_tags = split(/\./,$tags);
197 foreach my $t (@report_tags) {
198 print "\n\n=========== Starting to process tag $t\n";
199 print "==========================================\n\n";
202 foreach my $asset ($dom->findnodes('//asset')) {
203 if (index($asset->findvalue('./tag'),$t) != -1) {
204 push @asset_files, $asset->findvalue('./file');
208 foreach my $fname (@asset_files) {
209 my $asset_path = $mig_path . '../mig-asc/' . $fname;
210 open my $a, $asset_path or abort("Could not open $fname.");
211 while ( my $l = <$a> ) {
217 print_section_header(ucfirst($t),$fh);
218 my $linecount = $lines_per_page;
222 foreach my $asset ($dom->findnodes('//asset')) {
223 if (index($asset->findvalue('./tag'),$t) != -1) {
224 push @asset_files, $asset->findvalue('./file');
229 foreach my $report ($dom->findnodes('//report')) {
230 if (index($report->findvalue('./tag'),$t) != -1 and $report->findvalue('./iteration') eq '0') {
231 push @report_names, $report->findvalue('./name');
235 #only has one level of failover now but could change to array of hashes and loops
236 #but this keeps it simple and in practice I haven't needed more than two
239 foreach my $rname (@report_names) {
245 if ($debug_flag == 1) {print "\nchecking for $rname ... ";}
246 %report0 = find_report($dom,$t,$rname,'0',$debug_flag);
247 $check_tables0 = check_table($report0{query},$MIGSCHEMA,$debug_flag,$rname);
248 if ($check_tables0 == 1) { $r = print_query($fh,%report0); } else {
249 %report1 = find_report($dom,$t,$rname,'1',$debug_flag);
250 if (defined $report1{query}) {
251 $check_tables1 = check_table($report1{query},$MIGSCHEMA,$debug_flag,$rname);
252 if ($check_tables1 == 1) { $r = print_query($fh,%report1); }
263 ############ end of main logic
266 my $reports_xml = shift;
267 my $mig_path = shift;
269 if ($reports_xml =~ m/\//) { return $reports_xml; }
271 my $mig_test_file = $mig_path . '/../mig-xml/' . $reports_xml;
272 my $working_test_dir = getcwd();
273 my $working_test_file = $working_test_dir . '/' . $reports_xml;
275 if (-e $mig_test_file) { return $mig_test_file; }
276 if (-e $working_test_file) { return $working_test_file; }
285 my $iteration = shift;
286 my $debug_flag = shift;
289 if ($debug_flag == 1) {print "iteration $iteration ";}
290 foreach my $node ($dom->findnodes('//report')) {
291 if ($node->findvalue('./tag') =~ $tag and $node->findvalue('./iteration') eq $iteration and $node->findvalue('./name') eq $name) {
292 if ($debug_flag == 1) {print "succeeded ... \n";}
294 name => $node->findvalue('./name'),
295 report_title => $node->findvalue('./report_title'),
296 query => $node->findvalue('./query'),
297 heading => $node->findvalue('./heading'),
298 tag => $node->findvalue('./tag'),
299 iteration => $node->findvalue('./iteration'),
300 note => $node->findvalue('./note'),
305 if ($debug_flag == 1) {print "failed ... \n";}
307 name => "eaten by grue"
311 sub print_section_header {
316 #$t =~ s/(\w+)/\u$1/g;;
318 print $fh "== $t Reports\n";
322 sub create_report_name {
325 my @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
326 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
328 my $date = $year . '_' . $abbr[$mon] . '_' . $mday;
330 $report_file = $rt . ' ' . $date . '.asciidoc';
331 $report_file =~ s/ /_/g;
335 sub write_title_page {
339 my $captions_off = shift;
341 my @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
342 my $l = length($report_title);
343 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
346 print $fh "$mday $abbr[$mon] $year\n";
348 #print $fh ":title-logo-image: image::eolilogosmall.png[pdfwidth=3in]\n";
350 if ($captions_off == 1) { print $fh ":caption:\n"; }
356 my $MIGSCHEMA = shift;
357 my $debug_flag = shift;
358 my $report_name = shift;
360 if ($debug_flag == 1) {print "$query\n";}
364 my @qe = split(/ /,$query);
369 if ($qe[$i] eq 'FROM' or $qe[$i] eq 'JOIN') {
371 if ($qe[$q] ne '(SELECT') {
372 push @tables, $qe[$q];
377 if ($debug_flag == 1) {print "checking tables ... ";}
380 foreach my $table (@tables) {
383 if (index($table,'.') != -1) {
384 $schema = (split /\./,$table)[0];
385 $table = (split /\./,$table)[1];
387 $table = clean_query_string($table);
388 if (defined $schema) {
389 $schema = clean_query_string($schema);
390 $sql = 'SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = \'' . $schema . '\' AND table_name = \'' . $table . '\');';
392 $sql = 'SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = \'' . $MIGSCHEMA . '\' AND table_name = \'' . $table . '\');';
394 my $sth = $dbh->prepare($sql);
396 while (my @row = $sth->fetchrow_array) {
397 if ($row[0] eq '1') {
401 if ($debug_flag == 1) {print "detecting $table failed...\n";}
403 if ($row[0] eq '0') {$return_flag = 0;}
406 if ($return_flag == 1 and $debug_flag == 1) {print "succeeded ...\n";}
407 if ($return_flag == 0) {print "! a table failed the find test for report $report_name\n\n";}
411 sub clean_query_string {
414 $str =~ s/(?!_)[[:punct:]]//g; #remove punct except underscores
423 my $query = $report{query};
424 my $sth = $dbh->prepare($query);
429 while (my @row = $sth->fetchrow_array) {
430 if ($header_flag == 0) {
431 print $fh "\n.*$report{report_title}*\n";
433 my @h = split(/\./,$report{heading});
436 while ($h_count <= $h_length) {
437 print $fh "|*$h[$h_count-1]* ";
443 my $row_length = @row;
445 while ($r <= $row_length) {
446 if (! defined $row[$r-1] ) {
449 print $fh "|$row[$r-1] ";
454 if ($header_flag == 1) {
455 print $fh "|===\n\n";
456 print $fh $report{note};
459 print "successfully wrote output for $report{name}.\n\n";
467 $col .= chr( ( $i % 26 ) + ord('A') );
468 $i = int( $i / 26 ) - 1;
471 return scalar reverse $col;
476 print STDERR "$0: $msg", "\n";