/desktop-anime-bot

The project to hone skills with API

Primary LanguagePython

Anime bot

Проект по WEB

Приложение написано для оттачивания навыков работы с API, библиотеками urllib и PyQt5 и работы с json-файлами. Данные берутся с сайта shikimori.one.

Эксплуатация

data и static должны лежать в той же папке, что и приложение. В data хранятся json-файлы пользователей с информацией о запросах и кэшах этих запросов.

В папке static есть 4 папки:

  1. css - там есть файл dark.qss, который подключается к приложению, поэтому тема темная. Информацию об авторе есть в этом файле.
  2. db - хранит базу данных users_info.db с id пользователя, логином пользователя и зашифрованным паролем.
  3. forms - хранит формы, созданные в Qt Designer.
  4. logs - хранит логи об ошибках, которые случились во время запросов к серверу.

Работа приложения начинается с модуля Login. Там вас ожидает поля для ввода логина и пароля, ссылка "Нет аккаунта? Зарегистрируйтесь" и кнопка для входа в аккаунт. Вы можете зарегистрировать новый аккаунт, нажав "Нет аккаунта? Зарегистрируйтесь". Это кликабельный Label, для него создан отдельный класс. Вы можете зарегистрировать новый аккаунт или проверить работу на аккаунтах, которые представлены ниже.

  1. Логин: Admin Пароль: 12345678Qq
  2. Логин: Empty Пароль: 12345678Qq

В учетной записи Admin есть примеры работы некоторых запросов, показан пример загрузки из json. Empty же полностью пустый, как только что созданный аккаунт.

После регистрации, вы сможете зайти на свой аккаунт. После входа в аккаунт, вы окажетесь в окне "Чат", где вас поприветствует бот. Он расскажет про список доступных команд. Чтобы вызвать это меню повторно, вы можете ввести {Bot name}, help. Все, что выделено таким бирюзовым цветом - кликабельно. Чаще всего, это автозаполнение комманд, но если ещё в правом нижнем углу кликабельный label для выхода из аккаунта.

Также, для экономии места в QListWidget и чтобы одно сообщение не заняло все место (например, количество персонажей в аниме Наруто около 200), выводится ограниченное количество информации. Чтобы увидеть полную, просто кликните по QListWidgetItem и полная информация будет доступна в отдельном окне и все ссылки станут кликабельны.

ВАЖНО

Без интернета приложение работать не будет! На каждый запрос, где требуются данные от сервера, вы будете получать ответ, что сервер недоступен, а данные об ошибки будут записаны в файл с логами. Кэширование запросов писалось самостоятельно, иногда в коде присутствуют костыли. Поскольку на проект и так ушло много времени, то разобраться в асинхронном программировании для более грамотного распределения ресурсов (одновременная отправка запроса и просьба пользователя подождать без зависания программы) я просто не успел. Иногда, команды бота действительно выполняются не быстро, т.к. запрашивается сразу много информации. Например, команда character from выполняется около 6 секунд, т.к. нужно найти аниме, далее всех персонажей из аниме, затем найти в этом списке нужного, спарсить информацию о нём вместе с превью (опять запрос) и вывести результат. Но результаты кэшируется и запрос того же персонажа займет около 1 секунды, а персонажа из этого аниме около 2-3 секунд. Также, диалог сохраняется и после повторного входа в приложение выводится последнии 30 сообщений (15 ваши, 15 бота). Тут используется сохраненный кэш пользователя (после выхода из приложения, все запросы и данные о них сохраняются) и запрашивается только часть информации с сервера (json не умеет хранить фото, поток байт слишком тяжелый, так что превью запрашивается ещё раз, что занимает некоторое время). Во многом, загрузка будет зависить от ваших последних запросов. Если они "легкие" (например, чисто текст), то программа запустится быстро. Если запросы "тяжелые" (много превью), то программа будет запускаться дольше. Опять же, здесь бы помогло асинхронное программирование, т.к. можно было бы вывести окно ожидания и одновременно загружать данные, как при запуске Discord, например. Если вы не смотрите аниме и не знаете, какими данными протестировать бота, то Google вам в помощь. Найдите самые популярные аниме и попробуйте сделать эти запросы в разработанном боте.

Всего будет доступно 9 основных команд:

find anime

Синтаксис:

{name bot}, find_anime {name anime}

Альтернативный синтаксис:

{command symbol}find_anime {name anime}

Выводит информацию об аниме: скриншот-превью, название, рейтинг, статус, тип, когда состоялся релиз, дата выхода, количество эпизодов, описание и ссылку на страницу shikimori.one с данным аниме.

set new name

Синтаксис:

{name bot}, set_new_name {new name}

Альтернативный синтаксис:

{command symbol}set_new_name {new name}

Задает новое имя боту, по которому вы можете к нему обращаться.

random anime

Синтаксис:

{name bot}, random_anime

Альтернативный синтаксис:

{command symbol}random_anime

Выводит случайное аниме, в формате: скриншот-превью, название, рейтинг, статус, тип, когда состоялся релиз, дата выхода, количество эпизодов, описание и ссылку на страницу shikimori с данным аниме.

similar anime to

Синтаксис:

{name bot}, similar_anime_to {name anime} [count] [{10}]

Альтернативный синтаксис:

{command symbol}similar_anime_to {name anime} [count] [{10}]

