f56b088643
Base Image Build / prepare (push) Has been cancelled
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
Base Image Build / docker (amd64, ubuntu-24.04) (push) Has been cancelled
Base Image Build / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Base Image Build / create-manifest (push) Has been cancelled
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
# Generated by Django 6.0.3 on 2026-03-14 19:41
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
from django.db import migrations, models
|
|
|
|
|
|
def populate_exp_date_from_custom_properties(apps, schema_editor):
|
|
"""Backfill exp_date from custom_properties['user_info']['exp_date']."""
|
|
M3UAccountProfile = apps.get_model('m3u', 'M3UAccountProfile')
|
|
profiles_to_update = []
|
|
|
|
for profile in M3UAccountProfile.objects.filter(
|
|
custom_properties__isnull=False,
|
|
).exclude(custom_properties={}):
|
|
user_info = profile.custom_properties.get('user_info', {})
|
|
raw_exp = user_info.get('exp_date')
|
|
if raw_exp is None:
|
|
continue
|
|
|
|
parsed = None
|
|
try:
|
|
if isinstance(raw_exp, (int, float)):
|
|
parsed = datetime.fromtimestamp(float(raw_exp), tz=timezone.utc)
|
|
elif isinstance(raw_exp, str):
|
|
try:
|
|
parsed = datetime.fromtimestamp(float(raw_exp), tz=timezone.utc)
|
|
except ValueError:
|
|
parsed = datetime.fromisoformat(raw_exp)
|
|
except (ValueError, TypeError, OSError):
|
|
pass
|
|
|
|
if parsed is not None:
|
|
profile.exp_date = parsed
|
|
profiles_to_update.append(profile)
|
|
|
|
if profiles_to_update:
|
|
M3UAccountProfile.objects.bulk_update(profiles_to_update, ['exp_date'], batch_size=500)
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('m3u', '0018_add_profile_custom_properties'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.AddField(
|
|
model_name='m3uaccountprofile',
|
|
name='exp_date',
|
|
field=models.DateTimeField(blank=True, help_text='Account expiration date, auto-synced from custom_properties on save', null=True),
|
|
),
|
|
migrations.RunPython(
|
|
populate_exp_date_from_custom_properties,
|
|
reverse_code=migrations.RunPython.noop,
|
|
),
|
|
]
|