Open Nikola2222 opened 2 years ago
После долгой эксплуатации скрипта есть схожие пожелания, но нынешняя кодовая база парсеров не очень удачно вышла и её необходимо переписать. Про CLI вообще без комментариев, там всё плохо и печально и проблемно расширять функционал. И, например, тот же requests заменить на httpx, чтобы добавить поддержку async запросов для асинхронных решений
Провёл небольшие эксперименты, пришёл к выводу, что надо перестраивать базовую архитектуру, примерно как в yt-dlp:
Сначала собирать все нужные полезные данные, и потом на их основе проводить манипуляции. Накидал прототип парсера, вероятнее всего, на его основе буду переделывать архитектуру. Снизив к минимуму количество необходимых датаклассов как сейчас.
У shikimori ограничение на лимиты - 90 запросов в минуту, полностью на него полагаться не выйдет, в dev ветке лежит кодовый генератор python wrapper API на базе официальной документации, хреновый, но какой-то программный интерфейс есть
Я думал взять yt-dlp, создавать аниме экстракторы к yt-dlp и сделать cli интерфейс для yt-dlp. Но у yt-dlp нету механизма для выбора озвучки. Насчет shikimori, я уже сделал для себя скрипт который работает на библиотеке но для аунтефикации нужно целую инструкцию делать потому что токены надо получать.
Я думал взять yt-dlp, создавать аниме экстракторы к yt-dlp и сделать cli интерфейс для yt-dlp. Но у yt-dlp нету механизма для выбора озвучки. Насчет shikimori, я уже сделал для себя скрипт который работает на библиотеке но для аунтефикации нужно целую инструкцию делать потому что токены надо получать.
Извиняюсь за долгий ответ, словил ковид и лечился от него 😰, щас мне лучше, теперь по ответам на моё на видение развития проекта:
yt-dlp хороший инструмент, его реально использоваться для скачивания видео по прямым ссылкам на kodik/aniboom/sibnet etc. ссылках, но пока рано делать экстракторы под их решение, в планах перевести все запросы на httpx библиотеку, чтобы была поддержка http/2 протокола и asyncio, а также доработать решение выше, чтобы результаты поиска вхождений регулярных выражений было удобнее конвертировать в датаклассы для более удобной работы с полученными результатами. Оно пригодится, так как получение данных преимущественно идёт не через json api, на через парсинг html документа. Скриншот выше это не конечный результат программного интерфейса, будут доработки, как и с сама архитектура проекта будет переделана.
Shikimori можно без токена использовать, если только надо получать информацию о контенте, сторонние решения скорее всего не буду использовать, а буду полагаться на автоматическую генерацию API на основе их официальной документации, если конечно не будет готового под httpx, чтобы и sync и async умел одновременно.
Pull requests пока не буду принимать, пока не будет видна чёткая архитектура проекта, актуальное решение под получение подробных метаданных по типу картинок, описания, трейлеров и ТД не удобно и не годится
Хорошо, я понял. Нужна архитектура. Вот еще список не реализуемых желаний:
Хорошо, я понял. Нужна архитектура. Вот еще список не реализуемых желаний:
- [ ] Поиск аниме по жанрам, категориям, годам, типу, статусу. Для этого нужно чтобы экстракторы парсили всё на свете.
- [ ] Случайное аниме. Некоторые сайты умеют выдавать случайное аниме, например animego. Тоже парсить.
- [ ] Сортировка аниме. Сайты это умеют нужно только запрос кинуть и тоже парсить.
- [ ] Комментарии. Парсить комментарии прямо с сайтов.
- [ ] Расписание выхода серий. На некоторых сайтах это есть.
Это решение изначально был скрипт на 300 строк под animego и был рассчитан на применение в *nix системах в терминале. В ходе расширения проекта допустил косяки в написании, не задумываясь особо на расширяемость, гибкость и удобную ремонтопригодность проекта. Например, я зашел в один из экстракторов и запутался в коде 😅
В планах примерно у меня будут следующие действия:
Отделить программный интерфейс от CLI в отдельную библиотеку, так как есть запрос на использование в других проектах, CLI в таких случаях не нужен и бесполезен.
Как упоминалось выше, использовать другую библиотеку для запросов. Я буду использовать httpx, чтобы был sync и async методы отправки сразу. Будет отдельный класс под эту задачу, чтобы быстро под aiohttp тот же переделать если будет необходимость.
Слишком перегружен BaseHTTP класс под запросы, его надо дробить, отдельно делать класс под экстрактор
Избавиться от жесткой привязки объявленных датаклассов к BaseAnimeHTTP, как у меня сейчас сделано, чтобы если провалятся мои велосипедные эксперименты, то просто получать все поля регулярками через один метод и всё (как в yt-dlp). Ну или если кому-то не зайдет моя диктатура навязывания, то не будут применять мои наработки. Также под rest API (anilibria, vost) для удобной серелизации в датаклассы msgspec приглянулся как легковесная альтернатива pydantic, но это пока не точно.
После масштабного рефакторинга (скорее всего переписывание хех) можно будет действовать.
Из пунктов выше получение комментариев out of scope, этот проект про просмотр мультиков, а не создание альтернативного клиента под каждый источник (если конечно не докинут регулярных выражений). Случайный поиск я хотел добавить, но тогда регулярные выражения нестабильные были и в основном клиент крашился с ошибкой да и не везде он есть, - эта фича тоже под вопросом.
В dev ветке переписал код с рабочей реализацией animego, это не конечный вариант, регулярные выражения не проверены временем и могут "давать осечку".
Вкратце, следующие изменения:
https://github.com/vypivshiy/ani-cli-ru/tree/dev/anicli_api
В приоритете:
После этого будет перенос остальных экстракторов, обновление CLI утилиты, добавление shikimori
Это все хорошо, но писать регулярки это ад. Это их надо упрощать, почему нельзя весь html сериализовать или хотя бы делать срезы в нужных местах.
Это все хорошо, но писать регулярки это ад. Это их надо упрощать, почему нельзя весь html сериализовать или хотя бы делать срезы в нужных местах.
Это да, время надо для написание надёжных регулярных выражений, но это универсальный способ всё получать, а в некоторых местах вообще неприменимо будет использовать такие решения по типу bs4. Сложность только можно частично снизить документацией с примерами как здесь и здесь при быстрой проверке с помощью этого онлайн инструмента regex101
Насчёт bs4: Здесь, например, можно взять dl class "row"
элемент, а как дальше распарсить, чтобы занимало минимум строк кода и было надёжно и проще в фиксах при изменении не знаю. xpath/css селекторы будут не применимы в конкретно этом случае это точно.
Если я не прав, можешь написать идею с примером на bs4, его было бы использовать для упрощения для таких ситуаций, но он только эффективен в xml/html, большинство задач только регулярками решать
Да, я согласен. Это было просто моё нытьё.
определить шаблон структуры под парсеры. Чтобы было твёрдо и чётко
Я заметил что регулярки в SearchResult
и Ongoing
почти одинаковые. Можно это как-то сократить?
определить шаблон структуры под парсеры. Чтобы было твёрдо и чётко
Я заметил что регулярки в
SearchResult
иOngoing
почти одинаковые. Можно это как-то сократить?
Это обязательно надо делать, эта первая реализация like Proof of Concept, будут изменения
Насчёт bs4: я не использовал продвинутые фичи этой библиотеки, посмотрел документацию и оказывается умеет принимать регулярные выражения, списки и функции с необходимым фильтрами. https://www.crummy.com/software/BeautifulSoup/bs4/doc/#soupstrainer https://www.crummy.com/software/BeautifulSoup/bs4/doc/#a-regular-expression
И провёл тесты, если докинуть транслятор ключей на латиницу, то вполне оправдано частично от регулярок отказаться для упрощения написания
from bs4 import BeautifulSoup
import pathlib
def extract_meta(text: str):
soup = BeautifulSoup(text, "html.parser")
title = soup.find("div", attrs={"class": "anime-title"}).find_next("h1").get_text()
synonyms = [t.get_text(strip=True) for t in soup.find("div", attrs={"class": "synonyms"}).find_all("li")]
rating = soup.find("span", class_="rating-value").get_text(strip=True)
print(title, synonyms, rating)
meta_table = soup.find("dl", attrs={"class": "row"})
keys, values = [], []
for el in meta_table.find_all("dt"):
key = el.get_text(strip=True)
value = el.find_next("dd").get_text(strip=True)
keys.append(key)
values.append(value)
print(key, value)
rez = dict(zip(keys, values))
print(len(rez.keys()), rez)
print("----")
if __name__ == '__main__':
txt = pathlib.Path("test.html").read_text()
extract_meta(txt)
from anicli_api._http import BaseHTTPSync # equal httpx.get or requests.get with set headers
txt2 = BaseHTTPSync().session.get("https://animego.org/anime/eksperimenty-leyn-m1114").text
extract_meta(txt2)
txt3 = BaseHTTPSync().session.get("https://animego.org/anime/mastera-mecha-onlayn-309").text
extract_meta(txt3)
txt4 = BaseHTTPSync().session.get("https://animego.org/anime/vayolet-evergarden-film-m1778").text
extract_meta(txt4)
output:
Человек-бензопила ['Chainsaw Man', 'Chainsaw Man', 'チェンソーマン'] 9,6
Следующий эпизод 1 нояб. 2022 вт 18:00ожидается выход 4 серии
Тип ТВ Сериал
Эпизоды 3 /12
Статус Онгоинг
Жанр Демоны,Приключения,Сверхъестественное,Сёнэн,Экшен
Первоисточник Манга
Сезон Осень 2022
Выпуск с 12 октября 2022
Студия MAPPA
Рейтинг MPAA NC-17
Возрастные ограничения 18+
Длительность 25 мин. ~ серия
Снят по манге Человек-бензопила
Главные герои Дэндзи,Аки Хаякава,Макима,Пауэр
14 {'Следующий эпизод': '1 нояб. 2022 вт 18:00ожидается выход 4 серии', 'Тип': 'ТВ Сериал', 'Эпизоды': '3 /12', 'Статус': 'Онгоинг', 'Жанр': 'Демоны,Приключения,Сверхъестественное,Сёнэн,Экшен', 'Первоисточник': 'Манга', 'Сезон': 'Осень 2022', 'Выпуск': 'с 12 октября 2022', 'Студия': 'MAPPA', 'Рейтинг MPAA': 'NC-17', 'Возрастные ограничения': '18+', 'Длительность': '25 мин. ~ серия', 'Снят по манге': 'Человек-бензопила', 'Главные герои': 'Дэндзи,Аки Хаякава,Макима,Пауэр'}
----
Эксперименты Лэйн ['Serial Experiments Lain', 'Serial Experiments Lain', 'シリアルエクスペリメンツレイン'] 8,5
Тип ТВ Сериал
Эпизоды 13
Статус Вышел
Жанр Безумие,Детектив,Драма,Психологическое,Сверхъестественное,Фантастика
Первоисточник Оригинал
Сезон Лето 1998
Выпуск с 6 июля 1998 по 28 сентября 1998
Студия Triangle Staff
Рейтинг MPAA NC-17
Возрастные ограничения 18+
Длительность 23 мин. ~ серия
Озвучка XL Media
Режиссёр Масахико Мурата,Накамура Рютаро,Уэда Сигэру
Снят по манге Эксперименты Лэйн: Кошмар подделки
Автор оригинала Ясуюки Уэда
Главные герои Lain Iwakura
16 {'Тип': 'ТВ Сериал', 'Эпизоды': '13', 'Статус': 'Вышел', 'Жанр': 'Безумие,Детектив,Драма,Психологическое,Сверхъестественное,Фантастика', 'Первоисточник': 'Оригинал', 'Сезон': 'Лето 1998', 'Выпуск': 'с 6 июля 1998 по 28 сентября 1998', 'Студия': 'Triangle Staff', 'Рейтинг MPAA': 'NC-17', 'Возрастные ограничения': '18+', 'Длительность': '23 мин. ~ серия', 'Озвучка': 'XL Media', 'Режиссёр': 'Масахико Мурата,Накамура Рютаро,Уэда Сигэру', 'Снят по манге': 'Эксперименты Лэйн: Кошмар подделки', 'Автор оригинала': 'Ясуюки Уэда', 'Главные герои': 'Lain Iwakura'}
----
Мастера Меча Онлайн ['Sword Art Online', 'Sword Art Online', 'ソードアート・オンライン', 'S.A.O', 'SAO', 'Искусство Меча Онлайн'] 9,2
Тип ТВ Сериал
Эпизоды 25
Статус Вышел
Жанр Игры,Приключения,Романтика,Фэнтези,Экшен
Первоисточник Легкая новвела
Сезон Лето 2012
Выпуск с 8 июля 2012 по 23 декабря 2012
Студия A-1 Pictures Inc.
Рейтинг MPAA PG-13
Возрастные ограничения 18+
Длительность 23 мин. ~ серия
Озвучка AniDUB,AniLibria,SHIZA Project,Onibaku Group,AniMedia,СВ-Дубль
Режиссёр Морио Асака,Томохико Ито
Снят по ранобэ Мастера Меча Онлайн,Мастера Меча Онлайн: Прогрессив
Автор оригинала Рэки Кавахара
Главные герои Кадзуто Киригая,Сугуха Киригая,Асуна Юки
16 {'Тип': 'ТВ Сериал', 'Эпизоды': '25', 'Статус': 'Вышел', 'Жанр': 'Игры,Приключения,Романтика,Фэнтези,Экшен', 'Первоисточник': 'Легкая новвела', 'Сезон': 'Лето 2012', 'Выпуск': 'с 8 июля 2012 по 23 декабря 2012', 'Студия': 'A-1 Pictures Inc.', 'Рейтинг MPAA': 'PG-13', 'Возрастные ограничения': '18+', 'Длительность': '23 мин. ~ серия', 'Озвучка': 'AniDUB,AniLibria,SHIZA Project,Onibaku Group,AniMedia,СВ-Дубль', 'Режиссёр': 'Морио Асака,Томохико Ито', 'Снят по ранобэ': 'Мастера Меча Онлайн,Мастера Меча Онлайн: Прогрессив', 'Автор оригинала': 'Рэки Кавахара', 'Главные герои': 'Кадзуто Киригая,Сугуха Киригая,Асуна Юки'}
----
Вайолет Эвергарден. Фильм ['Violet Evergarden Movie', '劇場版 ヴァイオレット・エヴァーガーデン', 'Gekijouban Violet Evergarden'] 9,5
Тип Фильм
Жанр Драма,Повседневность,Фэнтези
Первоисточник Легкая новвела
Выпуск 18 сентября 2020
Студия Kyoto Animation
Рейтинг MPAA PG-13
Возрастные ограничения 16+
Длительность 2 ч. 20 мин.
Озвучка Reanimedia
Снят по ранобэ Вайолет Эвергарден
Главные герои Гилберт Бугенвиллея,Вайолет Эвергарден
11 {'Тип': 'Фильм', 'Жанр': 'Драма,Повседневность,Фэнтези', 'Первоисточник': 'Легкая новвела', 'Выпуск': '18 сентября 2020', 'Студия': 'Kyoto Animation', 'Рейтинг MPAA': 'PG-13', 'Возрастные ограничения': '16+', 'Длительность': '2 ч. 20 мин.', 'Озвучка': 'Reanimedia', 'Снят по ранобэ': 'Вайолет Эвергарден', 'Главные герои': 'Гилберт Бугенвиллея,Вайолет Эвергарден'}
----
Process finished with exit code 0
С архитектурой закончено, что осталось для релиза:
print
с input
, конечно лучше делать на ncurses или обёртке под неё для более красивого вывода и для возможности использования кнопок, но надо побыстрее закончить, в будущем потом на базе программного API выйдет переписать более менее рабочая версия есть с 75% покрытием тестами. осталось CI/CD настроить, остальные парсеры перенести, допилить документацию для контрибьютеров.
после этого приступлю к переписыванию CLI интерфейса в этом репозитории, а пока можешь посмотреть наработки https://github.com/vypivshiy/anicli-api
api обёртка пока более менее готова с какой то документацией и надежность есть хотя бы на уровне тестов, теперь будут эксперименты с дизайном CLI клиента на базе prompt_toolkit
Его выбрал по следующим причинам:
Это круто!
Накидал демку с архитектурой как у популярных популярных ботов и микро веб феймворков
Предполагаю, что такое решение будет сбалансировано в плане простоты добавления, изменения функционала и кастомизации. И если кому-то будет не лень, то реально и встраивать те же диалоговые окна
Пока не хватает middleware фильтров и прочие мелкие фиксы
Накидал более "реалистичную" демку CLI-prompt клиента.
В будущем примерно так будет выглядеть структура проекта, но есть недостатки:
.config
директории базовый файл конфигурации для модификаций.А так считаю удачной эту экспериментальную обёртку под prompt-toolkit, в будущем можно отделить эту логику в другой репозиторий, для удобного выполнения подобных задач.
очередная сырая демка. Функционал как в самых первых коммитах: только animego и по одному видео загружать
На основе prompt-toolkit сделан не только клон vim'a, но и клон tmux это значит что в теории можно сделать вкладки, и превратить это в консольный браузер где можно смотреть несколько аниме одновременно.
Я увидел удобную фичу в anipy-cli, где после каждого просмотра эпизода пользователю предлагают сразу запустить следующий эпизод, а то постоянно писать номера серий не очень удобно. Еще думаю нужно для красоты сделать чтобы название тайтла и номер серии передавались в заголовок окна mpv.
Я увидел удобную фичу в anipy-cli, где после каждого просмотра эпизода пользователю предлагают сразу запустить следующий эпизод, а то постоянно писать номера серий не очень удобно. Еще думаю нужно для красоты сделать чтобы название тайтла и номер серии передавались в заголовок окна mpv.
С заголовком mpv окна хорошая идея.
А теперь что сделано:
Отдаленно напоминает по дизайну фреймворки под ботов. Тема создания терминальных приложений в наше время маргинальная, по удобным инструментам всё скудно, поэтому имеем такой костыльный велосипед
Просмотр дополнительной информации о тайтле через pager элемент. Пришел к такому решению, так как это не часто вызываемая фича будет и незачем тратить пространство в терминале когда оно не нужно да и так удобнее просматривать информацию. И также решает проблему произвольного числа полей информации в объектах если не применять shikimori
просмотр пачками видосы. Работает пока криво и нестабильно, пока демонстрации ради работает
Экспериментально закинул в декодеры yt-dlp, тестировал минимально не знаю как поведет на практике. В теории, если будут mailru, okru, youtube источники попадатся, то ссылку переварит и перебросит в плеер
под субтитры накинул источник, динамический loader не видит этот модуль надо чинить
Пока еще сыро и присутствуют баги с недочетами, осталось их устранить и будет можно лить в мастер с pypi. И докину сюда доску с тасками как и что развивать в планах дальше, вроде на гитхабе так можно делать раз уж с архитектурной частью проекта более менее вопросы решены
Хочу больше функций, а именно: