File size: 7,005 Bytes
d0e0a14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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