Skip to content

Feat: Import schedule and speakers #2629

Merged
mariobehling merged 3 commits intofossasia:devfrom
ArnavBallinCode:test/import-sessions-speakers-v2
Apr 1, 2026
Merged

Feat: Import schedule and speakers #2629
mariobehling merged 3 commits intofossasia:devfrom
ArnavBallinCode:test/import-sessions-speakers-v2

Conversation

@ArnavBallinCode
Copy link
Copy Markdown
Member

@ArnavBallinCode ArnavBallinCode commented Feb 28, 2026

End-to-End Speaker/Session CSV Import + Organizer Schedule Editor Fixes

image image image image image image image image image Screenshot 2026-03-26 at 5 13 27 PM

This PR adds a complete organizer-side import flow for speakers and sessions from CSV, including mapping UI, async processing, data upsert logic, and schedule assignment support.

It also fixes organizer-only rendering issues in the schedule editor that could make sessions appear in public/frontend schedule views but not in the organizer editor.

What was happening before

  • Organizers had no full CSV import workflow for speakers/sessions in the navigation and orga views.
  • Session import did not reliably create or recover rooms for scheduling.
  • Async “processing” waiting pages could get stuck on transient backend errors.
  • Organizer schedule editor could show an empty grid when talk dates were outside event start/end window, even though sessions existed and rendered in other schedule views.
  • Some schedule API room description payloads could be null-like and break strict editor parsing.

What this PR changes

1) Organizer CSV import flows (new end-to-end UX)

  • Adds organizer navigation entries for speaker/session import.
  • Adds routes and views for:
    • Speaker CSV upload and column mapping flow.
    • Session CSV upload and column mapping flow.
  • Adds import templates for upload + mapping + preview/process pages.

2) New import mapping forms

  • Adds reusable CSV import form utilities and concrete mapping forms for speakers and sessions.
  • Supports CSV header normalization, suggestions, and static values.
  • Persists import mapping settings via event settings so organizers do not remap every run.
  • Supports mapping of dynamic submission questions (question_<id> fields).

3) Async import task plumbing

  • Registers talkimport task module.
  • Adds robust async processing flow for speaker/session imports.
  • Returns structured import result summary (created, updated, skipped, errors) for user feedback.

4) Speaker import behavior

  • Upserts speakers by identifier/code and email fallback.
  • Applies optional profile/user fields (locale, avatar metadata, biography).
  • Creates/updates SpeakerProfile as needed.
  • Links imported speakers to submissions by code/pk/title references.

5) Session import behavior

  • Upserts sessions by code and title fallback.
  • Resolves submission type, track, state, tags, duration, locale, notes, and question answers.
  • Ensures talk slots exist for WIP schedule visibility.
  • Imports start/end when present.
  • Links speakers from mapped fields.
  • Resolves room by exact/fuzzy/pk match, undeletes soft-deleted rooms, and creates missing rooms.
  • Creates imported rooms with safe defaults and appends to in-memory caches for same-run reuse.

6) Organizer schedule editor rendering fixes

  • Fixes room description serialization for schedule API so empty descriptions are emitted safely.
  • Expands schedule editor day tabs to include actual talk start dates, not only event date bounds.
    • This fixes cases where sessions exist (and render in other schedule views) but do not appear in organizer editor due to date-window mismatch.

7) Async waiting-page resilience

  • Replaces fragile jQuery polling logic with fetch-based polling.
  • Adds retry/backoff and error recovery behavior.
  • Keeps redirect behavior once async task completes.
  • Removes now-unneeded jQuery include from waiting page template.

8) Config and platform updates

  • Increases CSV upload limit from 1 MB to 10 MB for import use cases.
  • Adds event URL helpers for new import endpoints.
  • Wires default settings for speaker/submission import mappings.

What happens when (runtime flow)

Speaker import

  1. Organizer opens Speaker Import from orga nav.
  2. Uploads CSV.
  3. Maps columns in process form (with suggestions/static values).
  4. Async task runs and upserts users/profiles and links to submissions.
  5. Organizer gets completion message with created/updated/skipped/errors.

