API-сервер для доступа к основным функциям rutracker.org. Реализован клиент для android. Использован стек NodeJS-Express-MongoDB и библиотека rutracker-api.
Все GraphQL - запросы вызываются через /rtapi/graphql. Более подробная информация об используемых
типах доступна в схеме в server.js или в graphiql - для включения необходимо установить флаг
IS_GRAPHIQL_ENABLED в config.js в true.
-
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.
-
subscribeToRss(threadId: String!, token: String!): String!
Подписывает пользователя с firebase-токеномtokenна push - уведомления фида с idthreadId. Работа, связанная с push - уведомлениями, выполняется отдельным NodeJS процессомnotificationService.js. Передача информации между процессами осуществляется с помощью общей БД с коллекциейsubscriptions. ПроцессnotificationService.jsработает в бесконечном цикле: запрашивает из БД фиды, у которых есть подписчики, и выполняет сетевые вызовы к rutracker.org. При наличии обновлений, клиентам рассылаются push - уведомления и обновляются соответствующие записи в БД. Далее процесс засыпает наconfig.RSS_UPDATE_INTERVAL. -
unsubscribeFromRss(threadId: String!, token: String!): String!
Отписка от уведомлений фидаthreadId.
-
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.
-
Установить зависимости
npm i -
Сконфигурировать firebase - проект, файл конфигурации
***firebase-adminsdk***.jsonскопировать в корень проекта. -
Совместимость с MongoDB гарантирована для версии 4.4.14, для других версий совместимость не проверялась.
-
В корне проекта создать файл
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)
}- Запустить процессы
server.js,notificationService.js, например используя менеджер процессовpm2.