buildsys: not our job to handle editor files
[pve-docs.git] / pve-docs-mediawiki-import.in
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6
7 use IO::File;
8 use File::Basename;
9 use MediaWiki::API;
10 use HTML::Parser;
11
12 use JSON;
13
14 my $data_str = "";
15 while (<main::DATA>) { $data_str .= $_; }
16
17 my $fileinfo = decode_json($data_str);
18
19 my $config_fn = "/root/.pve-docs"; # format 'username:pw'
20
21 my $fh = IO::File->new("$config_fn") ||
22     die "Please configure the mediawiki user/passswd in '$config_fn'\n";
23
24 my $api_url = "http://localhost/mediawiki/api.php";
25
26 my $config = <$fh>;
27 chomp $config;
28
29 my ($username, $passwd) = split(':', $config, 2);
30
31 my $mw = MediaWiki::API->new();
32 $mw->{config}->{api_url} = $api_url;
33
34 # log in to the wiki
35 $mw->login({ lgname => $username, lgpassword => $passwd })
36     || die $mw->{error}->{code} . ': ' . $mw->{error}->{details};
37
38 sub update_page {
39     my ($pagename, $filename, $category) = @_;
40
41     print "update mediawiki page: $pagename\n";
42
43     my $ref = $mw->get_page( { title => $pagename } );
44     my $page =  $ref->{'*'} || '';
45
46     my $pve_content = "<!-- Do not edit - this is autogenerated content -->\n";
47
48     $pve_content .= "{{#pvedocs:$filename}}\n";
49     $pve_content .= "[[Category:$category]]\n" if $category;
50
51     my $starttag = '<!--PVE_IMPORT_START_MARKER-->';
52     my $endtag = '<!--PVE_IMPORT_END_MARKER-->';
53
54     $pve_content .= "<pvehide>\n";
55
56     my $parser_opts = {
57         api_version => 3,
58         text_h => [ sub { $pve_content .= shift }, "text" ],
59     };
60     my $parser = HTML::Parser->new(%$parser_opts);
61     $parser->ignore_elements(qw(script style));
62
63     my $fh = IO::File->new("/usr/share/pve-docs/$filename", "r") or
64         die "unable to open file '$filename' - $!\n";
65     while (defined(my $line = <$fh>)) {
66         $parser->parse($line);
67     }
68     $pve_content .= "</pvehide>\n";
69
70     $pve_content =~ s/\s+$//gm;
71
72     chomp $pve_content;
73
74     if ($page =~ m/^(.*)$starttag\n.*\n$endtag\n?(.*)$/s) {
75         my ($top_content, $bottom_content) = ($1, $2);
76         $page = $top_content;
77         $page .= "$starttag\n";
78         $page .= $pve_content;
79         $page .= "\n$endtag\n";
80         $page .= $bottom_content;
81     } elsif ($page =~ m/(.*)\{\{#pvedocs:.*?\}\}(.*)$/) {
82         # old style
83         my ($top_content, $bottom_content) = ($1, $2);
84         chomp $top_content;
85         chomp $bottom_content;
86         $page = $top_content;
87         $page .= "$starttag\n";
88         $page .= $pve_content;
89         $page .= "\n$endtag\n";
90         $page .= $bottom_content;
91     } else {
92         $page = "$starttag\n$pve_content\n$endtag\n$page";
93     }
94
95     my $timestamp = $ref->{timestamp};
96     my $wcmd = {
97         action => 'edit',
98         title => $pagename,
99         basetimestamp => $timestamp, # to avoid edit conflicts
100         text => $page,
101     };
102
103     $mw->edit($wcmd) ||
104         die $mw->{error}->{code} . ': ' . $mw->{error}->{details};
105 }
106
107 my $cat_refdoc = "Reference Documentation";
108
109
110 my $docs = {};
111 foreach my $source (sort keys %{$fileinfo->{toplevel}->{wiki}}) {
112     my $title = $fileinfo->{titles}->{wiki}->{$source};
113     my $filename = $fileinfo->{outfile}->{wiki}->{$source} ||
114         die "found no file name mapping for '$source'";
115
116     my $path = "/usr/share/pve-docs/$filename";
117     die "no such file '$path'" if ! -f $path;
118
119     update_page($title, $filename, $cat_refdoc);
120 }
121
122 # also update 'Get support' page, because this is used since a long
123 # time and is referenced from outside
124 update_page("Get support", 'getting-help-plain.html', 'HOWTO');
125
126 __END__