Параметр (count) {10} - необязательный параметр По умолчанию, находит 10 похожих аниме, если это возможно. Если указать параметр (count) и число через пробел, найдет необходимое число похожих аниме, если это возможно.

all characters from

Синтаксис:

{name bot}, all_characters_from {name anime}

Альтернативный синтаксис:

{command symbol}all_characters_from {name anime}

Выводит список всех персонажей из {name anime} в формате: Роль персонажа в аниме, имя. Сначала выводятся главные персонажи.

character from

Синтаксис:

{name bot}, character {character name} from {name anime}

Альтернативный синтаксис:

{command symbol}character {character name} from {name anime}

Выводит подробную информацию о персонаже из {name anime} в формате: Имя, ссылка на страницу shikimori.one, описание, список аниме и манги с данным персонажам, также с названиями, типом, ролью в произведении и ссылками на страницы shikimori.one на эти произведения.

franchise

Синтаксис:

{name bot}, franchise {name anime}

Альтернативный синтаксис:

{command symbol}franchise {name anime}

Выводит информацию о франшизе, в которой состоит это аниме, упорядоченной по году выхода, в формате: название, тип, дата выхода, ссылка на страницу shikimori.one. Если аниме не состоит во франшизе, выводит сообщение, что франшизу найти не удалось.

related to

Синтаксис:

{name bot}, related_to {name anime}

Альтернативный синтаксис:

{command symbol}related_to {name anime}

Находит аниме и мангу, которые напрямую связаны с {name anime}. Выводит информацию в формате: сначала список аниме, с типом, типом связи, названием и ссылкой на страницу shikimori.one, а после мангу в том же формате.

help

Синтаксис:

{name bot}, help

Альтернативный синтаксис:

{command symbol}help

Выводит краткую информацию о каждой команде.

Вспомогательная информация

Название аниме и самих персонажей можно писать как на русском, так и на английском.

Чтобы увидеть вводимый пароль в окне Register и Recovery Password, нажмите F1. Чтобы сгенерировать случайный пароль в соответствующих окнах, нажмите F2. Эту же информацию можно получить, если навести на поле ввода Password, тогда выскочит всплывающая подсказка (ToolTip) Требования к паролю прописаны в Модули и их назначение: Модуль Password.

Модули и их назначение

Всего в приложении реализовано 8 основных модулей (не считая самих форм, которые были преобразованы к классам с помощью утилиты pyuic).

Модуль Login

С этого окна начинается взаимодействие с программой. Здесь пользователь вводит свой логин и пароль, чтобы пройти этапы идентификации и аутентификации. Если логин и пароль верный, то авторизация прошла успешна, выдаем права пользователю и переходим к следующей части программы. Если пользователь не зарегистрирован в системе, он может зарегистрироваться при нажатии на ссылку "Нет аккаунта? Зарегистрируйтесь".

Класс Register

В этом окне вводятся данные для добавления нового пользователя в БД. Данные для ввода:

  • Логин
  • Пароль
  • Повторение пароля

Надежный пароль можно сгенерировать программно, если нажать F2. Тогда поля "Пароль" и "Повторение пароля" автоматически заполнятся. Так как пароли в поле ввода изначально скрыты, чтобы их увидеть, нужно нажать F1. Повторное нажатие F1 снова скроет пароль Если все данные заполнены корректно, то регистрация пройдёт успешно и новый пользователь добавиться в БД.

Модуль Password

Вспомогательный модуль, в котором реализованы классы исключений:

  • PasswordError - класс-родитель. Наследуется от Exception
  • LengthError - Ошибка длины пароля. Исключение поднимается, если пароль содержит менее 8 символов. Наследуется от PasswordError
  • LetterError - Ошибка символов в пароле. Исключение поднимается, если в пароле содержатся символы только одного регистра. Наследуется от PasswordError
  • DigitError - Ошибка цифр в пароле. Исключение поднимается, если пароль не содержит не одну цифру. Наследуется от PasswordError

Пароль проверяется по всем критериям и если он не соответствует одному или нескольким критериям, то выбрасывается исключение. Также, в модуле реализована генерация пароль из любого количества символов, который соответствует всем критериям.

Модуль Label

Реализует класс ClickableLabel наследуемый от QLabel. Позволяет сделать Label кликабельными.

Класс Client

После авторизации мы попадаем сюда. Если вы впервые зашли под своим аккаунтом (а точнее, если нет кэша в папке data), бот вас поприветствует и выведит help. В иной ситуации, бот подгрузит последнии 30 сообщений (15 ваших запросов и 15 ответов). Класс имеет прямую связь с ботом. Когда пользователь отправляет сообщение, вызывается метод бота reaction, который обрабатывает сообщение и отвечает на него. Также, класс отвечает за GUI.

Класс Bot

Реагирует на сообщение пользователя и выполняет соответствующие запросы. Команды бота были представлены выше. Если к боту обратились не по имени или не было (backslash) в команде, то бот ответит "Хм...". Если вы ввели имя бота, но команда не была распознана, то бот ответит "Да?". Если команда введена верно, бот запросит соответствующие данные и вернёт их пользователю.

Класс MessageRead

Открывает отдельное окно для чтения сообщения. Позволяет прочитать сообщение полностью, если оно не помещается в QListWidgetItem.

Класс Constants

Содержит константы: название БД, информацию о командах, краткий help.