105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
from fastapi import APIRouter,Depends
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi import HTTPException
|
|
from db_setup import get_session
|
|
from job.candidate.views import FileRead
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from pydantic import BaseModel, model_validator
|
|
from users.permissions import PermissionTag, require_permission
|
|
from job.job_post.views import JobPost
|
|
import logging
|
|
from job.job_post.plugins import PlatformAlias
|
|
from fastapi import UploadFile, File
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class JobPostCreate(BaseModel):
|
|
title: str
|
|
experience_min: int | None = None
|
|
experience_max: int | None = None
|
|
requirements: list[str] = []
|
|
optional_skills: list[str] = []
|
|
salary: str = "Anonymous"
|
|
location: str | None = None
|
|
employment_type: str | None = None
|
|
platform: str = "linkedin"
|
|
description: str | None = None
|
|
platform: str | None = None
|
|
channel_id: str | None = None
|
|
mode: str = "addToQueue"
|
|
due_at: str | None = None
|
|
|
|
@model_validator(mode="after")
|
|
def validate_mode_and_due_at(self):
|
|
allowed = {"addToQueue", "shareNow", "customScheduled"}
|
|
if self.mode not in allowed:
|
|
raise ValueError(f"mode must be one of {sorted(allowed)}")
|
|
if self.mode == "customScheduled" and not self.due_at:
|
|
raise ValueError("due_at is required when mode is customScheduled")
|
|
return self
|
|
|
|
@router.get("/jobs/alias")
|
|
async def get_job_alias():
|
|
try:
|
|
alias_lst=[k.name for k in PlatformAlias]
|
|
return JSONResponse(content={"data":alias_lst,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.post("/candidate/cv_upload")
|
|
async def cv_upload(
|
|
file: UploadFile = File(...),
|
|
current_user: dict = Depends(require_permission(PermissionTag.CANDIDATES_CREATE)),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
file_content = await file.read()
|
|
logger.info(f"Received file: {file.filename} ({len(file_content)} bytes)")
|
|
service=FileRead(session=session,filename=file.filename,file=file_content)
|
|
data=await service.read_file(file_content, file.filename)
|
|
|
|
return JSONResponse(content={"data":data,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.post("/job/post-job")
|
|
async def post_job(
|
|
payload: JobPostCreate,
|
|
current_user: dict = Depends(require_permission(PermissionTag.JOB_BOARD_CREATE)),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=JobPost(session=session)
|
|
data=await service.post_job(payload.model_dump(),current_user)
|
|
return JSONResponse(content={"data":data,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.get("/job/buffer/channels")
|
|
async def buffer_channels(
|
|
current_user: dict = Depends(require_permission(PermissionTag.JOB_BOARD_VIEW)),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=JobPost(session=session)
|
|
data=await service.list_channels()
|
|
return JSONResponse(content={"data":data,"total":len(data),"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|