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} |