mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-08-05 18:11:41 +00:00
Put static assets in a separate directory so they can be delivered directly by nginx
This commit is contained in:
@@ -318,93 +318,78 @@ To set up nginx as a reverse proxy that sits in front of Spothole, first ensure
|
||||
|
||||
Create a file at `/etc/nginx/sites-available/` called `spothole`. Give it the following contents, replacing
|
||||
`spothole.app` with the domain name on which you want to run Spothole. If you changed the port on which Spothole runs,
|
||||
update that on the "proxy_pass" line too.
|
||||
update that on the "proxy_pass" line, and if you installed Spothole somewhere other than `/home/spothole/spothole`,
|
||||
adjust the alias location for serving static files.
|
||||
|
||||
(The latter section, configuring the nginx server to serve static files directly, improves efficiency because it saves
|
||||
Spothole itself from serving JS, CSS etc. files. If you can't do this for some reason, e.g. your nginx and spothole are
|
||||
on different computers, you can omit the `location /static/ {}` block.)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name spothole.app;
|
||||
|
||||
# Global proxy settings
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_buffering on;
|
||||
|
||||
# Pass on IP address and host information to Spothole, in case logging this information is required
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Wellknown area for Lets Encrypt
|
||||
location /.well-known/ {
|
||||
alias /var/www/html/.well-known/;
|
||||
}
|
||||
|
||||
# Load static assets directly from the Spothole webassets directory
|
||||
location /static/ {
|
||||
alias /home/spothole/spothole/webassets/;
|
||||
expires 1h;
|
||||
add_header Cache-Control "public, max-age=3600, must-revalidate";
|
||||
}
|
||||
|
||||
# SSE endpoints
|
||||
location ~ ^/api/v1/(spots|alerts)/stream {
|
||||
location ~ ^/api/v1/(spots|alerts)/stream/? {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
|
||||
# Allow keep-alive
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
# Set correct content type for SSE API calls
|
||||
add_header Content-Type text/event-stream always;
|
||||
|
||||
# Set remove buffering, remove caching, add suitable timeouts for SSE API calls
|
||||
# Remove buffering, remove caching, add suitable timeouts for SSE API calls
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 24h;
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 24h;
|
||||
proxy_set_header X-Accel-Buffering no;
|
||||
add_header Cache-Control no-store always;
|
||||
|
||||
# Allow cross-origin requests to API
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
|
||||
# Pass on IP address and host information to Spothole, in case logging this information is required
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
}
|
||||
|
||||
# Other API endpoints
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
|
||||
# Allow keep-alive
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
# Set up buffering, remove caching, add suitable timeouts for API calls
|
||||
proxy_buffering on;
|
||||
# Remove buffering, remove caching, add suitable timeouts for API calls
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 30s;
|
||||
proxy_connect_timeout 10s;
|
||||
add_header Cache-Control no-store always;
|
||||
|
||||
# Allow cross-origin requests to API
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
|
||||
# Pass on IP address and host information to Spothole, in case logging this information is required
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Static assets
|
||||
# Templated pages
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
|
||||
# Allow keep-alive
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
# Set up buffering and caching, add suitable timeouts for static asset requests
|
||||
proxy_buffering on;
|
||||
proxy_read_timeout 30s;
|
||||
proxy_connect_timeout 10s;
|
||||
add_header Cache-Control "public, max-age=3600, must-revalidate" always;
|
||||
|
||||
# Pass on IP address and host information to Spothole, in case logging this information is required
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
add_header Cache-Control "no-cache, must-revalidate" always;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -467,7 +452,7 @@ To navigate your way around the source code, this list may help.
|
||||
|
||||
*HTML/JS/CSS front-end code*
|
||||
|
||||
* `/webassets` - Root for static files served by the web server
|
||||
* `/webassets` - Root for static files served by the web server. These are all served from a path starting `/static/`.
|
||||
* `/webassets/apidocs` - Contains the OpenAPI spec (`openapi.yml`)
|
||||
* `/webassets/css` - CSS files used by the web front-end
|
||||
* `/webassets/img` - image files used by the web front-end
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import tornado.web
|
||||
|
||||
from core.config import BASE_URL
|
||||
|
||||
|
||||
class ManifestHandler(tornado.web.RequestHandler):
|
||||
"""Handler for manifest.webmanifest, which needs BASE_URL inserted and a custom content-type"""
|
||||
|
||||
def get(self):
|
||||
self.set_header("Content-Type", "application/manifest+json; charset=UTF-8")
|
||||
self.render("manifest.webmanifest", baseurl=BASE_URL)
|
||||
+4
-2
@@ -15,6 +15,7 @@ from server.handlers.api.options import APIOptionsHandler
|
||||
from server.handlers.api.solar_conditions import APISolarConditionsHandler
|
||||
from server.handlers.api.spots import APISpotsHandler, APISpotsStreamHandler
|
||||
from server.handlers.api.status import APIStatusHandler
|
||||
from server.handlers.manifesthandler import ManifestHandler
|
||||
from server.handlers.metrics import PrometheusMetricsHandler
|
||||
from server.handlers.pagetemplate import PageTemplateHandler
|
||||
from server.handlers.quietstaticfilehandler import QuietStaticFileHandler
|
||||
@@ -100,11 +101,12 @@ class WebServer:
|
||||
if ALLOW_SPOTTING:
|
||||
ui_routes += [(r"/add-spot", PageTemplateHandler, {"template_name": "add_spot", **handler_opts})]
|
||||
|
||||
# API docs, Prometheus metrics, and finally static assets are always available regardless of API-only mode.
|
||||
# API docs, Prometheus metrics, webapp manifest and static assets are always available regardless of API-only mode.
|
||||
misc_routes = [
|
||||
(r"/apidocs", PageTemplateHandler, {"template_name": "apidocs", **handler_opts}),
|
||||
(r"/metrics", PrometheusMetricsHandler),
|
||||
(r"/(.*)", QuietStaticFileHandler, {"path": os.path.join(_HERE, "../webassets")})
|
||||
(r"/manifest.webmanifest", ManifestHandler),
|
||||
(r"/static/(.*)", QuietStaticFileHandler, {"path": os.path.join(_HERE, "../webassets")})
|
||||
]
|
||||
|
||||
app = tornado.web.Application(api_routes + ui_routes + misc_routes,
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/js/add-spot.js?v=1784989634"></script>
|
||||
<script src="/static/js/add-spot.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-add-spot").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/js/alerts.js?v=1784989634"></script>
|
||||
<script src="/static/js/alerts.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-alerts").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="text-center mb-4">
|
||||
<img src="/img/logo.png" width="192" height="60" alt="Spothole">
|
||||
<img src="/static/img/logo.png" width="192" height="60" alt="Spothole">
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "skeleton.html" %}
|
||||
{% block body %}
|
||||
<redoc spec-url="/apidocs/openapi.yml"></redoc>
|
||||
<redoc spec-url="/static/apidocs/openapi.yml"></redoc>
|
||||
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
|
||||
{% end %}
|
||||
|
||||
@@ -75,8 +75,8 @@
|
||||
<script>
|
||||
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
|
||||
</script>
|
||||
<script src="/js/spotsbandsandmap.js?v=1784989634"></script>
|
||||
<script src="/js/bands.js?v=1784989634"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1784994589"></script>
|
||||
<script src="/static/js/bands.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-bands").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
+13
-13
@@ -1,26 +1,26 @@
|
||||
{% extends "skeleton.html" %}
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/css/style.css?v=1784989634" type="text/css">
|
||||
<link href="/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
|
||||
<link href="/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
|
||||
<link href="/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/style.css?v=1784994589" type="text/css">
|
||||
<link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
|
||||
<link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
|
||||
<link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
|
||||
|
||||
<script src="/vendor/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="/vendor/js/moment-2.29.4.min.js"></script>
|
||||
<script src="/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
|
||||
<script src="/vendor/js/tinycolor2-1.6.0.min.js"></script>
|
||||
<script src="/static/vendor/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="/static/vendor/js/moment-2.29.4.min.js"></script>
|
||||
<script src="/static/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
|
||||
<script src="/static/vendor/js/tinycolor2-1.6.0.min.js"></script>
|
||||
|
||||
<script src="/js/utils.js?v=1784989634"></script>
|
||||
<script src="/js/ui-ham.js?v=1784989634"></script>
|
||||
<script src="/js/geo.js?v=1784989634"></script>
|
||||
<script src="/js/common.js?v=1784989634"></script>
|
||||
<script src="/static/js/utils.js?v=1784994589"></script>
|
||||
<script src="/static/js/ui-ham.js?v=1784994589"></script>
|
||||
<script src="/static/js/geo.js?v=1784994589"></script>
|
||||
<script src="/static/js/common.js?v=1784994589"></script>
|
||||
{% end %}
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
<nav id="header" class="navbar navbar-expand-lg bg-body p-0 border-bottom">
|
||||
<div class="container-fluid p-0">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/img/logo.png" class="logo" width="192" height="60" alt="Spothole">
|
||||
<img src="/static/img/logo.png" class="logo" width="192" height="60" alt="Spothole">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#navbar-toggler-content" aria-controls="navbar-toggler-content"
|
||||
|
||||
@@ -283,8 +283,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/vendor/js/chart-4.4.9.umd.min.js"></script>
|
||||
<script src="/js/conditions.js?v=1784989634"></script>
|
||||
<script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script>
|
||||
<script src="/static/js/conditions.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-conditions").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"short_name": "Spothole",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"start_url": "https://spothole.app/",
|
||||
"start_url": "{{ baseurl }}",
|
||||
"background_color": "white",
|
||||
"theme_color": "white",
|
||||
"description": "An Amateur Radio spotting tool bringing together DX clusters and outdoor programmes, providing a universal JSON API and web interface.",
|
||||
@@ -13,17 +13,17 @@
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
{
|
||||
"src": "/img/icon-192-pwa.png",
|
||||
"src": "/static/img/icon-192-pwa.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/img/icon-512-pwa.png",
|
||||
"src": "/static/img/icon-512-pwa.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"url": "https://spothole.app"
|
||||
"url": "{{ baseurl }}"
|
||||
}
|
||||
+14
-14
@@ -92,24 +92,24 @@
|
||||
|
||||
<link rel="stylesheet" href="/vendor/css/leaflet-1.9.4.min.css">
|
||||
<link rel="stylesheet" href="/vendor/css/leaflet-extra-markers-1.2.2.min.css">
|
||||
<script src="/vendor/js/leaflet-1.9.4.min.js"></script>
|
||||
<script src="/vendor/js/oms-leaflet-0.2.7.min.js"></script>
|
||||
<script src="/vendor/js/leaflet-providers-2.0.0.js"></script>
|
||||
<script src="/vendor/js/leaflet-extra-markers-1.2.2.min.js"></script>
|
||||
<script src="/vendor/js/leaflet-geodesic-2.7.2.umd.min.js"></script>
|
||||
<script src="/vendor/js/leaflet-vectorgrid-1.3.0.js"></script>
|
||||
<script src="/vendor/js/text-image-0.7.0.js"></script>
|
||||
<script src="/vendor/js/leaflet-terminator-1.1.0.min.js"></script>
|
||||
<script src="/vendor/js/leaflet-maidenhead.js"></script>
|
||||
<script src="/vendor/js/leaflet-ituzones.js"></script>
|
||||
<script src="/vendor/js/leaflet-cqzones.js"></script>
|
||||
<script src="/vendor/js/leaflet-workedallbritainireland.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-1.9.4.min.js"></script>
|
||||
<script src="/static/vendor/js/oms-leaflet-0.2.7.min.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-providers-2.0.0.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-extra-markers-1.2.2.min.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-geodesic-2.7.2.umd.min.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-vectorgrid-1.3.0.js"></script>
|
||||
<script src="/static/vendor/js/text-image-0.7.0.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-terminator-1.1.0.min.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-maidenhead.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-ituzones.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-cqzones.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-workedallbritainireland.js"></script>
|
||||
|
||||
<script>
|
||||
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
|
||||
</script>
|
||||
<script src="/js/spotsbandsandmap.js?v=1784989633"></script>
|
||||
<script src="/js/map.js?v=1784989633"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1784994589"></script>
|
||||
<script src="/static/js/map.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-map").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
content="An Amateur Radio spotting tool bringing together DX clusters and outdoor programmes, providing a universal JSON API and web interface."/>
|
||||
<meta property="og:description"
|
||||
content="An Amateur Radio spotting tool bringing together DX clusters and outdoor programmes, providing a universal JSON API and web interface."/>
|
||||
<link rel="canonical" href="https://spothole.app/"/>
|
||||
<meta property="og:url" content="https://spothole.app/"/>
|
||||
<meta property="og:image" content="https://spothole.app/img/banner.png"/>
|
||||
<meta property="twitter:image" content="https://spothole.app/img/banner.png"/>
|
||||
<link rel="canonical" href="{{ baseurl }}"/>
|
||||
<meta property="og:url" content="{{ baseurl }}"/>
|
||||
<meta property="og:image" content="{{ baseurl }}/static/img/banner.png"/>
|
||||
<meta property="twitter:image" content="{{ baseurl }}/static/img/banner.png"/>
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="author" content="Ian Renton"/>
|
||||
<meta property="og:locale" content="en_GB"/>
|
||||
@@ -26,14 +26,14 @@
|
||||
|
||||
<title>Spothole</title>
|
||||
|
||||
<link rel="icon" type="image/png" href="/img/icon-512.png">
|
||||
<link rel="icon" type="image/png" href="/static/img/icon-512.png">
|
||||
<link rel="apple-touch-icon" href="img/icon-512-pwa.png">
|
||||
<link rel="alternate icon" type="image/png" href="/img/icon-192.png">
|
||||
<link rel="alternate icon" type="image/png" href="/img/icon-32.png">
|
||||
<link rel="alternate icon" type="image/png" href="/img/icon-16.png">
|
||||
<link rel="alternate icon" type="image/png" href="/static/img/icon-192.png">
|
||||
<link rel="alternate icon" type="image/png" href="/static/img/icon-32.png">
|
||||
<link rel="alternate icon" type="image/png" href="/static/img/icon-16.png">
|
||||
<link rel="alternate icon" type="image/x-icon" href="/favicon.ico">
|
||||
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
|
||||
{% block head_extra %}{% end %}
|
||||
</head>
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
<script>
|
||||
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
|
||||
</script>
|
||||
<script src="/js/spotsbandsandmap.js?v=1784989633"></script>
|
||||
<script src="/js/spots.js?v=1784989633"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1784994589"></script>
|
||||
<script src="/static/js/spots.js?v=1784994589"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-spots").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/status.js?v=1784989634"></script>
|
||||
<script src="/static/js/status.js?v=1784994589"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#nav-link-status").addClass("active");
|
||||
|
||||
@@ -4,10 +4,10 @@ from datetime import timedelta
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from requests_cache import CachedSession
|
||||
|
||||
test = os.listdir("./")
|
||||
test = os.listdir("/")
|
||||
for item in test:
|
||||
if item.endswith(".png"):
|
||||
os.remove(os.path.join("./", item))
|
||||
os.remove(os.path.join("/", item))
|
||||
|
||||
cache = CachedSession("/tmp/cache", expire_after=timedelta(days=30))
|
||||
data = cache.get("https://raw.githubusercontent.com/k0swe/dxcc-json/refs/heads/main/dxcc.json").json()
|
||||
|
||||
@@ -184,7 +184,7 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
// Format DX flag
|
||||
let dx_flag = "<i class='fa-solid fa-globe-africa'></i>";
|
||||
if (a["dx_dxcc_id"] && a["dx_dxcc_id"] != null && a["dx_dxcc_id"] !== 0) {
|
||||
dx_flag = `<img src="img/flags/${a['dx_dxcc_id']}.png" class="flag" width="24" alt="${dx_country}" title="${dx_country}"/>`;
|
||||
dx_flag = `<img src="static/img/flags/${a['dx_dxcc_id']}.png" class="flag" width="24" alt="${dx_country}" title="${dx_country}"/>`;
|
||||
}
|
||||
|
||||
// Format dx calls
|
||||
|
||||
@@ -249,7 +249,7 @@ function createNewTableRowsForSpot(s, highlightNew) {
|
||||
dx_flag = "";
|
||||
}
|
||||
if (s["dx_dxcc_id"] && s["dx_dxcc_id"] != null && s["dx_dxcc_id"] !== 0) {
|
||||
dx_flag = `<img src="img/flags/${s['dx_dxcc_id']}.png" class="flag" width="24" alt="${dx_country}" title="${dx_country}"/>`;
|
||||
dx_flag = `<img src="static/img/flags/${s['dx_dxcc_id']}.png" class="flag" width="24" alt="${dx_country}" title="${dx_country}"/>`;
|
||||
}
|
||||
|
||||
// Format the frequency
|
||||
@@ -319,7 +319,7 @@ function createNewTableRowsForSpot(s, highlightNew) {
|
||||
// Format DE flag
|
||||
let de_flag = "<i class='fa-solid fa-circle-question'></i>";
|
||||
if (s["de_dxcc_id"] && s["de_dxcc_id"] != null && s["de_dxcc_id"] !== 0) {
|
||||
de_flag = `<img src="img/flags/${s['de_dxcc_id']}.png" class="flag" width="24" alt="${de_country}" title="${de_country}"/>`;
|
||||
de_flag = `<img src="static/img/flags/${s['de_dxcc_id']}.png" class="flag" width="24" alt="${de_country}" title="${de_country}"/>`;
|
||||
}
|
||||
|
||||
// Format de call
|
||||
|
||||
+52
-23
@@ -1,28 +1,57 @@
|
||||
const CACHE_NAME = 'Spothole';
|
||||
const CACHE_URLS = [
|
||||
'index.html',
|
||||
'./',
|
||||
'apidocs',
|
||||
'apidocs/openapi.yml',
|
||||
'about',
|
||||
'css/style.css',
|
||||
'js/add-spot.js',
|
||||
'js/alerts.js',
|
||||
'js/bands.js',
|
||||
'js/common.js',
|
||||
'js/map.js',
|
||||
'js/spots.js',
|
||||
'js/spotsbandsandmap.js',
|
||||
'js/status.js',
|
||||
'img/logo.png',
|
||||
'img/favicon.ico',
|
||||
'img/icon-32.png',
|
||||
'img/icon-192.png',
|
||||
'img/icon-512.png',
|
||||
'fa/css/fontawesome.min.css',
|
||||
'fa/css/solid.min.css',
|
||||
'fa/webfonts/fa-solid-900.ttf',
|
||||
'fa/webfonts/fa-solid-900.woff2'
|
||||
'static/apidocs/openapi.yml',
|
||||
'static/audio/ping.mp3',
|
||||
'static/css/style.css',
|
||||
'static/js/add-spot.js',
|
||||
'static/js/alerts.js',
|
||||
'static/js/bands.js',
|
||||
'static/js/common.js',
|
||||
'static/js/geo.js',
|
||||
'static/js/map.js',
|
||||
'static/js/spots.js',
|
||||
'static/js/spotsbandsandmap.js',
|
||||
'static/js/status.js',
|
||||
'static/js/ui-ham.js',
|
||||
'static/js/utils.js',
|
||||
'static/img/logo.png',
|
||||
'static/img/favicon.ico',
|
||||
'static/img/icon-32.png',
|
||||
'static/img/icon-192.png',
|
||||
'static/img/icon-512.png',
|
||||
'static/vendor/img/markers_default@2x.png',
|
||||
'static/vendor/img/markers_shadow.png',
|
||||
'static/vendor/img/markers_default.png',
|
||||
'static/vendor/img/markers_shadow@2x.png',
|
||||
'static/vendor/css/bootstrap-5.3.8.min.css',
|
||||
'static/vendor/css/images/marker-icon.png',
|
||||
'static/vendor/css/images/layers-2x.png',
|
||||
'static/vendor/css/images/marker-shadow.png',
|
||||
'static/vendor/css/images/layers.png',
|
||||
'static/vendor/css/images/marker-icon-2x.png',
|
||||
'static/vendor/css/leaflet-extra-markers-1.2.2.min.css',
|
||||
'static/vendor/css/leaflet-1.9.4.min.css',
|
||||
'static/vendor/css/fontawesome-6.7.2.min.css',
|
||||
'static/vendor/css/solid-6.7.2.min.css',
|
||||
'static/vendor/js/jquery-3.7.1.min.js',
|
||||
'static/vendor/js/chart-4.4.9.umd.min.js',
|
||||
'static/vendor/js/oms-leaflet-0.2.7.min.js',
|
||||
'static/vendor/js/leaflet-workedallbritainireland.js',
|
||||
'static/vendor/js/leaflet-providers-2.0.0.js',
|
||||
'static/vendor/js/text-image-0.7.0.js',
|
||||
'static/vendor/js/leaflet-vectorgrid-1.3.0.js',
|
||||
'static/vendor/js/leaflet-ituzones.js',
|
||||
'static/vendor/js/tinycolor2-1.6.0.min.js',
|
||||
'static/vendor/js/bootstrap-5.3.8.bundle.min.js',
|
||||
'static/vendor/js/moment-2.29.4.min.js',
|
||||
'static/vendor/js/leaflet-cqzones.js',
|
||||
'static/vendor/js/leaflet-extra-markers-1.2.2.min.js',
|
||||
'static/vendor/js/leaflet-terminator-1.1.0.min.js',
|
||||
'static/vendor/js/leaflet-1.9.4.min.js',
|
||||
'static/vendor/js/leaflet-geodesic-2.7.2.umd.min.js',
|
||||
'static/vendor/js/leaflet-maidenhead.js',
|
||||
'static/vendor/webfonts/fa-solid-900.ttf',
|
||||
'static/vendor/webfonts/fa-solid-900.woff2'
|
||||
];
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user