{"id":15091183,"url":"https://github.com/miskler/pytorrent","last_synced_at":"2025-10-06T10:30:58.396Z","repository":{"id":180772367,"uuid":"656744679","full_name":"Miskler/pytorrent","owner":"Miskler","description":"A service for hosting mods and downloading them from Steam.","archived":true,"fork":false,"pushed_at":"2023-08-04T19:30:22.000Z","size":38218,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-01T06:43:29.522Z","etag":null,"topics":["mod-downloader","open-api","open-source","openapi","opensource","python","python-3","python3","service","sqlite3","steam","steam-workshop","steamworkshop","threading"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Miskler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-06-21T14:48:15.000Z","updated_at":"2023-08-04T19:31:36.000Z","dependencies_parsed_at":"2023-07-12T20:16:18.098Z","dependency_job_id":null,"html_url":"https://github.com/Miskler/pytorrent","commit_stats":null,"previous_names":["miskler/pytorrent"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Miskler%2Fpytorrent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Miskler%2Fpytorrent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Miskler%2Fpytorrent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Miskler%2Fpytorrent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Miskler","download_url":"https://codeload.github.com/Miskler/pytorrent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235519935,"owners_count":19003201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mod-downloader","open-api","open-source","openapi","opensource","python","python-3","python3","service","sqlite3","steam","steam-workshop","steamworkshop","threading"],"created_at":"2024-09-25T10:36:17.720Z","updated_at":"2025-10-06T10:30:53.083Z","avatar_url":"https://github.com/Miskler.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Проект переехал - https://github.com/Open-Workshop\n\n# PyTorrent\n\n### Цель данного проекта - позволить скачивать моды всем!\n\n### Проект позволяет скачивать моды для игр с серверов **Valve**.\n\n## Структура проекта\n1. **Backend сервер**. Непосредственно общается с Steam, кэширует моды и отсылает пользователям по запросу.\nКэширование нужно для минимизации обращений к серверам Valve.\nТак как частые запросы туда могут расцениваться сервером как бот-активность *(и он будет прав)*.\nИз про кэшированных модов сервер составляет список который могут использовать сторонние приложения.\nСервер не позволяет скачивать моды со Steam на прямую.\nВместо этого нужно создать запрос на кеширование и после некоторое время опрашивать сервер о состоянии запроса.\nПосле мод будет добавлен в библиотеку сервера от куда его уже можно скачать.\n2. **Telegram бот**. Написаный мной бот для удобного взаимодействия пользователя с моим сервером. \nВыбрал этот вариант по причине легкости и *(как я понимаю, правилами **Telegram** это не запрешено)*.\n\n## Документация\n### Начало работы\nАдрес сервера: https://43093.zetalink.ru:8000\n\n### `/download/steam/{mod_id}`\nНужно передать `ID` мода **Steam**. \nЕсли у сервера уже есть этот мод - он его отправит как `ZIP` архив со сжатием `ZIP_BZIP2`.\nЕсли у сервера нет этого мода он отправит `JSON` с информацией о постановке мода на скачивание.\n\n**JSON ответы:**\n\n1. **Успешная постановка запроса на скачивание:**\n```\n{\"message\": \"request added to queue\", \"error_id\": 0, \"unsuccessful_attempts\": true / false, \"updating\": true / false}\n```\nHTTP code: `202`\n* `unsuccessful_attempts` - это пометка сообщает о том были ли провальные попытки скачать мод.\n* `updating` - если true - это значит, что у сервера был загружен мод, но ваш запрос спровоцировал проверку на \nобновление. Сервер удаляет у себя старую версию мода и начинает загрузку новой.\n\n2. **Сервер запускается:**\n```\n{\"message\": \"the server is not ready to process requests\", \"error_id\": 1}\n```\nHTTP code: `103`\n* Это ошибка возникает в ситуации когда сервер ещё не успел запустить службу по скачиванию модов,\nа на самом сервере этого мода нет.\n\n3. **Мод не найден:**\n```\n{\"message\": \"this mod was not found\", \"error_id\": 2}}\n```\nHTTP code: `404`\n\n4. **Сервер уже пытается скачать этот мод:**\n```\n{\"message\": \"your request is already being processed\", \"error_id\": 3}\n```\nHTTP code: `102`\n* Постоянно спрашивать состояние мода через эту функцию не рекомендую, так как она достаточно медленная. \nЛучше использовать `/info/mod/{mod_id}`.\n\n\n### `/download/{mod_id}`\nНужно передать `ID` мода. \nЕсли у сервера уже есть этот мод - он его отправит как `ZIP` архив со сжатием `ZIP_BZIP2`.\nЭта самая быстрая команда загрузки, но если на сервере не будет запрашиваемого мода никаких действий по его загрузке предпринято не будет.\n\n**JSON ответы:**\n\n1. **Мода нет на сервере:**\n```\n{\"message\": \"the mod is not on the server\", \"error_id\": 1}\n```\nHTTP code: `404`\n2. **Мод поврежден:**\n```\n{\"message\": \"the mod is damaged\", \"error_id\": 2}\n```\nHTTP code: `404`\n* Если по какой-то причине мод есть в БД, но его файла нет в системе, запись в БД будет удалена, а вам сообщено что мод был поврежден и отправлен не будет.\n\n\n### `/list/mods/`\nВозвращает список модов к конкретной игре, которые есть на сервере. Имеет необязательные аргументы:\n\n1. `page_size` *(int)* - количество элементов которое будет возвращено. *(диапазон значений `1...50`)*\n2. `page` *(int)* - \"страница\" которая будет возвращена. Рассчитывается как `page_size * page = offeset`.\n3. `sort` *(str)* - режим сортировки таблицы перед фильтрацией.\n    Префикс `i` указывает что сортировка должна быть инвертированной.\n    По умолчанию от меньшего к большему, с `i` от большего к меньшему.\n    1. NAME - сортировка по имени.\n    2. SIZE - сортировка по размеру.\n    3. DATE_CREATION - сортировка по дате создания.\n    4. DATE_UPDATE - сортировка по дате обновления.\n    5. DATE_REQUEST - сортировка по дате последнего запроса.\n    6. SOURCE - сортировка по источнику.\n    7. DOWNLOADS *(по умолчанию)* - сортировка по количеству загрузок.\n4. `tags` *(list[int])* - список **ID** тегов которые должны иметь отправленные в ответе игры.\n5. `games` *(list[int])* - **ID** игр с которыми связан мод. \nПо факту 1 мод связан максимум с 1 игрой, но архитектурой сервера это никак не ограничивается. \n6. `dependencies` *(bool)* - отправлять ли моды имеющие зависимость на другие моды. По умолчанию `False`.\n7. `primary_sources` *(list[str])* - фильтрация по первоисточникам. Например: `steam`, `local` и т.п..\n8. `name` *(str)* - фильтрация по имени. Необязательно писать полное имя.\n\n**JSON ответ:**\n```\n{\"message\": \"incorrect page size\", \"error_id\": 1}\n```\nHTTP code: `413`\n* Означает что размер страницы не входит в диапазон `1...50`.\n```\n{\"message\": \"the maximum complexity of filters is 30 elements in sum\", \"error_id\": 2}\n```\nHTTP code: `413`\n* Максимальное суммарное размер фильтров `tags`, `games`, `primary_sources` не должно превышать 30 элементов.\n```\n{\"database_size\": int, \"offeset\": int, \"results\": list[dict]}\n```\nHTTP code: `200`\n* `database_size` - общий размер базы данных с текущими фильтрами *(`game_id` и `source`)*.\n* `offeset` - итоговый рассчитанный сдвиг с `0` элемента в **БД**.\n* `results` - возвращает массив массивов в котором содержатся все элементы соответствующие текущему запросу *(пустой список если ничего не найдено)*.\nСодержание под массива:\n* * 1. `id` *(int)* - id мода.\n* * 2. `size` *(int)* - размер мода в байтах.\n* * 3. `date_creation` *(`YYYY-MM-DD HH:MI:SS`)* - дата появления в первоисточнике.\n* * 4. `date_update` *(`YYYY-MM-DD HH:MI:SS`)* - дата обновления в первоисточнике.\n* * 5. `date_request` *(`YYYY-MM-DD HH:MI:SS.MS`)* - дата последнего запроса.\n* * 6. `source` *(str)* - первоисточник.\n* * 7. `name` *(str)* - название мода.\n* * 8. `description` *(str)* - описание мода.\n* * 9. `condition` *(int)* - состояние мода *(`0` - загружен, `1` - можно запрашивать, не до конца провалидирован, `2` - скачивается)*.\n* * 10. `downloads` *(int)* - количество загрузок данного мода.\n\n\n### `/list/games/`\nВозвращает список игр, моды к которым есть на сервере. Имеет необязательные аргументы:\n\n1. `page_size` *(int)* - количество элементов которое будет возвращено.\n2. `page` *(int)* - \"страница\" которая будет возвращена. Рассчитывается как `page_size * page = offeset`.\n3. `sort` *(str)* - режим сортировки таблицы перед фильтрацией.\n    Префикс `i` указывает что сортировка должна быть инвертированной.\n    1. `NAME` - сортировка по имени.\n    2. `TYPE` - сортировка по типу *(`game` или `app`)*.\n    3. `CREATION_DATE` - сортировка по дате регистрации на сервере.\n    4. `MODS_DOWNLOADS` - сортировка по суммарному количеству скачанных модов для игры *(по умолчанию)*.\n    5. `MODS_COUNT` - сортировка по суммарному количеству модов для игры.\n    6. `SOURCE` - сортировка по источнику.\n4. `type_app` *(list[str])* - фильтрация по типу *(`game` или `app`)*.\n5. `genres` *(list[int])* - фильтрация по жанрам игр.\n6. `primary_sources` *(list[str])* - фильтрация по первоисточникам. Например: `steam`, `local` и т.п..\n7. `name` *(str)* - фильтрация по имени. Необязательно писать полное имя.\n\n**JSON ответ:**\n1. Некоректный размер страницы:\n```\n{\"message\": \"incorrect page size\", \"error_id\": 1}\n```\nHTTP code: `413`\n* Означает что размер страницы не входит в диапазон `1...50`.\n2. Слишком сложный запрос:\n```\n{\"message\": \"the maximum complexity of filters is 30 elements in sum\", \"error_id\": 2}\n```\nHTTP code: `413`\n* Максимальное суммарное размер фильтров `type_app`, `genres`, `primary_sources` не должно превышать 30 элементов.\n3. Нормальный ответ:\n```\n{\"database_size\": int, \"offeset\": int, \"results\": list[list]}\n```\nHTTP code: `404`\n* `database_size` - общий размер базы данных с текущими фильтрами.\n* `offeset` - итоговый рассчитанный сдвиг с `0` элемента в **БД**.\n* `results` - возвращает массив массивов в котором содержатся все элементы соответствующие текущему запросу *(пустой список если ничего не найдено)*.\nСодержание под массива:\n* * 1. `id` *(int)* - id игры.\n* * 2. `name` *(str)* - название игры.\n* * 3. `type` *(str)* - тип приложения *(`game` или `app`)*.\n* * 4. `logo` *(str)* - `url` ведущий на лого игры.\n* * 5. `short_description` *(str)* - короткое описание игры.\n* * 6. `description` *(str)* - описание игры.\n* * 7. `mods_downloads` *(int)* - суммарное количество загрузок у связанных с игрой модов.\n* * 8. `mods_count` *(int)* - количество связанных модов.\n* * 9. `creation_date` *(`YYYY-MM-DD HH:MI:SS.MS`)* - дата регистрации на сервере\n* * 10. `source` *(str)* - первоисточник.\n\n\n### `/list/tags/{game_id}`\nВозвращает список тегов закрепленных за игрой и её модами. Нужно передать ID интересующей игры.\nИмеет необязательные аргументы:\n\n1. `page_size` *(int)* - размер 1 страницы. Диапазон - 1...50 элементов.\n2. `page` *(int)* - номер странице. Не должна быть отрицательной.\n\n**JSON ответы:**\n\n1. Некоректный размер страницы:\n```\n{\"message\": \"incorrect page size\", \"error_id\": 1}\n```\nHTTP code: `413`\n2. Нормальный ответ:\n```\n{\"database_size\": genres_count, \"offset\": offset, \"results\": genres}\n```\nHTTP code: `200`\n* Структура подсловаря в `results`:\n* 1. `id` *(`int`)* - ID элемента.\n* 2. `name` *(`str`)* - название тега.\n\n\n### `/list/genres`\nВозвращает список жанров для игр.\nИмеет необязательные аргументы:\n\n1. `page_size` *(int)* - размер 1 страницы. Диапазон - 1...50 элементов.\n2. `page` *(int)* - номер странице. Не должна быть отрицательной.\n\n**JSON ответы:**\n\n1. Некоректный размер страницы:\n```\n{\"message\": \"incorrect page size\", \"error_id\": 1}\n```\nHTTP code: `413`\n2. Нормальный ответ:\n```\n{\"database_size\": genres_count, \"offset\": offset, \"results\": genres}\n```\nHTTP code: `200`\n* Структура подсловаря в `results`:\n* 1. `id` *(`int`)* - ID элемента.\n* 2. `name` *(`str`)* - название жанра.\n\n\n### `/list/resources_mods/{mod_id}`\nВозвращает список ресурсов у конкретного мода. Нужно передать ID интересующего мода.\nИмеет необязательные аргументы:\n\n1. `page_size` *(int)* - размер 1 страницы. Диапазон - 1...50 элементов.\n2. `page` *(int)* - номер странице. Не должна быть отрицательной.\n3. `types_resources` *(list[str])* - фильтрация по типам ресурсов. *(`logo` / `screenshot`)*, ограничение - 20 элементов.\n\n**JSON ответы:**\n\n1. Некоректный размер страницы:\n```\n{\"message\": \"incorrect page size\", \"error_id\": 1}\n```\nHTTP code: `413`\n* Означает что размер страницы не входит в диапазон `1...50`.\n2. Слишком сложный запрос:\n```\n{\"message\": \"the maximum complexity of filters is 30 elements in sum\", \"error_id\": 2}\n```\nHTTP code: `413`\n* Максимальный размер фильтра `types_resources` не должен превышать 30 элементов.\n3. Нормальный ответ:\n```\n{\"database_size\": int, \"offset\": int, \"results\": list[dict]}\n```\nHTTP code: `200`\n* Структура подсловаря в `results`:\n* 1. `date_event` *(`YYYY-MM-DD HH:MI:SS.MS`)* - дата последнего изменения записи на сервере.\n* 2. `id` *(`int`)* - ID ресурса.\n* 3. `url` *(`str`)* - ссылка на ресурс.\n* 4. `type` *(`str`)* - тип ресурса *(`logo` / `screenshot`)*.\n* 5. `owner_id` *(`int`)* - ID мода-владельца.\n\n\n### `/info/mod/{mod_id}`\nВозвращает информацию об конкретном моде, а так же его состояние на сервере. \nНужно передать `ID` мода. Имеет так же необязательный `bool` аргумент `dependencies` *(по умолчанию `false`)*.\n\n**JSON ответ:**\n```\n{\"result\": dict / null}\n```\nHTTP code: `200`\n* `results` - возвращает либо `null`, либо словарь с результатом поиска. Структура словаря:\n* * 1. `id` *(int)* - id мода.\n* * 2. `size` *(int)* - размер мода в байтах.\n* * 3. `date_creation` *(`YYYY-MM-DD HH:MI:SS`)* - дата появления в первоисточнике.\n* * 4. `date_update` *(`YYYY-MM-DD HH:MI:SS`)* - дата обновления в первоисточнике.\n* * 5. `date_request` *(`YYYY-MM-DD HH:MI:SS.MS`)* - дата последнего запроса.\n* * 6. `source` *(str)* - первоисточник.\n* * 7. `name` *(str)* - название мода.\n* * 8. `description` *(str)* - описание мода.\n* * 9. `condition` *(int)* - состояние мода *(`0` - загружен, `1` - можно запрашивать, не до конца провалидирован, `2` - скачивается)*.\n* * 10. `downloads` *(int)* - количество загрузок данного мода.\n* При `dependencies=true` возвращает дополнительные пункты: `dependencies` *(list[int])* - ограничено 20 элементами.\n`dependencies_count` *(int)* - возвращает общее число элементов.\n\n\n### `/info/game/{game_id}`\nВозвращает информацию о конкретной игре. \nНужно передать только `ID` игры.\n\n**JSON ответ:**\n```\n{\"result\": list / null}\n```\nHTTP code: `200`\n* `results` - возвращает словарь в котором содержится информация об игре.\nЕсли игра не найдена, возвращает `null`. Содержание словаря:\n* * 1. `id` *(int)* - id игры.\n* * 2. `name` *(str)* - название игры.\n* * 3. `type` *(str)* - тип приложения *(`game` или `app`)*.\n* * 4. `logo` *(str)* - `url` ведущий на лого игры.\n* * 5. `short_description` *(str)* - короткое описание игры.\n* * 6. `description` *(str)* - описание игры.\n* * 7. `mods_downloads` *(int)* - суммарное количество загрузок у связанных с игрой модов.\n* * 8. `mods_count` *(int)* - количество связанных модов.\n* * 9. `creation_date` *(`YYYY-MM-DD HH:MI:SS.MS`)* - дата регистрации на сервере\n* * 10. `source` *(str)* - первоисточник.\n\n\n### `/condition/mod/{ids_array}`\nВозвращает информацию о состоянии мода/модов на сервере.\nНужно передать массив с интересующими ID модов. **Диапазон - 1...50 элементов**\n\n**JSON ответ:**\n```\n{\"message\": \"the size of the array is not correct\", \"error_id\": 1}\n```\nHTTP code: `413`\n* Означает что массив вышел за диапазон в **1...50** элементов.\n```\n{id: 0/1/2, ...}\n```\nHTTP code: `200`\n* В ответе возвращает только те элементы которые были переданы в запросе И есть на сервере.\n* Об состояниях: *(`0` - загружен, `1` - можно запрашивать, не до конца провалидирован, `2` - скачивается)*.\n* Если мода нет в ответе - значит его нет на сервере.\n\n\n### `/statistics/delay`\nВозвращает информацию о скорости обработки запросов *(измеряется в миллисекундах)*.\nВ расчеты попадают 20 последних запросов.\n\n**JSON ответ:**\n```\n{\"fast\": int, \"full\": int}\n```\nHTTP code: `200`\n* `fast` - скорость ответа сервера на запрос о моде который есть на сервере.\n* `full` - скорость ответа сервера на запрос о моде которого нет на сервере.\nЗамер идет от момента получения запроса до момента переключение мода на состояние `1` \n*(можно запрашивать, не до конца провалидирован)*.\n\n* Если сервер прислал *(в одном из двух параметров)* `0` - недостаточно данных для статистики по этому пункту.\n\n\n### `/statistics/hour`\nВозвращает подробную статистику о запросах и работе сервера в конкретный день.\nИмеет необязательные аргументы:\n1. `day` *(`YYYY-MM-DD`; `str`)* - день по которому нужна статистика. По умолчанию - сегодня.\n2. `start_hour` *(`int`)* - фильтрация по минимальному значению часа *(диапазон 0...23)*.\n3. `end_hour` *(`int`)* - фильтрация по максимальному значению часа *(диапазон 0...23)*.\n\nПри фильтрации по часу отсекаются крайние значения, но не указанное.\nТ.е. - если указать в `start_hour` и в `end_hour` одно и тоже значение,\nто на выходе получите статистику только по этому часу.\n\n**JSON ответ:**\n1. Выход начального времени из 24-часового диапазона:\n```\n{\"message\": \"start_hour exits 24 hour format\", \"error_id\": 1}\n```\nHTTP code: `412`\n2. Выход конечного времени из 24-часового диапазона:\n```\n{\"message\": \"end_hour exits 24 hour format\", \"error_id\": 2}\n```\nHTTP code: `412`\n3. Противоречивый запрос:\n```\n{\"message\": \"conflicting request\", \"error_id\": 3}\n```\nHTTP code: `409`\n* Возникает когда начальное время \u003e конечного времени.\n4. Нормальный ответ:\n```\nlist[dict]\n```\nHTTP code: `200`\n* Содержание словаря:\n* 1. `count` *(`int`)* - количество чего-то в этот период времени.\n* 3. `type` *(`str`)* - тип поля.\n* 4. `date_time` *(`YYYY-MM-DD HH:MI:SS.MS` - где все что меньше часа всегда равно `0`)* - дата и час.\n\n\n### `/statistics/day`\nВозвращает подробную статистику о запросах и работе сервера в конкретный день.\n\nПринимает необязательные параметры:\n1. `start_date` *(`YYYY-MM-DD`; `str`)* - день от начала которого нужна статистика *(включительно)*.\nПо умолчанию = `end_date`-`7 days`.\n2. `end_date` *(`YYYY-MM-DD`; `str`)* - день до которого нужна статистика *(включительно)*.\nПо умолчанию - текущая дата.\n\nПри фильтрации по дня отсекаются крайние значения, но не указанные.\nТ.е. - если указать в `start_date` и в `end_date` одно и тоже значение,\nто на выходе получите статистику только по этому дню.\n\n**JSON ответ:**\n1. Противоречивый запрос:\n```\n{\"message\": \"conflicting request\", \"error_id\": 3}\n```\nHTTP code: `409`\n* Возникает когда начальная дата \u003e конечной даты.\n2. Нормальный ответ:\n```\nlist[dict]\n```\nHTTP code: `200`\n* Содержание словаря:\n* 1. `count` *(`int`)* - количество чего-то в этот период времени.\n* 3. `type` *(`str`)* - тип поля.\n* 4. `date` *(`YYYY-MM-DD`)* - дата.\n\n\n### `/statistics/info/all`\nВозвращает общую информацию о состоянии базы данных. Не принимает аргументов.\n\n**JSON ответ:**\n```\n{\"mods\": int, \"games\": int, \"genres\": int, \"mods_tags\": int, \"mods_dependencies\": int, \"statistics_days\": int}\n```\nHTTP code: `200`\n* `mods` *(`int`)* - суммарное по всем играм количество модов на сервере.\n* `games` *(`int`)* - количество проиндексированных.\n* `genres` *(`int`)* - количество проиндексированных жанров игр.\n* `mods_tags` *(`int`)* - суммарное по всем играм количество тегов для модов.\n* `mods_dependencies` *(`int`)* - количество модов у которых есть зависимости на другие моды.\n* `statistics_days` *(`int`)* - сколько уже дней ведётся статистика.\n* `mods_sent_count` *(`int`)* - сколько раз сервер отправил пользователям файлы с модами.\n\n\n### `/statistics/info/type_map`\nВозвращает карту переводов для типов в статистической ветке. Не принимает аргументов.\nОпределяет на каком языке отправить ответ через поле `Accept-Language` в `headers` запроса.\n\n**JSON ответ:**\n```\n{\"language\": select_language, \"result\": stc.cache_types_data(select_language)}\n```\nHTTP code: `200`\n* `language` *(`str`)* - выбранный сервером язык. \nПытается найти самый перевод для языков *(по пользовательскому приоритету)*.\nЕсли не удалось найти язык по пользовательскому приоритету - устанавливается `ru` как значение по умолчанию.\n* `result` *(`dict[str] = str`)* - возвращает словарь с переводами для типов которые получаются \nв `/statistics/day` и `/statistics/hour`.\n\n\n# Установка на свой сервер\n\nЕсли вы хотите по какой-то причине поднять сервер у себя, вот небольшая заметки :)\n\n1. Убедитесь что вы установили все зависимости из requirements.txt и у вас не возникли ошибки!\n2. Для корректного запуска сервера на Linux вам нужно выполнить [этот пункт](https://github.com/wmellema/Py-SteamCMD-Wrapper#prerequisites)\n3. Если у вас возникли какие-то проблемы с установкой - пишите мне!\n\n## Установка на Ubuntu:\n### Одной командой:\n```bash\nsudo adduser steam; sudo apt update; sudo apt upgrade; sudo apt-get install lib32stdc++6 -y; sudo apt install git -y; sudo apt install python3.10 -y; sudo apt -y install python3-pip; sudo apt install htop -y; sudo apt install screen -y; cd /home/steam; git clone https://github.com/Miskler/pytorrent.git; cd pytorrent; chmod -R 777 .; pip3 install -r requirements.txt; sudo snap install --classic certbot; sudo certbot certonly --standalone\n```\nЭто займет некоторое время :)\nПосле перейти к шагу 7!\n\n### Последовательно:\n1. Создание пользователя: \n```bash\nsudo adduser steam\n```\n2. Обновление всех пакетов: \n```bash\nsudo apt update; sudo apt upgrade\n```\n3. Установка по: *(после рекомендую перезапустить ОС)* \n```bash\nsudo apt-get install lib32stdc++6 -y; sudo apt install git -y; sudo apt install python3.10 -y; sudo apt -y install python3-pip; sudo apt install htop -y; sudo apt install screen -y\n``` \n4. Установка репозитория: \n```bash\ncd /home/steam; git clone https://github.com/Miskler/pytorrent.git; cd pytorrent; chmod -R 777 .\n```\n5. Установка зависимостей: \n```bash\npip3 install -r requirements.txt\n```\n6. Установка CertBot *(SSL сертификат)*: \n```bash\nsudo snap install --classic certbot; sudo ln -s /snap/bin/certbot /usr/bin/certbot; sudo certbot certonly --standalone\n```\n7. Создание файла с настройками для сервера:\nСоздайте файл в каталоге `backend` со следующим содержимым:\n```py\nbind = \"0.0.0.0:443\"  # Указывает Gunicorn слушать все IP-адреса на порту 443\n\n#По идее должен содержать значение:\ncertfile = \"/etc/letsencrypt/live/YOU_DOMEN.com/fullchain.pem\"  # Путь к вашему HTTPS сертификату (фактический путь см в логах certbot)\n#По идее должен содержать значение:\nkeyfile = \"/etc/letsencrypt/live/YOU_DOMEN.com/privkey.pem\"  # Путь к вашему приватному ключу (фактический путь см в логах certbot)\n\nworkers = 1  # Количество рабочих процессов Gunicorn\n```\n8. Запуск *(должны находится в каталоге `backend`)*:\n```bash\nscreen -S pytorrent_backend ./start.sh\n```\nЖмем сочитание клавиш `CTRL + A + D`\nПосле проверяем адрес - `https://YOU_DOMEN.com:8000/docs`. Если все ок вы увидете документацию.\n9. Запуск телеграм бота:\nСначало получаем ключ бота. После создаем файл `key.json` в папке `telegram_bot` и записываем в него:\n```py\n{\"key\": \"YOU KEY\"}\n```\nПосле выполняем команду:\n```bash\nscreen -S telegram_bot python3 main.py\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiskler%2Fpytorrent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiskler%2Fpytorrent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiskler%2Fpytorrent/lists"}