use v5.30; use MediaWiki::API; use HexGrid; use HexGrid::Pin; use MWTemplate; use Carp; use Data::Dumper; $Data::Dumper::Indent = 1; use feature "signatures"; no warnings "experimental::signatures"; my $api_url = "https://wiki.tensor.green/w/api.php"; my $region_template_name = "MapRegion"; my $site_template_name = "MapSite"; my $border_width = 1; my $border_colour = 'black'; my $show_coords = 1; my $grid = HexGrid->new(defaults => { style => { 'stroke-width' => $border_width, stroke => $border_colour }, show_coords => $show_coords }); my $mw = MediaWiki::API->new(); $mw->{config}->{api_url} = $api_url; my $region_pages = $mw->list ( { action => 'query', list => 'categorymembers', cmtitle => 'Category:Regions', cmlimit => 'max' } ) || croak $mw->{error}->{code} . ': ' . $mw->{error}->{details}; say STDERR "Regions found: " . join(", ", map { $_->{title} } @$region_pages); foreach my $region_page_ref (@$region_pages) { my $region_name = $region_page_ref->{title}; say STDERR "Processing Region: $region_name"; my $region_page = $mw->get_page({ title => $region_name }); my $tile_page = $mw->get_page({ title => "$region_name/Tiles" }); process_region($grid, $region_name, $region_page->{'*'}, $tile_page->{'*'}); } my $site_query_results = $mw->api ( { action => 'query', generator => 'categorymembers', prop => 'info|revisions', gcmtitle => 'Category:Sites', gcmlimit => 'max', rvprop => 'content', inprop => 'url', } ) || croak $mw->{error}->{code} . ': ' . $mw->{error}->{details}; # say STDERR "Sites found: " . join(" ,", map { $_->{title} } @$site_pages); # say STDERR Dumper($site_query_results); foreach my $site_page_ref (values %{$site_query_results->{query}{pages}}) { say STDERR Dumper($site_page_ref); my $site_name = $site_page_ref->{title}; say STDERR "Processing Site $site_name"; my $site_url = $site_page_ref->{canonicalurl}; my $site_content = $site_page_ref->{revisions}[0]{'*'}; my $parsed_template = MWTemplate::Parse($site_content, $site_template_name); my ($nw,$sw) = split /,/, $parsed_template->{named_params}{coords}; my $imageinfo_query_results = $mw->api({ action => 'query', prop => 'imageinfo', titles => "File:$parsed_template->{named_params}{icon}", iiprop => 'url' }) || carp $mw->{error}->{code} . ': ' . $mw->{error}->{details}; my %image_pages = %{$imageinfo_query_results->{query}{pages}}; my $image_url = (values %image_pages)[0]{imageinfo}[0]{url}; my $pin = HexGrid::Pin->new ( name => $site_name, id => "${site_name}_pin", icon => $image_url, link => $site_url, description => $parsed_template->{named_params}{abstract} ); # say STDERR Dumper($pin); $grid->get_tile_at($nw, $sw)->pin($pin); } say wrap_in_html($grid); sub process_region($grid, $region_name, $region_spec, $tiles) { my $region = $grid->make_region($region_name); my $parsed_template = MWTemplate::Parse($region_spec, $region_template_name); $region->{defaults}{colour} = $parsed_template->{named_params}{colour}; my $image_info = $mw->api({ action => 'query', prop => 'imageinfo', titles => "File:$parsed_template->{named_params}{background}", iiprop => 'url' }) || carp $mw->{error}->{code} . ': ' . $mw->{error}->{details}; $region->{defaults}{image} = []; foreach my $page (values %{$image_info->{query}{pages}}) { push @{$region->{defaults}{image}}, $page->{imageinfo}[0]{url}; } foreach my $coords (split /;/, $tiles) { # The below regex is a whitespace forgiving version of /^(-?\d+),(-?\d+)/, an int pair do { carp "Skipping bad spec: $coords"; next; } unless $coords =~ /^\s*(-?\s*\d+)\s*,\s*(-?\s*\d+)\s*$/; $region->make_tile_at($1,$2); } } sub wrap_in_html($grid) { my $html_builder = ""; $html_builder .= "\n\n"; $html_builder .= "\n" . < function clickPin(pinId, containerId) { let popup = document.getElementById(pinId + '-popup'); popup.style.visibility = popup.style.visibility == 'visible' ? 'hidden' : 'visible'; } EOS $html_builder .= "\n" . $grid->render; $html_builder .= "\n\n"; return $html_builder; }