122 lines
4.9 KiB
Python
122 lines
4.9 KiB
Python
import html
|
||
from aiogram import Router, F
|
||
from aiogram.filters import Command
|
||
from aiogram.types import Message, CallbackQuery
|
||
from database import Database
|
||
from kwork import get_kwork_projects
|
||
from ai import filter_vacancies_with_ai
|
||
from aiogram import F
|
||
from aiogram.types import CallbackQuery
|
||
import logging
|
||
from keyboards import get_pagination_kb
|
||
|
||
router = Router()
|
||
db = Database("users.db")
|
||
|
||
@router.message(Command("search"))
|
||
async def search_projects(message: Message):
|
||
args = message.text.split()
|
||
start_p, end_p = 1, 1
|
||
|
||
if len(args) == 3:
|
||
if args[1].isdigit() and args[2].isdigit():
|
||
start_p, end_p = int(args[1]), int(args[2])
|
||
elif len(args) == 2:
|
||
if args[1].isdigit():
|
||
start_p, end_p = int(args[1]), int(args[1])
|
||
|
||
user_data = await db.get_user(message.from_user.id)
|
||
if not user_data or user_data[0] is None:
|
||
await message.answer("⚠️ Твой профиль еще не настроен.")
|
||
return
|
||
|
||
sphere, lang, prefs = user_data
|
||
user_preferences = f"- Сфера: {sphere}\n- Стек: {lang}\n- Доп: {prefs}"
|
||
|
||
msg = await message.answer(f"⏳ <b>Собираю свежие проекты и анализирую их нейросетью...</b>\n<i>Это может занять около минуты.</i>")
|
||
|
||
try:
|
||
raw_vacancies = await get_kwork_projects(start_page=start_p, end_page=end_p)
|
||
|
||
if not raw_vacancies:
|
||
await msg.edit_text("❌ Проектов не найдено.")
|
||
return
|
||
|
||
filtered_vacancies = await filter_vacancies_with_ai(raw_vacancies, user_preferences)
|
||
|
||
if not filtered_vacancies:
|
||
await msg.edit_text("😔 Подходящих проектов сейчас нет.")
|
||
return
|
||
|
||
await msg.delete()
|
||
await message.answer(f"🎯 <b>Найдено {len(filtered_vacancies)} подходящих проектов:</b>")
|
||
for vac in filtered_vacancies:
|
||
title = html.escape(vac.get('title', 'Без названия'))
|
||
price = html.escape(vac.get('price', 'По договоренности'))
|
||
desc = html.escape(vac.get('description', ''))
|
||
url = vac.get('url', '#')
|
||
|
||
text = (
|
||
f"💼 <b>{title}</b>\n\n"
|
||
f"💰 <b>Бюджет:</b> {price}\n"
|
||
f"📝 <b>Описание:</b> {desc}...\n\n"
|
||
f"🔗 <a href='{url}'>Смотреть на Kwork</a>"
|
||
)
|
||
# Отправляем, отключая превью ссылок, чтобы не захламлять чат
|
||
await message.answer(text, disable_web_page_preview=True)
|
||
|
||
except Exception as e:
|
||
print(f"Ошибка в поиске: {e}")
|
||
await msg.edit_text("❌ Произошла ошибка при анализе проектов. Попробуй еще раз чуть позже.")
|
||
|
||
async def build_pages_text(page_num: int):
|
||
raw_vacancies = await get_kwork_projects(start_page=page_num, end_page=page_num)
|
||
|
||
if not raw_vacancies:
|
||
return "❌ На этой странице проектов не найдено."
|
||
|
||
text = f"📂 <b>Все проекты (Страница {page_num}):</b>\n\n"
|
||
for i, vac in enumerate(raw_vacancies, 1):
|
||
title = html.escape(vac.get('title', 'Без названия'))
|
||
price = html.escape(vac.get('price', 'По договоренности'))
|
||
url = vac.get('url', '#')
|
||
desc = html.escape(vac.get('description', ''))[:100] + "..."
|
||
|
||
text += f"{i}. <a href='{url}'>{title}</a>\n💰 {price}\n📝 {desc}\n\n"
|
||
|
||
return text
|
||
|
||
@router.message(Command("all"))
|
||
async def command_all_vancancies(message: Message):
|
||
wait_msg = await message.answer("⏳ Загружаю список проектов...")
|
||
try:
|
||
page = 1
|
||
content = await build_pages_text(page)
|
||
await wait_msg.edit_text(
|
||
content,
|
||
reply_markup=get_pagination_kb(page),
|
||
disable_web_page_preview=True
|
||
)
|
||
except Exception as e:
|
||
logging.error(f"Error in /all: {e}")
|
||
await wait_msg.edit_text("⚠️ Ошибка при загрузке данных.")
|
||
|
||
# Обработка нажатий на кнопки пагинации
|
||
@router.callback_query(F.data.startswith("browse_"))
|
||
async def process_pagination(callback: CallbackQuery):
|
||
page = int(callback.data.split("_")[1])
|
||
|
||
await callback.message.edit_text("🔄 Обновляю список...")
|
||
|
||
try:
|
||
content = await build_pages_text(page)
|
||
await callback.message.edit_text(
|
||
content,
|
||
reply_markup=get_pagination_kb(page),
|
||
disable_web_page_preview=True
|
||
)
|
||
await callback.answer()
|
||
except Exception as e:
|
||
logging.error(f"Error in pagination: {e}")
|
||
await callback.answer("Ошибка при смене страницы", show_alert=True)
|