192 lines
6.2 KiB
Python
192 lines
6.2 KiB
Python
|
from fastapi import FastAPI, APIRouter, Depends, Request, HTTPException, Form
|
|||
|
from datetime import datetime
|
|||
|
from dotenv import load_dotenv
|
|||
|
import os
|
|||
|
|
|||
|
|
|||
|
from fastapi.responses import HTMLResponse
|
|||
|
from fastapi.responses import JSONResponse
|
|||
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|||
|
from sqlalchemy.orm import sessionmaker
|
|||
|
from sqlalchemy import create_engine
|
|||
|
from sqlalchemy.orm import Session
|
|||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|||
|
from sqlalchemy.future import select
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
from pydantic import BaseModel, HttpUrl
|
|||
|
from urllib.parse import urlparse, parse_qs
|
|||
|
from linkedin_api import Linkedin
|
|||
|
import logging
|
|||
|
from utils.logging_setup import configure_global_logging
|
|||
|
|
|||
|
from models.models import async_session, Job
|
|||
|
|
|||
|
|
|||
|
load_dotenv()
|
|||
|
# # Ваши учетные данные LinkedIn
|
|||
|
|
|||
|
|
|||
|
configure_global_logging()
|
|||
|
|
|||
|
router = APIRouter()
|
|||
|
|
|||
|
|
|||
|
username = os.getenv('USERNAME')
|
|||
|
password = os.getenv('PASSWD')
|
|||
|
api = Linkedin(username, password)
|
|||
|
|
|||
|
|
|||
|
DATABASE_URL = os.getenv('DATABASE_URL') # Ваши параметры подключения
|
|||
|
engine = create_engine(DATABASE_URL)
|
|||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class UrlModel(BaseModel):
|
|||
|
link_profile: HttpUrl # Используем HttpUrl для проверки валидности URL
|
|||
|
|
|||
|
|
|||
|
async def get_session() -> AsyncSession:
|
|||
|
async with async_session() as session:
|
|||
|
yield session
|
|||
|
|
|||
|
|
|||
|
async def get_or_create_profile(
|
|||
|
db: AsyncSession, link: str, first_name: str, last_name: str, geoLocationName: str, all_skills: list, all_languages: list
|
|||
|
):
|
|||
|
# Проверяем, существует ли запись с таким first_name и last_name
|
|||
|
query = select(Profile).filter(Profile.link == link)
|
|||
|
result = await db.execute(query)
|
|||
|
profile = result.scalars().first()
|
|||
|
|
|||
|
# Если профиля нет, создаём новый
|
|||
|
if not profile:
|
|||
|
profile = Profile(
|
|||
|
link = link,
|
|||
|
first_name=first_name,
|
|||
|
last_name=last_name,
|
|||
|
location=geoLocationName,
|
|||
|
skills=all_skills,
|
|||
|
languages=all_languages
|
|||
|
)
|
|||
|
db.add(profile)
|
|||
|
await db.commit()
|
|||
|
# await db.refresh(profile)
|
|||
|
|
|||
|
return profile
|
|||
|
|
|||
|
|
|||
|
@router.post("/link_profile")
|
|||
|
async def profile_url(data: UrlModel, db: AsyncSession = Depends(get_session)):
|
|||
|
# Проверяем, что ссылка начинается с "https://xander"
|
|||
|
if not str(data.link_profile).startswith("https://www.linkedin.com/"):
|
|||
|
# Возвращаем исключение с кодом 400 и сообщением об ошибке
|
|||
|
raise HTTPException(status_code=400, detail="Incorrect link")
|
|||
|
url_profiles = str(data.link_profile)
|
|||
|
path = urlparse(url_profiles).path
|
|||
|
print(path)
|
|||
|
|
|||
|
# Пропускаем '/in/' и получаем последнюю часть
|
|||
|
profiles = path.split("/")[2]
|
|||
|
|
|||
|
print(profiles)
|
|||
|
|
|||
|
profile = api.get_profile(profiles)
|
|||
|
logging.info(f"{profile}")
|
|||
|
firstName = profile['firstName']
|
|||
|
lastName = profile['lastName']
|
|||
|
locationName = profile['locationName']
|
|||
|
geoLocationName = profile['geoLocationName']
|
|||
|
headline = profile['headline']
|
|||
|
educations = profile['education']
|
|||
|
education = [
|
|||
|
{
|
|||
|
"schoolName": item.get("schoolName"),
|
|||
|
"Field_of_Study": item.get("fieldOfStudy"),
|
|||
|
"Degree": item.get('degreeName'),
|
|||
|
"Grade": "??",
|
|||
|
"Start Date": item.get("timePeriod", {}).get("startDate", {}).get("year"),
|
|||
|
"End Date": item.get("timePeriod", {}).get("endDate", {}).get("year"),
|
|||
|
"Currently study here": '??',
|
|||
|
"Description": "??"
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
for item in educations
|
|||
|
]
|
|||
|
|
|||
|
experiences = profile['experience']
|
|||
|
experience = [
|
|||
|
{
|
|||
|
"companyName": item.get("companyName"),
|
|||
|
"title": item.get("title"),
|
|||
|
"Employment type": "??",
|
|||
|
"Location": item.get('geoLocationName'),
|
|||
|
"Location Type": "??",
|
|||
|
"Start Date": {
|
|||
|
"month": item.get("timePeriod", {}).get("startDate", {}).get("month"),
|
|||
|
"year": item.get("timePeriod", {}).get("startDate", {}).get("year"),
|
|||
|
},
|
|||
|
"End Date":{
|
|||
|
"month": item.get("timePeriod", {}).get("endDate", {}).get("month"),
|
|||
|
"year": item.get("timePeriod", {}).get("endDate", {}).get("year"),
|
|||
|
},
|
|||
|
"Currently study here": '??',
|
|||
|
"Description": item.get('description')
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
for item in experiences
|
|||
|
]
|
|||
|
|
|||
|
volunteers = profile['volunteer']
|
|||
|
volunteer = [
|
|||
|
{
|
|||
|
"Organization": item.get("companyName"),
|
|||
|
"Role": item.get("role"),
|
|||
|
"Cause": item.get("cause"),
|
|||
|
"Location": item.get('geoLocationName'),
|
|||
|
"Start Date": {
|
|||
|
"month": item.get("timePeriod", {}).get("startDate", {}).get("month"),
|
|||
|
"year": item.get("timePeriod", {}).get("startDate", {}).get("year"),
|
|||
|
},
|
|||
|
"End Date":{
|
|||
|
"month": item.get("timePeriod", {}).get("endDate", {}).get("month"),
|
|||
|
"year": item.get("timePeriod", {}).get("endDate", {}).get("year"),
|
|||
|
},
|
|||
|
"Currently study here": '??',
|
|||
|
"Description": item.get('description')
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
for item in volunteers
|
|||
|
]
|
|||
|
all_skills = profile['skills']
|
|||
|
skills = [item['name'] for item in all_skills]
|
|||
|
all_languages = profile['languages']
|
|||
|
languages = [item['name'] for item in all_languages]
|
|||
|
profile = await get_or_create_profile(
|
|||
|
db, data.link_profile, firstName, lastName, f"{geoLocationName} {locationName}", skills, languages
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# Если профиль не в виде словаря, возвращаем его напрямую
|
|||
|
return {"FirstName": firstName,
|
|||
|
"LastName":lastName,
|
|||
|
"Location": f"{geoLocationName} {locationName}",
|
|||
|
"Statement":headline,
|
|||
|
'Education - list': education,
|
|||
|
'Experience - list': experience,
|
|||
|
"Volunteering - list": volunteer,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
"skills": skills,
|
|||
|
"languages":languages}
|