Session import

  1. Organizer opens Session Import from orga nav.
  2. Uploads CSV.
  3. Maps columns in process form.
  4. Async task upserts submissions, ensures talk slots, links speakers, applies schedule fields.
  5. Missing rooms are resolved/undeleted/created as needed.
  6. Imported sessions become available in schedule editor and can be released.

Schedule editor

  • Editor now computes visible day range from both:
    • event start/end, and
    • talk start dates in payload.
  • This prevents organizer-only “empty grid” when talk dates differ from event date window.

Edge cases covered

  • Missing/expired uploaded CSV file.
  • Invalid or empty parsed CSV.
  • Missing required speaker/session identity fields.
  • Identifier/code overflow constraints.
  • Soft-deleted room recovery.
  • Duplicate room names in same import run.
  • Unknown state/type/track fallback behavior.
  • Transient async polling failures and temporary backend pressure.
  • Empty/null-like room descriptions in schedule payload.

Summary

Adds organizer CSV import for speakers and sessions with async processing and event-scoped mapping settings.

Key Behavior

  • Imports run through Celery tasks and return created/updated/skipped/error summaries.
  • Missing/expired cached upload files now redirect safely back to upload step.
  • Speaker matching supports event profile by code, global user by code, and email fallback.
  • Session upsert is by code then title fallback.
  • Speaker-session linking works in both import orders (sessions->speakers and speakers->sessions).
  • Start/end/room mapping is applied to WIP talk slots when slot exists.

Stability Fixes

  • Registered talk import tasks in Celery autodiscovery (base/tasks.py).
  • Sanitized row-level DB errors for user-facing responses.
  • Added length-safe handling/fallback for imported speaker/session IDs.

Config

  • CSV upload size limit is validated via MAX_SIZE_CONFIG[UPLOAD_SIZE_CSV] (default currently 10 MB).

Files Updated in Final Patch

  • app/eventyay/base/services/talkimport.py
  • app/eventyay/base/tasks.py
  • app/eventyay/orga/views/speaker.py
  • app/eventyay/orga/views/submission.py

Copilot AI review requested due to automatic review settings February 28, 2026 14:52
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Feb 28, 2026

Reviewer's Guide

Adds a two-step CSV-based import flow for speakers and sessions in the organizer UI, wiring new upload & mapping forms to Celery-backed import tasks that upsert users, speaker profiles, submissions, links, and metadata based on configurable column mappings stored in event settings.

Sequence diagram for the new speaker CSV import flow

sequenceDiagram
    actor Organizer
    participant Browser
    participant SpeakerImportView
    participant CachedFile
    participant SpeakerImportProcessView
    participant CeleryBroker
    participant import_speakers
    participant Database

    Organizer->>Browser: Open speakers_import URL
    Browser->>SpeakerImportView: GET speakers/import/
    SpeakerImportView-->>Browser: Render CSVImportForm

    Organizer->>Browser: Select CSV and submit form
    Browser->>SpeakerImportView: POST speakers/import/ (file)
    SpeakerImportView->>CachedFile: create(expires, file, filename speaker_import.csv)
    SpeakerImportView-->>Browser: Redirect to speakers/import/<file_id>/

    Organizer->>Browser: Follow redirect
    Browser->>SpeakerImportProcessView: GET speakers/import/<file_id>/
    SpeakerImportProcessView->>CachedFile: get(file_id, filename speaker_import.csv)
    SpeakerImportProcessView->>Database: parse_csv(file)
    SpeakerImportProcessView-->>Browser: Render SpeakerImportProcessForm + preview

    Organizer->>Browser: Submit column mapping
    Browser->>SpeakerImportProcessView: POST speakers/import/<file_id>/ (mapping)
    SpeakerImportProcessView->>Database: Save event.settings.speaker_import_settings
    SpeakerImportProcessView->>CeleryBroker: Enqueue task import_speakers(event_id, file_id, settings, locale, user_id)
    SpeakerImportProcessView-->>Browser: Render AsyncAction polling page

    loop Until task finished
        Browser->>SpeakerImportProcessView: GET speakers/import/<file_id>/?async_id=...
        SpeakerImportProcessView->>CeleryBroker: Check task state
        CeleryBroker-->>SpeakerImportProcessView: Task pending or finished
        SpeakerImportProcessView-->>Browser: Progress or redirect
    end

    CeleryBroker->>import_speakers: Run task
    import_speakers->>CachedFile: get(file_id)
    import_speakers->>Database: parse_csv(file)
    loop For each CSV row
        import_speakers->>Database: Upsert User, SpeakerProfile, SpeakerRole
        import_speakers->>Database: event.log_action eventyay.speaker.imported
    end
    import_speakers->>CachedFile: delete(file)
    import_speakers-->>CeleryBroker: Task success

    SpeakerImportProcessView-->>Browser: Redirect to speakers list on success
