Allow to upload ADIF files

This commit is contained in:
Thomas Kolb 2023-11-16 22:45:44 +01:00
parent 36bf7cb02f
commit 40f004c81a
5 changed files with 45 additions and 15 deletions

View file

@ -570,7 +570,7 @@ def render(ref_lat, ref_lon, output_stream, adif_stream):
.marker_label { .marker_label {
fill: blue; fill: blue;
font-size: 2px; font-size: 8px;
font-family: sans-serif; font-family: sans-serif;
text-anchor: middle; text-anchor: middle;
} }

View file

@ -4,15 +4,12 @@ function update_map(event)
document.getElementById("svgcontainer").innerHTML = '<p id="loading">Generating, please wait…</p>'; document.getElementById("svgcontainer").innerHTML = '<p id="loading">Generating, please wait…</p>';
var lat = document.getElementById('lat').value; var formdata = new FormData(document.getElementById('mapinfo'));
var lon = document.getElementById('lon').value;
request_url = new URL("/render/map.svg", document.URL);
request_url.searchParams.append("lat", lat);
request_url.searchParams.append("lon", lon);
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.open("GET", request_url);
request.open("POST", "/render/map.svg", true);
//request.setRequestHeader('Content-type', 'multipart/form-data');
request.addEventListener('load', function(event) { request.addEventListener('load', function(event) {
if (request.status >= 200 && request.status < 300) { if (request.status >= 200 && request.status < 300) {
@ -31,11 +28,11 @@ function update_map(event)
link.innerHTML = "Download this map."; link.innerHTML = "Download this map.";
link_container.appendChild(link); // Or append it whereever you want link_container.appendChild(link); // Or append it whereever you want
URL.revokeObjectURL(blobUrl); //URL.revokeObjectURL(blobUrl);
} else { } else {
console.warn(request.statusText, request.responseText); console.warn(request.statusText, request.responseText);
} }
}); });
request.send(); request.send(formdata);
} }

View file

@ -31,6 +31,11 @@ div.form * input[type=text] {
text-align: right; text-align: right;
} }
div.form * input[type=file] {
flex: 3;
margin-left: 1em;
}
div.form * input[type=submit] { div.form * input[type=submit] {
flex: 1; flex: 1;
} }

View file

@ -12,10 +12,11 @@
<body> <body>
<h1>QSOMap: Azimuthal-equidistant SVG map generator</h1> <h1>QSOMap: Azimuthal-equidistant SVG map generator</h1>
<p>Here you can generate a map in <a href="https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection">azimuthal-equidistant projection</a> for any point on Earth. You get a map where the specified coordinate is in the center, and all other locations are projected such that locations with the same physical distance from the given coordinate are also the same distance from the center on the map.</p> <p>Here you can generate a map in <a href="https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection">azimuthal-equidistant projection</a> for any point on Earth. You get a map where the specified coordinate is in the center, and all other locations are projected such that locations with the same physical distance from the given coordinate are also the same distance from the center on the map.</p>
<p>You can optionally upload an ADIF file. All QSOs that have a QTH locator attached are then marked on the map.</p>
<p>The generated output is a Scalable Vector Graphics (SVG) image that can be edited as needed. I recommend <a href="https://inkscape.org">Inkscape</a> as an SVG editor.</p> <p>The generated output is a Scalable Vector Graphics (SVG) image that can be edited as needed. I recommend <a href="https://inkscape.org">Inkscape</a> as an SVG editor.</p>
<p><strong>Please note:</strong> It may take a few seconds to generate the map. Please give it some time. The map will appear below the form along with a download link. If you have JavaScript disabled, the map will replace this page.</p> <p><strong>Please note:</strong> It may take a few seconds to generate the map. Please give it some time. The map will appear below the form along with a download link. If you have JavaScript disabled, the map will replace this page.</p>
<div class="form"> <div class="form">
<form action="/render/map.svg" onsubmit="update_map(event);"> <form id="mapinfo" action="/render/map.svg" onsubmit="update_map(event);">
<div> <div>
<label for="lat">Map center latitude:</label> <label for="lat">Map center latitude:</label>
<input type="text" id="lat" name="lat" value="49.585"> <input type="text" id="lat" name="lat" value="49.585">
@ -24,6 +25,10 @@
<label for="lon">Map center longitude:</label> <label for="lon">Map center longitude:</label>
<input type="text" id="lon" name="lon" value="11.015"> <input type="text" id="lon" name="lon" value="11.015">
</div> </div>
<div>
<label for="adif">ADIF file (optional):</label>
<input type="file" id="adif" name="adif">
</div>
<div> <div>
<input type="submit" value="Generate!"> <input type="submit" value="Generate!">
</div> </div>

31
web.py
View file

@ -1,15 +1,38 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from bottle import Bottle, request, response, template, static_file from bottle import Bottle, request, response, template, static_file
from io import StringIO from io import StringIO, BytesIO
import qsomap import qsomap
app = application = Bottle() app = application = Bottle()
@app.route('/render/map.svg') @app.get('/render/map.svg')
@app.post('/render/map.svg')
def render(): def render():
svg_stream = StringIO() svg_stream = StringIO()
qsomap.render(float(request.query.lat), float(request.query.lon), svg_stream, None)
adiffile = request.files.get('adif')
if adiffile and len(adiffile.filename) > 0:
if adiffile.filename[-4:] not in ['.adi', '.adf'] and adiffile.filename[-5:] not in ['.adif']:
return "File extension not allowed."
if adiffile.content_length > 1024 * 1024:
return "Maximum allowed ADIF file size: 1 MiB."
# parse ADIF data as UTF-8
adif_bytes = adiffile.file.read()
adif_unicode = adif_bytes.decode('utf-8')
print("==========================================")
print(adif_unicode)
print("==========================================")
adif_stream = StringIO(adif_unicode)
qsomap.render(float(request.params.lat), float(request.params.lon), svg_stream, adif_stream)
else:
qsomap.render(float(request.params.lat), float(request.params.lon), svg_stream, None)
response.content_type = 'image/svg+xml' response.content_type = 'image/svg+xml'
return svg_stream.getvalue() return svg_stream.getvalue()
@ -25,4 +48,4 @@ def send_static(filename):
return static_file(filename, root='./static') return static_file(filename, root='./static')
if __name__ == "__main__": if __name__ == "__main__":
app.run(host='localhost', port=8080) app.run(host='localhost', port=8080, debug=True)