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 = 0; 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; say STDERR "Getting Region pages"; my $region_query_results = $mw->api ( { action => 'query', generator => 'categorymembers', gcmtitle => 'Category:Regions', gcmlimit => 'max', prop => 'info|revisions', rvprop => 'content', inprop => 'url', } ) || croak $mw->{error}->{code} . ': ' . $mw->{error}->{details}; my (@tile_pages, %background_pages); foreach my $page (values %{$region_query_results->{query}{pages}}) { my $region = $grid->make_region($page->{title}); my $parsed_template = MWTemplate::Parse($page->{revisions}[0]{'*'}, $region_template_name); $region->{defaults}{colour} = $parsed_template->{named_params}{colour}; push @tile_pages, "$page->{title}/Tiles"; push @{$background_pages{"File:$parsed_template->{named_params}{background}"}}, $region; } say STDERR "Getting Background image pages"; my $background_query_results = $mw->api({ action => 'query', prop => 'imageinfo', titles => join('|', keys %background_pages), iiprop => 'url' }) || carp $mw->{error}->{code} . ': ' . $mw->{error}->{details}; foreach my $page (values %{$background_query_results->{query}{pages}}) { # say STDERR Dumper($page); if($page->{imageinfo}) { # say STDERR Dumper($page->{title}); foreach my $region (@{$background_pages{$page->{title}}}) { $region->{defaults}{image} = $page->{imageinfo}[0]{url}; } } } say STDERR "Getting Tile pages"; my $tile_query_results = $mw->api ( { action => 'query', titles => join('|', @tile_pages), prop => 'revisions', rvprop => 'content', } ) || croak $mw->{error}->{code} . ': ' . $mw->{error}->{details}; foreach my $page (values %{$tile_query_results->{query}{pages}}) { my $content = $page->{revisions}[0]{'*'}; my ($region_name) = $page->{title} =~ /(.*)\/Tiles/; my $region = $grid->{regions}{$region_name}; foreach my $coords (split /;/, $content) { # 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); } } say STDERR "Getting Site pages"; 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); foreach my $site_page_ref (values %{$site_query_results->{query}{pages}}) { 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} ); $grid->get_tile_at($nw, $sw)->pin($pin); } say wrap_in_html($grid); 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; }