brestok's picture
init
d0e0a14
import base64
import io
import os
from fastapi import Depends, Query, File, UploadFile, HTTPException
from fastapi.templating import Jinja2Templates
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi.requests import Request
from project.bot import bot_router
from project.bot.records import FileVoiceRecord
from project.bot.utils import generate_ai_report, encode_file_to_base64, transcript_audio_from_base64, \
generate_image_description, compress_and_save_image
from project.bot.models import AudioRecord, Folder, ImageRecord, Report
from project.bot.schemas import AudioImageIDsSchema, DataBytesSchema, RecordSchema, AudioRecordBase64Schema
from project.database import get_async_session
from project.users import current_user
from project.users.models import User
template = Jinja2Templates(directory='project/bot/templates')
@bot_router.get('/', name='main')
async def main(request: Request):
return template.TemplateResponse("home.html", {'request': request})
@bot_router.post('/report', name='report')
async def create_report(ids: AudioImageIDsSchema, session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_user)):
reports = await session.execute(select(Report.id).where(Report.user_id == user.id))
reports = reports.scalars().all()
if len(reports) >= 12:
raise HTTPException(status_code=403, detail="You cannot request more than 12 reports.")
audio_transcription = await session.execute(
select(AudioRecord.transcription).where(AudioRecord.id.in_(ids.audio_ids)))
audio_transcription = audio_transcription.scalars().all()
image_descriptions = await session.execute(
select(ImageRecord.transcription).where(ImageRecord.id.in_(ids.image_ids)))
image_descriptions = image_descriptions.scalars().all()
report = await generate_ai_report(audio_transcription + image_descriptions, ids.language)
report.user = user
report_content = report.content
session.add(report)
await session.commit()
return report_content
@bot_router.get('/user-folders', name='users-records')
async def get_folders(session: AsyncSession = Depends(get_async_session), user: User = Depends(current_user)):
folders = await session.execute(select(Folder.name).where(Folder.user_id == user.id))
return folders.scalars().all()
@bot_router.post('/delete-record', name='delete-record')
async def delete_record(record: RecordSchema, session: AsyncSession = Depends(get_async_session)):
if record.type == 'audio':
record = await session.execute(select(AudioRecord).where(AudioRecord.id == record.record_id))
record = record.scalars().first()
file_path = record.audio_path
await session.delete(record)
await session.commit()
try:
os.remove(file_path)
except FileNotFoundError:
pass
elif record.type == 'image':
record = await session.execute(select(ImageRecord).where(ImageRecord.id == record.record_id))
record = record.scalars().first()
await session.delete(record)
await session.commit()
@bot_router.get('/folder-records', name='folder-records')
async def get_folder_records(folder: int = Query(...), session: AsyncSession = Depends(get_async_session)):
records = await session.execute(select(AudioRecord).where(AudioRecord.folder_id == folder))
return records.scalars().all()
@bot_router.post('/upload-file-record', name='file-record')
async def upload_file_record(data: DataBytesSchema, session: AsyncSession = Depends(get_async_session)):
file_record = FileVoiceRecord(session, data.data_bytes)
await file_record.save()
@bot_router.get('/record/{record_id}/{model}/transcription', name='record-transcription')
async def get_record_transcription(record_id: int, model: str, session: AsyncSession = Depends(get_async_session)):
if model == 'audio':
record = await session.execute(select(AudioRecord.transcription).where(AudioRecord.id == record_id))
elif model == 'image':
record = await session.execute(select(ImageRecord.transcription).where(ImageRecord.id == record_id))
return record.scalars().first()
@bot_router.get('/record/{record_id}/{model}/play', name='record-play')
async def play_record(record_id: int, model: str, session: AsyncSession = Depends(get_async_session)):
if model == 'audio':
file_path = await session.execute(select(AudioRecord.audio_path).where(AudioRecord.id == record_id))
else:
file_path = await session.execute(select(ImageRecord.image_path).where(ImageRecord.id == record_id))
file_path = file_path.scalars().first()
base64_content = await encode_file_to_base64(file_path)
return base64_content
@bot_router.post('/transcript-record', name='transcript-record')
async def transcript_record(data: AudioRecordBase64Schema, session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_user)):
transcription, file_path = await transcript_audio_from_base64(data.audio)
record = AudioRecord()
record.audio_path = file_path
record.transcription = transcription
record.folder = await user.get_base_folder(session=session)
session.add(record)
await session.commit()
return transcription
@bot_router.get('/get-records', name='all-records')
async def get_records(session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_user)
):
folder = await user.get_base_folder(session=session)
if not folder:
folder = Folder()
folder.name = 'Default'
folder.owner = user
folder.user_id = user.id
session.add(folder)
await session.commit()
records = await session.execute(select(AudioRecord).where(AudioRecord.folder == folder))
records = records.scalars().all()
images = await session.execute(select(ImageRecord).where(ImageRecord.folder == folder))
images = images.scalars().all()
data = {'audio': records, 'images': images}
return data
@bot_router.post('/upload-image', name='upload-image')
async def upload_image(image: UploadFile = File(...), session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_user)):
image_content = await image.read()
file_format = image.filename.split('.')[-1].lower()
if file_format == 'jpg':
file_format = 'jpeg'
base64_image = base64.b64encode(image_content).decode()
image_description = await generate_image_description(base64_image, file_format)
image_path = compress_and_save_image(image_content)
image_object = ImageRecord()
image_object.transcription = image_description
image_object.image_path = image_path
image_object.folder = await user.get_base_folder(session=session)
session.add(image_object)
await session.commit()
return image_description