give modules default loggers so they are usable on their own (in tests)
[scpubgit/System-Introspector-Report.git] / lib / System / Introspector / Report / Publish / MediaWiki.pm
CommitLineData
499ebcdd 1package System::Introspector::Report::Publish::MediaWiki;
2use Moo;
0331d9cd 3use Try::Tiny;
55dfa20f 4use Log::Contextual::WarnLogger;
5use Log::Contextual qw( :log ),
6 -default_logger => Log::Contextual::WarnLogger->new({
7 env_prefix => 'SI_REPORT_MEDIAWIKI',
8 levels => [qw( error fatal warn )],
9 });
10
499ebcdd 11use aliased 'System::Introspector::Report::Publish::MediaWiki::Connection';
12
13has page_options => (
14 is => 'ro',
15 default => sub { {} },
16 init_arg => 'page',
17);
18
499ebcdd 19has connection => (is => 'ro', lazy => 1, builder => 1, handles => {
20 get_page => 'get',
21 put_page => 'put',
22});
23
7a479e54 24has api_uri => (is => 'ro', required => 1);
25has username => (is => 'ro', required => 1);
26has password => (is => 'ro', required => 1);
27has allow_create => (is => 'ro', default => sub { 0 });
28has http_auth => (is => 'ro');
29has http_realm => (is => 'ro');
0331d9cd 30
31sub _build_producer { Producer->new }
32
33sub _build_connection {
34 my ($self) = @_;
35 return Connection->new(
7a479e54 36 api_uri => $self->api_uri,
37 username => $self->username,
38 password => $self->password,
39 allow_create => $self->allow_create,
0331d9cd 40 $self->http_auth ? (
41 http_auth => 1,
42 http_realm => $self->http_realm,
43 ) : (),
44 );
45}
499ebcdd 46
47sub publish {
48 my ($self, $reports) = @_;
49 my $pages = $self->page_options;
7f86d23e 50 log_info {
51 sprintf "Pushing reports to MediaWiki at '%s'", $self->api_uri;
52 };
499ebcdd 53 for my $page (sort keys %$pages) {
54 $self->_publish_page($reports, $page, $pages->{$page});
55 }
72599a55 56 log_info { "Finished pushing to MediaWiki" };
499ebcdd 57 return 1;
58}
59
60sub _sort_reports {
61 my ($self, $reports, $included) = @_;
62 my @matchers = map {
63 $self->_prepare_matcher_from($_);
64 } ref($included) ? @{$included} : $included;
65 my @grouped;
66 for my $report (@$reports) {
67 my ($group_idx) = grep {
68 $self->_match_id($report, $matchers[$_]);
69 } 0 .. $#matchers;
70 if (defined $group_idx) {
71 push @{$grouped[$group_idx]}, $report;
72 }
73 }
74 return [ map { (@$_) } @grouped ];
75}
76
7a479e54 77sub _publish_dynamic {
78 my ($self, $reports, $page_name, $key, $options) = @_;
79 my %reports_by_key;
80 for my $report (@$reports) {
81 my $value = $report->{meta}{$key};
82 next unless defined $value;
83 push @{ $reports_by_key{$value} ||= [] }, $report;
84 }
85 for my $value (keys %reports_by_key) {
86 (my $effective_page = $page_name)
87 =~ s{\%\(meta:\Q$key\E\)}{$value};
88 my $assoc = $reports_by_key{$value};
89 $self->_publish_page($assoc, $effective_page, $options);
90 }
91 return 1;
92}
93
499ebcdd 94sub _publish_page {
21e7cc98 95 my ($self, $reports, $page_name, $options) = @_;
7a479e54 96 if ($page_name =~ m{\%\(meta:(.+?)\)}) {
97 return $self->_publish_dynamic($reports, $page_name, $1, $options);
98 }
499ebcdd 99 my $sorted = $self->_sort_reports($reports, $options->{report} || []);
7a479e54 100 unless (scalar @$sorted) {
82dc985c 101 log_debug { "Skipping page '$page_name': No reports to publish" };
7a479e54 102 return 1;
103 }
7a479e54 104 my $do_create = $options->{create};
105 return try {
0331d9cd 106 my $page = $self->get_page($page_name);
7a479e54 107 if ($page->is_new and not $do_create) {
1acc31a2 108 log_trace { "Skipping page '$page_name': Does not yet exist" };
7a479e54 109 return 1;
110 }
111 my $is_changed = $page->update($sorted);
112 unless ($is_changed) {
82dc985c 113 log_debug { "Not pushing page '$page_name': No changes" };
7a479e54 114 return 1;
115 }
ac3652dc 116 log_debug { "Updating page '$page_name'" };
0331d9cd 117 $self->put_page($page);
7a479e54 118 return 1;
0331d9cd 119 }
120 catch {
72599a55 121 log_error { "Error during page update: $_" };
7a479e54 122 return 1;
0331d9cd 123 };
499ebcdd 124}
125
126with $_ for qw(
127 System::Introspector::Report::Publish::API
128);
129
1301;