Skip to content

arBespalov/rt-api

Repository files navigation

API-сервер для доступа к основным функциям rutracker.org. Реализован клиент для android. Использован стек NodeJS-Express-MongoDB и библиотека rutracker-api.

Описание API

GraphQL

Все GraphQL - запросы вызываются через /rtapi/graphql. Более подробная информация об используемых типах доступна в схеме в server.js или в graphiql - для включения необходимо установить флаг IS_GRAPHIQL_ENABLED в config.js в true.

Queries
  • search(query: String!, sort: String!, order: String!, startIndex: Int!, endIndex: Int!): SearchResult!
    Поиск раздач на трекере.

    • Параметр sort может принимать одно из следующих значений: "registered", "title", "downloads", "size", "lastMessage", "seeds" или "leeches".
    • Параметр order может принимать значение "desc" или "asc".
    • startIndex и endIndex - параметры пагинации.

    При запросе сначала проверяется кэш, если он пуст, то запрос проксируется на rutracker.org, результат кэшируется и возвращается клиенту. Время жизни кэша задается константой SEARCH_QUERIES_CACHING_TIME в config.js. Кэш, на данный момент, реализован в виде локальной переменной searchQueriesCache. Для работы механизма поисковых подсказок, параллельно обработке запроса, обновляется MongoDB - коллекция sugg.

  • magnetLink(id: String!): String!
    Возвращает magnet - ссылку для торрента с указанным id.

  • getRss(threadId: String!): RssChannel!
    Для получения списка раздач для конкретной категории/форума, используется механизм RSS-фидов, предоставляемых rutracker.org по адресу http://feed.rutracker.cc/atom/f/${threadId}.atom. RSS - фид доступен для каждого форума. Данный способ, очевидно, требует меньше ресурсов, чем парсинг HTML. Реализовано кэширование через БД - это связано с тем, что ту же БД использует процесс notificationService.js, занимающийся рассылкой push - уведомлений. Время жизни кэша устанавливается константой config.RSS_UPDATE_TIMEOUT.

  • getSearchSuggestions(query: String!): [String!]!
    Вызывается при пользовательском вводе в строку поиска. Коллекция подсказок sugg наполняется ранее выполненными поисковыми запросами всех пользователей. Для реализации "partitial text search", недоступного в MongoDB "из коробки", в коллекции, наряду с самим текстом поисковой подсказки, хранятся поисковые токены, представляющие собой N-грамму подсказки: например, для слова "страна" токены будут иметь вид "ст стр стра стран страна". Количество возвращаемых клиенту подсказок определяется константой config.SEARCH_SUGGESTIONS_PER_QUERY.

  • getTrendingSearches: [String!]!
    Возвращает популярные запросы за config.TRENDS_OBSERVING_DAYS_COUNT дней. Реализовано благодаря тому, что коллекция sugg вместе с поисковым запросом также хранит массив временных меток запросов пользователей. Тренды обновляются независимо, согласно расписанию (config.TRENDS_UPDATE_START_CRON_STYLE), и кэшируются в переменной trendingSuggestions.

Mutations
  • subscribeToRss(threadId: String!, token: String!): String!
    Подписывает пользователя с firebase-токеном token на push - уведомления фида с id threadId. Работа, связанная с push - уведомлениями, выполняется отдельным NodeJS процессом notificationService.js. Передача информации между процессами осуществляется с помощью общей БД с коллекцией subscriptions. Процесс notificationService.js работает в бесконечном цикле: запрашивает из БД фиды, у которых есть подписчики, и выполняет сетевые вызовы к rutracker.org. При наличии обновлений, клиентам рассылаются push - уведомления и обновляются соответствующие записи в БД. Далее процесс засыпает на config.RSS_UPDATE_INTERVAL.

  • unsubscribeFromRss(threadId: String!, token: String!): String!
    Отписка от уведомлений фида threadId.

