mirror of
https://git.vectorsigma.ru/public/tubearchivist.git
synced 2026-08-04 21:39:49 +00:00
remove old migrations
This commit is contained in:
@@ -1,76 +0,0 @@
|
|||||||
"""backup config for sqlite reset and restore"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django.core.management.base import BaseCommand
|
|
||||||
from home.models import CustomPeriodicTask
|
|
||||||
from home.src.ta.settings import EnvironmentSettings
|
|
||||||
from rest_framework.authtoken.models import Token
|
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
"""export"""
|
|
||||||
|
|
||||||
help = "Exports all users and their auth tokens to a JSON file"
|
|
||||||
FILE = Path(EnvironmentSettings.CACHE_DIR) / "backup" / "migration.json"
|
|
||||||
|
|
||||||
def handle(self, *args, **kwargs):
|
|
||||||
"""entry point"""
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"user_data": self.get_users(),
|
|
||||||
"schedule_data": self.get_schedules(),
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(self.FILE, "w", encoding="utf-8") as json_file:
|
|
||||||
json_file.write(json.dumps(data))
|
|
||||||
|
|
||||||
def get_users(self):
|
|
||||||
"""get users"""
|
|
||||||
|
|
||||||
users = User.objects.all()
|
|
||||||
|
|
||||||
user_data = []
|
|
||||||
|
|
||||||
for user in users:
|
|
||||||
user_info = {
|
|
||||||
"username": user.name,
|
|
||||||
"is_staff": user.is_staff,
|
|
||||||
"is_superuser": user.is_superuser,
|
|
||||||
"password": user.password,
|
|
||||||
"tokens": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
token = Token.objects.get(user=user)
|
|
||||||
user_info["tokens"] = [token.key]
|
|
||||||
except Token.DoesNotExist:
|
|
||||||
user_info["tokens"] = []
|
|
||||||
|
|
||||||
user_data.append(user_info)
|
|
||||||
|
|
||||||
return user_data
|
|
||||||
|
|
||||||
def get_schedules(self):
|
|
||||||
"""get schedules"""
|
|
||||||
|
|
||||||
all_schedules = CustomPeriodicTask.objects.all()
|
|
||||||
schedule_data = []
|
|
||||||
|
|
||||||
for schedule in all_schedules:
|
|
||||||
schedule_info = {
|
|
||||||
"name": schedule.name,
|
|
||||||
"crontab": {
|
|
||||||
"minute": schedule.crontab.minute,
|
|
||||||
"hour": schedule.crontab.hour,
|
|
||||||
"day_of_week": schedule.crontab.day_of_week,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule_data.append(schedule_info)
|
|
||||||
|
|
||||||
return schedule_data
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
"""restore config from backup"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from common.src.env_settings import EnvironmentSettings
|
|
||||||
from django.core.management.base import BaseCommand
|
|
||||||
from django_celery_beat.models import CrontabSchedule
|
|
||||||
from rest_framework.authtoken.models import Token
|
|
||||||
from task.models import CustomPeriodicTask
|
|
||||||
from task.src.task_config import TASK_CONFIG
|
|
||||||
from user.models import Account
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
"""export"""
|
|
||||||
|
|
||||||
help = "Exports all users and their auth tokens to a JSON file"
|
|
||||||
FILE = Path(EnvironmentSettings.CACHE_DIR) / "backup" / "migration.json"
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
|
||||||
"""handle"""
|
|
||||||
self.stdout.write("restore users and schedules")
|
|
||||||
data = self.get_config()
|
|
||||||
self.restore_users(data["user_data"])
|
|
||||||
self.restore_schedules(data["schedule_data"])
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(
|
|
||||||
" ✓ restore completed. Please restart the container."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_config(self) -> dict:
|
|
||||||
"""get config from backup"""
|
|
||||||
with open(self.FILE, "r", encoding="utf-8") as json_file:
|
|
||||||
data = json.loads(json_file.read())
|
|
||||||
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(f" ✓ json file found: {self.FILE}")
|
|
||||||
)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def restore_users(self, user_data: list[dict]) -> None:
|
|
||||||
"""restore users from config"""
|
|
||||||
self.stdout.write("delete existing users")
|
|
||||||
Account.objects.all().delete()
|
|
||||||
|
|
||||||
self.stdout.write("recreate users")
|
|
||||||
for user_info in user_data:
|
|
||||||
user = Account.objects.create(
|
|
||||||
name=user_info["username"],
|
|
||||||
is_staff=user_info["is_staff"],
|
|
||||||
is_superuser=user_info["is_superuser"],
|
|
||||||
password=user_info["password"],
|
|
||||||
)
|
|
||||||
for token in user_info["tokens"]:
|
|
||||||
Token.objects.create(user=user, key=token)
|
|
||||||
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(
|
|
||||||
f" ✓ recreated user with name: {user_info['username']}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def restore_schedules(self, schedule_data: list[dict]) -> None:
|
|
||||||
"""restore schedules"""
|
|
||||||
self.stdout.write("delete existing schedules")
|
|
||||||
CustomPeriodicTask.objects.all().delete()
|
|
||||||
|
|
||||||
self.stdout.write("recreate schedules")
|
|
||||||
for schedule in schedule_data:
|
|
||||||
task_name = schedule["name"]
|
|
||||||
description = TASK_CONFIG[task_name].get("title")
|
|
||||||
crontab, _ = CrontabSchedule.objects.get_or_create(
|
|
||||||
minute=schedule["crontab"]["minute"],
|
|
||||||
hour=schedule["crontab"]["hour"],
|
|
||||||
day_of_week=schedule["crontab"]["day_of_week"],
|
|
||||||
timezone=EnvironmentSettings.TZ,
|
|
||||||
)
|
|
||||||
task = CustomPeriodicTask.objects.create(
|
|
||||||
name=task_name,
|
|
||||||
task=task_name,
|
|
||||||
description=description,
|
|
||||||
crontab=crontab,
|
|
||||||
)
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(f" ✓ recreated schedule: {task}")
|
|
||||||
)
|
|
||||||
@@ -19,7 +19,6 @@ from common.src.ta_redis import RedisArchivist
|
|||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.utils import dateformat
|
from django.utils import dateformat
|
||||||
from django_celery_beat.models import CrontabSchedule, PeriodicTasks
|
from django_celery_beat.models import CrontabSchedule, PeriodicTasks
|
||||||
from redis.exceptions import ResponseError
|
|
||||||
from task.models import CustomPeriodicTask
|
from task.models import CustomPeriodicTask
|
||||||
from task.src.config_schedule import ScheduleBuilder
|
from task.src.config_schedule import ScheduleBuilder
|
||||||
from task.src.task_manager import TaskManager
|
from task.src.task_manager import TaskManager
|
||||||
@@ -49,12 +48,9 @@ class Command(BaseCommand):
|
|||||||
self._version_check()
|
self._version_check()
|
||||||
self._index_setup()
|
self._index_setup()
|
||||||
self._snapshot_check()
|
self._snapshot_check()
|
||||||
self._mig_app_settings()
|
|
||||||
self._create_default_schedules()
|
self._create_default_schedules()
|
||||||
self._update_schedule_tz()
|
self._update_schedule_tz()
|
||||||
self._init_app_config()
|
self._init_app_config()
|
||||||
self._mig_channel_tags()
|
|
||||||
self._mig_video_channel_tags()
|
|
||||||
self._mig_fix_download_channel_indexed()
|
self._mig_fix_download_channel_indexed()
|
||||||
self._mig_add_default_playlist_sort()
|
self._mig_add_default_playlist_sort()
|
||||||
|
|
||||||
@@ -159,39 +155,6 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write("[7] setup snapshots")
|
self.stdout.write("[7] setup snapshots")
|
||||||
ElasticSnapshot().setup()
|
ElasticSnapshot().setup()
|
||||||
|
|
||||||
def _mig_app_settings(self) -> None:
|
|
||||||
"""update from v0.4.13 to v0.5.0, migrate application settings"""
|
|
||||||
self.stdout.write("[MIGRATION] move appconfig to ES")
|
|
||||||
try:
|
|
||||||
config = RedisArchivist().get_message("config")
|
|
||||||
except ResponseError:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(" Redis does not support JSON decoding")
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if not config or config == {"status": False}:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(" no config values to migrate")
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
path = "ta_config/_doc/appsettings"
|
|
||||||
response, status_code = ElasticWrap(path).post(config)
|
|
||||||
|
|
||||||
if status_code in [200, 201]:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(" ✓ migrated appconfig to ES")
|
|
||||||
)
|
|
||||||
RedisArchivist().del_message("config", save=True)
|
|
||||||
return
|
|
||||||
|
|
||||||
message = " 🗙 failed to migrate app config"
|
|
||||||
self.stdout.write(self.style.ERROR(message))
|
|
||||||
self.stdout.write(response)
|
|
||||||
sleep(60)
|
|
||||||
raise CommandError(message)
|
|
||||||
|
|
||||||
def _create_default_schedules(self) -> None:
|
def _create_default_schedules(self) -> None:
|
||||||
"""create default schedules for new installations"""
|
"""create default schedules for new installations"""
|
||||||
self.stdout.write("[8] create initial schedules")
|
self.stdout.write("[8] create initial schedules")
|
||||||
@@ -293,70 +256,6 @@ class Command(BaseCommand):
|
|||||||
self.style.SUCCESS(f" Status code: {status_code}")
|
self.style.SUCCESS(f" Status code: {status_code}")
|
||||||
)
|
)
|
||||||
|
|
||||||
def _mig_channel_tags(self) -> None:
|
|
||||||
"""update from v0.4.13 to v0.5.0, migrate incorrect data types"""
|
|
||||||
self.stdout.write("[MIGRATION] fix incorrect channel tags types")
|
|
||||||
path = "ta_channel/_update_by_query"
|
|
||||||
data = {
|
|
||||||
"query": {"match": {"channel_tags": False}},
|
|
||||||
"script": {
|
|
||||||
"source": "ctx._source.channel_tags = []",
|
|
||||||
"lang": "painless",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
response, status_code = ElasticWrap(path).post(data)
|
|
||||||
if status_code in [200, 201]:
|
|
||||||
updated = response.get("updated")
|
|
||||||
if updated:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(f" ✓ fixed {updated} channel tags")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(" no channel tags needed fixing")
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
message = " 🗙 failed to fix channel tags"
|
|
||||||
self.stdout.write(self.style.ERROR(message))
|
|
||||||
self.stdout.write(response)
|
|
||||||
sleep(60)
|
|
||||||
raise CommandError(message)
|
|
||||||
|
|
||||||
def _mig_video_channel_tags(self) -> None:
|
|
||||||
"""update from v0.4.13 to v0.5.0, migrate incorrect data types"""
|
|
||||||
self.stdout.write("[MIGRATION] fix incorrect video channel tags types")
|
|
||||||
path = "ta_video/_update_by_query"
|
|
||||||
data = {
|
|
||||||
"query": {"match": {"channel.channel_tags": False}},
|
|
||||||
"script": {
|
|
||||||
"source": "ctx._source.channel.channel_tags = []",
|
|
||||||
"lang": "painless",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
response, status_code = ElasticWrap(path).post(data)
|
|
||||||
if status_code in [200, 201]:
|
|
||||||
updated = response.get("updated")
|
|
||||||
if updated:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(
|
|
||||||
f" ✓ fixed {updated} video channel tags"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.stdout.write(
|
|
||||||
self.style.SUCCESS(
|
|
||||||
" no video channel tags needed fixing"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
message = " 🗙 failed to fix video channel tags"
|
|
||||||
self.stdout.write(self.style.ERROR(message))
|
|
||||||
self.stdout.write(response)
|
|
||||||
sleep(60)
|
|
||||||
raise CommandError(message)
|
|
||||||
|
|
||||||
def _mig_fix_download_channel_indexed(self) -> None:
|
def _mig_fix_download_channel_indexed(self) -> None:
|
||||||
"""migrate from v0.5.2 to 0.5.3, fix missing channel_indexed"""
|
"""migrate from v0.5.2 to 0.5.3, fix missing channel_indexed"""
|
||||||
self.stdout.write("[MIGRATION] fix incorrect video channel tags types")
|
self.stdout.write("[MIGRATION] fix incorrect video channel tags types")
|
||||||
|
|||||||
Reference in New Issue
Block a user