Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Больше #13

Open
12 tasks
Nikola2222 opened this issue Sep 24, 2022 · 21 comments
Open
12 tasks

Больше #13

Nikola2222 opened this issue Sep 24, 2022 · 21 comments
Labels
enhancement New feature or request

Comments

@Nikola2222
Copy link
Contributor

Nikola2222 commented Sep 24, 2022

Хочу больше функций, а именно:

  • Просмотр диапазона серий. Например, написал "1-5" и воспроизводиться от 1 до 5 серии последовательно.
  • Возможность переключать источники без перезапуска.
  • Возможность менять качество видео прямо во время работы (без перезапуска).
  • Запоминание выбранной озвучки. Например, в первый раз выбрал озвучку и дальше автоматически воспроизводится в этой озвучке.
  • Возможность добавлять свои параметры к mpv.
  • История просмотренных серий.
  • Конфигурационный файл. В котором можно указать прокси, качество видео по умолчанию и т.д.
  • Поиск аниме одновременно во всех или нескольких источниках.
  • Экстракторы парсили больше информации об аниме из источников (описание, рейтинг, дата выхода и т.д.).
  • Возможность добавлять свои параметры к ffmpeg.
  • Полная интеграция с Shikimori.
  • и еще больше парсеров
@vypivshiy vypivshiy added the enhancement New feature or request label Sep 24, 2022
@vypivshiy
Copy link
Owner

После долгой эксплуатации скрипта есть схожие пожелания, но нынешняя кодовая база парсеров не очень удачно вышла и её необходимо переписать. Про CLI вообще без комментариев, там всё плохо и печально и проблемно расширять функционал.
И, например, тот же requests заменить на httpx, чтобы добавить поддержку async запросов для асинхронных решений

@vypivshiy
Copy link
Owner

Провёл небольшие эксперименты, пришёл к выводу, что надо перестраивать базовую архитектуру, примерно как в yt-dlp:

  • Сначала собирать все нужные полезные данные, и потом на их основе проводить манипуляции. Накидал прототип парсера, вероятнее всего, на его основе буду переделывать архитектуру. Снизив к минимуму количество необходимых датаклассов как сейчас.
    image

  • У shikimori ограничение на лимиты - 90 запросов в минуту, полностью на него полагаться не выйдет, в dev ветке лежит кодовый генератор python wrapper API на базе официальной документации, хреновый, но какой-то программный интерфейс есть

@Nikola2222
Copy link
Contributor Author

Я думал взять yt-dlp, создавать аниме экстракторы к yt-dlp и сделать cli интерфейс для yt-dlp. Но у yt-dlp нету механизма для выбора озвучки.
Насчет shikimori, я уже сделал для себя скрипт который работает на библиотеке но для аунтефикации нужно целую инструкцию делать потому что токены надо получать.

@vypivshiy
Copy link
Owner

Я думал взять yt-dlp, создавать аниме экстракторы к yt-dlp и сделать cli интерфейс для yt-dlp. Но у yt-dlp нету механизма для выбора озвучки. Насчет shikimori, я уже сделал для себя скрипт который работает на библиотеке но для аунтефикации нужно целую инструкцию делать потому что токены надо получать.

Извиняюсь за долгий ответ, словил ковид и лечился от него 😰, щас мне лучше, теперь по ответам на моё на видение развития проекта:

yt-dlp хороший инструмент, его реально использоваться для скачивания видео по прямым ссылкам на kodik/aniboom/sibnet etc. ссылках, но пока рано делать экстракторы под их решение, в планах перевести все запросы на httpx библиотеку, чтобы была поддержка http/2 протокола и asyncio, а также доработать решение выше, чтобы результаты поиска вхождений регулярных выражений было удобнее конвертировать в датаклассы для более удобной работы с полученными результатами. Оно пригодится, так как получение данных преимущественно идёт не через json api, на через парсинг html документа. Скриншот выше это не конечный результат программного интерфейса, будут доработки, как и с сама архитектура проекта будет переделана.
image

Shikimori можно без токена использовать, если только надо получать информацию о контенте, сторонние решения скорее всего не буду использовать, а буду полагаться на автоматическую генерацию API на основе их официальной документации, если конечно не будет готового под httpx, чтобы и sync и async умел одновременно.

Pull requests пока не буду принимать, пока не будет видна чёткая архитектура проекта, актуальное решение под получение подробных метаданных по типу картинок, описания, трейлеров и ТД не удобно и не годится

@Nikola2222 Nikola2222 reopened this Oct 5, 2022
@Nikola2222
Copy link
Contributor Author

Nikola2222 commented Oct 5, 2022

Хорошо, я понял. Нужна архитектура.
Вот еще список не реализуемых желаний:

  • Поиск аниме по жанрам, категориям, годам, типу, статусу. Для этого нужно чтобы экстракторы парсили всё на свете.
  • Случайное аниме. Некоторые сайты умеют выдавать случайное аниме, например animego. Тоже парсить.
  • Сортировка аниме. Сайты это умеют нужно только запрос кинуть и тоже парсить.
  • Комментарии. Парсить комментарии прямо с сайтов.
  • Расписание выхода серий. На некоторых сайтах это есть.

@vypivshiy
Copy link
Owner

Хорошо, я понял. Нужна архитектура. Вот еще список не реализуемых желаний:

  • Поиск аниме по жанрам, категориям, годам, типу, статусу. Для этого нужно чтобы экстракторы парсили всё на свете.
  • Случайное аниме. Некоторые сайты умеют выдавать случайное аниме, например animego. Тоже парсить.
  • Сортировка аниме. Сайты это умеют нужно только запрос кинуть и тоже парсить.
  • Комментарии. Парсить комментарии прямо с сайтов.
  • Расписание выхода серий. На некоторых сайтах это есть.

Это решение изначально был скрипт на 300 строк под animego и был рассчитан на применение в *nix системах в терминале. В ходе расширения проекта допустил косяки в написании, не задумываясь особо на расширяемость, гибкость и удобную ремонтопригодность проекта. Например, я зашел в один из экстракторов и запутался в коде 😅

В планах примерно у меня будут следующие действия:

  • Отделить программный интерфейс от CLI в отдельную библиотеку, так как есть запрос на использование в других проектах, CLI в таких случаях не нужен и бесполезен.

  • Как упоминалось выше, использовать другую библиотеку для запросов. Я буду использовать httpx, чтобы был sync и async методы отправки сразу. Будет отдельный класс под эту задачу, чтобы быстро под aiohttp тот же переделать если будет необходимость.

  • Слишком перегружен BaseHTTP класс под запросы, его надо дробить, отдельно делать класс под экстрактор

  • Избавиться от жесткой привязки объявленных датаклассов к BaseAnimeHTTP, как у меня сейчас сделано, чтобы если провалятся мои велосипедные эксперименты, то просто получать все поля регулярками через один метод и всё (как в yt-dlp). Ну или если кому-то не зайдет моя диктатура навязывания, то не будут применять мои наработки. Также под rest API (anilibria, vost) для удобной серелизации в датаклассы msgspec приглянулся как легковесная альтернатива pydantic, но это пока не точно.

После масштабного рефакторинга (скорее всего переписывание хех) можно будет действовать.

Из пунктов выше получение комментариев out of scope, этот проект про просмотр мультиков, а не создание альтернативного клиента под каждый источник (если конечно не докинут регулярных выражений). Случайный поиск я хотел добавить, но тогда регулярные выражения нестабильные были и в основном клиент крашился с ошибкой да и не везде он есть, - эта фича тоже под вопросом.

@vypivshiy
Copy link
Owner

В dev ветке переписал код с рабочей реализацией animego, это не конечный вариант, регулярные выражения не проверены временем и могут "давать осечку".

Вкратце, следующие изменения:

  • Больше абстракций базовых компонентов и их реализация не так прибита к экстракторам.
  • re_models обёртка под поиски по регулярным выражениям считаю, что вышла удачно, можно чуть меньше писать кода и сразу получать словарь. Никаких дополнительных зависимостей, есть возможность далее серелизовать словари или в обычные датаклассы или в pydantic модели, например. В экстракторах их использование по желанию, возможно обойтись обычным re модулем и преобразовывать (как в yt-dlp)
  • Удобный доступ получения ссылок из kodik/aniboom, теперь будет возвращать все доступные ссылки, чтобы не искать заново. Работают независимо от экстракторов.
  • Структура экстрактора усложнилась, появился промежуточный датакласс, чтобы получать больше информации о тайтле, буду ещё экспериментировать по упрощению кода.

https://github.com/vypivshiy/ani-cli-ru/tree/dev/anicli_api

В приоритете:

  • определить шаблон структуры под парсеры. Чтобы было твёрдо и чётко
  • asyncio
  • Покрыть авто тестами
  • задокументировать как с этим всем работать

После этого будет перенос остальных экстракторов, обновление CLI утилиты, добавление shikimori

@Nikola2222
Copy link
Contributor Author

Это все хорошо, но писать регулярки это ад. Это их надо упрощать, почему нельзя весь html сериализовать или хотя бы делать срезы в нужных местах.

@vypivshiy
Copy link
Owner

vypivshiy commented Oct 25, 2022

Это все хорошо, но писать регулярки это ад. Это их надо упрощать, почему нельзя весь html сериализовать или хотя бы делать срезы в нужных местах.

Это да, время надо для написание надёжных регулярных выражений, но это универсальный способ всё получать, а в некоторых местах вообще неприменимо будет использовать такие решения по типу bs4. Сложность только можно частично снизить документацией с примерами как здесь и здесь при быстрой проверке с помощью этого онлайн инструмента regex101
image
Насчёт bs4: Здесь, например, можно взять dl class "row" элемент, а как дальше распарсить, чтобы занимало минимум строк кода и было надёжно и проще в фиксах при изменении не знаю. xpath/css селекторы будут не применимы в конкретно этом случае это точно.

Если я не прав, можешь написать идею с примером на bs4, его было бы использовать для упрощения для таких ситуаций, но он только эффективен в xml/html, большинство задач только регулярками решать

@Nikola2222
Copy link
Contributor Author

Да, я согласен. Это было просто моё нытьё.

определить шаблон структуры под парсеры. Чтобы было твёрдо и чётко

Я заметил что регулярки в SearchResult и Ongoing почти одинаковые. Можно это как-то сократить?

@vypivshiy
Copy link
Owner

определить шаблон структуры под парсеры. Чтобы было твёрдо и чётко

Я заметил что регулярки в 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

@vypivshiy
Copy link
Owner

С архитектурой закончено, что осталось для релиза:

  • покрыть автотестами (пока без asyncio), чтобы выловить ошибки и в будущем контролировать качество кода.
  • реализовать async методы, хотя бы в animego (пока есть реализация на уровне абстракций)
  • минимально рабочую CLI обёртку (пока без shikimori и прочих фич) на встроенных print с input, конечно лучше делать на ncurses или обёртке под неё для более красивого вывода и для возможности использования кнопок, но надо побыстрее закончить, в будущем потом на базе программного API выйдет переписать
  • Документацию по high-level использованию API и разработка своих парсеров под источники
  • Написать изменения по сравнению со старыми версиями

@vypivshiy
Copy link
Owner

более менее рабочая версия есть с 75% покрытием тестами.
осталось CI/CD настроить, остальные парсеры перенести, допилить документацию для контрибьютеров.

после этого приступлю к переписыванию CLI интерфейса в этом репозитории, а пока можешь посмотреть наработки
https://github.com/vypivshiy/anicli-api

@vypivshiy
Copy link
Owner

api обёртка пока более менее готова с какой то документацией и надежность есть хотя бы на уровне тестов,
теперь будут эксперименты с дизайном CLI клиента на базе prompt_toolkit

Его выбрал по следующим причинам:

  • проект проверенный временем, он не заброшен как urwid, например
  • достаточен для задачи сделать простой CLI инструмент без навороченных виджетов, в отличии от устаревшего и заброшенного urwid или активно разрабатывающегося, но не готового textual
  • pure python без зависимостей
  • неплохая документация и куча примеров с готовыми проектами (от aws клиента, ipython до клона vim - pyvim).
  • готовые шаблоны по типу checkbox'ов, автодополнений команд, стили, история команд (как в fish оболочке выделение есть).

