[trails] Add auto GPX and FIT file importing
All checks were successful
build & deploy / test (push) Successful in 1m51s
build & deploy / build-and-deploy (push) Successful in 32s

This commit is contained in:
2026-05-21 10:52:23 -04:00
parent 08152de086
commit cb50de13c0
17 changed files with 4012 additions and 8 deletions

View File

@ -1,9 +1,11 @@
import logging
import os
import tempfile
from books.koreader import fetch_file_from_webdav
from profiles.models import UserProfile
from scrobbles.models import KoReaderImport
from scrobbles.tasks import process_koreader_import
from scrobbles.models import KoReaderImport, TrailGPXImport
from scrobbles.tasks import process_koreader_import, process_trail_gpx_import
from scrobbles.utils import get_file_md5_hash
from webdav.client import get_webdav_client
@ -13,7 +15,6 @@ logger = logging.getLogger(__name__)
def import_from_webdav_for_all_users(restart=False):
"""Grab a list of all users with WebDAV enabled and kickoff imports for them"""
# WebDavImport = apps.get_model("scrobbles", "WebDavImport")
webdav_enabled_user_ids = UserProfile.objects.filter(
webdav_url__isnull=False,
webdav_user__isnull=False,
@ -23,6 +24,7 @@ def import_from_webdav_for_all_users(restart=False):
logger.info(f"Start import of {webdav_enabled_user_ids.count()} webdav accounts")
koreader_import_count = 0
trail_gpx_import_count = 0
for user_id in webdav_enabled_user_ids:
webdav_client = get_webdav_client(user_id)
@ -78,4 +80,54 @@ def import_from_webdav_for_all_users(restart=False):
process_koreader_import.delay(koreader_import.id)
koreader_import_count += 1
return koreader_import_count
trail_gpx_import_count += scan_webdav_for_gpx(webdav_client, user_id)
return koreader_import_count, trail_gpx_import_count
def scan_webdav_for_gpx(webdav_client, user_id):
try:
webdav_client.info("gpx/")
except:
logger.info("No gpx/ directory on webdav", extra={"user_id": user_id})
return 0
try:
files = webdav_client.list("gpx/")
except Exception as e:
logger.warning("Could not list gpx/", extra={"user_id": user_id, "error": str(e)})
return 0
gpx_extensions = (".gpx", ".fit")
new_imports = 0
already_imported = set(
TrailGPXImport.objects.filter(user_id=user_id)
.values_list("original_filename", flat=True)
)
for fname in files:
fname = os.path.basename(fname)
if not fname.lower().endswith(gpx_extensions):
continue
if fname in already_imported:
logger.debug(f"Skipping already-imported {fname}")
continue
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=fname)
try:
webdav_client.download_sync(remote_path=f"gpx/{fname}", local_path=tmp.name)
imp = TrailGPXImport.objects.create(
user_id=user_id,
original_filename=fname,
)
with open(tmp.name, "rb") as f:
imp.gpx_file.save(fname, f, save=True)
process_trail_gpx_import.delay(imp.id)
new_imports += 1
except Exception as e:
logger.error(f"Failed to import {fname}: {e}")
finally:
os.unlink(tmp.name)
return new_imports