Skip to content

Commit

Permalink
add basic server to serve GUI files
Browse files Browse the repository at this point in the history
  • Loading branch information
hannaeko committed Sep 7, 2023
1 parent 9c301b1 commit 80e36dd
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist
/share/dist
/share/manifest.json
/dist-electron
/release-builds
/tmp
Expand Down
15 changes: 11 additions & 4 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"allowedCommonJsDependencies": [
"file-saver"
],
"outputPath": "dist",
"outputPath": "share/dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.app.json",
Expand All @@ -49,8 +49,8 @@
"src/.htaccess"
],
"styles": [
"node_modules/fork-awesome/css/fork-awesome.min.css",
"src/styles.scss"
"src/styles.scss",
"node_modules/fork-awesome/css/fork-awesome.min.css"
],
"scripts": [],
"aot": true,
Expand All @@ -72,7 +72,14 @@
},
"production": {
"localize": true,
"optimization": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
Expand Down
136 changes: 136 additions & 0 deletions lib/Zonemaster/GUI.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package Zonemaster::GUI;

use strict;
use warnings;

use Dancer2;
use Carp;
use Data::Dumper;
use I18N::AcceptLanguage;
use TOML::Tiny qw(from_toml);
use File::Slurp qw( read_file );
use File::ShareDir qw( dist_dir );


our $VERSION = '0.0.0';

# Generate configuration
get '/:lang/app.config.json' => sub {
send_as JSON => config->{client_config}
};

# Serve additional assets
get '/:lang/additional/**' => sub {
my ( $path ) = splat;

if ( grep /^\.{2,}$/, @{$path} ) {
pass;
} else {
if ( defined config->{additional_assets_directory} ) {
send_file( path( config->{additional_assets_directory}, @{$path} ), system_path => 1 );
}
}
};

# Serve localized GUI assets, serve index.html for all other requests under /:lang
get '/:lang/?**?' => sub {
my $lang = route_parameters->get('lang');
my ( $path ) = splat;
my $filename = path( 'dist', $lang, @{$path} );

if ( ! grep { $_ eq $lang } @{config->{enabled_languages}} ) {
pass;
} else {
if (-f path( config->{public_dir}, $filename )) {
send_file $filename;
} else {
template 'index.html', {
styles => config->{static_resources}->{styles},
scripts => config->{static_resources}->{scripts},
baseurl => join('/', config->{base_url}, $lang, ""),
lang => $lang,
};
}
}
};

# For all other request, redirect based on the browser prefered language
get '/**?' => sub {
my ( $path ) = splat;
my $accept_language = request_header 'Accept-Language';
my $acceptor = I18N::AcceptLanguage->new( defaultLanguage => config->{default_language});
my $lang = $acceptor->accepts($accept_language, config->{enabled_languages});

redirect uri_for( join('/', config->{base_url}, $lang, @{$path}) );
};

sub build_app {
my $config_file_name = $ENV{ZONEMASTER_GUI_CONFIG_FILE} // "zonemaster-gui.toml";
my $config_file = read_file $config_file_name;
my $config = from_toml($config_file);
my $install_directory = dist_dir('Zonemaster-GUI');

if (! exists $config->{general}->{default_language}) {
croak "Please set `default_language` in configuration file.";
}

if (! exists $config->{general}->{enabled_languages}) {
croak "Please set `enabled_languages` in configuration file.";
}

my $base_url = $config->{general}->{base_url} // '';

set (
public_dir => $install_directory,
static_handler => false,
template => 'template_toolkit',
views => path($install_directory, 'templates'),
base_url => $base_url,
default_language => $config->{general}->{default_language},
enabled_languages => [ @{$config->{general}->{enabled_languages}} ],
);

my %client_config;
while( my ($key, $value) = each %{$config->{client}} ) {
$key =~ s/_([[:alpha:]])/\U$1/g;
$client_config{$key} = $value;
}

$client_config{defaultLanguage} = $config->{general}->{default_language};
$client_config{enabledLanguages} = $config->{general}->{enabled_languages};

set client_config => \%client_config;

my $manifest_file = read_file path($install_directory, "manifest.json");
my $static_resources = decode_json($manifest_file);
my %final_static_resources;

my @additional_styles = map { join('/', 'additional', $_) } @{$config->{customization}->{additional_styles}};
my @additional_scripts = map { join('/', 'additional', $_) } @{$config->{customization}->{additional_scripts}};

my $override_default_style = $config->{general}->{override_default_style} // 0;

$final_static_resources{styles} =
$override_default_style ?
\@additional_styles :
[ @{$static_resources->{styles}}, @additional_styles ];

$final_static_resources{scripts} = [ @{$static_resources->{scripts}}, @additional_scripts ];

set (
static_resources => \%final_static_resources,
additional_assets_directory => $config->{customization}->{additional_assets_directory},
);

if ( exists $config->{customization}->{template_override_directory} ) {
set engines => {
template => {
template_toolkit => {
include_path => $config->{customization}->{template_override_directory}
}
}
}
}

return to_app;
}
1 change: 1 addition & 0 deletions lib/auto/share/dist/Zonemaster-GUI
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "node scripts/faq.js && ng build --configuration production",
"build": "node scripts/faq.js && ng build --configuration production && node scripts/create_manifest.js ",
"release": "npm run build && node scripts/create_release.js",
"lint": "ng lint",
"e2e": "playwright test",
Expand Down
25 changes: 25 additions & 0 deletions scripts/create_manifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const fs = require('fs');

fs.readdir('./share/dist/en', (err, files) => {
const manifest = {
styles: [],
scripts: [],
};

files.forEach(file => {
if (file.endsWith('.css')) {
manifest.styles.push(file);
} else if(file.endsWith('.js')) {
manifest.scripts.push(file);
}
});


fs.writeFile('./share/manifest.json', JSON.stringify(manifest), err => {
if (err) {
console.error(err)
} else {
console.log('manifest.json written')
}
})
});
6 changes: 6 additions & 0 deletions scripts/zonemaster-gui
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env perl
use Dancer2;
use Zonemaster::GUI;

Zonemaster::GUI::build_app;
start;
54 changes: 54 additions & 0 deletions share/templates/index.html.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!doctype html>
<html lang="[% lang %]">
<head>
<meta charset="utf-8">
<title>Zonemaster</title>

<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="assets/favicon/zonemaster_57x57.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/favicon/zonemaster_114x114.png" />
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/favicon/zonemaster_72x72.png" />
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/favicon/zonemaster_144x144.png" />
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="assets/favicon/zonemaster_60x60.png" />
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="assets/favicon/zonemaster_120x120.png" />
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="assets/favicon/zonemaster_76x76.png" />
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="assets/favicon/zonemaster_152x152.png" />
<link rel="icon" type="image/png" href="assets/favicon/zonemaster_196x196.png" sizes="196x196" />
<link rel="icon" type="image/png" href="assets/favicon/zonemaster_96x96.png" sizes="96x96" />
<link rel="icon" type="image/png" href="assets/favicon/zonemaster_32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="assets/favicon/zonemaster_16x16.png" sizes="16x16" />
<link rel="icon" type="image/png" href="assets/favicon/zonemaster_128x128.png" sizes="128x128" />
<meta name="application-name" content="Zonemaster">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="assets/favicon/zonemaster_144x144.png">

<meta name="msapplication-square70x70logo" content="assets/favicon/zonemaster_70x70.png" />
<meta name="msapplication-square150x150logo" content="assets/favicon/zonemaster_150x150.png" />
<meta name="msapplication-wide310x150logo" content="assets/favicon/zonemaster_310x150.png" />
<meta name="msapplication-square310x310logo" content="assets/favicon/zonemaster_310x310.png" />
<meta name="theme-color" content="#ffffff">

<base href="[% baseurl %]">
[% FOREACH file_name IN styles %]
<link rel="stylesheet" href="[% file_name %]">
[% END %]
</head>
<body>
<app-root>
<div style="text-align:center">
Loading
</div>
</app-root>


<noscript>
<p>Please enable JavaScript to use this website!</p>
</noscript>

[% FOREACH file_name IN scripts %]
<script src="[% file_name %]" type="module"></script>
[% END %]
</body>
</html>
2 changes: 1 addition & 1 deletion src/environments/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ export const common = {
'sv': 'Svenska'
},
enabledLanguages: [ 'da', 'en', 'es', 'fi', 'fr', 'nb', 'sv' ],
configUrl: 'assets/app.config.json',
configUrl: 'app.config.json',
pollingInterval: 5 * 1000,
}

0 comments on commit 80e36dd

Please sign in to comment.