From bfcafd219f39882c712b278eb8256d726fab61a5 Mon Sep 17 00:00:00 2001 From: lizerk Date: Thu, 12 Mar 2026 16:37:44 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D1=83=D1=81=20=D1=87=D0=B5=D0=BA?= =?UTF-8?q?=20=D1=87=D0=B0=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/commands/README.md | 28 +++++- .../management/commands/check_chats.py | 91 ++++++++++++++++++- 2 files changed, 116 insertions(+), 3 deletions(-) diff --git a/backend/communications/management/commands/README.md b/backend/communications/management/commands/README.md index c91bb96c..70dcb647 100644 --- a/backend/communications/management/commands/README.md +++ b/backend/communications/management/commands/README.md @@ -103,6 +103,29 @@ cd backend .venv/bin/python manage.py check_chats --check 6 ``` +#### Исправить все чаты с некорректными типами (заменить на group) + +```bash +.venv/bin/python manage.py check_chats --fix +``` + +#### Исправить с указанием целевого типа + +```bash +# Заменить все некорректные типы на "channel" +.venv/bin/python manage.py check_chats --fix --target-type channel +``` + +#### Изменить тип конкретного чата + +```bash +# Изменить тип чата с ID 6 на "group" +.venv/bin/python manage.py check_chats --change-type 6 group + +# Изменить тип чата с ID 15 на "channel" +.venv/bin/python manage.py check_chats --change-type 15 channel +``` + #### Удалить все чаты с некорректными типами (с подтверждением) ```bash @@ -134,9 +157,12 @@ cd backend - `--find` - Найти все чаты с некорректными типами - `--check CHAT_ID` - Проверить конкретный чат по ID +- `--fix` - Исправить все чаты с некорректными типами (по умолчанию заменяет на group) +- `--change-type CHAT_ID NEW_TYPE` - Изменить тип конкретного чата +- `--target-type TYPE` - Целевой тип для опции --fix (по умолчанию: group) - `--cleanup` - Удалить все чаты с некорректными типами - `--delete CHAT_ID` - Удалить конкретный чат по ID -- `--no-confirm` - Не запрашивать подтверждение при удалении +- `--no-confirm` - Не запрашивать подтверждение при удалении/изменении --- diff --git a/backend/communications/management/commands/check_chats.py b/backend/communications/management/commands/check_chats.py index f94e809d..32cdbfa3 100644 --- a/backend/communications/management/commands/check_chats.py +++ b/backend/communications/management/commands/check_chats.py @@ -36,6 +36,17 @@ class Command(BaseCommand): metavar='CHAT_ID', help='Проверить конкретный чат по ID', ) + parser.add_argument( + '--fix', + action='store_true', + help='Исправить все чаты с некорректными типами (заменить на group)', + ) + parser.add_argument( + '--change-type', + nargs=2, + metavar=('CHAT_ID', 'NEW_TYPE'), + help='Изменить тип конкретного чата (например: --change-type 6 group)', + ) parser.add_argument( '--cleanup', action='store_true', @@ -47,10 +58,17 @@ class Command(BaseCommand): metavar='CHAT_ID', help='Удалить конкретный чат по ID', ) + parser.add_argument( + '--target-type', + type=str, + default='group', + choices=VALID_TYPES, + help='Целевой тип для исправления (по умолчанию: group)', + ) parser.add_argument( '--no-confirm', action='store_true', - help='Не запрашивать подтверждение при удалении', + help='Не запрашивать подтверждение при удалении/изменении', ) def handle(self, *args, **options): @@ -58,12 +76,21 @@ class Command(BaseCommand): self.find_invalid_chats() elif options['check']: self.check_chat(options['check']) + elif options['fix']: + self.fix_invalid_chats( + target_type=options['target_type'], + no_confirm=options['no_confirm'] + ) + elif options['change_type']: + chat_id = int(options['change_type'][0]) + new_type = options['change_type'][1] + self.change_chat_type(chat_id, new_type, no_confirm=options['no_confirm']) elif options['cleanup']: self.cleanup_invalid_chats(no_confirm=options['no_confirm']) elif options['delete']: self.delete_chat(options['delete'], no_confirm=options['no_confirm']) else: - self.stdout.write(self.style.ERROR('Укажите действие: --find, --check, --cleanup или --delete')) + self.stdout.write(self.style.ERROR('Укажите действие: --find, --check, --fix, --change-type, --cleanup или --delete')) self.stdout.write('Используйте --help для справки') def find_invalid_chats(self): @@ -104,10 +131,70 @@ class Command(BaseCommand): if chat.type not in VALID_TYPES: self.stdout.write(self.style.ERROR(f'\n⚠️ Чат имеет некорректный тип: {chat.type}')) self.stdout.write(self.style.NOTICE(f'Допустимые типы: {", ".join(VALID_TYPES)}')) + self.stdout.write(self.style.NOTICE(f'Для изменения типа используйте: python manage.py check_chats --change-type {chat_id} group')) self.stdout.write(self.style.NOTICE(f'Для удаления используйте: python manage.py check_chats --delete {chat_id}')) else: self.stdout.write(self.style.SUCCESS(f'\n✅ Чат в порядке, тип корректен')) + def fix_invalid_chats(self, target_type='group', no_confirm=False): + """Исправляет все чаты с некорректными типами""" + invalid_chats = Chat.objects.exclude(type__in=VALID_TYPES) + + if not invalid_chats.exists(): + self.stdout.write(self.style.SUCCESS('✅ Все чаты имеют корректные типы')) + return + + count = invalid_chats.count() + self.stdout.write(self.style.WARNING(f'⚠️ Найдено {count} чатов с некорректными типами\n')) + self.stdout.write(f'Чаты для исправления (будет установлен тип: {target_type}):') + + for chat in invalid_chats: + self.stdout.write(f' • ID {chat.id}: {chat.name} (текущий тип: {chat.type} → новый тип: {target_type})') + + if not no_confirm: + confirm = input(f'\n⚠️ Изменить тип у {count} чатов на "{target_type}"? (yes/no): ') + if confirm.lower() not in ['yes', 'y', 'да']: + self.stdout.write(self.style.ERROR('❌ Отменено')) + return + + updated = invalid_chats.update(type=target_type) + self.stdout.write(self.style.SUCCESS(f'\n✅ Успешно обновлено {updated} чатов')) + self.stdout.write(f'Всем чатам установлен тип: {target_type}') + + def change_chat_type(self, chat_id, new_type, no_confirm=False): + """Изменяет тип конкретного чата""" + try: + chat = Chat.objects.get(id=chat_id) + except Chat.DoesNotExist: + raise CommandError(f'❌ Чат с ID {chat_id} не найден') + + if new_type not in VALID_TYPES: + raise CommandError( + f'❌ Некорректный тип: {new_type}\n' + f'Допустимые типы: {", ".join(VALID_TYPES)}' + ) + + self.stdout.write(f'Изменение типа чата ID {chat_id}:') + self.stdout.write(f' Название: {chat.name}') + self.stdout.write(f' Текущий тип: {chat.type}') + self.stdout.write(f' Новый тип: {new_type}') + self.stdout.write(f' Участников: {chat.participants.count()}') + + if chat.type == new_type: + self.stdout.write(self.style.WARNING(f'\n⚠️ Чат уже имеет тип "{new_type}"')) + return + + if not no_confirm: + confirm = input(f'\n⚠️ Изменить тип с "{chat.type}" на "{new_type}"? (yes/no): ') + if confirm.lower() not in ['yes', 'y', 'да']: + self.stdout.write(self.style.ERROR('❌ Отменено')) + return + + old_type = chat.type + chat.type = new_type + chat.save(update_fields=['type']) + self.stdout.write(self.style.SUCCESS(f'\n✅ Тип чата "{chat.name}" изменен с "{old_type}" на "{new_type}"')) + def cleanup_invalid_chats(self, no_confirm=False): """Удаляет все чаты с некорректными типами""" invalid_chats = Chat.objects.exclude(type__in=VALID_TYPES)