REST

  • GET "/rtapi/torrent/file?id=..."
    Возвращает torrent - файл для раздачи с указанным id.

  • GET /rtapi/torrent/description?id=...&sduiversion=...
    Запрашивает с rutracker.org HTML - страницу раздачи и с помощью cheerio парсит её. Большинство искомых параметров (seeds, leeches, state и т.д.) имеют статичное место в верстке, однако авторское описание раздачи нестандартизированно, и может содержать различные элементы (текст, изображения, ссылки, спойлеры и т.д.) в различном порядке и на разных уровнях вложенности. Для преобразования HTML - кода описания раздачи в JSON, содержащий кастомный Server-Driven UI, реализован конвертер htmlToSDUIConverter.js. Рекурсивно проходя HTML - дерево, он отбрасывает лишнюю информацию и наполняет JSON только тем, что нужно клиенту для отрисовки UI - для текстового поля это будет сам текст и параметры шрифта, для изображения - ссылка на изображение и его размеры (для отрисовки placeholder'а во время загрузки на клиенте). Параметр запроса sduiversion позволяет обновлять механизмы SDUI, сохраняя прозрачную поддержку старых версий.

Логирование

Для логирования используется winston. Все логи уровня error с помощью библиотеки winston-telegram отправляются в telegram - бот. Необходимые для работы параметры TELEGRAM_BOT_TOKEN и TELEGRAM_CHAT_ID указываются в config.js. Логи уровня debug и verbose пишутся в соответствующие, ежедневно обновляемые файлы в /log. В логи уровня error также попадают необработанные исключения, ведущие к остановке процесса, и необработанные исключения GraphQL.

Инструкция по запуску

  1. Установить зависимости npm i

  2. Сконфигурировать firebase - проект, файл конфигурации ***firebase-adminsdk***.json скопировать в корень проекта.

  3. Совместимость с MongoDB гарантирована для версии 4.4.14, для других версий совместимость не проверялась.

  4. В корне проекта создать файл config.js со следующим содержимым:

module.exports.config = {
    PORT: // порт, на котором сервер слушает входящие соединения (тип: number)
    SEARCH_QUERIES_CACHING_TIME: // время жизни кэша поисковых запросов (тип: number, миллисекунды)
    USERNAME: // логин пользователя на rutracker.org (тип: string)
    PASSWORD: // пароль пользователя на rutracker.org (тип: string)
    HOST: // 'https://rutracker.org/' или зеркало (тип: string)
    RSS_UPDATE_TIMEOUT: // таймаут повторного запроса фида, при котором возвращается
                        // кэшированный результат (тип: number, миллисекунды)
    RSS_UPDATE_INTERVAL: // интервал запроса обновлений для push - уведомлений
                         // (тип: number, миллисекунды)
    SEARCH_SUGGESTIONS_PER_QUERY: // количество возвращаемых клиенту подсказок для
                                  // автокомплита (тип: number)
    TELEGRAM_BOT_TOKEN: // токен telegram - бота для логов (тип: string)
    TELEGRAM_CHAT_ID: // chatId telegram - пользователя, которому отправляются логи (тип: number)
    TRENDS_OBSERVING_DAYS_COUNT: // количество дней, за которые рассчитываются поисковые тренды
                                 // (тип: number)
    TRENDS_UPDATE_START_CRON_STYLE: // время запуска процесса обновления трендов в crontab - стиле,
                                    // например, каждую ночь в 3:00: '0 3 * * *' (тип: string)
    FIREBASE_ADMIN_SDK_CONFIG_FILE_NAME: // имя файла ***firebase-adminsdk***.json (тип: string)
    MONGODB_CONNECTION_STRING: // дефолтное значение для локальной установки:
                               // 'mongodb://127.0.0.1:27017/' (тип: string)
    IS_GRAPHIQL_ENABLED: false // рекомендуется только для debug - режима (тип: boolean)
}
  1. Запустить процессы server.js, notificationService.js, например используя менеджер процессов pm2.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors