|
|
@@ -5,7 +5,7 @@ import logging
|
|
|
import re as _re
|
|
|
import zipfile
|
|
|
from collections import defaultdict
|
|
|
-from datetime import date, datetime, time, timedelta, timezone
|
|
|
+from datetime import date, datetime, timedelta, timezone
|
|
|
from html import escape as html_escape
|
|
|
from pathlib import Path
|
|
|
|
|
|
@@ -60,7 +60,7 @@ from backend.app.services.print_storage import (
|
|
|
from backend.app.services.printer_media import VIDEO_SUFFIXES, match_ipcam_chunks
|
|
|
from backend.app.utils.archive_paths import archive_photos_dir, find_archive_photo
|
|
|
from backend.app.utils.http import build_content_disposition, download_error_response, safe_download_filename
|
|
|
-from backend.app.utils.local_time import to_naive_utc
|
|
|
+from backend.app.utils.local_time import day_zone, local_date_end, local_date_start, to_naive_utc
|
|
|
from backend.app.utils.threemf_tools import (
|
|
|
default_plate_gcode_name,
|
|
|
expand_to_project_slots,
|
|
|
@@ -192,7 +192,7 @@ def _visible_archive_clauses(user, can_read_all: bool, printer_scope: PrinterSco
|
|
|
|
|
|
def _ensure_archive_visible(
|
|
|
archive: PrintArchive | None,
|
|
|
- user: User | None,
|
|
|
+ user: User | ApiKeyActor | None,
|
|
|
can_read_all: bool,
|
|
|
printer_scope: PrinterScope,
|
|
|
) -> PrintArchive:
|
|
|
@@ -437,10 +437,13 @@ async def list_archives(
|
|
|
project_id: int | None = None,
|
|
|
date_from: date | None = Query(None),
|
|
|
date_to: date | None = Query(None),
|
|
|
+ tz: str | None = Query(
|
|
|
+ None, max_length=64, description="IANA zone the dates are calendar days in; the server's when omitted"
|
|
|
+ ),
|
|
|
limit: int = 50,
|
|
|
offset: int = 0,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -461,6 +464,7 @@ async def list_archives(
|
|
|
offset=offset,
|
|
|
visible_to_user_id=visible_to_user_id,
|
|
|
printer_scope=printer_scope,
|
|
|
+ day_zone=day_zone(tz),
|
|
|
)
|
|
|
|
|
|
# Get sets of duplicate hashes and duplicate (name, hash) pairs (efficient single queries),
|
|
|
@@ -567,7 +571,7 @@ async def list_archives(
|
|
|
@router.get("/last-per-printer", response_model=list[ArchiveResponse])
|
|
|
async def list_last_archive_per_printer(
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -626,7 +630,7 @@ async def list_last_archive_per_printer(
|
|
|
@router.get("/no-3mf-warning")
|
|
|
async def no_3mf_warning(
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -732,11 +736,14 @@ async def no_3mf_warning(
|
|
|
async def list_archives_slim(
|
|
|
date_from: date | None = Query(None),
|
|
|
date_to: date | None = Query(None),
|
|
|
+ tz: str | None = Query(
|
|
|
+ None, max_length=64, description="IANA zone the dates are calendar days in; the server's when omitted"
|
|
|
+ ),
|
|
|
created_by_id: int | None = Query(None, description="Filter by user who created the print (-1 for no user)"),
|
|
|
limit: int = Query(default=10000, le=50000),
|
|
|
offset: int = 0,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -767,10 +774,10 @@ async def list_archives_slim(
|
|
|
created_by_id = current_user.id
|
|
|
filters = []
|
|
|
if date_from:
|
|
|
- dt_from = datetime.combine(date_from, time.min, tzinfo=timezone.utc)
|
|
|
+ dt_from = local_date_start(date_from, day_zone(tz))
|
|
|
filters.append(PrintLogEntry.created_at >= dt_from)
|
|
|
if date_to:
|
|
|
- dt_to = datetime.combine(date_to, time.max, tzinfo=timezone.utc)
|
|
|
+ dt_to = local_date_end(date_to, day_zone(tz))
|
|
|
filters.append(PrintLogEntry.created_at <= dt_to)
|
|
|
_apply_run_user_filter(filters, created_by_id)
|
|
|
if (clause := printer_scope.where(PrintLogEntry.printer_id)) is not None:
|
|
|
@@ -853,7 +860,7 @@ async def search_archives(
|
|
|
limit: int = 50,
|
|
|
offset: int = 0,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1028,11 +1035,14 @@ async def analyze_failures(
|
|
|
days: int | None = None,
|
|
|
date_from: date | None = Query(None),
|
|
|
date_to: date | None = Query(None),
|
|
|
+ tz: str | None = Query(
|
|
|
+ None, max_length=64, description="IANA zone the dates are calendar days in; the server's when omitted"
|
|
|
+ ),
|
|
|
printer_id: int | None = None,
|
|
|
project_id: int | None = None,
|
|
|
created_by_id: int | None = Query(None, description="Filter by user who created the print (-1 for no user)"),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1066,6 +1076,7 @@ async def analyze_failures(
|
|
|
project_id=project_id,
|
|
|
created_by_id=created_by_id,
|
|
|
printer_scope=printer_scope,
|
|
|
+ day_zone=day_zone(tz),
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -1073,7 +1084,7 @@ async def analyze_failures(
|
|
|
async def compare_archives(
|
|
|
archive_ids: str = Query(..., description="Comma-separated archive IDs (2-5)"),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1140,10 +1151,13 @@ async def export_archives(
|
|
|
status: str | None = None,
|
|
|
date_from: str | None = Query(None, description="Start date (ISO format)"),
|
|
|
date_to: str | None = Query(None, description="End date (ISO format)"),
|
|
|
+ tz: str | None = Query(
|
|
|
+ None, max_length=64, description="IANA zone the dates are calendar days in; the server's when omitted"
|
|
|
+ ),
|
|
|
search: str | None = None,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
printer_scope: PrinterScope = RequestPrinterScope,
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1176,7 +1190,11 @@ async def export_archives(
|
|
|
date_to_dt = None
|
|
|
if date_from:
|
|
|
try:
|
|
|
- date_from_dt = to_naive_utc(datetime.fromisoformat(date_from))
|
|
|
+ # A date on its own is a local calendar day (DB-C12).
|
|
|
+ if len(date_from) == 10:
|
|
|
+ date_from_dt = to_naive_utc(local_date_start(date.fromisoformat(date_from), day_zone(tz)))
|
|
|
+ else:
|
|
|
+ date_from_dt = to_naive_utc(datetime.fromisoformat(date_from))
|
|
|
except (ValueError, OverflowError):
|
|
|
raise HTTPException(400, "Invalid date_from format")
|
|
|
if date_to:
|
|
|
@@ -1184,7 +1202,7 @@ async def export_archives(
|
|
|
# A date on its own ends with that day, as every other date filter
|
|
|
# here reads it; read as midnight it left out the whole day.
|
|
|
if len(date_to) == 10:
|
|
|
- date_to_dt = datetime.combine(date.fromisoformat(date_to), time.max)
|
|
|
+ date_to_dt = to_naive_utc(local_date_end(date.fromisoformat(date_to), day_zone(tz)))
|
|
|
else:
|
|
|
date_to_dt = to_naive_utc(datetime.fromisoformat(date_to))
|
|
|
except (ValueError, OverflowError):
|
|
|
@@ -1260,6 +1278,9 @@ async def export_stats(
|
|
|
async def get_archive_stats(
|
|
|
date_from: date | None = Query(None, description="Start date (inclusive), YYYY-MM-DD"),
|
|
|
date_to: date | None = Query(None, description="End date (inclusive), YYYY-MM-DD"),
|
|
|
+ tz: str | None = Query(
|
|
|
+ None, max_length=64, description="IANA zone the dates are calendar days in; the server's when omitted"
|
|
|
+ ),
|
|
|
created_by_id: int | None = Query(None, description="Filter by user who created the print (-1 for no user)"),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
current_user: User | None = RequirePermissionIfAuthEnabled(Permission.STATS_READ),
|
|
|
@@ -1280,10 +1301,10 @@ async def get_archive_stats(
|
|
|
# Build date filter conditions scoped to PrintLogEntry (event-time).
|
|
|
base_conditions = []
|
|
|
if date_from:
|
|
|
- dt_from = datetime.combine(date_from, time.min, tzinfo=timezone.utc)
|
|
|
+ dt_from = local_date_start(date_from, day_zone(tz))
|
|
|
base_conditions.append(PrintLogEntry.created_at >= dt_from)
|
|
|
if date_to:
|
|
|
- dt_to = datetime.combine(date_to, time.max, tzinfo=timezone.utc)
|
|
|
+ dt_to = local_date_end(date_to, day_zone(tz))
|
|
|
base_conditions.append(PrintLogEntry.created_at <= dt_to)
|
|
|
_apply_run_user_filter(base_conditions, created_by_id)
|
|
|
# Only prints on printers the caller may see (#1727)
|
|
|
@@ -1479,8 +1500,8 @@ async def get_archive_stats(
|
|
|
elif energy_tracking_mode == "total":
|
|
|
# Total consumption mode with a date filter (#941): use hourly snapshots
|
|
|
# to compute per-plug (endpoint - baseline) deltas.
|
|
|
- dt_from = datetime.combine(date_from, time.min, tzinfo=timezone.utc) if date_from else None
|
|
|
- dt_to = datetime.combine(date_to, time.max, tzinfo=timezone.utc) if date_to else None
|
|
|
+ dt_from = local_date_start(date_from, day_zone(tz)) if date_from else None
|
|
|
+ dt_to = local_date_end(date_to, day_zone(tz)) if date_to else None
|
|
|
total_energy_kwh, energy_data_warming_up = await _sum_snapshot_deltas(db, dt_from=dt_from, dt_to=dt_to)
|
|
|
costed = await snapshot_cost(db, fallback_price=energy_cost_per_kwh, dt_from=dt_from, dt_to=dt_to)
|
|
|
total_energy_cost = cost_at_average_price(total_energy_kwh, costed.kwh, costed.cost, energy_cost_per_kwh)
|
|
|
@@ -1650,7 +1671,7 @@ async def _sum_snapshot_deltas(
|
|
|
@router.get("/tags")
|
|
|
async def get_all_tags(
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1782,7 +1803,7 @@ async def delete_tag(
|
|
|
async def get_archive(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1812,7 +1833,7 @@ async def get_archive(
|
|
|
async def get_archive_delete_impact(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1842,7 +1863,7 @@ async def get_archive_delete_impact(
|
|
|
async def list_archive_runs(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1875,7 +1896,7 @@ async def find_similar_archives(
|
|
|
archive_id: int,
|
|
|
limit: int = 10,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -1909,7 +1930,7 @@ async def update_archive(
|
|
|
archive_id: int,
|
|
|
update_data: ArchiveUpdate,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -2068,7 +2089,7 @@ async def update_archive(
|
|
|
async def toggle_favorite(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -2266,7 +2287,7 @@ async def recalculate_all_costs(
|
|
|
async def get_archive_duplicates(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2337,7 +2358,7 @@ async def delete_archive(
|
|
|
),
|
|
|
),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_DELETE_ALL,
|
|
|
Permission.ARCHIVES_DELETE_OWN,
|
|
|
@@ -2407,7 +2428,7 @@ async def download_archive(
|
|
|
archive_id: int,
|
|
|
inline: bool = False,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2440,7 +2461,7 @@ async def download_archive_with_filename(
|
|
|
archive_id: int,
|
|
|
filename: str,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2468,7 +2489,7 @@ async def download_archive_with_filename(
|
|
|
async def create_archive_slicer_token(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2531,7 +2552,7 @@ async def download_archive_for_slicer(
|
|
|
async def get_thumbnail(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2570,7 +2591,7 @@ async def get_thumbnail(
|
|
|
@router.get("/{archive_id}/printer-media")
|
|
|
async def get_archive_printer_media(
|
|
|
archive_id: int,
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2715,7 +2736,7 @@ async def get_archive_printer_media(
|
|
|
@router.post("/{archive_id}/media-download-token")
|
|
|
async def create_archive_media_download_token(
|
|
|
archive_id: int,
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(Permission.ARCHIVES_READ_ALL, Permission.ARCHIVES_READ_OWN)
|
|
|
),
|
|
|
printer_scope: PrinterScope = RequestPrinterScope,
|
|
|
@@ -2771,7 +2792,7 @@ async def download_archive_media_with_token(
|
|
|
async def get_timelapse(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -2817,7 +2838,7 @@ async def get_timelapse(
|
|
|
async def delete_timelapse(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_DELETE_ALL,
|
|
|
Permission.ARCHIVES_DELETE_OWN,
|
|
|
@@ -3280,7 +3301,7 @@ async def upload_timelapse(
|
|
|
async def get_timelapse_info(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -3317,7 +3338,7 @@ async def get_timelapse_thumbnails(
|
|
|
count: int = Query(10, ge=1, le=30),
|
|
|
width: int = Query(160, ge=80, le=320),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -3475,7 +3496,7 @@ async def upload_photo(
|
|
|
archive_id: int,
|
|
|
file: UploadFile = File(...),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -3523,7 +3544,7 @@ async def get_photo(
|
|
|
archive_id: int,
|
|
|
filename: str,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -3575,7 +3596,7 @@ async def delete_photo(
|
|
|
archive_id: int,
|
|
|
filename: str,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_DELETE_ALL,
|
|
|
Permission.ARCHIVES_DELETE_OWN,
|
|
|
@@ -3860,7 +3881,7 @@ async def get_qrcode(
|
|
|
request: Request,
|
|
|
size: int = 200,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -3923,7 +3944,7 @@ async def get_qrcode(
|
|
|
async def get_archive_capabilities(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -4151,7 +4172,7 @@ async def get_gcode(
|
|
|
archive_id: int,
|
|
|
plate: int | None = None,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -4209,7 +4230,7 @@ async def get_gcode(
|
|
|
async def get_plate_preview(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -4436,7 +4457,7 @@ async def upload_archives_bulk(
|
|
|
async def get_archive_plates(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -4758,7 +4779,7 @@ async def get_plate_thumbnail(
|
|
|
archive_id: int,
|
|
|
plate_index: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -4845,7 +4866,7 @@ async def get_filament_requirements(
|
|
|
request_id: str | None = None,
|
|
|
full_slots: bool = False,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5159,7 +5180,7 @@ async def reprint_archive(
|
|
|
async def get_project_page(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5190,7 +5211,7 @@ async def update_project_page(
|
|
|
archive_id: int,
|
|
|
update_data: dict,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -5225,7 +5246,7 @@ async def get_project_image(
|
|
|
archive_id: int,
|
|
|
image_path: str,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_media_token_ownership(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5319,7 +5340,7 @@ async def upload_source_3mf(
|
|
|
archive_id: int,
|
|
|
file: UploadFile = File(...),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -5371,7 +5392,7 @@ async def upload_source_3mf(
|
|
|
async def download_source_3mf(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5406,7 +5427,7 @@ async def download_source_3mf_for_slicer(
|
|
|
archive_id: int,
|
|
|
filename: str,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5437,7 +5458,7 @@ async def download_source_3mf_for_slicer(
|
|
|
async def create_source_slicer_token(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5592,7 +5613,7 @@ async def upload_source_3mf_by_name(
|
|
|
async def delete_source_3mf(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_DELETE_ALL,
|
|
|
Permission.ARCHIVES_DELETE_OWN,
|
|
|
@@ -5630,7 +5651,7 @@ async def upload_f3d(
|
|
|
archive_id: int,
|
|
|
file: UploadFile = File(...),
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_UPDATE_ALL,
|
|
|
Permission.ARCHIVES_UPDATE_OWN,
|
|
|
@@ -5682,7 +5703,7 @@ async def upload_f3d(
|
|
|
async def download_f3d(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_READ_ALL,
|
|
|
Permission.ARCHIVES_READ_OWN,
|
|
|
@@ -5716,7 +5737,7 @@ async def download_f3d(
|
|
|
async def delete_f3d(
|
|
|
archive_id: int,
|
|
|
db: AsyncSession = Depends(get_db),
|
|
|
- auth_result: tuple[User | None, bool] = Depends(
|
|
|
+ auth_result: tuple[User | ApiKeyActor | None, bool] = Depends(
|
|
|
require_ownership_permission(
|
|
|
Permission.ARCHIVES_DELETE_ALL,
|
|
|
Permission.ARCHIVES_DELETE_OWN,
|