mirror of
https://github.com/joaovitoriasilva/endurain.git
synced 2026-01-10 08:17:59 -05:00
Support tcx files
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -62,7 +62,7 @@ frontend/app/cypress/screenshots/
|
||||
# Editor directories and files
|
||||
frontend/app/.vscode/*
|
||||
frontend/app/!.vscode/extensions.json
|
||||
frontend/app/.idea
|
||||
.idea
|
||||
frontend/app/*.suo
|
||||
frontend/app/*.ntvs*
|
||||
frontend/app/*.njsproj
|
||||
|
||||
@@ -33,6 +33,7 @@ import activities.activity_streams.schema as activity_streams_schema
|
||||
import activities.activity_workout_steps.crud as activity_workout_steps_crud
|
||||
|
||||
import gpx.utils as gpx_utils
|
||||
import tcx.utils as tcx_utils
|
||||
import fit.utils as fit_utils
|
||||
|
||||
import core.logger as core_logger
|
||||
@@ -296,7 +297,7 @@ def parse_and_store_activity_from_file(
|
||||
if parsed_info is not None:
|
||||
created_activities = []
|
||||
idsToFileName = ""
|
||||
if file_extension.lower() == ".gpx":
|
||||
if file_extension.lower() in (".gpx", ".tcx",):
|
||||
# Store the activity in the database
|
||||
created_activity = store_activity(parsed_info, db)
|
||||
created_activities.append(created_activity)
|
||||
@@ -409,7 +410,7 @@ def parse_and_store_activity_from_uploaded_file(
|
||||
if parsed_info is not None:
|
||||
created_activities = []
|
||||
idsToFileName = ""
|
||||
if file_extension.lower() == ".gpx":
|
||||
if file_extension.lower() in (".gpx", '.tcx'):
|
||||
# Store the activity in the database
|
||||
created_activity = store_activity(parsed_info, db)
|
||||
created_activities.append(created_activity)
|
||||
@@ -519,6 +520,10 @@ def parse_file(
|
||||
user_privacy_settings,
|
||||
db,
|
||||
)
|
||||
elif file_extension.lower() == '.tcx':
|
||||
parsed_info = tcx_utils.parse_tcx_file(
|
||||
filename, token_user_id, user_privacy_settings, db,
|
||||
)
|
||||
elif file_extension.lower() == ".fit":
|
||||
# Parse the FIT file
|
||||
parsed_info = fit_utils.parse_fit_file(filename, db)
|
||||
|
||||
0
backend/app/tcx/__init__.py
Normal file
0
backend/app/tcx/__init__.py
Normal file
70
backend/app/tcx/utils.py
Normal file
70
backend/app/tcx/utils.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import tcxreader
|
||||
import activities.activity.schema as activities_schema
|
||||
|
||||
|
||||
def parse_tcx_file(file, user_id, user_privacy_settings, db):
|
||||
tcx_file = tcxreader.TCXReader().read(file)
|
||||
trackpoints = tcx_file.trackpoints_to_dict()
|
||||
|
||||
lat_lon_waypoints = [{'time': trackpoint['time'],
|
||||
'lat': trackpoint['latitude'],
|
||||
'lon': trackpoint['longitude']}
|
||||
for trackpoint in trackpoints]
|
||||
distance = tcx_file.distance
|
||||
|
||||
activity = activities_schema.Activity(
|
||||
user_id=user_id,
|
||||
name=tcx_file.activity_type,
|
||||
distance=round(distance) if distance else 0,
|
||||
activity_type=1,
|
||||
start_time=tcx_file.start_time.strftime("%Y-%m-%dT%H:%M:%S"),
|
||||
end_time=tcx_file.end_time.strftime("%Y-%m-%dT%H:%M:%S"),
|
||||
total_elapsed_time=(tcx_file.end_time - tcx_file.start_time).total_seconds(),
|
||||
total_timer_time=(tcx_file.end_time - tcx_file.start_time).total_seconds(),
|
||||
hide_start_time=user_privacy_settings.hide_activity_start_time or False,
|
||||
hide_location=user_privacy_settings.hide_activity_location or False,
|
||||
hide_map=user_privacy_settings.hide_activity_map or False,
|
||||
hide_hr=user_privacy_settings.hide_activity_hr or False,
|
||||
hide_power=user_privacy_settings.hide_activity_power or False,
|
||||
hide_cadence=user_privacy_settings.hide_activity_cadence or False,
|
||||
hide_elevation=user_privacy_settings.hide_activity_elevation or False,
|
||||
hide_speed=user_privacy_settings.hide_activity_speed or False,
|
||||
hide_pace=user_privacy_settings.hide_activity_pace or False,
|
||||
hide_laps=user_privacy_settings.hide_activity_laps or False,
|
||||
hide_workout_sets_steps=user_privacy_settings.hide_activity_workout_sets_steps
|
||||
or False,
|
||||
hide_gear=user_privacy_settings.hide_activity_gear or False,
|
||||
)
|
||||
|
||||
laps = [{
|
||||
"start_time": lap.start_time,
|
||||
"start_position_lat": lap.trackpoints[0].latitude,
|
||||
"start_position_long": lap.trackpoints[0].longitude,
|
||||
"end_position_lat": lap.trackpoints[-1].latitude,
|
||||
"end_position_long": lap.trackpoints[-1].longitude,
|
||||
} for lap in tcx_file.laps]
|
||||
|
||||
hr_waypoints = []
|
||||
vel_waypoints = []
|
||||
pace_waypoints = []
|
||||
cad_waypoints = []
|
||||
ele_waypoints = []
|
||||
power_waypoints = []
|
||||
|
||||
return {
|
||||
"activity": activity,
|
||||
"is_elevation_set": bool(ele_waypoints),
|
||||
"ele_waypoints": ele_waypoints,
|
||||
"is_power_set": bool(power_waypoints),
|
||||
"power_waypoints": power_waypoints,
|
||||
"is_heart_rate_set": bool(hr_waypoints),
|
||||
"hr_waypoints": hr_waypoints,
|
||||
"is_velocity_set": bool(vel_waypoints),
|
||||
"vel_waypoints": vel_waypoints,
|
||||
"pace_waypoints": pace_waypoints,
|
||||
"is_cadence_set": bool(cad_waypoints),
|
||||
"cad_waypoints": cad_waypoints,
|
||||
"is_lat_lon_set": bool(lat_lon_waypoints),
|
||||
"lat_lon_waypoints": lat_lon_waypoints,
|
||||
"laps": laps,
|
||||
}
|
||||
64
backend/poetry.lock
generated
64
backend/poetry.lock
generated
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alembic"
|
||||
@@ -50,7 +50,7 @@ sniffio = ">=1.1"
|
||||
|
||||
[package.extras]
|
||||
doc = ["Sphinx (>=8.2,<9.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"]
|
||||
test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"]
|
||||
test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""]
|
||||
trio = ["trio (>=0.26.1)"]
|
||||
|
||||
[[package]]
|
||||
@@ -76,7 +76,7 @@ mongodb = ["pymongo (>=3.0)"]
|
||||
redis = ["redis (>=3.0)"]
|
||||
rethinkdb = ["rethinkdb (>=2.4.0)"]
|
||||
sqlalchemy = ["sqlalchemy (>=1.4)"]
|
||||
test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6", "anyio (>=4.5.2)", "gevent", "pytest", "pytz", "twisted"]
|
||||
test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6 ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "anyio (>=4.5.2)", "gevent ; python_version < \"3.14\"", "pytest", "pytz", "twisted ; python_version < \"3.14\""]
|
||||
tornado = ["tornado (>=4.3)"]
|
||||
twisted = ["twisted"]
|
||||
zookeeper = ["kazoo"]
|
||||
@@ -200,7 +200,7 @@ pyproject_hooks = "*"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
|
||||
test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
|
||||
test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0) ; python_version < \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.11\"", "setuptools (>=67.8.0) ; python_version >= \"3.12\"", "wheel (>=0.36.0)"]
|
||||
typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
|
||||
uv = ["uv (>=0.1.18)"]
|
||||
virtualenv = ["virtualenv (>=20.0.35)"]
|
||||
@@ -528,10 +528,10 @@ files = [
|
||||
cffi = {version = ">=1.14", markers = "platform_python_implementation != \"PyPy\""}
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"]
|
||||
docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs ; python_full_version >= \"3.8.0\"", "sphinx-rtd-theme (>=3.0.0) ; python_full_version >= \"3.8.0\""]
|
||||
docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"]
|
||||
nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"]
|
||||
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
|
||||
nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_full_version >= \"3.8.0\""]
|
||||
pep8test = ["check-sdist ; python_full_version >= \"3.8.0\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
|
||||
sdist = ["build (>=1.0.0)"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi (>=2024)", "cryptography-vectors (==45.0.4)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
|
||||
@@ -553,7 +553,7 @@ files = [
|
||||
wrapt = ">=1.10,<2"
|
||||
|
||||
[package.extras]
|
||||
dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"]
|
||||
dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "distlib"
|
||||
@@ -722,7 +722,7 @@ files = [
|
||||
[package.extras]
|
||||
docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"]
|
||||
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"]
|
||||
typing = ["typing-extensions (>=4.12.2)"]
|
||||
typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""]
|
||||
|
||||
[[package]]
|
||||
name = "findpython"
|
||||
@@ -901,7 +901,7 @@ description = "Lightweight in-process concurrent programming"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"
|
||||
markers = "python_version == \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"
|
||||
files = [
|
||||
{file = "greenlet-3.2.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:1afd685acd5597349ee6d7a88a8bec83ce13c106ac78c196ee9dde7c04fe87be"},
|
||||
{file = "greenlet-3.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:761917cac215c61e9dc7324b2606107b3b292a8349bdebb31503ab4de3f559ac"},
|
||||
@@ -1132,7 +1132,7 @@ httpcore = "==1.*"
|
||||
idna = "*"
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli", "brotlicffi"]
|
||||
brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
|
||||
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (==1.*)"]
|
||||
@@ -1169,12 +1169,12 @@ files = [
|
||||
zipp = ">=3.20"
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||
cover = ["pytest-cov"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
enabler = ["pytest-enabler (>=2.2)"]
|
||||
perf = ["ipython"]
|
||||
test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
|
||||
test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
|
||||
type = ["pytest-mypy"]
|
||||
|
||||
[[package]]
|
||||
@@ -1222,7 +1222,7 @@ files = [
|
||||
|
||||
[package.extras]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
|
||||
test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||
|
||||
[[package]]
|
||||
name = "jaraco-functools"
|
||||
@@ -1240,7 +1240,7 @@ files = [
|
||||
more_itertools = "*"
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||
cover = ["pytest-cov"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
enabler = ["pytest-enabler (>=2.2)"]
|
||||
@@ -1261,7 +1261,7 @@ files = [
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"]
|
||||
test = ["async-timeout ; python_version < \"3.11\"", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"]
|
||||
trio = ["trio"]
|
||||
|
||||
[[package]]
|
||||
@@ -1303,7 +1303,7 @@ pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""}
|
||||
SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""}
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||
completion = ["shtab (>=1.1.0)"]
|
||||
cover = ["pytest-cov"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
@@ -1971,8 +1971,8 @@ psycopg-pool = {version = "*", optional = true, markers = "extra == \"pool\""}
|
||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
binary = ["psycopg-binary (==3.2.9)"]
|
||||
c = ["psycopg-c (==3.2.9)"]
|
||||
binary = ["psycopg-binary (==3.2.9) ; implementation_name != \"pypy\""]
|
||||
c = ["psycopg-c (==3.2.9) ; implementation_name != \"pypy\""]
|
||||
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "isort-psycopg", "isort[colors] (>=6.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "types-shapely (>=2.0)", "wheel (>=0.37)"]
|
||||
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
pool = ["psycopg-pool"]
|
||||
@@ -2102,7 +2102,7 @@ typing-inspection = ">=0.4.0"
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator (>=2.0.0)"]
|
||||
timezone = ["tzdata"]
|
||||
timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
@@ -2650,6 +2650,18 @@ docs = ["autodoc_pydantic", "matplotlib", "myst-nb", "pydata-sphinx-theme", "sph
|
||||
lint = ["mypy", "pre-commit", "ruff", "types-Flask", "types-pytz", "types-requests"]
|
||||
tests = ["pytest", "pytest-cov", "pytest-mock", "pytest-xdist", "responses"]
|
||||
|
||||
[[package]]
|
||||
name = "tcxreader"
|
||||
version = "0.4.11"
|
||||
description = "tcxreader is a reader for Garmin’s TCX file format. It also works well with missing data!"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.6"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "tcxreader-0.4.11-py3-none-any.whl", hash = "sha256:fffff13f81c7f54fff734da91d61b6814d2b1422917a7011f6639281d150fd0e"},
|
||||
{file = "tcxreader-0.4.11.tar.gz", hash = "sha256:27a79f48754a968b801ba80890cfb2ac1835ba27387a257c514b90db73edc20b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "timezonefinder"
|
||||
version = "6.5.9"
|
||||
@@ -2679,7 +2691,7 @@ h3 = ">4"
|
||||
numpy = {version = ">=1.23,<3", markers = "python_version >= \"3.9\""}
|
||||
|
||||
[package.extras]
|
||||
numba = ["numba (>=0.56,<1)", "numba (>=0.59,<1)"]
|
||||
numba = ["numba (>=0.56,<1) ; python_version < \"3.12\"", "numba (>=0.59,<1) ; python_version >= \"3.12\""]
|
||||
pytz = ["pytz (>=2022.7.1)"]
|
||||
|
||||
[[package]]
|
||||
@@ -2820,7 +2832,7 @@ files = [
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
|
||||
h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
@@ -2857,7 +2869,7 @@ click = ">=7.0"
|
||||
h11 = ">=0.8"
|
||||
|
||||
[package.extras]
|
||||
standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
||||
standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
@@ -2878,7 +2890,7 @@ platformdirs = ">=3.9.1,<5"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
|
||||
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
|
||||
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""]
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
@@ -3148,7 +3160,7 @@ files = [
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||
cover = ["pytest-cov"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
enabler = ["pytest-enabler (>=2.2)"]
|
||||
@@ -3271,4 +3283,4 @@ cffi = ["cffi (>=1.11)"]
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "^3.13"
|
||||
content-hash = "d6f9d91d8b95294866ac83f2a641bac39544f7853bcd85f7cc414ba57cd13767"
|
||||
content-hash = "472146eccb12487e040b0ca73accec16bf22ee68dcd4e5f3cce6e62d65951d0b"
|
||||
|
||||
@@ -20,6 +20,7 @@ opentelemetry-instrumentation-fastapi = "^0.49b0"
|
||||
opentelemetry-exporter-otlp = "^1.25.0"
|
||||
python-multipart = "^0.0.20"
|
||||
gpxpy = "^1.6.2"
|
||||
tcxreader = "^0.4.11"
|
||||
alembic = "^1.14.0"
|
||||
joserfc = "^1.0.1"
|
||||
bcrypt = "^4.2.1"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<div class="modal-body">
|
||||
<!-- date fields -->
|
||||
<label for="activityGpxFileAdd"><b>* {{ $t("homeView.fieldLabelUploadGPXFile") }}</b></label>
|
||||
<input class="form-control mt-1 mb-1" type="file" name="activityGpxFileAdd" accept=".gpx,.fit" required>
|
||||
<input class="form-control mt-1 mb-1" type="file" name="activityGpxFileAdd" accept=".gpx,.fit,.tcx" required>
|
||||
<p>* {{ $t("generalItems.requiredField") }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
Reference in New Issue
Block a user