image

image

@Nikola2222
Copy link
Contributor Author

Это круто!

@vypivshiy
Copy link
Owner

Накидал демку с архитектурой как у популярных популярных ботов и микро веб феймворков

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

Пока не хватает middleware фильтров и прочие мелкие фиксы

image

demo.mp4

https://github.com/vypivshiy/ani-cli-ru/tree/dev

@vypivshiy
Copy link
Owner

Накидал более "реалистичную" демку CLI-prompt клиента.

В будущем примерно так будет выглядеть структура проекта, но есть недостатки:

  • не конфигурируются подсказки, не поменять стили.
  • нет обработчика ВСЕХ событий из терминала. Например, чтобы встроить запись в shikimori без переписывания кода просмотра тайтлов, на срабатывание ошибок и ТД
  • надо заменить print на pretty_format_print, для более красивого и кастомизируемого вывода.
  • не решен вопрос удобной модификации клиента, так как будет установка через pip, в site-packages не очень вариант залезать и добавлять нужное, всё держится на глобальной переменной класса CliApp, наверное буду пилить что-то по типу blueprint как в flask. Или делать костыль и генерировать в .config директории базовый файл конфигурации для модификаций.
  • Возможно что-то ещё упустил.
  • не работает debug флаг

А так считаю удачной эту экспериментальную обёртку под prompt-toolkit, в будущем можно отделить эту логику в другой репозиторий, для удобного выполнения подобных задач.

demo2.mp4

@vypivshiy
Copy link
Owner

очередная сырая демка. Функционал как в самых первых коммитах: только animego и по одному видео загружать

cli_demo.mp4

@Nikola2222
Copy link
Contributor Author

На основе prompt-toolkit сделан не только клон vim'a, но и клон tmux это значит что в теории можно сделать вкладки, и превратить это в консольный браузер где можно смотреть несколько аниме одновременно.

@Nikola2222
Copy link
Contributor Author

output3.mp4

Я увидел удобную фичу в anipy-cli, где после каждого просмотра эпизода пользователю предлагают сразу запустить следующий эпизод, а то постоянно писать номера серий не очень удобно.
Еще думаю нужно для красоты сделать чтобы название тайтла и номер серии передавались в заголовок окна mpv.

@vypivshiy
Copy link
Owner

Я увидел удобную фичу в anipy-cli, где после каждого просмотра эпизода пользователю предлагают сразу запустить следующий эпизод, а то постоянно писать номера серий не очень удобно. Еще думаю нужно для красоты сделать чтобы название тайтла и номер серии передавались в заголовок окна mpv.

С заголовком mpv окна хорошая идея.

А теперь что сделано:

  • Надстройка над prompt-toolkit под CLI-REPL приложения с автоматической генерацией комплитера и FSM с ручным кешированием объектов для перекидывания значений по состояниям, чтобы немного упростить написание и модификацию приложения.

Отдаленно напоминает по дизайну фреймворки под ботов. Тема создания терминальных приложений в наше время маргинальная, по удобным инструментам всё скудно, поэтому имеем такой костыльный велосипед

  • Просмотр дополнительной информации о тайтле через pager элемент. Пришел к такому решению, так как это не часто вызываемая фича будет и незачем тратить пространство в терминале когда оно не нужно да и так удобнее просматривать информацию. И также решает проблему произвольного числа полей информации в объектах если не применять shikimori

  • просмотр пачками видосы. Работает пока криво и нестабильно, пока демонстрации ради работает

  • Экспериментально закинул в декодеры yt-dlp, тестировал минимально не знаю как поведет на практике. В теории, если будут mailru, okru, youtube источники попадатся, то ссылку переварит и перебросит в плеер

  • под субтитры накинул источник, динамический loader не видит этот модуль надо чинить

Пока еще сыро и присутствуют баги с недочетами, осталось их устранить и будет можно лить в мастер с pypi. И докину сюда доску с тасками как и что развивать в планах дальше, вроде на гитхабе так можно делать раз уж с архитектурной частью проекта более менее вопросы решены

demo4.mp4

@vypivshiy vypivshiy pinned this issue Jan 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants