Skip to content

Sync Media with MEDIA_PLUGINS setting robustly#1830

Open
hmpf wants to merge 4 commits into
mainfrom
fix-sync-media
Open

Sync Media with MEDIA_PLUGINS setting robustly#1830
hmpf wants to merge 4 commits into
mainfrom
fix-sync-media

Conversation

@hmpf
Copy link
Copy Markdown
Contributor

@hmpf hmpf commented Mar 3, 2026

Scope and purpose

While testing #1803 it turned out the argus_notificationprofile.Medium table was never synced properly with the MEDIA_PLUGINS setting.

How to test manually

  1. Open the admin on the Medium table in the browser
  2. Change the MEDIA_PLUGINS setting (comment out/in lines)
  3. Hard reload the admin page
  4. Observe how the "installed" column in the admin page changes

Contributor Checklist

Every pull request should have this checklist filled out, no matter how small it is.
More information about contributing to Argus can be found in the
Development docs.

  • Added a changelog fragment for towncrier
  • Added/amended tests for new/changed code
  • Added/changed documentation, including updates to the user manual if feature flow or UI is considerably changed
  • Linted/formatted the code with ruff and djLint, easiest by using pre-commit
  • The first line of the commit message continues the sentence "If applied, this commit will ...", starts with a capital letter, does not end with punctuation and is 50 characters or less long. See our how-to
  • If applicable: Created new issues if this PR does not fix the issue completely/there is further work to be done
  • If this results in changes in the UI: Added screenshots of the before and after
  • If this results in changes to the database model: Updated the ER diagram

@hmpf hmpf self-assigned this Mar 3, 2026
@hmpf hmpf added the bug Something is not working as expected label Mar 3, 2026
@hmpf hmpf requested review from a team, aleksfl and johannaengland March 3, 2026 14:08
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 3, 2026

Test results

    6 files  1 182 suites   1m 55s ⏱️
  861 tests   860 ✅ 1 💤 0 ❌
5 166 runs  5 160 ✅ 6 💤 0 ❌

Results for commit fba53ae.

♻️ This comment has been updated with latest results.

@hmpf hmpf changed the title Fix sync media Sync Media with MEDIA_PLUGINS setting robustly Mar 3, 2026
@hmpf hmpf force-pushed the fix-sync-media branch 3 times, most recently from 0069cdc to 6a19a9b Compare March 5, 2026 09:02
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 5, 2026

@hmpf hmpf added the rc-next Prioritized candidate for next release label Mar 5, 2026
@hmpf hmpf moved this from 📋 Backlog to 🏗 In progress in Argus development, public Mar 5, 2026
Copy link
Copy Markdown
Contributor

@johannaengland johannaengland left a comment

Choose a reason for hiding this comment

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

The tests are failing since you're never actually calling the sync_media function.

@github-project-automation github-project-automation Bot moved this from 🏗 In progress to ♻ Changes requested in Argus development, public Apr 14, 2026
@johannaengland
Copy link
Copy Markdown
Contributor

I rebased the branch onto the newest main and fixed merge conflicts, so that I could review the PR, but I also noticed that the linting failed, which is why the tests weren't run. Linting failed due to the sync_media function being duplicate. I removed the duplicate. But now the tests are failing, so I'll wait with a review until the tests have been fixed by @hmpf

@hmpf hmpf force-pushed the fix-sync-media branch 2 times, most recently from 5eab970 to 47f37cd Compare April 24, 2026 06:12
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 59.49367% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.77%. Comparing base (b1cc4a5) to head (fba53ae).

Files with missing lines Patch % Lines
src/argus/notificationprofile/media/__init__.py 61.76% 13 Missing ⚠️
...ificationprofile/management/commands/sync_media.py 0.00% 12 Missing ⚠️
src/argus/htmx/destination/views.py 62.50% 3 Missing ⚠️
src/argus/notificationprofile/models.py 83.33% 2 Missing ⚠️
src/argus/notificationprofile/v2/views.py 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1830      +/-   ##
==========================================
- Coverage   88.01%   87.77%   -0.24%     
==========================================
  Files         139      140       +1     
  Lines        6916     6962      +46     
==========================================
+ Hits         6087     6111      +24     
- Misses        829      851      +22     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hmpf hmpf requested a review from johannaengland April 24, 2026 06:21
@hmpf hmpf moved this from ♻ Changes requested to ❓ Ready for review in Argus development, public Apr 24, 2026
@sonarqubecloud
Copy link
Copy Markdown

Comment thread src/argus/notificationprofile/media/__init__.py
def handle(self, *args, **options):
if options.get("list", False):
sys.stdout.write("Sync MEDIA_PLUGINS setting to MEDIA table")
sys.exit(0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit/Q: Would a simple return not suffice here instead of forcibly exiting?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I simplified it instead.

Comment on lines +172 to +174
except ValidationError:
# should send 410 probably
return HttpResponseRedirect(self.get_success_url())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Hmm, this doesn't seem to give sufficient feedback to the user if the delete doesn't happen but they get a success response, it's probably confusing.

LOG.info("%s media plugin is now installed and registered correctly", media.name)


def api_safely_get_medium_object(media_slug, version: str = API_STABLE_VERSION):
Copy link
Copy Markdown
Contributor

@Simrayz Simrayz Apr 24, 2026

Choose a reason for hiding this comment

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

This function changed from throwing an exception (which the system can handle) to just returning None for uninstalled media. Doesn't this add caller overhead? Maybe add a specific exception for "MediaNotInstalled".
Edit: This error is instead thrown in the API view, by raising a ValidationError. Would it not be simple to just raise it in api_safely_get_medium_object and omit the if not medium check in v2/views.py?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tech debt, not updated for supporting both API and HTMx. Will fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

api_safely_get_medium_object is called many, many places. This is becoming a rather expensive fix..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looks like we'll have to postpone this PR, I don't think I'll have the time to finish it this sprint:

The problem is the remaining intermixing of API and non API in the destinations CRUD handling.

The purpose of this PR was to not crash out hard in the HTMx frontend when the MEDIA_PLUGINS setting was out of sync with the rows in the Media table, which was fulfilled.

Making "api_safely_get_medium_object" better would need yet another refactor, so I need to down-prioritize this.

Comment on lines +188 to 192
medium = api_safely_get_medium_object(destination.media.slug)
if not medium:
raise ValidationError(f"Media {destination.media.slug} of destination not installed")
try:
medium = api_safely_get_medium_object(destination.media.slug, self.version)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm, api_safely_get_medium_object is assigned twice, the first instance only to check for existence, but then the medium is discarded and the db is queried again on line 192. Could you not just add self.version to the call on line 188? The version is only used in api_safely_get_medium_object if the media exists (passed to the classobj), so it makes essentially no difference to omit version here.

@github-project-automation github-project-automation Bot moved this from ❓ Ready for review to ♻ Changes requested in Argus development, public Apr 24, 2026
post_save.connect(create_default_timeslot, "argus_auth.User")
post_save.connect(sync_email_destination, "argus_auth.User")
post_migrate.connect(sync_media, sender=self)
post_migrate.connect(trigger_sync_media, sender=self)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But this means it is only synced after migrations? The settings can be changed without running migrations

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is needed for the tests to work. It's either this or running sync_media whenever PersonUserFactory is used, or turn off the signal that creates the default destination from email address.

The idea is to run the management command, like collectstatic, on every startup.

Follow-up: we should probably have a command "sync" that collects all the stuff we want to do before running up the actual server in prod:

  • migrate (should be togglable)
  • collectstatic
  • sync_media
  • .. whatever else we ever need to do in the future

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see, then we should document that really well, that this needs to be run any time the media settings are changed

@hmpf hmpf requested a review from johannaengland April 27, 2026 07:35
@hmpf
Copy link
Copy Markdown
Contributor Author

hmpf commented Apr 27, 2026

The tests are failing since you're never actually calling the sync_media function.

Fixed by adding back the post_migrate signal.

@hmpf hmpf moved this from ♻ Changes requested to 🏗 In progress in Argus development, public Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is not working as expected rc-next Prioritized candidate for next release

Projects

Status: 🏗 In progress

Development

Successfully merging this pull request may close these issues.

3 participants