Improve vacancy rendering in messages
All checks were successful
release / docker (push) Successful in 38s
All checks were successful
release / docker (push) Successful in 38s
This commit is contained in:
parent
6ff25281e2
commit
b224ef29d3
@ -1,12 +1,14 @@
|
||||
import asyncio
|
||||
import io
|
||||
import os
|
||||
import asyncio
|
||||
import traceback
|
||||
from typing import Literal
|
||||
|
||||
from asgiref.sync import sync_to_async
|
||||
from langchain.agents import create_agent
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
||||
from pydantic import BaseModel
|
||||
from pypdf import PdfReader
|
||||
from telegram import (
|
||||
InlineKeyboardButton,
|
||||
@ -23,8 +25,6 @@ from telegram.ext import (
|
||||
filters,
|
||||
)
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import Literal
|
||||
from vacancies.conf.settings import DB_URI
|
||||
from vacancies.main.models import Customer, CustomerCV, JobTitle
|
||||
from vacancies.main.recommendations import get_next_vacancy
|
||||
@ -59,7 +59,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
|
||||
|
||||
async def next_vacancy(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
await context.bot.send_message(update.effective_chat.id, "⏳ Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
|
||||
customer_cv = await CustomerCV.objects.filter(customer__telegram_id=update.effective_user.id).afirst()
|
||||
if not customer_cv:
|
||||
@ -75,7 +75,8 @@ async def next_vacancy(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
|
||||
await context.bot.send_message(
|
||||
chat_id=update.effective_chat.id,
|
||||
text=vacancy.content,
|
||||
parse_mode="Markdown",
|
||||
text=vacancy.get_formatted_response(),
|
||||
reply_markup=InlineKeyboardMarkup([[
|
||||
InlineKeyboardButton("Откликнуться", url=vacancy.link),
|
||||
]]),
|
||||
@ -91,7 +92,7 @@ async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
checkpointer=checkpointer,
|
||||
)
|
||||
|
||||
message = await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
message = await context.bot.send_message(update.effective_chat.id, "⏳ Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
|
||||
response = await agent.ainvoke(
|
||||
input={"messages": [{"role": "user", "content": f'user_id = {update.effective_user.id}\n{update.message.text}'}]},
|
||||
@ -107,7 +108,7 @@ async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> N
|
||||
|
||||
|
||||
async def handle_document(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
message = await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
message = await context.bot.send_message(update.effective_chat.id, "⏳ Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||
|
||||
if not update.message.document:
|
||||
await context.bot.send_message(chat_id=update.effective_chat.id, text="Не удалось прочитать информацию из файла! Попробуйте другой формат.")
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
from itertools import batched
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
from pydantic import BaseModel
|
||||
from itertools import batched
|
||||
from typing import Literal
|
||||
from vacancies.main.models import Vacancy, JobTitle
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
import clickhouse_connect
|
||||
from django.core.management import BaseCommand
|
||||
from django.conf import settings
|
||||
from django.core.management import BaseCommand
|
||||
from django.utils import timezone
|
||||
from langchain_openai import ChatOpenAI
|
||||
from pydantic import BaseModel
|
||||
|
||||
from vacancies.main.models import JobTitle, Vacancy
|
||||
|
||||
query = """
|
||||
SELECT DISTINCT ON (message) id, chat_username, telegram_id, message, timestamp
|
||||
@ -42,6 +43,8 @@ class Command(BaseCommand):
|
||||
job_title: Literal[tuple(job_titles)]
|
||||
min_salary_rub: int | None
|
||||
max_salary_rub: int | None
|
||||
company_name: str
|
||||
requirements: str
|
||||
|
||||
openai_client = ChatOpenAI(model_name="gpt-5-mini", temperature=0, seed=42, top_p=1)
|
||||
structured_llm = openai_client.with_structured_output(Structure)
|
||||
@ -76,6 +79,8 @@ class Command(BaseCommand):
|
||||
job_title_id=job_title_map[response.job_title],
|
||||
min_salary_rub=response.min_salary_rub,
|
||||
max_salary_rub=response.max_salary_rub,
|
||||
company_name=response.company_name,
|
||||
requirements=response.requirements,
|
||||
content=message,
|
||||
timestamp=timezone.make_aware(timestamp),
|
||||
link=f"https://t.me/{chat_username}/{telegram_id}",
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import asyncio
|
||||
|
||||
from django.core.management import BaseCommand
|
||||
from vacancies.main.models import CustomerCV
|
||||
from vacancies.main.bot import application
|
||||
from vacancies.main.recommendations import get_next_vacancy
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
|
||||
from vacancies.main.bot import application
|
||||
from vacancies.main.models import CustomerCV
|
||||
from vacancies.main.recommendations import get_next_vacancy
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Generates new recommended vacancies"
|
||||
@ -18,7 +19,8 @@ class Command(BaseCommand):
|
||||
if vacancy := get_next_vacancy(customer_cv):
|
||||
await application.bot.send_message(
|
||||
chat_id=customer_cv.customer.chat_id,
|
||||
text=vacancy.content,
|
||||
text=vacancy.get_formatted_response(),
|
||||
parse_mode="Markdown",
|
||||
reply_markup=InlineKeyboardMarkup([[
|
||||
InlineKeyboardButton("Откликнуться", url=vacancy.link),
|
||||
]]),
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-09 19:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0011_remove_customercv_job_title_customercv_job_titles_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='vacancy',
|
||||
name='company_name',
|
||||
field=models.CharField(default='test', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='vacancy',
|
||||
name='requirements',
|
||||
field=models.TextField(default='test'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -45,6 +45,8 @@ class Vacancy(models.Model):
|
||||
external_id = models.CharField(max_length=255, unique=True)
|
||||
min_salary_rub = models.PositiveIntegerField(null=True, blank=True, default=None)
|
||||
max_salary_rub = models.PositiveIntegerField(null=True, blank=True, default=None)
|
||||
company_name = models.CharField(max_length=255)
|
||||
requirements = models.TextField()
|
||||
content = models.TextField()
|
||||
timestamp = models.DateTimeField()
|
||||
link = models.URLField()
|
||||
@ -52,6 +54,25 @@ class Vacancy(models.Model):
|
||||
def __str__(self):
|
||||
return self.job_title.title
|
||||
|
||||
def get_formatted_response(self):
|
||||
response = f"""
|
||||
💼 **Вакансия**: {self.job_title}
|
||||
\n🏢 **Компания**: {self.company_name}
|
||||
\n📝 **Требования**: {self.requirements}
|
||||
"""
|
||||
if self.min_salary_rub:
|
||||
if self.max_salary_rub:
|
||||
response += f"\n💸 **ЗП**: от {self.min_salary_rub} т.р."
|
||||
else:
|
||||
response += f"\n💸 **ЗП**: {self.min_salary_rub} т.р. - {self.max_salary_rub} т.р."
|
||||
elif self.max_salary_rub:
|
||||
response += f"\n💸 **ЗП**: до {self.max_salary_rub} т.р."
|
||||
|
||||
return response
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'Vacancies'
|
||||
|
||||
|
||||
class RecommendedVacancy(models.Model):
|
||||
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="recommended_vacancies")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user