mirror of
https://github.com/bszczuka/steel-training.git
synced 2025-12-21 13:23:02 +01:00
distdance unit conversion to meters
This commit is contained in:
46
app.py
46
app.py
@@ -1,12 +1,15 @@
|
||||
import math
|
||||
|
||||
from flask import Flask, render_template, request, send_file
|
||||
from flask import Flask, render_template, request, send_file, flash, redirect, url_for
|
||||
from weasyprint import HTML
|
||||
from flask_babel import Babel, _
|
||||
|
||||
import io
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
secret_key = os.urandom(24)
|
||||
app.secret_key = secret_key
|
||||
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
|
||||
app.config['BABEL_SUPPORTED_LOCALES'] = ['en', 'pl'] # Add supported languages here
|
||||
app.config['BABEL_DEFAULT_TIMEZONE'] = 'UTC'
|
||||
@@ -154,8 +157,8 @@ def custom():
|
||||
|
||||
@app.route('/generate-pdf', methods=['POST'])
|
||||
def generate_pdf():
|
||||
distance = int(request.form.get('distance', 1) or 1)
|
||||
distance_in_mm = distance * 10
|
||||
distance = float(request.form.get('distance', 1) or 1)
|
||||
distance_in_mm = distance * 1000
|
||||
stage = request.form.get('stage')
|
||||
size = request.form.get('size')
|
||||
distance_type = request.form.get('distance_type')
|
||||
@@ -174,7 +177,7 @@ def generate_pdf():
|
||||
|
||||
rendered_html = render_template(
|
||||
'pdf_template.html',
|
||||
distance=distance_in_mm/10,
|
||||
distance=distance_in_mm/1000,
|
||||
size=size,
|
||||
stage=stage,
|
||||
target_info=target_info,
|
||||
@@ -187,14 +190,14 @@ def generate_pdf():
|
||||
pdf_file = io.BytesIO()
|
||||
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||
pdf_file.seek(0)
|
||||
filename = 'Steel Training - ' + stage.replace('_', ' ') + ' - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||
filename = 'Steel Training - ' + stage.replace('_', ' ') + ' - ' + str(distance) + 'm-' + size + '.pdf'
|
||||
|
||||
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||
|
||||
|
||||
@app.route('/generate-pdf-shootoff', methods=['POST'])
|
||||
def generate_pdf_shootoff():
|
||||
distance = int(request.form.get('distance', 1) or 1)
|
||||
distance = float(request.form.get('distance', 1) or 1) * 100
|
||||
size = request.form.get('size')
|
||||
distance_type = request.form.get('distance_type')
|
||||
target_count = 6
|
||||
@@ -213,7 +216,7 @@ def generate_pdf_shootoff():
|
||||
|
||||
rendered_html = render_template(
|
||||
'pdf_template_shootoff.html',
|
||||
distance=distance,
|
||||
distance=distance/100,
|
||||
size=size,
|
||||
wall_length=wall_length,
|
||||
gap=SHOOTOFF_GAP*scale,
|
||||
@@ -227,13 +230,13 @@ def generate_pdf_shootoff():
|
||||
pdf_file = io.BytesIO()
|
||||
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||
pdf_file.seek(0)
|
||||
filename = 'Steel Training - Shootoff - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||
filename = 'Steel Training - Shootoff - ' + str(distance) + 'm-' + size + '.pdf'
|
||||
|
||||
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||
|
||||
@app.route('/generate-pdf-ipsc', methods=['POST'])
|
||||
def generate_pdf_ipsc():
|
||||
distance = int(request.form.get('distance', 1) or 1)
|
||||
distance = float(request.form.get('distance', 1) or 1) * 100
|
||||
size = request.form.get('size')
|
||||
distance_type = request.form.get('distance_type')
|
||||
target_type = request.form.get('target_type')
|
||||
@@ -252,7 +255,7 @@ def generate_pdf_ipsc():
|
||||
|
||||
rendered_html = render_template(
|
||||
'pdf_template_ipsc.html',
|
||||
distance=distance,
|
||||
distance=round((distance / 100), 2),
|
||||
size=size,
|
||||
wall_length=target_line,
|
||||
target_height=scale * original_target_height,
|
||||
@@ -270,15 +273,20 @@ def generate_pdf_ipsc():
|
||||
pdf_file = io.BytesIO()
|
||||
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||
pdf_file.seek(0)
|
||||
filename = 'Steel Training - IPSC - EL Presidente - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||
filename = 'Steel Training - IPSC - EL Presidente - ' + str(distance) + 'm-' + size + '.pdf'
|
||||
|
||||
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||
|
||||
@app.route('/generate-pdf-custom', methods=['POST'])
|
||||
def generate_pdf_custom():
|
||||
distance = int(request.form.get('distance', 1) or 1)
|
||||
simulated_distance_meters = int(request.form.get('simulated_distance') or 1)
|
||||
simulated_distance = simulated_distance_meters * 100
|
||||
|
||||
distance = float(request.form.get('distance', 1) or 1)
|
||||
simulated_distance = float(request.form.get('simulated_distance') or 1)
|
||||
if distance > simulated_distance:
|
||||
flash(_('Simulated distance cannot be greater than actual distance'), 'danger')
|
||||
|
||||
return redirect(url_for('custom'))
|
||||
|
||||
size = request.form.get('size')
|
||||
target_type = request.form.get('target_type')
|
||||
scale = distance / simulated_distance
|
||||
@@ -297,14 +305,14 @@ def generate_pdf_custom():
|
||||
target_width=scale * original_target_width,
|
||||
gap=scale * IPSC_GAP + scale * original_target_width,
|
||||
target_type=target_type,
|
||||
simulated_distance=simulated_distance_meters
|
||||
simulated_distance=simulated_distance
|
||||
)
|
||||
# return rendered_html
|
||||
|
||||
pdf_file = io.BytesIO()
|
||||
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||
pdf_file.seek(0)
|
||||
filename = 'Steel Training - '+target_type.upper()+' - Sim: ' + str(simulated_distance_meters) + 'm - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||
filename = 'Steel Training - '+target_type.upper()+' - Sim: ' + str(simulated_distance) + 'm - ' + str(distance) + 'm-' + size + '.pdf'
|
||||
|
||||
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||
|
||||
@@ -318,7 +326,6 @@ def calculate_distance(desired_wall_length, stage, size):
|
||||
|
||||
distance = 1
|
||||
step = 1000
|
||||
|
||||
while True:
|
||||
targets = [f't{i}' for i in range(1, 6)]
|
||||
target_info = [_target_info(distance, stage, size, target) for target in targets]
|
||||
@@ -332,7 +339,7 @@ def calculate_distance(desired_wall_length, stage, size):
|
||||
step = step / 10
|
||||
continue
|
||||
distance += step;
|
||||
if distance > 7000:
|
||||
if distance > 25000:
|
||||
break
|
||||
|
||||
return distance
|
||||
@@ -391,7 +398,6 @@ def calculate_distance_shootoff(desired_wall_length, size, target_count):
|
||||
target_line = (target_count - 1) * SHOOTOFF_GAP
|
||||
scale = distance / SHOOTOFF_DISTANCE
|
||||
wall_length = target_line * scale + wall_extra_space_for_paper
|
||||
print(distance, wall_length, desired_wall_length)
|
||||
if abs(wall_length - desired_wall_length) <= 0.5:
|
||||
break
|
||||
if wall_length > desired_wall_length:
|
||||
@@ -399,7 +405,7 @@ def calculate_distance_shootoff(desired_wall_length, size, target_count):
|
||||
step = step / 10
|
||||
continue
|
||||
distance += step;
|
||||
if distance > 700:
|
||||
if distance > 2500:
|
||||
break
|
||||
|
||||
return distance
|
||||
|
||||
@@ -54,6 +54,23 @@
|
||||
Wesprzyj projekt
|
||||
</a>
|
||||
</div>
|
||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||
{% if messages %}
|
||||
<div class="mt-4">
|
||||
{% for category, message in messages %}
|
||||
{% if category == 'danger' %}
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
||||
<strong class="font-bold">{% trans %}Error{% endtrans %}</strong>
|
||||
{%else%}
|
||||
<div class="bg-blue-100 border border-blue-400 text-blue-700 px-4 py-3 rounded relative" role="alert">
|
||||
<strong class="font-bold">{% trans %}Info{% endtrans %}</strong>
|
||||
{%endif%}
|
||||
<span class="block sm:inline">{{ message }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{% include 'setup.html' %}
|
||||
<div class="mb-6 max-w-2xl mx-auto mt-4">
|
||||
<h2>{%trans%}Simulated distance{%endtrans%} [m]</h2>
|
||||
<input type="number" id="simulated_distance" name="simulated_distance" min="1" max="300" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
||||
<input type="number" id="simulated_distance" name="simulated_distance" step="0.1" min="1" max="5000" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
||||
</div>
|
||||
<div class="mb-6 max-w-2xl mx-auto">
|
||||
<h2>{%trans%}Select the target type{%endtrans%}</h2>
|
||||
@@ -19,7 +19,7 @@
|
||||
{% with target_width=5, target_height=5 %}
|
||||
{% include 'ts2_svg.html' %}
|
||||
{% endwith %}
|
||||
<input type="radio" id="ts2" name="target_type" value="ts2" required class="m-1"> <!-- Margin added for spacing -->
|
||||
<input type="radio" id="ts2" name="target_type" value="ts2" required class="m-1">
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between h-full">
|
||||
@@ -28,7 +28,7 @@
|
||||
{% with target_width=3, target_height=8.5 %}
|
||||
{% include 'popper_svg.html' %}
|
||||
{% endwith %}
|
||||
<input type="radio" id="popper" name="target_type" value="popper" required class="m-1"> <!-- Margin added for spacing -->
|
||||
<input type="radio" id="popper" name="target_type" value="popper" required class="m-1">
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between h-full">
|
||||
@@ -37,7 +37,7 @@
|
||||
{% with target_width=4.5, target_height=5.8 %}
|
||||
{% include 'ipsc_svg.html' %}
|
||||
{% endwith %}
|
||||
<input type="radio" id="ipsc" name="target_type" value="ipsc" required class="m-1"> <!-- Margin added for spacing -->
|
||||
<input type="radio" id="ipsc" name="target_type" value="ipsc" required class="m-1">
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between h-full">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Steel Training - {{ stage.split('_') | map('capitalize') | join(' ') }} - {{ distance }} cm
|
||||
<title>Steel Training - {{ stage.split('_') | map('capitalize') | join(' ') }} - {{ distance }}m
|
||||
- {{ size|capitalize }}</title>
|
||||
<style>
|
||||
@page {
|
||||
@@ -83,11 +83,11 @@
|
||||
</div>
|
||||
|
||||
<p>{%trans%}Wall length required{%endtrans%}: {{ wall_length/10 }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance|round(1,'ceil') }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance }}m</p>
|
||||
<p>{%trans%}Stage preparation{%endtrans%}:</p>
|
||||
<ul>
|
||||
<li>{%trans%}Place the first target with the 'ZERO point' marker on the left side of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}cm {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}m {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Ensure that the starting field is positioned in a convenient location within the room, so that nothing obstructs the drawing and aiming at targets across the entire width of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}If necessary, adjust the first target along with the ZERO point and repeat the two previous steps{%endtrans%}</li>
|
||||
<li>{%trans%}Place the remaining targets on the wall according to the distances indicated on the position markers at the bottom of each target. Ensure that all targets are aligned in a single line parallel to the ground{%endtrans%}</li>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Steel Training | {%trans%}Target{%endtrans%}: {{ target_type|upper }} | {%trans%}Simulated distance{%endtrans%}: {{ simulated_distance }}m | {%trans%}Place target on{%endtrans%}: {{distance}}cm</title>
|
||||
<title>Steel Training | {%trans%}Target{%endtrans%}: {{ target_type|upper }} | {%trans%}Simulated distance{%endtrans%}: {{ simulated_distance }}m | {%trans%}Place target on{%endtrans%}: {{distance}}m</title>
|
||||
<style>
|
||||
@page {
|
||||
size: {{size}};
|
||||
@@ -75,7 +75,7 @@
|
||||
{% endwith %}
|
||||
<br>
|
||||
<div class="mounting-info">
|
||||
{%trans%}Target{%endtrans%}: {{ target_type|upper }} | {%trans%}Simulated distance{%endtrans%}: {{ simulated_distance }}m | {%trans%}Place target on{%endtrans%}: {{distance}}cm
|
||||
{%trans%}Target{%endtrans%}: {{ target_type|upper }} | {%trans%}Simulated distance{%endtrans%}: {{ simulated_distance }}m | {%trans%}Place target on{%endtrans%}: {{distance}}m
|
||||
<br>
|
||||
Steel Training
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Steel Training - IPSC - El Presidente - {{ distance }} cm
|
||||
<title>Steel Training - IPSC - El Presidente - {{ distance }} m
|
||||
- {{ size|capitalize }}</title>
|
||||
<style>
|
||||
@page {
|
||||
@@ -76,11 +76,11 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p>{%trans%}Wall length required{%endtrans%}: {{ wall_length|round(1,'ceil') }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance|round(1,'ceil') }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance }}m</p>
|
||||
<p>{%trans%}Stage preparation{%endtrans%}:</p>
|
||||
<ul>
|
||||
<li>{%trans%}Place the first target with the 'ZERO point' marker on the left or right side of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position|round(1,'ceil') }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}cm {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position|round(1,'ceil') }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}m {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Ensure that the starting field is positioned in a convenient location within the room, so that nothing obstructs the drawing and aiming at targets across the entire width of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}If necessary, adjust the first target along with the ZERO point and repeat the two previous steps{%endtrans%}</li>
|
||||
<li>{%trans%}Place the remaining targets on the wall according to the distances indicated on the position markers at the bottom of each target. Ensure that all targets are aligned in a single line parallel to the ground{%endtrans%}</li>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Steel Training - Shootoff - {{ distance }} cm
|
||||
<title>Steel Training - Shootoff - {{ distance }} m
|
||||
- {{ size|capitalize }}</title>
|
||||
<style>
|
||||
@page {
|
||||
@@ -110,11 +110,11 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p>{%trans%}Wall length required{%endtrans%}: {{ wall_length|round(1,'ceil') }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance|round(1,'ceil') }}cm</p>
|
||||
<p>{%trans%}Distance from wall{%endtrans%}: {{ distance }}m</p>
|
||||
<p>{%trans%}Stage preparation{%endtrans%}:</p>
|
||||
<ul>
|
||||
<li>{%trans%}Place the first target with the 'ZERO point' marker on the left or right side of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position|round(1,'ceil') }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}cm {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Set shooting box{%endtrans%} {{ box_position|round(1,'ceil') }}cm {%trans%}from 'ZERO' point (along the wall) and{%endtrans%} {{distance}}m {%trans%}from the wall{%endtrans%}</li>
|
||||
<li>{%trans%}Ensure that the starting field is positioned in a convenient location within the room, so that nothing obstructs the drawing and aiming at targets across the entire width of the wall{%endtrans%}</li>
|
||||
<li>{%trans%}If necessary, adjust the first target along with the ZERO point and repeat the two previous steps{%endtrans%}</li>
|
||||
<li>{%trans%}Place the remaining targets on the wall according to the distances indicated on the position markers at the bottom of each target. Ensure that all targets are aligned in a single line parallel to the ground{%endtrans%}</li>
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
</div>
|
||||
<div class="mb-6 max-w-2xl mx-auto mt-4">
|
||||
<h2>{%trans%}Distance{%endtrans%} [cm]</h2>
|
||||
<input type="number" id="distance" name="distance" min="100" max="700" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
||||
<h2>{%trans%}Distance{%endtrans%} [m]</h2>
|
||||
<input type="number" id="distance" name="distance" step="0.01" min="0.5" max="100" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 max-w-2xl mx-auto mt-10">
|
||||
|
||||
Binary file not shown.
@@ -90,3 +90,9 @@ msgstr "Niestandardowy"
|
||||
|
||||
msgid "Select the target type"
|
||||
msgstr "Wybierz rodzaj celu"
|
||||
|
||||
msgid "Simulated distance cannot be greater than actual distance"
|
||||
msgstr "Dystans symulowany nie może być większy niż dystans od ściany"
|
||||
|
||||
msgid "Error"
|
||||
msgstr "Błąd"
|
||||
Reference in New Issue
Block a user