diff --git a/package.json b/package.json index b42e5c6..3293835 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "envalid": "^7.2.2", "express": "^4.17.1", "got": "^11.8.3", + "moment": "^2.29.1", "safe-compare": "^1.1.4", "telegraf": "^4.4.2" }, diff --git a/src/bots/factory/bots/approved/callback_data.ts b/src/bots/factory/bots/approved/callback_data.ts index c705768..226cf02 100644 --- a/src/bots/factory/bots/approved/callback_data.ts +++ b/src/bots/factory/bots/approved/callback_data.ts @@ -16,3 +16,5 @@ export const RANDOM_SEQUENCE = 'random_sequence'; export const LANG_SETTINGS = 'lang_settings'; export const ENABLE_LANG_PREFIX = 'lang_on_'; export const DISABLE_LANG_PREFIX = 'lang_off_'; + +export const UPDATE_LOG_PREFIX = 'update_log_'; diff --git a/src/bots/factory/bots/approved/index.ts b/src/bots/factory/bots/approved/index.ts index 71cc670..d5be12b 100644 --- a/src/bots/factory/bots/approved/index.ts +++ b/src/bots/factory/bots/approved/index.ts @@ -15,7 +15,7 @@ import { download } from './services/downloader'; import { createOrUpdateUserSettings, getUserSettings } from './services/user_settings'; import { formatBook, formatAuthor, formatSequence, formatTranslator } from './format'; import { getPaginatedMessage, registerLanguageSettingsCallback, registerPaginationCommand, registerRandomItemCallback } from './utils'; -import { getRandomKeyboard, getUserAllowedLangsKeyboard } from './keyboard'; +import { getRandomKeyboard, getUpdateLogKeyboard, getUserAllowedLangsKeyboard } from './keyboard'; export async function createApprovedBot(token: string, state: BotState): Promise { @@ -28,7 +28,7 @@ export async function createApprovedBot(token: string, state: BotState): Promise async function setMyCommands() { await bot.telegram.setMyCommands([ {command: "random", description: "Попытать удачу"}, - {command: "update_log", description: "Информация об обновлении каталога"}, + {command: "update_log", description: "Обновления каталога"}, {command: "settings", description: "Настройки"}, {command: "help", description: "Помощь"}, ]); @@ -82,7 +82,7 @@ export async function createApprovedBot(token: string, state: BotState): Promise bot.command("random", async (ctx: Context) => { ctx.reply("Что хотим получить?", { - reply_markup: getRandomKeyboard().reply_markup + reply_markup: getRandomKeyboard().reply_markup, }) }); @@ -90,6 +90,30 @@ export async function createApprovedBot(token: string, state: BotState): Promise registerRandomItemCallback(bot, CallbackData.RANDOM_AUTHOR, BookLibrary.getRandomAuthor, formatAuthor); registerRandomItemCallback(bot, CallbackData.RANDOM_SEQUENCE, BookLibrary.getRandomSequence, formatSequence); + bot.command("update_log", async (ctx: Context) => { + ctx.reply("Обновление каталога: ", { + reply_markup: getUpdateLogKeyboard().reply_markup, + }); + }); + + bot.action(new RegExp(CallbackData.UPDATE_LOG_PREFIX), async (ctx: Context) => { + if (!ctx.callbackQuery || !('data' in ctx.callbackQuery)) return; + + const userSettings = await getUserSettings(ctx.callbackQuery.from.id); + const allowedLangs = userSettings.allowed_langs.map((lang) => lang.code); + + const data = ctx.callbackQuery.data.split("_"); + const page = parseInt(data[4]); + + const arg = `${data[2]}_${data[3]}`; + + const pMessage = await getPaginatedMessage(CallbackData.UPDATE_LOG_PREFIX, arg, page, allowedLangs, BookLibrary.getBooks, formatBook); + + await ctx.reply(pMessage.message, { + reply_markup: pMessage.keyboard.reply_markup + }); + }); + bot.command("settings", async (ctx: Context) => { const keyboard = Markup.inlineKeyboard([ [Markup.button.callback("Языки", CallbackData.LANG_SETTINGS)] diff --git a/src/bots/factory/bots/approved/keyboard.ts b/src/bots/factory/bots/approved/keyboard.ts index f865c0c..804f9f2 100644 --- a/src/bots/factory/bots/approved/keyboard.ts +++ b/src/bots/factory/bots/approved/keyboard.ts @@ -1,11 +1,12 @@ import { Markup } from 'telegraf'; import { InlineKeyboardMarkup } from 'typegram'; +import moment from 'moment'; -import { RANDOM_BOOK, RANDOM_AUTHOR, RANDOM_SEQUENCE, ENABLE_LANG_PREFIX, DISABLE_LANG_PREFIX } from './callback_data'; +import { RANDOM_BOOK, RANDOM_AUTHOR, RANDOM_SEQUENCE, ENABLE_LANG_PREFIX, DISABLE_LANG_PREFIX, UPDATE_LOG_PREFIX } from './callback_data'; import { getUserSettings, getLanguages } from './services/user_settings'; -export function getPaginationKeyboard(prefix: string, query: string, page: number, totalPages: number): Markup.Markup { +export function getPaginationKeyboard(prefix: string, query: string | number, page: number, totalPages: number): Markup.Markup { function getRow(delta: number) { const row = []; @@ -43,6 +44,23 @@ export function getRandomKeyboard(): Markup.Markup { ]); } + +export function getUpdateLogKeyboard(): Markup.Markup { + const format = "YYYY-MM-DD"; + + const now = moment().format(format); + const d3 = moment().subtract(3, 'days').format(format); + const d7 = moment().subtract(7, 'days').format(format); + const d30 = moment().subtract(30, 'days').format(format); + + return Markup.inlineKeyboard([ + [Markup.button.callback('За 3 дня', `${UPDATE_LOG_PREFIX}${d3}_${now}_1`)], + [Markup.button.callback('За 7 дней', `${UPDATE_LOG_PREFIX}${d7}_${now}_1`)], + [Markup.button.callback('За 30 дней', `${UPDATE_LOG_PREFIX}${d30}_${now}_1`)], + ]); +} + + const DEFAULT_ALLOWED_LANGS_CODES = ['ru', 'be', 'uk']; export async function getUserAllowedLangsKeyboard(userId: number): Promise> { diff --git a/src/bots/factory/bots/approved/services/book_library.ts b/src/bots/factory/bots/approved/services/book_library.ts index 2e10987..60c91bb 100644 --- a/src/bots/factory/bots/approved/services/book_library.ts +++ b/src/bots/factory/bots/approved/services/book_library.ts @@ -108,6 +108,19 @@ async function _makeRequest(url: string, searchParams?: string | Record> { + const queryDates = query.split("_"); + + const searchParams = getAllowedLangsSearchParams(allowedLangs); + searchParams.append('page', page.toString()); + searchParams.append('size', PAGE_SIZE.toString()); + searchParams.append('uploaded_gte', queryDates[0]); + searchParams.append('uploaded_lte', queryDates[1]); + + return _makeRequest>(`/api/v1/books/`, searchParams); +} + + export async function getBookById(book_id: number): Promise { return _makeRequest(`/api/v1/books/${book_id}`); } diff --git a/src/bots/factory/bots/approved/utils.ts b/src/bots/factory/bots/approved/utils.ts index 5c5c5bc..16bbd37 100644 --- a/src/bots/factory/bots/approved/utils.ts +++ b/src/bots/factory/bots/approved/utils.ts @@ -13,12 +13,12 @@ interface PreparedMessage { } -export async function getPaginatedMessage( +export async function getPaginatedMessage( prefix: string, - data: any, + data: D, page: number, allowedLangs: string[], - itemsGetter: (data: any, page: number, allowedLangs: string[]) => Promise>, + itemsGetter: (data: D, page: number, allowedLangs: string[]) => Promise>, itemFormater: (item: T) => string, ): Promise { const itemsPage = await itemsGetter(data, page, allowedLangs); @@ -34,6 +34,7 @@ export async function getPaginatedMessage( }; } + export function registerPaginationCommand( bot: Telegraf, prefix: string,