Loading

Sequence diagram for the new session CSV import flow

sequenceDiagram
    actor Organizer
    participant Browser
    participant SubmissionImportView
    participant CachedFile
    participant SubmissionImportProcessView
    participant CeleryBroker
    participant import_submissions
    participant Database

    Organizer->>Browser: Open submissions_import URL
    Browser->>SubmissionImportView: GET submissions/import/
    SubmissionImportView-->>Browser: Render CSVImportForm

    Organizer->>Browser: Select CSV and submit form
    Browser->>SubmissionImportView: POST submissions/import/ (file)
    SubmissionImportView->>CachedFile: create(expires, file, filename session_import.csv)
    SubmissionImportView-->>Browser: Redirect to submissions/import/<file_id>/

    Organizer->>Browser: Follow redirect
    Browser->>SubmissionImportProcessView: GET submissions/import/<file_id>/
    SubmissionImportProcessView->>CachedFile: get(file_id, filename session_import.csv)
    SubmissionImportProcessView->>Database: parse_csv(file)
    SubmissionImportProcessView-->>Browser: Render SessionImportProcessForm + preview

    Organizer->>Browser: Submit column mapping
    Browser->>SubmissionImportProcessView: POST submissions/import/<file_id>/ (mapping)
    SubmissionImportProcessView->>Database: Save event.settings.submission_import_settings
    SubmissionImportProcessView->>CeleryBroker: Enqueue task import_submissions(event_id, file_id, settings, locale, user_id)
    SubmissionImportProcessView-->>Browser: Render AsyncAction polling page

    loop Until task finished
        Browser->>SubmissionImportProcessView: GET submissions/import/<file_id>/?async_id=...
        SubmissionImportProcessView->>CeleryBroker: Check task state
        CeleryBroker-->>SubmissionImportProcessView: Task pending or finished
        SubmissionImportProcessView-->>Browser: Progress or redirect
    end

    CeleryBroker->>import_submissions: Run task
    import_submissions->>CachedFile: get(file_id)
    import_submissions->>Database: parse_csv(file)
    loop For each CSV row
        import_submissions->>Database: Upsert Submission, SpeakerRole, SpeakerProfile, Room assignment, Tags, Answers
        import_submissions->>Database: event.log_action eventyay.submission.imported
    end
    import_submissions->>CachedFile: delete(file)
    import_submissions-->>CeleryBroker: Task success

    SubmissionImportProcessView-->>Browser: Redirect to submissions list on success
Loading

Class diagram for new CSV import forms, helpers, and views

classDiagram
    class CSVImportForm {
        +FileField file
        +clean_file()
    }

    class ImportField {
        +str identifier
        +str label
        +bool required
        +str help_text
        +list~str~ suggestions
        +Iterable static_choices
    }

    class SpeakerImportProcessForm {
        -list~str~ headers
        -Event event
        -dict~str,str~ _initial_data
        +__init__(*args, headers, event, initial, **kwargs)
        -_find_suggestion(field_spec)
        +clean()
    }

    class SessionImportProcessForm {
        -list~str~ headers
        -Event event
        -dict~str,str~ _initial_data
        +__init__(*args, headers, event, initial, **kwargs)
        -_find_suggestion(field_spec)
        -_add_question_fields()
        +clean()
    }

    class SpeakerImportView {
        +permission_required
        +template_name
        +form_class
        +form_valid(form)
    }

    class SpeakerImportProcessView {
        +permission_required
        +template_name
        +form_class
        +task
        +known_errortypes
        +file
        +parsed
        +get_form_kwargs()
        +preview_rows()
        +headers()
        +get(request, *args, **kwargs)
        +form_valid(form)
        +get_success_url(value)
        +get_error_url()
        +get_success_message(value)
    }

    class SubmissionImportView {
        +permission_required
        +template_name
        +form_class
        +form_valid(form)
    }

    class SubmissionImportProcessView {
        +permission_required
        +template_name
        +form_class
        +task
        +known_errortypes
        +file
        +parsed
        +get_form_kwargs()
        +preview_rows()
        +headers()
        +get(request, *args, **kwargs)
        +form_valid(form)
        +get_success_url(value)
        +get_error_url()
        +get_success_message(value)
    }

    class ImportExecutionError {
    }

    class ProfiledEventTask {
    }

    class ImportTasksModule {
        +import_speakers(event, fileid, settings, locale, user)
        +import_submissions(event, fileid, settings, locale, user)
        +_import_speaker_row(event, settings, record, acting_user)
        +_import_submission_row(event, settings, record, acting_user)
        +_resolve_csv(mapping_value, record)
        +_truthy(value)
        +_find_submission_by_ref(event, ref)
        +_find_user_for_speaker(event, ref)
        +_safe_int(value)
        +_set_question_answer(submission, question_id, answer_text)
    }

    class DjangoForm {
    }

    class EventPermissionRequired {
    }

    class FormView {
    }

    class AsyncAction {
    }

    CSVImportForm --|> DjangoForm
    SpeakerImportProcessForm --|> DjangoForm
    SessionImportProcessForm --|> DjangoForm

    SpeakerImportView --|> EventPermissionRequired
    SpeakerImportView --|> FormView

    SubmissionImportView --|> EventPermissionRequired
    SubmissionImportView --|> FormView

    SpeakerImportProcessView --|> EventPermissionRequired
    SpeakerImportProcessView --|> AsyncAction
    SpeakerImportProcessView --|> FormView

    SubmissionImportProcessView --|> EventPermissionRequired
    SubmissionImportProcessView --|> AsyncAction
    SubmissionImportProcessView --|> FormView

    ImportField <.. SpeakerImportProcessForm
    ImportField <.. SessionImportProcessForm

    ImportExecutionError <.. ImportTasksModule
    ProfiledEventTask <.. ImportTasksModule
Loading

File-Level Changes

Change Details Files
Introduce async CSV import pipeline for speakers and sessions backed by CachedFile storage and Celery tasks.
  • Add views for uploading CSVs, persisting them as CachedFile objects, and redirecting to per-file import processing URLs.
  • Implement AsyncAction-based process views that parse CSV headers, build mapping forms, show a small preview, save chosen mappings into event settings, and dispatch Celery tasks.
  • Wire new URL routes for speaker and submission import, including per-file processing endpoints.
app/eventyay/orga/views/speaker.py
app/eventyay/orga/views/submission.py
app/eventyay/orga/urls.py
app/eventyay/base/models/event.py
app/eventyay/base/configurations/default_setting.py
Add CSV mapping forms and header auto-matching utilities for speakers and sessions, including dynamic fields for submission questions.
  • Define CSVImportForm with file-type and size validation constrained by MAX_SIZE_CONFIG.
  • Create SpeakerImportProcessForm and SessionImportProcessForm that build ChoiceFields from detected CSV headers and optional static choices, with validation for required mappings (e.g., title, name).
  • Implement header normalization and fuzzy matching helpers plus dynamic question_* mapping fields based on active TalkQuestions.
app/eventyay/orga/forms/importers.py
Implement core import logic for speakers and sessions as reusable Celery tasks with robust upsert and lookup behavior.
  • Define import_speakers and import_submissions Celery tasks using ProfiledEventTask, scoped DB access, and shared parse_csv utilities, including per-row error capture and logging.
  • Implement speaker upsert logic using email and optional identifier, preserving certain fields when empty, and linking to submissions via SpeakerRole.
  • Implement submission upsert logic resolving types, tracks, states, tags, rooms, speakers and custom question answers, using defensive parsing and defaults for invalid or missing data.
app/eventyay/base/services/talkimport.py
Add organizer UI for imports including navigation links and dedicated templates for upload and mapping steps.
  • Add sidebar navigation links for Speakers → Import and Sessions → Import, respecting permission checks and active-state highlighting.
  • Create upload templates for speakers and sessions that describe the flow and present the CSV file field.
  • Create mapping templates for speakers and sessions that render CSV previews and the dynamically-built mapping forms, with validation error display and call-to-action buttons.
app/eventyay/orga/templates/orga/base.html
app/eventyay/orga/templates/orga/speaker/import.html
app/eventyay/orga/templates/orga/speaker/import_process.html
app/eventyay/orga/templates/orga/submission/import.html
app/eventyay/orga/templates/orga/submission/import_process.html

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The speaker avatar-related mapping fields (avatar_url, avatar_source, avatar_license) are exposed in SpeakerImportProcessForm but never consumed in _import_speaker_row, so either wire these through to SpeakerProfile/metadata or drop them from the form to avoid confusing organizers.
  • The helper _find_user_for_speaker (and the identifier lookup in _import_speaker_row) iterate over all SpeakerProfile rows twice in Python; consider replacing these loops with direct SpeakerProfile.objects.filter(...).select_related('user') queries (by user__code / user__fullname) to keep imports efficient for events with many speakers.
  • In both import_speakers and import_submissions, the errors list is populated but never used; either surface these row-level errors to callers/logs or remove the accumulation to keep the task code simpler.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The speaker avatar-related mapping fields (`avatar_url`, `avatar_source`, `avatar_license`) are exposed in `SpeakerImportProcessForm` but never consumed in `_import_speaker_row`, so either wire these through to `SpeakerProfile`/metadata or drop them from the form to avoid confusing organizers.
- The helper `_find_user_for_speaker` (and the identifier lookup in `_import_speaker_row`) iterate over all `SpeakerProfile` rows twice in Python; consider replacing these loops with direct `SpeakerProfile.objects.filter(...).select_related('user')` queries (by `user__code` / `user__fullname`) to keep imports efficient for events with many speakers.
- In both `import_speakers` and `import_submissions`, the `errors` list is populated but never used; either surface these row-level errors to callers/logs or remove the accumulation to keep the task code simpler.

## Individual Comments

### Comment 1
<location path="app/eventyay/base/services/talkimport.py" line_range="114-123" />
<code_context>
+def _import_speaker_row(event, settings, record, acting_user):
</code_context>
<issue_to_address>
**issue (bug_risk):** Speaker import ignores avatar-related mappings defined in the mapping form.

`SPEAKER_IMPORT_FIELDS` includes `avatar_url`, `avatar_source`, and `avatar_license`, but `_import_speaker_row` never reads or persists these values. Users can map these fields with no effect. Please either fully support importing and storing these fields, or remove them from `SPEAKER_IMPORT_FIELDS` so we don’t expose non-functional mappings.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds organizer-facing CSV import workflows for speakers and sessions, integrating with existing async task infrastructure and persisting per-event column mappings to streamline repeated bulk onboarding.

Changes:

  • Added Celery-backed import tasks for speakers and sessions, including upsert/linking logic.
  • Added CSV upload + column-mapping forms/views/templates for organizer dashboard import flows.
  • Wired new routes, sidebar navigation links, event URL helpers, and event settings for stored mappings.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
app/eventyay/base/services/talkimport.py Implements the asynchronous speaker/session import tasks and row processing logic.
app/eventyay/orga/forms/importers.py Adds CSV upload + column mapping forms, including header auto-suggestions and dynamic question fields.
app/eventyay/orga/views/speaker.py Adds speaker import upload + mapping/process views and task dispatch.
app/eventyay/orga/views/submission.py Adds session import upload + mapping/process views and task dispatch.
app/eventyay/orga/urls.py Registers new organizer URLs for speaker/session import flows.
app/eventyay/base/models/event.py Adds new orga_urls helpers for import endpoints.
app/eventyay/base/configurations/default_setting.py Registers new event settings keys for persisting import mappings.
app/eventyay/orga/templates/orga/base.html Adds organizer sidebar navigation links for the new import pages.
app/eventyay/orga/templates/orga/speaker/import.html New speaker CSV upload template.
app/eventyay/orga/templates/orga/speaker/import_process.html New speaker column-mapping + preview template.
app/eventyay/orga/templates/orga/submission/import.html New session CSV upload template.
app/eventyay/orga/templates/orga/submission/import_process.html New session column-mapping + preview template.

@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch 2 times, most recently from e763536 to e602b83 Compare February 28, 2026 15:10
Copilot AI review requested due to automatic review settings February 28, 2026 15:10
@ArnavBallinCode ArnavBallinCode marked this pull request as draft February 28, 2026 15:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 12 out of 12 changed files in this pull request and generated 12 comments.

@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from e602b83 to fd677c0 Compare February 28, 2026 15:24
@ArnavBallinCode
Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 12 out of 12 changed files in this pull request and generated 8 comments.

@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from fd677c0 to be94670 Compare February 28, 2026 16:50
@Saksham-Sirohi
Copy link
Copy Markdown
Collaborator

@shivam-pawar-7217, removing your comment as this is irrelevant

@fossasia fossasia deleted a comment from shivam-pawar-7217 Mar 1, 2026
Copilot AI review requested due to automatic review settings March 1, 2026 09:56
@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from be94670 to 77603ab Compare March 1, 2026 09:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 12 out of 12 changed files in this pull request and generated no new comments.

@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from 77603ab to 05377c1 Compare March 1, 2026 10:05
Copilot AI review requested due to automatic review settings March 1, 2026 10:19
@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from 05377c1 to dc57ec6 Compare March 1, 2026 10:19
Copilot AI review requested due to automatic review settings March 18, 2026 14:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 14 out of 14 changed files in this pull request and generated 6 comments.

Copilot AI review requested due to automatic review settings March 26, 2026 08:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 4 comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 19 out of 19 changed files in this pull request and generated 2 comments.

@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from a0793a3 to 9f616e7 Compare March 26, 2026 11:40
@ArnavBallinCode ArnavBallinCode changed the title Feat Import sessions and speakers Feat Import Schedule and speakers Mar 26, 2026
Copilot AI review requested due to automatic review settings March 26, 2026 11:49
@ArnavBallinCode ArnavBallinCode force-pushed the test/import-sessions-speakers-v2 branch from 9f616e7 to d75a577 Compare March 26, 2026 11:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 19 out of 19 changed files in this pull request and generated 5 comments.

Copilot AI review requested due to automatic review settings April 1, 2026 14:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 19 out of 19 changed files in this pull request and generated 2 comments.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 1, 2026 15:41
Copy link
Copy Markdown
Collaborator

@Saksham-Sirohi Saksham-Sirohi left a comment

Choose a reason for hiding this comment

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

Looks Good! Works

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 19 out of 19 changed files in this pull request and generated 1 comment.

Comment on lines +295 to +296
cf = CachedFile.objects.get(id=fileid)
try:
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

import_submissions fetches the CachedFile with CachedFile.objects.get(id=fileid) without handling CachedFile.DoesNotExist. If the cached upload expires or is deleted before the Celery task runs, this will raise an unexpected exception (not in known_errortypes), leading to a generic error/redirect and making the UX less recoverable. Mirror import_speakers by catching DoesNotExist and raising ImportExecutionError with a user-facing message.

Suggested change
cf = CachedFile.objects.get(id=fileid)
try:
try:
cf = CachedFile.objects.get(id=fileid)
except CachedFile.DoesNotExist:
raise ImportExecutionError(_('The uploaded file could not be found. Please upload it again.'))
try:

Copilot uses AI. Check for mistakes.
@mariobehling mariobehling changed the title Feat Import Schedule and speakers Feat: Import schedule and speakers Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants