| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 | 
							- from fastapi import FastAPI,Cookie, Depends, Query, status,File, UploadFile,Request,Response,HTTPException
 
- from fastapi.templating import Jinja2Templates
 
- from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
 
- from pydantic import BaseModel
 
- from typing import List, Optional
 
- from os.path import isfile, isdir, join
 
- import threading
 
- import zhtts
 
- import os 
 
- import urllib
 
- import requests
 
- from bs4 import BeautifulSoup
 
- from PIL import Image,ImageDraw,ImageFont
 
- import pyttsx3
 
- import rpyc
 
- import random
 
- import time
 
- import math
 
- import hashlib
 
- import re
 
- import asyncio
 
- import urllib.request
 
- from fastapi.responses import FileResponse
 
- from fastapi.middleware.cors import CORSMiddleware
 
- import dataset
 
- from datetime import datetime, timedelta
 
- from util.swap_face import swap_face
 
- from fastapi.staticfiles import StaticFiles
 
- import shutil
 
- import io
 
- from first import first
 
- from passlib.context import CryptContext
 
- from jose import JWTError, jwt
 
- from fastapi_jwt_auth import AuthJWT
 
- from fastapi_jwt_auth.exceptions import AuthJWTException
 
- from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
 
- import models
 
- import pymysql
 
- import mailer
 
- from moviepy.editor import VideoFileClip
 
- import traceback
 
- import logging
 
- import gSlide
 
- import aiofiles
 
- import json
 
- import util.user
 
- pymysql.install_as_MySQLdb()
 
- app = FastAPI()
 
- mode = 'run'
 
- app.add_middleware(
 
-     CORSMiddleware,
 
-     allow_origins=["*"],
 
-     allow_credentials=True,
 
-     allow_methods=["*"],
 
-     allow_headers=["*"],
 
- )
 
- SECRET_KEY = "df2f77bd544240801a048bd4293afd8eeb7fff3cb7050e42c791db4b83ebadcd"
 
- ALGORITHM = "HS256"
 
- ACCESS_TOKEN_EXPIRE_DAYS = 5
 
- pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
 
- app.mount("/static", StaticFiles(directory="static"), name="static")
 
- app.mount("/static/img", StaticFiles(directory="static/img"), name="static/img")
 
- app.mount("/templates", StaticFiles(directory="templates"), name="templates")
 
- templates = Jinja2Templates(directory="templates")
 
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
 
- tmp_video_dir = '../OpenshotService/tmp_video/'
 
- tmp_avatar_dir = '../../face_swap/tmp_avatar/'  #change source face path here
 
- resource_server = 'www.choozmo.com:8168/'
 
- resource_folder = '/var/www/html/'
 
- video_sub_folder = 'ai_anchor_video/'
 
- avatar_sub_folder = 'swap_save/'
 
- tmp_img_sub_folder = 'tmp_img/'
 
- pttx_sub_folder = 'tmp_pttx/'
 
- img_upload_folder = '/var/www/html/'+tmp_img_sub_folder
 
- video_dest = '/var/www/html/'+video_sub_folder
 
- avatar_dest = '/var/www/html/'+avatar_sub_folder
 
- pttx_dest = '/var/www/html/'+pttx_sub_folder
 
- # @app.get("/index2")
 
- # async def index2():
 
- #     return FileResponse('static/index2.html')
 
- @app.get("/index_eng")
 
- async def index2():
 
-     return FileResponse('static/index_eng.html')
 
- # home page
 
- @app.get("/index", response_class=HTMLResponse)
 
- async def get_home_page(request: Request, response: Response):
 
-     return templates.TemplateResponse("index.html", {"request": request, "response": response})
 
- @app.get("/checkStatus")
 
- async def checkStatus():
 
-     errorList = []
 
-     try:
 
-         conn = rpyc.classic.connect("192.168.1.105",18812)
 
-         conn.close()
 
-     except:
 
-         errorList.append('105:18812 server')
 
-     try:
 
-         c = rpyc.connect("localhost", 8858)
 
-         c.close()
 
-     except:
 
-         errorList.append('make_video(docker name : new openshot)')
 
-     
 
-     try:
 
-         c = rpyc.connect("localhost", 8868)
 
-         c.close()
 
-     except:
 
-         errorList.append('swap_face(docker name : fcontainer)')
 
-     
 
-     return {'errors':errorList}
 
- @app.get("/", response_class=HTMLResponse)
 
- async def get_home_page(request: Request, response: Response):
 
-     return templates.TemplateResponse("index.html", {"request": request, "response": response})
 
- @app.get("/make_video")
 
- async def get_home_page(request: Request, response: Response, Authorize: AuthJWT = Depends()):
 
-     try:
 
-         Authorize.jwt_required()
 
-     except Exception as e:
 
-         print(e)
 
-         return {'msg':{'eng':'Please login first','zh':'請先登入帳號'}}
 
-     current_user = Authorize.get_jwt_subject()
 
-     return templates.TemplateResponse("make_video.html", {"request": request, "response": response})
 
- @app.get("/make_video_long", response_class=HTMLResponse)
 
- async def get_home_page(request: Request, response: Response, Authorize: AuthJWT = Depends()):
 
-     try:
 
-         Authorize.jwt_required()
 
-     except Exception as e:
 
-         print(e)
 
-         return {'msg':{'eng':'Please login first','zh':'請先登入帳號'}}
 
-     current_user = Authorize.get_jwt_subject()
 
-     return templates.TemplateResponse("make_video_long.html", {"request": request, "response": response})
 
- @app.get("/make_video_slide", response_class=HTMLResponse)
 
- async def make_video_slide(request: Request, response: Response, Authorize: AuthJWT = Depends()):
 
-     try:
 
-         Authorize.jwt_required()
 
-     except Exception as e:
 
-         print(e)
 
-         return {'msg':{'eng':'Please login first','zh':'請先登入帳號'}}
 
-     current_user = Authorize.get_jwt_subject()
 
-     return templates.TemplateResponse("make_video_slide.html", {"request": request, "response": response})
 
- @app.post('/user_profile', response_class=HTMLResponse)
 
- async def user_profile(token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = get_user_id(token)
 
-     user_obj = first(db.query('SELECT * FROM users where id ="'+str(user_id)+'"'))
 
-     if user_obj is None:
 
-         raise HTTPException(
 
-             status_code=status.HTTP_401_UNAUTHORIZED,
 
-             detail="Missing token",
 
-             headers={"WWW-Authenticate": "Bearer"},
 
-         )
 
-     video_num = str(first(db.query('SELECT COUNT(*) FROM history_input WHERE user_id ='+str(user_obj['id'])))['COUNT(*)'])
 
-     total_sec = str(first(db.query('SELECT SUM(duration) FROM history_input where user_id='+str(user_obj['id'])))['SUM(duration)'])
 
-     left_sec = user_obj['left_time']
 
-     video_info_list = []
 
-     statement = 'SELECT * FROM history_input WHERE user_id='+str(user_obj['id'])+' ORDER BY timestamp DESC LIMIT 50'
 
-     for row in db.query(statement):
 
-         video_info_list.append({'id':row['id'],'title':row['name'],'duration':row['duration'],'url':row['link'],'time_stamp':row['timestamp'].strftime("%m/%d/%Y, %H:%M:%S")})
 
-     dic_return = {'user_info':{'id':user_id,'userName':user_obj['username'],'email':user_obj['email'],'video_num':video_num,'total_sec':total_sec,'left_sec':user_obj['left_time']},'video_info':video_info_list}
 
-     str_return = json.dumps(dic_return)
 
-     return str_return
 
- @app.post('/edit_profile')
 
- async def edit_profile(userModel : models.UserProfile ,token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     print(token)
 
-     user_id = get_user_id(token)
 
-     print(user_id)
 
-     user_obj = next(iter(db.query('SELECT * FROM users where id ="'+str(user_id)+'"')))
 
-     user_obj['email'] = userModel.email
 
-     db['users'].update(user_obj,['id'])
 
-     return {'msg':'ok'}
 
- # login & register page
 
- @app.get("/login", response_class=HTMLResponse)
 
- async def get_login_and_register_page(request: Request):
 
-     return templates.TemplateResponse("login.html", {"request": request})
 
- @app.post("/login")
 
- async def login_for_access_token(request: Request, form_data: OAuth2PasswordRequestForm = Depends(), Authorize: AuthJWT = Depends()):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user = authenticate_user(form_data.username, form_data.password)
 
-     if not user:
 
-         raise HTTPException(
 
-             status_code=status.HTTP_401_UNAUTHORIZED,
 
-             detail="Incorrect username or password",
 
-             headers={"WWW-Authenticate": "Bearer"},
 
-         )
 
-     access_token_expires = timedelta(days=ACCESS_TOKEN_EXPIRE_DAYS)
 
-     access_token = create_access_token(
 
-         data={"sub": user.username}, expires_delta=access_token_expires
 
-     )
 
-     table = db['users']
 
-     user.token = access_token
 
-     table.update(dict(user), ['username'])
 
-     expires = timedelta(days=ACCESS_TOKEN_EXPIRE_DAYS)
 
-     access_token = Authorize.create_access_token(subject=user.username, expires_time=expires)
 
-     refresh_token = Authorize.create_refresh_token(subject=user.username, expires_time =expires)
 
-     Authorize.set_access_cookies(access_token)
 
-     Authorize.set_refresh_cookies(refresh_token)
 
-     #return templates.TemplateResponse("index.html", {"request": request, "msg": 'Login'})
 
-     if util.user.email_veri_pass(form_data.username):
 
-         return {"access_token": access_token, "token_type": "bearer",'veri':'ok'}
 
-     else:
 
-         return {"access_token": access_token, "token_type": "bearer",'veri':'fail'}
 
- @app.post("/token")
 
- async def access_token(form_data: OAuth2PasswordRequestForm = Depends(), Authorize: AuthJWT = Depends()):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user = authenticate_user(form_data.username, form_data.password)
 
-     if not user:
 
-         raise HTTPException(
 
-             status_code=status.HTTP_401_UNAUTHORIZED,
 
-             detail="Incorrect username or password",
 
-             headers={"WWW-Authenticate": "Bearer"},
 
-         )
 
-     access_token_expires = timedelta(days=ACCESS_TOKEN_EXPIRE_DAYS)
 
-     access_token = create_access_token(
 
-         data={"sub": user.username}, expires_delta=access_token_expires
 
-     )
 
-     return {"access_token": access_token, "token_type": "bearer"}
 
- #前後端分離完全實現後拔除
 
- @app.post("/register_old")
 
- async def register_old(request: Request):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user = models.User(**await request.form())
 
-     user_obj = first(db.query('SELECT * FROM users where username ="'+str(user.username)+'"'))
 
-     if user_obj == None:
 
-         id = user_register(user)
 
-         if type(id) is int:
 
-             code = str(time.time()).replace('.','')
 
-             db['register_veri_code'].insert({'code':code,'user_id':id})
 
-             mailer.register_verify('請至點擊網址驗證 : https://www.choozmo.com:8887/verify_email?code='+code, user.email)
 
-             return {'msg':{'eng':'Register success! Please login at previous page','zh':'註冊成功! 請回到上頁登入帳號'}}
 
-         else :
 
-             return {'msg':'error'}
 
-         #return templates.TemplateResponse("make_video.html", {"request": request, "success": True},status_code=status.HTTP_302_FOUND)
 
-         #return templates.TemplateResponse("login.html", {'request': request,"success": True}, status_code=status.HTTP_302_FOUND)
 
-     else:
 
-         return {'msg':{'eng':user.username+' is duplicated user name try another','zh':user.username+'重複,請更改'}}
 
- @app.post("/register")
 
- async def register(request: models.register_req):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_obj = first(db.query('SELECT * FROM users where username ="'+str(request.username)+'"'))
 
-     
 
-     if user_obj == None:
 
-         id = user_register(request)
 
-         if type(id) is int:
 
-             code = str(time.time()).replace('.','')
 
-             db['register_veri_code'].insert({'code':code,'user_id':id})
 
-             mailer.register_verify('請至點擊網址驗證 : https://www.choozmo.com:8887/verify_email?code='+code, request.email)
 
-             return {'msg':{'eng':'Register success! Please login at previous page','zh':'註冊成功! 請回到上頁登入帳號'}}
 
-         else :
 
-             return {'msg':'error'}
 
-     else:
 
-         return {'msg':{'eng':user.username+' is duplicated user name try another','zh':user.username+'重複,請更改'}}
 
- @app.get('/logout')
 
- def logout(request: Request, Authorize: AuthJWT = Depends()):
 
-     Authorize.jwt_required()
 
-     Authorize.unset_jwt_cookies()
 
-     return {"msg": "ok"}
 
- @app.get('/verify_email')
 
- async def verify_email(code):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     veri_obj = first(db.query('SELECT * FROM register_veri_code where code ="'+str(code)+'"'))
 
-     if veri_obj != None:
 
-         db['register_veri_code'].delete(code=code)
 
-     return {"msg": "ok"}
 
- @app.get("/reset_pwd_page_email")
 
- async def reset_pwd_page():
 
-     return FileResponse('static/reset_pwd_email.html')
 
- @app.get("/reset_pwd_page")
 
- async def reset_pwd_page():
 
-     return FileResponse('static/reset_pwd.html')
 
- @app.get('/send_reset_pwd')
 
- async def send_reset_pwd(user_id,email):
 
-     code = str(time.time()).replace('.','')
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     db['reset_pw_code'].insert({'code':code,'user_id':user_id,'email':email})
 
-     msg = '請至點擊網址以重設密碼 : https://www.choozmo.com:8887/reset_pwd_page    通行碼為 '+ code
 
-     print(msg)
 
-     msg =msg.encode(encoding='utf-8')
 
-     print(msg)
 
-     print(type(user_id))
 
-     if int(user_id) != -1:
 
-         print('print at first place')
 
-         print(user_id)
 
-         user_dict = next(iter(db.query('SELECT * FROM users where id ="'+str(user_id)+'"')))
 
-     else:
 
-         user_id = util.user.get_id_by_email(email)
 
-         print(user_id)
 
-         user_dict = next(iter(db.query('SELECT * FROM users where id ="'+str(user_id)+'"')))
 
-     mailer.send(msg, user_dict['email'])
 
-     return {'msg':'ok'}
 
- @app.post('/reset_pwd')
 
- async def reset_password(req :models.reset_pwd):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     print(req.code)
 
-     veri_obj = next(iter(db.query('SELECT * FROM reset_pw_code where code ="'+str(req.code)+'"')))
 
-     print(veri_obj['user_id'])
 
-     user_id = util.user.get_id_by_email(veri_obj['email'])
 
-     print(user_id)
 
-     db.query('UPDATE users SET password = '+'"'+get_password_hash(req.password)+'" where id ='+str(user_id))
 
-     
 
-     if veri_obj != None:
 
-         db['reset_pw_code'].delete(code=req.code)
 
-     return {"msg": "ok"}
 
- @app.get("/gen_avatar")
 
- async def avatar():
 
-     return FileResponse('static/gen_avatar.html')
 
- @app.post("/swapFace")
 
- async def swapFace(req:models.swap_req):
 
-     if 'http' not in req.imgurl:
 
-         req.imgurl= 'http://'+req.imgurl
 
-     try:
 
-         im = Image.open(requests.get(req.imgurl, stream=True).raw)
 
-         im= im.convert("RGB")
 
-     except:
 
-         return {'msg':"無法辨別圖片網址"+req.imgurl}
 
-     name_hash = str(time.time()).replace('.','')
 
-     
 
-     x = threading.Thread(target=gen_avatar, args=(name_hash,req.imgurl))
 
-     x.start()
 
-     return {'msg':'ok'}
 
- @app.post("/uploadfile/")
 
- async def create_upload_file(file: UploadFile = File(...)):
 
-     img_name = str(time.time()).replace('.','')
 
-     try:
 
-         if file.content_type=='video/mp4':
 
-             async with aiofiles.open(img_upload_folder+img_name+'.mp4', 'wb') as out_file:
 
-                 content = await file.read()
 
-                 await out_file.write(content) 
 
-             return {"msg": resource_server+tmp_img_sub_folder+img_name+'.mp4'}
 
-         else:
 
-             contents = await file.read()
 
-             image = Image.open(io.BytesIO(contents))
 
-             image= image.convert("RGB")
 
-             image.save(img_upload_folder+img_name+'.jpg')
 
-             return {"msg": resource_server+tmp_img_sub_folder+img_name+'.jpg'}
 
-     except Exception as e:
 
-         logging.error(traceback.format_exc())
 
-         return {'msg':'檔案無法使用'}
 
- @app.post("/upload_pttx/")
 
- async def upload_pttx(file: UploadFile = File(...)):
 
-     try:
 
-         if "_" in file.filename:
 
-             return {'msg':'檔案無法使用檔名不能含有"_"符號'}
 
-         else:
 
-             pttx_name = file.filename+'_'+str(time.time()).replace('.','')
 
-             with open(pttx_dest+pttx_name, "wb+") as file_object:
 
-                 file_object.write(file.file.read())
 
-             return {"msg": resource_server+pttx_sub_folder+pttx_name}
 
-     except Exception as e:
 
-         logging.error(traceback.format_exc())
 
-         return {'msg':'檔案無法使用'}
 
- @app.post("/make_anchor_video_gSlide")
 
- async def make_anchor_video_gSlide(req:models.gSlide_req,token: str = Depends(oauth2_scheme)):
 
-     if req.url_type == 0:
 
-         name, text_content, image_urls = gSlide.parse_slide_url(req.slide_url,eng=False)
 
-     else :
 
-         filename = req.slide_url.replace(resource_server+pttx_sub_folder,resource_folder+pttx_sub_folder)
 
-         name, text_content, image_urls = gSlide.parse_pttx_url(filename,img_upload_folder,resource_server+tmp_img_sub_folder,eng=False)
 
-     if len(image_urls) != len(text_content):
 
-         return {'msg':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}
 
-     for idx in range(len(image_urls)):
 
-         if 'http' not in image_urls[idx]:
 
-             image_urls[idx] = 'http://'+image_urls[idx]
 
-     if req.multiLang==0:
 
-         for txt in text_content:
 
-             if re.search('[a-zA-Z]', txt) !=None:
 
-                 print('語言錯誤')
 
-                 return {'msg':'輸入字串不能包含英文字!'}
 
-             if re.search(',', txt) !=None:
 
-                 print('包含非法符號')
 
-                 return {'msg':'輸入不能含有,符號'}
 
-     name_hash = str(time.time()).replace('.','')
 
-     for imgu in image_urls:
 
-         try:
 
-             if get_url_type(imgu) =='video/mp4':
 
-                 r=requests.get(imgu)
 
-             else:
 
-                 im = Image.open(requests.get(imgu, stream=True).raw)
 
-                 im= im.convert("RGB")
 
-         except:
 
-             return {'msg':"無法辨別圖片網址"+imgu}
 
-     user_id = get_user_id(token)
 
-     proto_req = models.request_normal()
 
-     proto_req.text_content = text_content
 
-     proto_req.name = name
 
-     proto_req.image_urls = image_urls
 
-     proto_req.avatar = req.avatar
 
-     proto_req.multiLang = req.multiLang
 
-     video_id = save_history(proto_req,name_hash,user_id)
 
-     x = threading.Thread(target=gen_video_queue, args=(name_hash,name, text_content, image_urls,int(req.avatar),req.multiLang,video_id,user_id))
 
-     x.start()
 
-     return {"msg":"製作影片需要時間,請您耐心等候,成果會傳送至LINE群組中"} 
 
- @app.post("/make_anchor_video_long")
 
- async def make_anchor_video_long(req:models.request,token: str = Depends(oauth2_scheme)):
 
-     left_tag = [m.start() for m in re.finditer('{', req.text_content[0])]
 
-     if len(req.image_urls) != len(left_tag):
 
-         return {'msg':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}
 
-     for idx in range(len(req.image_urls)):
 
-         if 'http' not in req.image_urls[idx]:
 
-             req.image_urls[idx] = 'http://'+req.image_urls[idx]
 
-     if req.multiLang==0:
 
-         for txt in req.text_content:
 
-             if re.search('[a-zA-Z]', txt) !=None:
 
-                 print('語言錯誤')
 
-                 return {'msg':'輸入字串不能包含英文字!'}
 
-             if re.search(',', txt) !=None:
 
-                 print('包含非法符號')
 
-                 return {'msg':'輸入不能含有,符號'}
 
-     name_hash = str(time.time()).replace('.','')
 
-     for imgu in req.image_urls:
 
-         try:
 
-             if get_url_type(imgu) =='video/mp4':
 
-                 r=requests.get(imgu)
 
-             else:
 
-                 im = Image.open(requests.get(imgu, stream=True).raw)
 
-                 im= im.convert("RGB")
 
-         except:
 
-             return {'msg':"無法辨別圖片網址"+imgu}
 
-     user_id = get_user_id(token)
 
-     video_id = save_history(req,name_hash,user_id)
 
-     x = threading.Thread(target=gen_video_long_queue, args=(name_hash,req.name, req.text_content, req.image_urls,int(req.avatar),req.multiLang,video_id,user_id))
 
-     x.start()
 
-     return {"msg":"ok"} 
 
- @app.post("/make_anchor_video")
 
- async def make_anchor_video(req:models.request,token: str = Depends(oauth2_scheme)):
 
-     if len(req.image_urls) != len(req.text_content):
 
-         return {'msg':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}
 
-     for idx in range(len(req.image_urls)):
 
-         if 'http' not in req.image_urls[idx]:
 
-             req.image_urls[idx] = 'http://'+req.image_urls[idx]
 
-     if req.multiLang==0:
 
-         for txt in req.text_content:
 
-             if re.search('[a-zA-Z]', txt) !=None:
 
-                 print('語言錯誤')
 
-                 return {'msg':'輸入字串不能包含英文字!'}
 
-             if re.search(',', txt) !=None:
 
-                 print('包含非法符號')
 
-                 return {'msg':'輸入不能含有,符號'}
 
-     name_hash = str(time.time()).replace('.','')
 
-     for imgu in req.image_urls:
 
-         try:
 
-             if get_url_type(imgu) =='video/mp4':
 
-                 r=requests.get(imgu)
 
-             else:
 
-                 im = Image.open(requests.get(imgu, stream=True).raw)
 
-                 im= im.convert("RGB")
 
-         except:
 
-             return {'msg':"無法辨別圖片網址"+imgu}
 
-     user_id = get_user_id(token)
 
-     video_id = save_history(req,name_hash,user_id)
 
-     x = threading.Thread(target=gen_video_queue, args=(name_hash,req.name, req.text_content, req.image_urls,int(req.avatar),req.multiLang,video_id,user_id))
 
-     x.start()
 
-     return {'msg':'ok'}
 
- @app.post("/make_anchor_video_eng")
 
- async def make_anchor_video_eng(req:models.request_eng,token: str = Depends(oauth2_scheme)):
 
-     if len(req.image_urls) != len(req.sub_titles) or len(req.sub_titles) != len(req.text_content):
 
-         return {'msg':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}
 
-     for idx in range(len(req.image_urls)):
 
-         if 'http' not in req.image_urls[idx]:
 
-             req.image_urls[idx] = 'http://'+req.image_urls[idx]
 
-     name_hash = str(time.time()).replace('.','')
 
-     for imgu in req.image_urls:
 
-         try:
 
-             if get_url_type(imgu) =='video/mp4':
 
-                 r=requests.get(imgu)
 
-             else:
 
-                 im = Image.open(requests.get(imgu, stream=True).raw)
 
-                 im= im.convert("RGB")
 
-         except:
 
-             return {'msg':"無法辨別圖片網址"+imgu}
 
-     user_id = get_user_id(token)
 
-     video_id = save_history(req,name_hash, user_id)
 
-     x = threading.Thread(target=gen_video_queue_eng, args=(name_hash,req.name, req.text_content, req.image_urls,req.sub_titles,int(req.avatar),video_id))
 
-     x.start()
 
-     return {"msg":"ok"} 
 
- @app.post("/save_draft")
 
- async def save_draft(req:models.video_draft,token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = get_user_id(token)
 
-     
 
-     txt_content_seperate_by_dot = ''
 
-     for txt in req.text_content:
 
-         txt_content_seperate_by_dot += txt+","
 
-     txt_content_seperate_by_dot = txt_content_seperate_by_dot[:-1]
 
-     img_urls_seperate_by_dot = ''
 
-     for iurl in req.image_urls:
 
-         img_urls_seperate_by_dot += iurl+","
 
-     img_urls_seperate_by_dot = img_urls_seperate_by_dot[:-1]
 
-     time_stamp = datetime.fromtimestamp(time.time())
 
-     time_stamp = time_stamp.strftime("%Y-%m-%d %H:%M:%S")
 
-     if req.id==-1:
 
-         pk = db['draft'].insert({'title':req.title,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot
 
-         ,'user_id':user_id,'avatar':req.avatar,'multiLang':req.multiLang,'time_stamp':time_stamp})
 
-     else:
 
-         db['draft'].update({'id':req.id,'title':req.title,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot
 
-         ,'user_id':user_id,'avatar':req.avatar,'multiLang':req.multiLang,'time_stamp':time_stamp},['id'])
 
-     
 
-     return {'msg':'ok'}
 
- @app.post('/draft_list')
 
- async def draft_list(token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = get_user_id(token)
 
-     statement = 'SELECT * FROM draft WHERE user_id='+str(user_id)+' ORDER BY time_stamp DESC LIMIT 50'
 
-     logs = []
 
-     for row in db.query(statement):
 
-         logs.append({'id':row['id'],'title':row['title'],'avatar':row['avatar'],'mulitLang':row['multiLang']
 
-         ,'text_content':row['text_content'].split(','),'image_urls':row['image_urls'].split(',')})
 
-     return logs
 
- @app.post('/del_draft')
 
- async def del_draft(id_obj:models.id_obj,token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = get_user_id(token)
 
-     statement = 'SELECT * FROM draft WHERE user_id="'+str(user_id)+'" and id ="'+str(id_obj.id)+'"'
 
-     if first(db.query(statement)) is not None:
 
-         db['draft'].delete(id=id)
 
-     else:
 
-         return {'msg':'wrong id'}
 
-     
 
-     return {'msg':'ok'}
 
- @app.get("/history_input_old")
 
- async def history_input_old(request: Request, Authorize: AuthJWT = Depends()):
 
-     Authorize.jwt_required()
 
-     current_user = Authorize.get_jwt_subject()
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = first(db.query('SELECT * FROM users where username="' + current_user +'"'))['id']
 
-     statement = 'SELECT * FROM history_input WHERE user_id="'+str(user_id)+'" ORDER BY timestamp DESC LIMIT 50'
 
-     logs = []
 
-     for row in db.query(statement):
 
-         logs.append({'id':row['id'],'name':row['name'],'text_content':row['text_content'].split(','),'link':row['link'],'image_urls':row['image_urls'].split(',')})
 
-     return logs
 
- @app.post("/history_input")
 
- async def history_input(token: str = Depends(oauth2_scheme)):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     user_id = get_user_id(token)
 
-     user_obj = first(db.query('SELECT * FROM users where id ="'+str(user_id)+'"'))
 
-     statement = 'SELECT * FROM history_input WHERE user_id="'+str(user_id)+'" ORDER BY timestamp DESC LIMIT 50'
 
-     logs = []
 
-     for row in db.query(statement):
 
-         logs.append({'id':row['id'],'name':row['name'],'text_content':row['text_content'].split(','),'link':row['link'],'image_urls':row['image_urls'].split(',')})
 
-     return logs
 
- @AuthJWT.load_config
 
- def get_config():
 
-     return models.Settings()
 
- @app.exception_handler(AuthJWTException)
 
- def authjwt_exception_handler(request: Request, exc: AuthJWTException):
 
-     return JSONResponse(
 
-         status_code=exc.status_code,
 
-         content={"detail": exc.message}
 
-     )
 
- def get_user_id(token):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     credentials_exception = HTTPException(
 
-         status_code=status.HTTP_401_UNAUTHORIZED,
 
-         detail="Could not validate credentials",
 
-         headers={"WWW-Authenticate": "Bearer"},
 
-     )
 
-     try:
 
-         payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
 
-         username: str = payload.get("sub")
 
-         if username is None:
 
-             raise credentials_exception
 
-         token_data = models.TokenData(username=username)
 
-     except JWTError:
 
-         raise credentials_exception
 
-     user = get_user(username=token_data.username)
 
-     if user is None:
 
-         raise credentials_exception
 
-     user_id = first(db.query('SELECT * FROM users where username="' + user.username+'"'))['id']
 
-     return user_id
 
- def check_user_exists(username):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     if int(next(iter(db.query('SELECT COUNT(*) FROM AI_anchor.users WHERE username = "'+username+'"')))['COUNT(*)']) > 0:
 
-         return True
 
-     else:
 
-         return False
 
- def get_user(username: str):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     if not check_user_exists(username):  # if user don't exist
 
-         return False
 
-     user_dict = next(
 
-         iter(db.query('SELECT * FROM AI_anchor.users where username ="'+username+'"')))
 
-     user = models.User(**user_dict)
 
-     return user
 
-     
 
- def user_register(user):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     table = db['users']
 
-     user.password = get_password_hash(user.password)
 
-     id = table.insert(dict(user))
 
-     return id
 
- def get_password_hash(password):
 
-     return pwd_context.hash(password)
 
- def verify_password(plain_password, hashed_password):
 
-     return pwd_context.verify(plain_password, hashed_password)
 
- def authenticate_user(username: str, password: str):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     if not check_user_exists(username):  # if user don't exist
 
-         return False
 
-     user_dict = next(iter(db.query('SELECT * FROM AI_anchor.users where username ="'+username+'"')))
 
-     user = models.User(**user_dict)
 
-     if not verify_password(password, user.password):
 
-         return False
 
-     return user
 
- def create_access_token(data: dict, expires_delta):
 
-     to_encode = data.copy()
 
-     
 
-     expire = datetime.utcnow() + expires_delta
 
-     to_encode.update({"exp": expire})
 
-     encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
 
-     return encoded_jwt
 
- def save_history(req,name_hash,user_id):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     log_table = db['history_input']
 
-     txt_content_seperate_by_dot = ''
 
-     for txt in req.text_content:
 
-         txt_content_seperate_by_dot += txt+","
 
-     txt_content_seperate_by_dot = txt_content_seperate_by_dot[:-1]
 
-     img_urls_seperate_by_dot = ''
 
-     for iurl in req.image_urls:
 
-         img_urls_seperate_by_dot += iurl+","
 
-     img_urls_seperate_by_dot = img_urls_seperate_by_dot[:-1]
 
-     time_stamp = datetime.fromtimestamp(time.time())
 
-     time_stamp = time_stamp.strftime("%Y-%m-%d %H:%M:%S")
 
-     pk = log_table.insert({'name':req.name,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot
 
-     ,'user_id':user_id,'link':'www.choozmo.com:8168/'+video_sub_folder+name_hash+'.mp4','timestamp':time_stamp})
 
-     return pk
 
-     
 
- def get_url_type(url):
 
-     req = urllib.request.Request(url, method='HEAD', headers={'User-Agent': 'Mozilla/5.0'})
 
-     r = urllib.request.urlopen(req)
 
-     contentType = r.getheader('Content-Type')
 
-     return contentType
 
- def notify_group(msg):
 
-     #'WekCRfnAirSiSxALiD6gcm0B56EejsoK89zFbIaiZQD' is ChoozmoTeam
 
-     glist=['7vilzohcyQMPLfAMRloUawiTV4vtusZhxv8Czo7AJX8','WekCRfnAirSiSxALiD6gcm0B56EejsoK89zFbIaiZQD','1dbtJHbWVbrooXmQqc4r8OyRWDryjD4TMJ6DiDsdgsX','HOB1kVNgIb81tTB4Ort1BfhVp9GFo6NlToMQg88vEhh']
 
-     for gid in glist:
 
-         headers = {"Authorization": "Bearer " + gid,"Content-Type": "application/x-www-form-urlencoded"}
 
-         r = requests.post("https://notify-api.line.me/api/notify",headers=headers, params={"message": msg})
 
- def gen_video_long_queue(name_hash,name,text_content, image_urls,avatar,multiLang,video_id,user_id):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     time_stamp = datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S")
 
-     txt_content_seperate_by_dot = ''
 
-     for txt in text_content:
 
-         txt_content_seperate_by_dot += txt+","
 
-     txt_content_seperate_by_dot = txt_content_seperate_by_dot[:-1]
 
-     img_urls_seperate_by_dot = ''
 
-     for iurl in image_urls:
 
-         img_urls_seperate_by_dot += iurl+","
 
-     img_urls_seperate_by_dot = img_urls_seperate_by_dot[:-1]
 
-     
 
-     db['video_queue'].insert({'name_hash':name_hash,'name':name,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot,'multiLang':multiLang,'avatar':avatar,'timestamp':time_stamp})
 
-     while True:
 
-         
 
-         if first(db.query('SELECT * FROM video_queue_status'))['status'] == 1:#only one row in this table, which is the id 1 one
 
-             print('another process running, leave loop')#1 means already running
 
-             break
 
-         if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] == 0:
 
-             print('all finish, leave loop')
 
-             break
 
-         top1 = first(db.query('SELECT * FROM video_queue'))
 
-         try:
 
-         # if True:
 
-             db.query('UPDATE video_queue_status SET status = 1;')
 
-             c = rpyc.connect("localhost", 8858)
 
-             c._config['sync_request_timeout'] = None
 
-             remote_svc = c.root
 
-             my_answer = remote_svc.call_video_gen(top1['name_hash'],top1['name'],top1['text_content'].split(','), top1['image_urls'].split(','),top1['multiLang'],top1['avatar']) # method call
 
-             shutil.copy(tmp_video_dir+top1['name_hash']+'.mp4',video_dest+top1['name_hash']+'.mp4')
 
-             os.remove(tmp_video_dir+top1['name_hash']+'.mp4')
 
-             vid_duration = VideoFileClip(video_dest+top1['name_hash']+'.mp4').duration
 
-             user_obj = first(db.query('SELECT * FROM users where id ="'+str(user_id)+'"'))
 
-             line_token = user_obj['line_token']         # aa
 
-             left_time = user_obj['left_time']
 
-             email = user_obj['email']
 
-             print('left_time is '+str(left_time))
 
-             db.query('UPDATE history_input SET duration ='+str(vid_duration)+' WHERE id='+str(video_id)+';')
 
-             if left_time is None:
 
-                 left_time = 5*60
 
-             if left_time < vid_duration:
 
-                 msg = '您本月額度剩下'+str(left_time)+'秒,此部影片有'+str(vid_duration)+'秒, 若要繼續產生影片請至 192.168.1.106:8887/confirm_add_value?name_hash='+name_hash+' 加值'
 
-                 print(msg)
 
-                 msg =msg.encode(encoding='utf-8')
 
-                 mailer.send_left_not_enough(msg, email)
 
-                 #notify_line_user(msg, line_token)
 
-                 notify_group(name+":帳號餘額不足,請至email查看詳細資訊")
 
-             else:
 
-                 left_time = left_time - vid_duration
 
-                 db.query('UPDATE users SET left_time ='+str(left_time)+' WHERE id='+str(user_id)+';')
 
-                 notify_group(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+name_hash+".mp4")
 
-                 #notify_line_user(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+name_hash+".mp4", line_token)
 
-         except Exception as e:
 
-             logging.error(traceback.format_exc())
 
-             print('video generation error')
 
-             notify_group('長影片錯誤-測試')
 
-         db['video_queue'].delete(id=top1['id'])
 
-         db.query('UPDATE video_queue_status SET status = 0')
 
- def gen_video_queue(name_hash,name,text_content, image_urls,avatar,multiLang,video_id,user_id):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     time_stamp = datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S")
 
-     txt_content_seperate_by_dot = ''
 
-     for txt in text_content:
 
-         txt_content_seperate_by_dot += txt+","
 
-     txt_content_seperate_by_dot = txt_content_seperate_by_dot[:-1]
 
-     img_urls_seperate_by_dot = ''
 
-     for iurl in image_urls:
 
-         img_urls_seperate_by_dot += iurl+","
 
-     img_urls_seperate_by_dot = img_urls_seperate_by_dot[:-1]
 
-     
 
-     db['video_queue'].insert({'name_hash':name_hash,'name':name,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot,'multiLang':multiLang,'avatar':avatar,'timestamp':time_stamp})
 
-     while True:
 
-         
 
-         if first(db.query('SELECT * FROM video_queue_status'))['status'] == 1:#only one row in this table, which is the id 1 one
 
-             print('another process running, leave loop')#1 means already running
 
-             break
 
-         if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] == 0:
 
-             print('all finish, leave loop')
 
-             break
 
-         top1 = first(db.query('SELECT * FROM video_queue'))
 
-         try:
 
-         # if True:
 
-             db.query('UPDATE video_queue_status SET status = 1;')
 
-             c = rpyc.connect("localhost", 8858)
 
-             c._config['sync_request_timeout'] = None
 
-             remote_svc = c.root
 
-             my_answer = remote_svc.call_video(top1['name_hash'],top1['name'],top1['text_content'].split(','), top1['image_urls'].split(','),top1['multiLang'],top1['avatar']) # method call
 
-             shutil.copy(tmp_video_dir+top1['name_hash']+'.mp4',video_dest+top1['name_hash']+'.mp4')
 
-             os.remove(tmp_video_dir+top1['name_hash']+'.mp4')
 
-             vid_duration = VideoFileClip(video_dest+top1['name_hash']+'.mp4').duration
 
-             user_obj = first(db.query('SELECT * FROM users where id ="'+str(user_id)+'"'))
 
-             line_token = user_obj['line_token']         # aa
 
-             left_time = user_obj['left_time']
 
-             email = user_obj['email']
 
-             print('left_time is '+str(left_time))
 
-             db.query('UPDATE history_input SET duration ='+str(vid_duration)+' WHERE id='+str(video_id)+';')
 
-             if left_time is None:
 
-                 left_time = 5*60
 
-             if left_time < vid_duration:
 
-                 msg = '您本月額度剩下'+str(left_time)+'秒,此部影片有'+str(vid_duration)+'秒, 若要繼續產生影片請至 192.168.1.106:8887/confirm_add_value?name_hash='+name_hash+' 加值'
 
-                 print(msg)
 
-                 msg =msg.encode(encoding='utf-8')
 
-                 mailer.send_left_not_enough(msg, email)
 
-                 notify_group(msg)
 
-                 #notify_line_user(msg, line_token)
 
-             else:
 
-                 left_time = left_time - vid_duration
 
-                 db.query('UPDATE users SET left_time ='+str(left_time)+' WHERE id='+str(user_id)+';')
 
-                 notify_group(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+name_hash+".mp4")
 
-                 #notify_line_user(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+name_hash+".mp4", line_token)
 
-         except Exception as e:
 
-             logging.error(traceback.format_exc())
 
-             print('video generation error')
 
-             notify_group('影片錯誤')
 
-         db['video_queue'].delete(id=top1['id'])
 
-         db.query('UPDATE video_queue_status SET status = 0')
 
- def gen_video_queue_eng(name_hash,name,text_content, image_urls,sub_titles,avatar,video_id):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     time_stamp = datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S")
 
-     txt_content_seperate_by_dot = ''
 
-     for txt in text_content:
 
-         txt_content_seperate_by_dot += txt+","
 
-     txt_content_seperate_by_dot = txt_content_seperate_by_dot[:-1]
 
-     img_urls_seperate_by_dot = ''
 
-     for iurl in image_urls:
 
-         img_urls_seperate_by_dot += iurl+","
 
-     img_urls_seperate_by_dot = img_urls_seperate_by_dot[:-1]
 
-     subtitles_seperate_by_dot = ''
 
-     for sub in sub_titles:
 
-         subtitles_seperate_by_dot += sub+","
 
-     subtitles_seperate_by_dot = subtitles_seperate_by_dot[:-1]
 
-     db['video_queue'].insert({'name_hash':name_hash,'name':name,'text_content':txt_content_seperate_by_dot,'image_urls':img_urls_seperate_by_dot,'subtitles':subtitles_seperate_by_dot,'avatar':avatar,'timestamp':time_stamp})
 
-     while True:
 
-         if first(db.query('SELECT * FROM video_queue_status'))['status'] == 1:#only one row in this table, which is the id 1 one
 
-             print('another process running, leave loop')
 
-             break
 
-         if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] == 0:
 
-             print('all finish, leave loop')
 
-             break
 
-         top1 = first(db.query('SELECT * FROM video_queue'))
 
-         try:
 
-             db.query('UPDATE video_queue_status SET status = 1;')
 
-             c = rpyc.connect("localhost", 8858)
 
-             c._config['sync_request_timeout'] = None
 
-             remote_svc = c.root
 
-             my_answer = remote_svc.call_video_eng(top1['name_hash'],top1['name'],top1['text_content'].split(','), top1['image_urls'].split(','),top1['subtitles'].split(','),top1['avatar']) # method call
 
-             shutil.copy(tmp_video_dir+top1['name_hash']+'.mp4',video_dest+top1['name_hash']+'.mp4')
 
-             os.remove(tmp_video_dir+top1['name_hash']+'.mp4')
 
-             notify_group(name+"(ENG)的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+name_hash+".mp4")
 
-         except:
 
-             print('video generation error')
 
-             notify_group('影片錯誤')
 
-         db['video_queue'].delete(id=top1['id'])
 
-         db.query('UPDATE video_queue_status SET status = 0')
 
- def gen_avatar(name_hash, imgurl):
 
-     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
 
-     db['avatar_queue'].insert({'name_hash':name_hash,'imgurl':imgurl})
 
-     while True:
 
-         statement = 'SELECT * FROM avatar_service_status'#only one row in this table, which is the id 1 one
 
-         status = -1
 
-         for row in db.query(statement):
 
-             status = row['status']
 
-         if status == 1:
 
-             print('leave process loop')
 
-             break
 
-         statement = 'SELECT * FROM avatar_queue'
 
-         works = []
 
-         for row in db.query(statement):
 
-             works.append({'id':row['id'],'name_hash':row['name_hash'],'imgurl':row['imgurl']})
 
-         if len(works)==0:
 
-             print('leave process loop')
 
-             break
 
-         try:
 
-             statement = 'UPDATE avatar_service_status SET status = 1 WHERE id=1;'
 
-             db.query(statement)
 
-             name_hash = works[0]['name_hash']
 
-             imgurl = works[0]['imgurl']
 
-             c = rpyc.connect("localhost", 8868)
 
-             c._config['sync_request_timeout'] = None
 
-             remote_svc = c.root
 
-             my_answer = remote_svc.call_avatar(name_hash,imgurl) # method call
 
-             shutil.copy(tmp_avatar_dir+name_hash+'.mp4',avatar_dest+name_hash+'.mp4')
 
-             os.remove(tmp_avatar_dir+name_hash+'.mp4')
 
-             
 
-         except:
 
-             print('gen error')
 
-             notify_group('無法辨識人臉')
 
-         db['avatar_queue'].delete(id=works[0]['id'])
 
-         statement = 'UPDATE avatar_service_status SET status = 0 WHERE id=1;'  #only one row in this table, which id 1 one
 
-         db.query(statement)
 
- def call_voice(text):
 
-     print(text)
 
-     print(len(text))
 
-     print(type(text))
 
-     c = rpyc.connect("localhost", 8858)
 
-     c._config['sync_request_timeout'] = None
 
-     remote_svc = c.root
 
-     my_answer = remote_svc.make_speech(text) # method call
 
-     src_path = '/home/ming/AI_Anchor/OpenshotService/speech.mp3'
 
-     shutil.copy(src_path,'/home/ming/speech.mp3')
 
-     os.remove(src_path)
 
- class text_in(BaseModel):
 
-     text: str
 
- @app.post("/make_voice")
 
- async def make_voice(in_text:text_in):
 
-     x = threading.Thread(target=call_voice, args=(in_text.text,))
 
-     x.start()
 
-     
 
-         
 
-     
 
-       
 
-         
 
-         
 
-         
 
 
  |