You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pve-docs-mediawiki-import.in 3.2KB

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