Check for new Dispatcharr versions on GitHub and create a notification if available. This task should be run periodically (e.g., daily) via Celery Beat. For dev builds (identified by __timestamp__), checks for stable releases only. For production builds, checks for stable releases.
()
| 785 | |
| 786 | @shared_task |
| 787 | def check_for_version_update(): |
| 788 | """ |
| 789 | Check for new Dispatcharr versions on GitHub and create a notification if available. |
| 790 | This task should be run periodically (e.g., daily) via Celery Beat. |
| 791 | |
| 792 | For dev builds (identified by __timestamp__), checks for stable releases only. |
| 793 | For production builds, checks for stable releases. |
| 794 | |
| 795 | Note: Dev builds are container images from the dev branch and don't have GitHub releases. |
| 796 | This checks if a stable release is available so dev users know when to upgrade. |
| 797 | """ |
| 798 | import requests |
| 799 | from datetime import datetime, timezone |
| 800 | from packaging import version as pkg_version |
| 801 | from version import __version__, __timestamp__ |
| 802 | from core.models import SystemNotification |
| 803 | from core.utils import dispatcharr_http_headers, send_websocket_notification |
| 804 | |
| 805 | try: |
| 806 | is_dev_build = __timestamp__ is not None |
| 807 | DISPATCHARR_HEADERS = dispatcharr_http_headers(content_type=None) |
| 808 | |
| 809 | if is_dev_build: |
| 810 | # Check Docker Hub for newer dev builds |
| 811 | docker_hub_url = "https://hub.docker.com/v2/repositories/dispatcharr/dispatcharr/tags/dev" |
| 812 | |
| 813 | response = requests.get(docker_hub_url, headers=DISPATCHARR_HEADERS, timeout=10) |
| 814 | |
| 815 | if response.status_code != 200: |
| 816 | logger.warning(f"Failed to check Docker Hub for dev updates: HTTP {response.status_code}") |
| 817 | return |
| 818 | |
| 819 | dev_tag_data = response.json() |
| 820 | docker_last_updated = dev_tag_data.get("last_updated") |
| 821 | |
| 822 | if not docker_last_updated: |
| 823 | logger.warning("No last_updated timestamp found in Docker Hub response") |
| 824 | return |
| 825 | |
| 826 | # Parse timestamps for comparison |
| 827 | local_dt = datetime.strptime(__timestamp__, "%Y%m%d%H%M%S").replace(tzinfo=timezone.utc) |
| 828 | docker_dt = datetime.fromisoformat(docker_last_updated.replace('Z', '+00:00')) |
| 829 | |
| 830 | # Calculate difference in minutes |
| 831 | diff_minutes = (docker_dt - local_dt).total_seconds() / 60 |
| 832 | |
| 833 | # Threshold to account for build/push time differences |
| 834 | THRESHOLD_MINUTES = 10 |
| 835 | |
| 836 | if diff_minutes > THRESHOLD_MINUTES: |
| 837 | logger.info(f"New dev build available on Docker Hub (updated {int(diff_minutes)} minutes after current build)") |
| 838 | |
| 839 | # Delete any old version update notifications (both dev and stable, in case user switched) |
| 840 | deleted_count = SystemNotification.objects.filter( |
| 841 | notification_type='version_update' |
| 842 | ).delete()[0] |
| 843 | if deleted_count > 0: |
| 844 | logger.debug(f"Deleted {deleted_count} old dev build notification(s)") |
nothing calls this directly
no test coverage detected