Client
This commit is contained in:
parent
a3723bcdd6
commit
8bb87c6bba
2599
logs/app.log
2599
logs/app.log
File diff suppressed because it is too large
Load Diff
|
@ -117,10 +117,14 @@ class Job(Base):
|
||||||
job_level = Column(String(50), nullable=True) # Entry-level, Junior, Mid
|
job_level = Column(String(50), nullable=True) # Entry-level, Junior, Mid
|
||||||
job_type = Column(String(50), nullable=True) # Full-time, Part-time
|
job_type = Column(String(50), nullable=True) # Full-time, Part-time
|
||||||
days_posted = Column(Integer, nullable=True)
|
days_posted = Column(Integer, nullable=True)
|
||||||
|
|
||||||
hourly_rate = Column(Float, nullable=True)
|
hourly_rate = Column(Float, nullable=True)
|
||||||
link = Column(String(2083), nullable=True) # URL вакансии
|
link = Column(String(2083), nullable=True) # URL вакансии
|
||||||
link_company = Column(String(2083), nullable=True) # URL компании
|
link_company = Column(String(2083), nullable=True) # URL компании
|
||||||
active = Column(Boolean, default=True) # Вакансия активна?
|
active = Column(Boolean, default=True) # Вакансия активна?
|
||||||
|
about = Column(Text, nullable=True)
|
||||||
|
date_posted = Column(DateTime)
|
||||||
|
|
||||||
text = Column(Text, nullable=True)
|
text = Column(Text, nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
from fastapi import FastAPI, HTTPException, APIRouter, Request, Header, Depends
|
from fastapi import FastAPI, HTTPException, APIRouter, Request, Header, Depends
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
import json
|
import json
|
||||||
from model.database import get_async_session, Client
|
from model.database import get_async_session, Client
|
||||||
from utils.clients import upsert_client
|
from utils.clients import upsert_client, del_jobs, add_jobs, get_applied_jobs
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
API_KEY = "4545454"
|
API_KEY = "4545454"
|
||||||
|
@ -38,24 +41,44 @@ async def client(data: JsonData, x_api_key: str = Header(...), db: Session = Dep
|
||||||
if isinstance(data.json_data, str):
|
if isinstance(data.json_data, str):
|
||||||
try:
|
try:
|
||||||
data.json_data = json.loads(data.json_data)
|
data.json_data = json.loads(data.json_data)
|
||||||
|
first_name = data.json_data['first_name']
|
||||||
|
# print(first_name)
|
||||||
|
last_name = data.json_data['last_name']
|
||||||
|
email_addr = data.json_data['email_addr']
|
||||||
|
user_id = data.json_data['user_id']
|
||||||
|
phone_num = data.json_data['phone_num']
|
||||||
|
|
||||||
|
print(first_name)
|
||||||
|
|
||||||
|
|
||||||
|
# Создаем отдельные сессии для работы с БД
|
||||||
|
async_session_maker = async_sessionmaker(bind=db.bind, expire_on_commit=False)
|
||||||
|
async with async_session_maker() as db1, async_session_maker() as db2:
|
||||||
|
client_task = upsert_client(db1, user_id, first_name, last_name, email_addr, phone_num, str(data.json_data))
|
||||||
|
del_task = del_jobs(db2, user_id)
|
||||||
|
|
||||||
|
|
||||||
|
client, _ = await asyncio.gather(client_task, del_task)
|
||||||
|
|
||||||
|
# ## TODO Получить данные для фильтра!
|
||||||
|
ads = await add_jobs(db, user_id)
|
||||||
|
get_jobs = await get_applied_jobs(db, user_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
raise HTTPException(status_code=400, detail="Invalid JSON format")
|
raise HTTPException(status_code=400, detail="Invalid JSON format")
|
||||||
|
|
||||||
print("Полученные данные:", data.json_data)
|
print("Полученные данные:", data.json_data)
|
||||||
return {"message": "JSON получен", "data": "ok"}
|
return {"message": "JSON получен", "data": get_jobs}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# first_name = parsed_data['first_name']
|
# data = await upsert_client(db, first_name, last_name, email_addr, parsed_data)
|
||||||
# last_name = parsed_data['last_name']
|
# client = await upsert_client(db, user_id, first_name, last_name, email_addr, phone_num, str(data.json_data))
|
||||||
# email_addr = parsed_data['email_addr']
|
|
||||||
# user_id = parsed_data['user_id']
|
|
||||||
# phone_num = parsed_data['phone_num']
|
|
||||||
|
|
||||||
# print(first_name)
|
# resp = await idss(db, user_id)
|
||||||
# # data = await upsert_client(db, first_name, last_name, email_addr, parsed_data)
|
# resp2 = await idss(db, user_id, first_name)
|
||||||
# client = await upsert_client(db, user_id, first_name, last_name, email_addr, phone_num, str(parsed_data))
|
|
||||||
# print(f"Received data: data={client}")
|
|
|
@ -80,13 +80,14 @@ async def get_job(db: AsyncSession, job_id: str):
|
||||||
location = jobs['formattedLocation']
|
location = jobs['formattedLocation']
|
||||||
title = jobs['title']
|
title = jobs['title']
|
||||||
listed_at = jobs['listedAt']
|
listed_at = jobs['listedAt']
|
||||||
|
listed_ats = datetime.utcfromtimestamp(listed_at / 1000).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
company_info = jobs.get("companyDetails", {}).get("com.linkedin.voyager.deco.jobs.web.shared.WebCompactJobPostingCompany", {}).get("companyResolutionResult", {})
|
company_info = jobs.get("companyDetails", {}).get("com.linkedin.voyager.deco.jobs.web.shared.WebCompactJobPostingCompany", {}).get("companyResolutionResult", {})
|
||||||
company_name = company_info.get("name", "Unknown")
|
company_name = company_info.get("name", "Unknown")
|
||||||
company_url = company_info.get("url", "")
|
company_url = company_info.get("url", "")
|
||||||
|
|
||||||
link = f'https://www.linkedin.com/jobs/view/{job_id}/'
|
link = f'https://www.linkedin.com/jobs/view/{job_id}/'
|
||||||
|
# about =
|
||||||
|
|
||||||
workplace_types = jobs.get("workplaceTypesResolutionResults", {})
|
workplace_types = jobs.get("workplaceTypesResolutionResults", {})
|
||||||
|
|
||||||
|
@ -114,9 +115,12 @@ async def get_job(db: AsyncSession, job_id: str):
|
||||||
if job:
|
if job:
|
||||||
logging.info(f"🔄 Обновление вакансии {job_id} в базе...")
|
logging.info(f"🔄 Обновление вакансии {job_id} в базе...")
|
||||||
job.text = json.dumps(jobs)
|
job.text = json.dumps(jobs)
|
||||||
|
job.about = text
|
||||||
job.link = link
|
job.link = link
|
||||||
|
# job.days_posted = listed_ats
|
||||||
job.location = location
|
job.location = location
|
||||||
job.job_company = company_name
|
job.job_company = company_name
|
||||||
|
job.date_posted = listed_ats
|
||||||
job.link_company = company_url
|
job.link_company = company_url
|
||||||
job.location_type = localized_name
|
job.location_type = localized_name
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
from sqlalchemy.future import select
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
from sqlalchemy import or_
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
from model.database import Client
|
from model.database import Client, AppliedJob, Job
|
||||||
|
|
||||||
async def upsert_client(db: AsyncSession, user_id: str, user_login: str, user_nicename: str, user_email: str, phone: str, json_data: str):
|
async def upsert_client(db: AsyncSession, user_id: str, user_login: str, user_nicename: str, user_email: str, phone: str, json_data: str):
|
||||||
# Проверяем, существует ли клиент с таким логином или email
|
# Проверяем, существует ли клиент с таким логином или email
|
||||||
|
@ -41,3 +43,81 @@ async def upsert_client(db: AsyncSession, user_id: str, user_login: str, user_n
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
await db.rollback() # В случае ошибки откатываем изменения
|
await db.rollback() # В случае ошибки откатываем изменения
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def del_jobs(db: AsyncSession, user_id: str):
|
||||||
|
jobs = await db.execute(
|
||||||
|
select(AppliedJob).where(
|
||||||
|
AppliedJob.client_id == user_id,
|
||||||
|
or_(AppliedJob.status == "Scheduled", AppliedJob.status.is_(None))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
jobs = jobs.scalars().all()
|
||||||
|
|
||||||
|
for job in jobs:
|
||||||
|
await db.delete(job)
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def add_jobs(db: AsyncSession, user_id: str):
|
||||||
|
# Фильтруем вакансии по переданным параметрам
|
||||||
|
query = select(Job).filter(Job.active == 3)
|
||||||
|
result = await db.execute(query)
|
||||||
|
jobs = result.scalars().all() # Получаем список вакансий
|
||||||
|
|
||||||
|
if not jobs:
|
||||||
|
return {"message": "Нет вакансий по данному фильтру"}
|
||||||
|
|
||||||
|
# Создаём записи в AppliedJob
|
||||||
|
applied_jobs = [
|
||||||
|
AppliedJob(client_id=user_id, job_id=job.job_id)
|
||||||
|
for job in jobs
|
||||||
|
]
|
||||||
|
|
||||||
|
db.add_all(applied_jobs) # Добавляем в сессию
|
||||||
|
await db.commit() # Фиксируем изменения
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {"message": f"{len(applied_jobs)} вакансий добавлено в AppliedJob"}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_applied_jobs(db, client_id: int):
|
||||||
|
query = (
|
||||||
|
select(AppliedJob)
|
||||||
|
.options(joinedload(AppliedJob.job)) # Подгружаем данные о вакансии
|
||||||
|
.where(AppliedJob.client_id == client_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await db.execute(query)
|
||||||
|
applied_jobs = result.scalars().all()
|
||||||
|
|
||||||
|
if not applied_jobs:
|
||||||
|
return {"message": "Нет откликов на вакансии"}
|
||||||
|
|
||||||
|
jobs_list = []
|
||||||
|
|
||||||
|
for applied in applied_jobs:
|
||||||
|
job = applied.job # Получаем объект Job из отношения AppliedJob.job
|
||||||
|
|
||||||
|
jobs_list.append({
|
||||||
|
"id": job.job_id,
|
||||||
|
"title": job.job_title,
|
||||||
|
"company": job.job_company,
|
||||||
|
"postedDate": job.days_posted,
|
||||||
|
"location": job.location,
|
||||||
|
"jobType": job.job_type,
|
||||||
|
"salary": f"${job.minimum_annual_salary}K" if job.minimum_annual_salary else "Not specified",
|
||||||
|
"level": job.job_level,
|
||||||
|
"status": applied.status if applied.status else "Scheduled",
|
||||||
|
"requiredSkills": "",
|
||||||
|
"aboutJob": job.about,
|
||||||
|
"jobLink": job.link
|
||||||
|
})
|
||||||
|
|
||||||
|
return jobs_list
|
Loading…
Reference in New Issue