Sync developer notifications from JSON file to database. - Adds new notifications that don't exist in the DB - Removes DB notifications that are no longer in the JSON file - Updates existing notifications if they've changed Returns a dict with counts of added, updated, and rem
()
| 234 | |
| 235 | |
| 236 | def sync_developer_notifications() -> dict[str, int]: |
| 237 | """ |
| 238 | Sync developer notifications from JSON file to database. |
| 239 | |
| 240 | - Adds new notifications that don't exist in the DB |
| 241 | - Removes DB notifications that are no longer in the JSON file |
| 242 | - Updates existing notifications if they've changed |
| 243 | |
| 244 | Returns a dict with counts of added, updated, and removed notifications. |
| 245 | """ |
| 246 | from core.models import SystemNotification |
| 247 | |
| 248 | results = {'added': 0, 'updated': 0, 'removed': 0, 'skipped': 0} |
| 249 | |
| 250 | notifications = load_developer_notifications() |
| 251 | json_notification_keys = set() |
| 252 | notifications_to_remove = set() # Track notifications to remove (out of range or expired) |
| 253 | |
| 254 | for notif_data in notifications: |
| 255 | notification_id = notif_data.get('id') |
| 256 | if not notification_id: |
| 257 | logger.warning("Notification missing 'id' field, skipping") |
| 258 | results['skipped'] += 1 |
| 259 | continue |
| 260 | |
| 261 | json_notification_keys.add(notification_id) |
| 262 | |
| 263 | # Check version constraints (only add if current version is in range) |
| 264 | if not is_version_in_range( |
| 265 | __version__, |
| 266 | notif_data.get('min_version'), |
| 267 | notif_data.get('max_version') |
| 268 | ): |
| 269 | logger.debug(f"Notification {notification_id} not in version range, marking for removal") |
| 270 | results['skipped'] += 1 |
| 271 | notifications_to_remove.add(notification_id) |
| 272 | continue |
| 273 | |
| 274 | # Parse expires_at if provided |
| 275 | expires_at = None |
| 276 | if notif_data.get('expires_at'): |
| 277 | try: |
| 278 | expires_at = datetime.fromisoformat( |
| 279 | notif_data['expires_at'].replace('Z', '+00:00') |
| 280 | ) |
| 281 | # Skip if already expired and mark for removal |
| 282 | if expires_at < timezone.now(): |
| 283 | logger.debug(f"Notification {notification_id} has expired, marking for removal") |
| 284 | results['skipped'] += 1 |
| 285 | notifications_to_remove.add(notification_id) |
| 286 | continue |
| 287 | except (ValueError, TypeError) as e: |
| 288 | logger.warning(f"Invalid expires_at for {notification_id}: {e}") |
| 289 | |
| 290 | # Map notification_type from JSON to model choices |
| 291 | type_mapping = { |
| 292 | 'version_update': SystemNotification.NotificationType.VERSION_UPDATE, |
| 293 | 'setting_recommendation': SystemNotification.NotificationType.SETTING_RECOMMENDATION, |
no test coverage detected