Skip to content

feat(import): import content from Yodeck via an extensible import-provider framework - #3144

Merged
vpetersson merged 6 commits into
masterfrom
feat/import-content-yodeck
Jul 8, 2026
Merged

feat(import): import content from Yodeck via an extensible import-provider framework#3144
vpetersson merged 6 commits into
masterfrom
feat/import-content-yodeck

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Issues Fixed

Not associated with a tracked issue. Adds a new capability: migrating content into Anthias from another digital signage platform (the inbound mirror of the existing Migrate-to-Screenly export wizard).

Description

Adds an extensible import-provider framework with Yodeck as the first provider. Built as a framework because more providers are planned as stacked PRs (ScreenCloud, OptiSign, NoviSign, PiSignage) — each is a new module plus one registry entry, with no change to the endpoints, wizard, or CLI.

  • Framework (lib/integrations/): a transport-agnostic ImportProvider ABC + neutral RemoteMediaItem / ImportOutcome dataclasses + a registry. Providers may be REST or GraphQL backed.
  • Yodeck provider: validates an API token, pages through /api/v2/media/, and imports image / video / webpage media (audio / document are skipped with a reported reason). Image/video originals are downloaded into the asset dir and flow through the existing CreateAssetSerializerV2 pipeline (rename → normalise → duration probe); webpages store the URL. Re-imports are idempotent via metadata.import_source.
  • API: POST /api/v2/integrations/import/<provider>/{validate,item} (validate + enumerate in one call; per-item import with live progress), matching the Screenly endpoints' error hygiene.
  • UI: a data-driven "Import content" section in Settings plus a wizard mirroring the Migrate-to-Screenly Alpine flow, with an "Enable imported assets" toggle.
  • CLI: manage.py import_content --provider yodeck --token … [--workspace] [--dry-run].
  • Refactor: extracted the v2 create view's persist + dispatch logic into api.helpers.persist_new_asset so imported and uploaded assets share one code path.
  • Import traffic deliberately does not send the Anthias User-Agent (a self-identifying UA on a competitor's API invites vendor-side blocking).

Follow-ups before this is fully field-ready: the resolver (_resolve_source in yodeck.py) is isolated and defensive but two Yodeck detail-object field names still need confirming against a live token — the key holding a webpage's destination URL, and whether a directly-uploaded image/video exposes an original-file URL (beyond thumbnail_url); if not, those are skipped-with-reason rather than guessed.

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices.
  • I have tested my changes for x86 devices.
  • I added a documentation for the changes I have made (when necessary).

🤖 Generated with Claude Code

…ramework

- add a transport-agnostic ImportProvider framework (registry + Yodeck provider)
- import Yodeck image/video/webpage media as Anthias assets; skip audio/document
- reuse the v2 create pipeline via api.helpers.persist_new_asset (idempotent re-runs)
- expose POST /api/v2/integrations/import/<provider>/{validate,item}
- add a Settings "Import content" wizard and an import_content management command
- cover the provider + endpoints with unit tests

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@vpetersson
vpetersson requested a review from a team as a code owner July 8, 2026 06:27
@vpetersson vpetersson self-assigned this Jul 8, 2026
@vpetersson
vpetersson requested a review from Copilot July 8, 2026 06:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an inbound “import content” capability to Anthias via an extensible import-provider framework, introducing Yodeck as the first provider and wiring it through UI, API, and CLI while reusing the existing asset creation pipeline.

Changes:

  • Introduces ImportProvider/RemoteMediaItem/ImportOutcome abstractions plus a provider registry, with a new Yodeck provider implementation.
  • Adds v2 API endpoints + a new Settings wizard page to validate tokens, enumerate remote media, and import items with progress reporting.
  • Refactors v2 asset creation persistence/dispatch into api.helpers.persist_new_asset and adds a manage.py import_content command.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/anthias_server/lib/integrations/yodeck.py Implements Yodeck REST import provider (token validation, listing, per-item import + download).
src/anthias_server/lib/integrations/registry.py Registers import providers and exposes provider metadata for UI/API/CLI discovery.
src/anthias_server/lib/integrations/base.py Defines provider-neutral contracts and dataclasses for import.
src/anthias_server/lib/integrations/init.py Documents the integrations import subsystem.
src/anthias_server/app/views.py Adds settings import wizard view and injects provider list into Settings page context.
src/anthias_server/app/urls.py Routes the provider-specific import wizard page.
src/anthias_server/app/templates/settings.html Renders “Import content” cards for registered providers.
src/anthias_server/app/templates/import_content.html Implements the Alpine-driven import wizard UI (token → select → progress).
src/anthias_server/app/management/commands/import_content.py Adds CLI for validating/listing/importing content from a provider.
src/anthias_server/api/views/v2.py Adds import validate/item endpoints; refactors asset create path to call persist_new_asset.
src/anthias_server/api/urls/v2.py Registers new v2 import endpoints.
src/anthias_server/api/tests/test_yodeck_import.py Adds unit coverage for provider logic and new endpoints/pages.
src/anthias_server/api/tests/test_assets.py Updates dispatch patching to match persist_new_asset refactor.
src/anthias_server/api/serializers/v2.py Adds request serializers for import validate and import item endpoints.
src/anthias_server/api/helpers.py Introduces persist_new_asset shared persistence/dispatch helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/anthias_server/lib/integrations/yodeck.py
Comment thread src/anthias_server/lib/integrations/yodeck.py Outdated
Comment thread src/anthias_server/api/views/v2.py
vpetersson and others added 2 commits July 8, 2026 06:38
- guard _default_duration against non-numeric input (mypy arg-type)
- narrow the import_item Asset|None branch (mypy assignment)
- drop http:// test literal to clear the SonarCloud new-code security gate
- reuse one provider instance in tests (S5778) and simplify the CLI (S3776)
- add management-command tests

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- scope the Yodeck API token to the Yodeck host on download, never
  forwarding it to a pre-signed CDN original (credential leak)
- correct the pagination stop-condition comment
- return a uniform import-item response shape on error (asset_id/skipped/
  reason present alongside error), matching the success path + schema
- test the download auth-scoping both ways

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- skip Yodeck "webpage" media that resolves to Yodeck-hosted apps/widgets
  (internal URLs that would import as broken assets)
- add a website docs page describing content import, what's supported, and
  what's skipped (audio/documents, apps/internal content, non-downloadable
  originals)

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment thread src/anthias_server/lib/integrations/yodeck.py
Comment thread src/anthias_server/lib/integrations/yodeck.py Outdated
Comment thread src/anthias_server/api/views/v2.py
- restrict URL selection to http(s) (validate_url also accepts rtsp/rtmp)
- sanitise the download file extension to safe .<alnum> so a hostile
  file_extension can't escape the asset directory (path traversal)
- return the uniform error shape from the unknown-provider branch

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…nload

- token is entered as "<label>:<token>" (matches the Yodeck auth header
  "Authorization: Token <label>:<token_value>"), reflected in token_help
- document that arguments.download_from_url is the original-file download
  link for uploaded (source: local) media too — resolves via the existing
  _file_url path (token attached for the Yodeck host, dropped on the S3
  redirect); no code change needed

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@vpetersson
vpetersson merged commit d9f644d into master Jul 8, 2026
9 checks passed
@vpetersson
vpetersson deleted the feat/import-content-yodeck branch July 8, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants