12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310 |
- 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 util.models
- import pymysql
- import mailer
- from moviepy.editor import VideoFileClip
- import traceback
- import logging
- import gSlide
- import aiofiles
- import json
- import util.user
- from routers import apiConrad
- #https://www.choozmo.com:8887/verify_email?code=16370312713065429 =>
- #https://video.choozmo.com/verify_email.html?code=16370312713065429
- pymysql.install_as_MySQLdb()
- app = FastAPI()
- app.include_router(apiConrad.router)
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- print("db loaded")
- mode = 'run'
- app.add_middleware(
- CORSMiddleware,
- allow_origins=["*"],
- #allow_origins=["https://show.choozmo.com","https://video.choozmo.com"],
- allow_credentials=True,
- allow_methods=["POST","GET"],
- #allow_headers=["*"],
- allow_headers = ["Authorization","Accept","accept","Origin","Content-Type","X-LS-CORS-Template","X-LS-Auth-Token","X-LS-Auth-User-Token","Content-Type","X-LS-Sync-Result","X-LS-Sequence","token"],
- )
- 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
- speech_dest = '/var/www/html/speech/'
- # @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.111",18812)
- conn.close()
- except:
- errorList.append('111: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_check()
- if 'ok'!=verify_jwt_token(token):
- return {'msg':{'eng':'Please login first','zh':'請先登入帳號'}}
-
- user_id = get_user_id(token)
- user_obj = first(db.query('SELECT * FROM users where id ="'+str(user_id)+'"'))
- if user_obj['invite_code'] is None:
- util.user.init_invite_code(user_id)
- 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'],'invite_code':user_obj['invite_code']}
- ,'video_info':video_info_list}
- str_return = json.dumps(dic_return)
-
- return str_return
- @app.post('/edit_profile')
- async def edit_profile(userModel : util.models.UserProfile ,token: str = Depends(oauth2_scheme)):
- db_check()
- 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_check()
- 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:
- veri_obj = first(db.query('SELECT * FROM register_veri_code where user_id ="'+str(user.id)+'"'))
- mailer.register_verify('請至點擊網址驗證 : https://video.choozmo.com/verify_email.html?code='+veri_obj['code'], user.email)
- return {"access_token": access_token, "token_type": "bearer",'veri':'fail'}
- @app.post("/token")
- async def access_token(form_data: OAuth2PasswordRequestForm = Depends(), Authorize: AuthJWT = Depends()):
-
- 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_check()
- user = util.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)
- result = util.user.add_to_basic_role(id)
- print(result)
- if type(id) is int:
- code = str(time.time()).replace('.','')
- db['register_veri_code'].insert({'code':code,'user_id':id})
- mailer.register_verify('請至點擊網址驗證 : https://video.choozmo.com/verify_email.html?code='+code, user.email)
- return {'msg':{'eng':'Register success! Please login at previous page','zh':'註冊成功! 請回到上頁登入帳號'}}
- else :
- return {'msg':{'eng':'error','zh':'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: util.models.register_req):
- db_check()
- user_obj = first(db.query('SELECT * FROM users where username ="'+str(request.username)+'"'))
-
- if user_obj == None:
- id = user_register(request)
- udata = dict(id=id, left_time=60)
- db['users'].update(udata, ['id'])
- result = util.user.add_to_basic_role(id)
- print(result)
- if type(id) is int:
- code = str(time.time()).replace('.','')
- db['register_veri_code'].insert({'code':code,'user_id':id})
- try:
- mailer.register_verify('請至點擊網址驗證 : https://video.choozmo.com/verify_email.html?code='+code, request.email)
- return {'msg':{'eng':'Register success! Please check your mailbox to verify your email','zh':'註冊成功! 請至信箱收取驗證信'}}
- except:
- return {'msg':{'eng':'Invalid email address','zh':'無法寄送認證信!'}}
- else :
- return {'msg':{'eng':'error','zh':'error'}}
- else:
- return {'msg':{'eng':user_obj['username']+' is duplicated user name try another','zh':user_obj['username']+'重複,請更改'}}
- @app.post("/register_by_invite")
- async def register_by_invite(request: util.models.register_invite_req):
- db_check()
- user_obj = first(db.query('SELECT * FROM users where username ="'+str(request.username)+'"'))
-
- if user_obj == None:
- invcode = request.invite_code
- sha = hashlib.sha256()
- sha.update(str(time.time()).replace('.','').encode())
- request.invite_code = sha.hexdigest()
- id = user_register(request)
- result = util.user.add_to_basic_role(id)
- udata = dict(id=id, left_time=60)
- db['users'].update(udata, ['id'])
- if type(id) is int:
- code = str(time.time()).replace('.','')
- db['register_veri_code'].insert({'code':code,'user_id':id})
- try:
- mailer.register_verify('請至點擊網址驗證 : https://video.choozmo.com/verify_email.html?code='+code, request.email)
- except:
- return {'msg':{'eng':'Invalid email address','zh':'無法寄送認證信!'}}
- util.user.add_time_by_invite(invcode)
- return {'msg':{'eng':'Register success! Please login at previous page','zh':'註冊成功! 請回到上頁登入帳號'}}
- else :
- return {'msg':{'eng':'error','zh':'error'}}
- else:
- return {'msg':{'eng':user_obj['username']+' is duplicated user name try another','zh':user_obj['username']+'重複,請更改'}}
- @app.get('/logout')
- def logout(request: Request, Authorize: AuthJWT = Depends()):
- Authorize.jwt_required()
- Authorize.unset_jwt_cookies()
- return {"msg": "ok"}
- @app.post('/logout_jwt')
- def logout(token: str = Depends(oauth2_scheme)):
- db_check()
- time_stamp = datetime.fromtimestamp(time.time())
- time_stamp = time_stamp.strftime("%Y-%m-%d %H:%M:%S")
- db['jwt_black_list'].insert({'token':token,'datetime':time_stamp})
- return {"msg": "ok"}
- @app.post('/get_role')
- async def get_role(token: str = Depends(oauth2_scheme)):
-
- user_id = util.user.get_user_id(token)
- roles = util.user.get_user_role(user_id)
- return roles
- @app.post('/create_role')
- async def get_role(token: str = Depends(oauth2_scheme)):
-
- user_id = get_user_id(token)
- return user_id
- @app.post('/get_avatar_by_role')
- async def get_role(token: str = Depends(oauth2_scheme)):
- user_id = util.user.get_user_id(token)
- avatar_info = util.user.get_avatar_by_role(user_id)
- return avatar_info
- @app.get('/verify_email')
- async def verify_email(code):
- db_check()
- 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):
- db_check()
- code = str(time.time()).replace('.','')
-
- 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 :util.models.reset_pwd):
- db_check()
- 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:util.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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+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':{'eng':'file cant be prossessed','zh':'檔案無法使用'}}
- @app.post("/upload_pttx/")
- async def upload_pttx(file: UploadFile = File(...)):
- try:
- if "#" in file.filename:
- return {'msg':{'eng':'symbol"#" is not allowed in file name','zh':'檔案無法使用檔名不能含有"#"符號'}}
- else:
- pttx_name = file.filename.replace('.pptx','#')+str(time.time()).replace('.','')+'.pptx'
- 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':{'eng':'file cant be prossessed','zh':'檔案無法使用'}}
- @app.post("/make_anchor_video_gSlide")
- async def make_anchor_video_gSlide(req:util.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':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
-
- for idx in range(len(image_urls)):
- if 'http' not in image_urls[idx]:
- image_urls[idx] = 'http://'+image_urls[idx]
-
- mulitLang, hasError = Check_text_content(text_content)
- if hasError is not False :
- return hasError
- imgError = Check_image_url(image_urls)
- if imgError is not False :
- return imgError
-
- name_hash = str(time.time()).replace('.','')
- user_id = get_user_id(token)
- proto_req = util.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)
- freeTrial = 0
- if 6 in util.user.get_user_role_list(user_id):
- freeTrial = 1
- print(freeTrial)
- x = threading.Thread(target=gen_video_queue, args=(name_hash,name, text_content, image_urls,int(req.avatar),req.multiLang,video_id,user_id,freeTrial))
- x.start()
- return {"msg":"ok"}
- @app.post("/make_anchor_video_long")
- async def make_anchor_video_long(req:util.models.request,token: str = Depends(oauth2_scheme)):
- db_check()
- left_tag = [m.start() for m in re.finditer('{', req.text_content[0])]
- if len(req.image_urls) != len(left_tag):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':'English is not allowed in subtitles','zh':'輸入字串不能包含英文字!'}}
- if re.search(',', txt) !=None:
- print('包含非法符號')
- return {'msg':{'eng':'symbol "," is not allowede','zh':'輸入不能含有","符號'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- 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()
-
- returnMsg = ''
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- returnMsg = {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- returnMsg = {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return returnMsg
- @app.post("/make_anchor_video")
- async def make_anchor_video(req:util.models.request,token: str = Depends(oauth2_scheme)):
- db_check()
- if len(req.image_urls) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':'English is not allowed in subtitles','zh':'輸入字串不能包含英文字!'}}
- if re.search(',', txt) !=None:
- print('包含非法符號')
- return {'msg':{'eng':'symbol "," is not allowede','zh':'輸入不能含有","符號'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- user_id = get_user_id(token)
- video_id = save_history(req,name_hash,user_id)
- freeTrial = 0
- if 6 in util.user.get_user_role_list(user_id):
- freeTrial = 1
- print(freeTrial)
- 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,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {'msg':'ok'}
- #not auth
- @app.post("/make_anchor_video_noAuth")
- async def make_anchor_video_noAuth(req:util.models.request):
- db_check()
- if len(req.image_urls) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':'English is not allowed in subtitles','zh':'輸入字串不能包含英文字!'}}
- if re.search(',', txt) !=None:
- print('包含非法符號')
- return {'msg':{'eng':'symbol "," is not allowede','zh':'輸入不能含有","符號'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- user_id = get_user_id(token)
- video_id = save_history(req,name_hash,user_id)
- freeTrial = 0
- if 6 in util.user.get_user_role_list(user_id):
- freeTrial = 1
- print(freeTrial)
- 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,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {'msg':'ok'}
-
- @app.post("/make_anchor_video_noAuth2" , response_class=JSONResponse)
- async def make_anchor_video_noAuth2(req:util.models.request):
- db_check()
- if len(req.image_urls) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':'English is not allowed in subtitles','zh':'輸入字串不能包含英文字!'}}
- if re.search(',', txt) !=None:
- print('包含非法符號')
- return {'msg':{'eng':'symbol "," is not allowede','zh':'輸入不能含有","符號'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- video_id = save_history(req,name_hash,-1)
- freeTrial = 0
- 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,-1,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {'msg':'ok'}
- @app.post("/make_anchor_video_eng")
- async def make_anchor_video_eng(req:util.models.request_eng,token: str = Depends(oauth2_scheme)):
- db_check()
- if len(req.image_urls) != len(req.sub_titles) or len(req.sub_titles) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- user_id = get_user_id(token)
- video_id = save_history(req,name_hash, user_id)
- freeTrial = 0
- if 6 in util.user.get_user_role_list(user_id):
- freeTrial = 1
- print(freeTrial)
- 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,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {"msg":"ok"}
- @app.post("/make_anchor_video_eng_noAuth")
- async def make_anchor_video_eng(req:util.models.request_eng):
- db_check()
- if len(req.image_urls) != len(req.sub_titles) or len(req.sub_titles) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
-
- video_id = save_history(req,name_hash, -1)
- freeTrial = 1
- 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,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {"msg":"ok"}
- @app.post("/make_anchor_video_eng_noAuth2")
- async def make_anchor_video_eng(req:util.models.request_eng):
- db_check()
- if len(req.image_urls) != len(req.sub_titles) or len(req.sub_titles) != len(req.text_content):
- return {'msg':{'eng':'number of subtitles and images(videos) should be the same','zh':'副標題數量、圖片(影片)數量以及台詞數量必須一致'}}
- 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':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
-
- video_id = save_history(req,name_hash, -1)
- freeTrial = 1
- 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,freeTrial))
- x.start()
-
- if first(db.query('SELECT COUNT(1) FROM video_queue'))['COUNT(1)'] >= 3:
- return {'msg':{'eng':'There are many videos have been processing, please wait.','zh':'目前有多部影片處理中,煩請耐心等候'}}
- else:
- return {'msg':{'eng':'Processing video requires a few minutes, please wait for notification','zh':'影片處理需要數分鐘,請等待通知'}}
- return {"msg":"ok"}
- @app.post("/save_draft")
- async def save_draft(req:util.models.video_draft,token: str = Depends(oauth2_scheme)):
- db_check()
- 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_check()
- 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:util.models.id_obj,token: str = Depends(oauth2_scheme)):
- db_check()
- 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_obj.id)
- else:
- return {'msg':'wrong id'}
-
- return {'msg':'ok'}
- @app.get("/history_input_old")
- async def history_input_old(request: Request, Authorize: AuthJWT = Depends()):
- db_check()
- Authorize.jwt_required()
- current_user = Authorize.get_jwt_subject()
-
- 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_check()
- 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'],'avatar':row['avatar'],'text_content':row['text_content'].split(','),'link':row['link'],'image_urls':row['image_urls'].split(',')})
- return logs
- @app.post("/history_input_noAuth")
- async def history_input_noAuth():
- db_check()
- statement = 'SELECT * FROM history_input ORDER BY timestamp DESC LIMIT 50'
- logs = []
- for row in db.query(statement):
- logs.append({'id':row['id'],'name':row['name'],'avatar':row['avatar'],'text_content':row['text_content'].split(','),'link':row['link'],'image_urls':row['image_urls'].split(',')})
- return logs
- @AuthJWT.load_config
- def get_config():
- return util.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_check()
- 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 = util.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_check()
- 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):
-
- 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 = util.models.User(**user_dict)
- return user
-
- def user_register(user):
- db_check()
- 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_check()
- 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 = util.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_check()
- 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','avatar':req.avatar,'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 notify_choozmo(msg):
- #'WekCRfnAirSiSxALiD6gcm0B56EejsoK89zFbIaiZQD' is ChoozmoTeam
- glist = ['WekCRfnAirSiSxALiD6gcm0B56EejsoK89zFbIaiZQD']
- 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 Check_text_content(text_content):
- mulitLang = 0
- status = False
- for txt in text_content:
- if re.search('[a-zA-Z]', txt) !=None:
- mulitLang = 1
- if re.search(',', txt) !=None:
- print('包含非法符號')
- status = {'msg':{'eng':'symbol "," is not allowede','zh':'輸入不能含有","符號'}}
- return mulitLang, status
- def Check_image_url(image_urls):
- status =False
- 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:
- status = {'msg':{'eng':req.imgurl+'cant be proccessed','zh':"無法辨別圖片網址"+req.imgurl}}
- return status
-
- 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')
- if name_hash == 'keepRunning':
- if first(db.query('SELECT COUNT(1) FROM video_queue where video_type="longvideo"'))['COUNT(1)'] == 0:
- return
- db.query('UPDATE video_queue_status SET status = 0;')
- print('start clear long video')
- else:
- 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,'video_type':'longvideo','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 where video_type="longvideo"'))['COUNT(1)'] == 0:
- print('all finish, leave loop')
- break
- top1 = first(db.query('SELECT * FROM video_queue where video_type="longvideo"'))
- 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.107: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')
- db.close()
- def gen_video_queue(name_hash,name,text_content, image_urls,avatar,multiLang,video_id,user_id,freeTrial):
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- if name_hash == 'keepRunning':
- if first(db.query('SELECT COUNT(1) FROM video_queue where video_type="short"'))['COUNT(1)'] == 0:
- return
- db.query('UPDATE video_queue_status SET status = 0;')
- print('start clear short video')
- else:
- 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,'video_type':'short','avatar':avatar,'timestamp':time_stamp,'freeTrial':freeTrial})
- while True:
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- 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 where video_type="short"'))['COUNT(1)'] == 0:
- print('all finish, leave loop')
- break
- try:
- db.close()
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- top1 = first(db.query('SELECT * FROM video_queue where video_type="short"'))
- print(top1)
- print(top1['name_hash'])
- # 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'],top1['freeTrial']) # 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
- line_token=''
- left_time=10000
- email=''
- if user_id!=-1:
- 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 and freeTrial!=1:
- msg = '您本月額度剩下'+str(left_time)+'秒,此部影片有'+str(vid_duration)+'秒, 若要繼續產生影片請至 192.168.1.107: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
- if user_id != -1:
- db.query('UPDATE users SET left_time ='+str(left_time)+' WHERE id='+str(user_id)+';')
- notify_group(top1['name']+"的影片已經產生完成囉! www.choozmo.com:8168/"+video_sub_folder+top1['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')
- db.close()
- db.close()
- def gen_video_queue_eng(name_hash,name,text_content, image_urls,sub_titles,avatar,video_id,freeTrial):
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- if name_hash == 'keepRunning':
- if first(db.query('SELECT COUNT(1) FROM video_queue where video_type="eng"'))['COUNT(1)'] == 0:
- return
- db.query('UPDATE video_queue_status SET status = 0;')
- print('start clear eng video')
- else:
- 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,'video_type':'eng','avatar':avatar,'timestamp':time_stamp,'freeTrial':freeTrial})
- while True:
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- 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 where video_type=="eng"'))['COUNT(1)'] == 0:
- print('all finish, leave loop')
- break
- top1 = first(db.query('SELECT * FROM video_queue where video_type=="eng"'))
- 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'],top1['freeTrial']) # method call
- shutil.copy(tmp_video_dir+top1['name']+'.mp4',video_dest+top1['name_hash']+'.mp4')
- os.remove(tmp_video_dir+top1['name_hash']+'.mp4')
- notify_group(top1['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')
- db.close()
- db.close()
- def gen_avatar(name_hash, imgurl):
- db_check()
- 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()
- @app.post("/gen_speech")
- async def make_voice(req:util.models.speech_req):
- call_speech(req.text,req.speaker)
- return {'msg':'wait please'}
- def call_speech(text,speaker):
- conn = rpyc.classic.connect("192.168.1.105",8838)
- ros = conn.modules.os
- ros.system('docker exec -it mingc_tts bash gen_speech.sh '+text+' '+speaker)
- while True:
- print('waiting...')
- if ros.path.exists('/home/ming/workspace/TTS_fs2/fast_speech2_ming024/output/result/AISHELL3/'+text+'.wav'):
- break
- time.sleep(5)
- print('waiting...')
- fr=conn.builtins.open('/home/ming/workspace/TTS_fs2/fast_speech2_ming024/output/result/AISHELL3/'+text+'.wav','rb')
- fw=open(text+'.wav','wb')
- while True:
- b=fr.read(1024)
- if b:
- fw.write(b)
- else:
- break
- fr.close()
- fw.close()
- shutil.copy(text+'.wav',speech_dest+text+'.wav')
- os.remove(text+'.wav')
- notify_choozmo("speech at www.choozmo.com:8168/speech/"+text+".wav")
- def verify_jwt_token(token):
- for row in db.query('SELECT * FROM jwt_black_list'):
- print(row)
- print(first(db.query('SELECT COUNT(*) FROM jwt_black_list where token="'+token+'"'))['COUNT(*)'])
- if first(db.query('SELECT COUNT(*) FROM jwt_black_list where token="'+token+'"'))['COUNT(*)'] == 0:
- return 'ok'
- else:
- return 'please login again'
- def db_check():
- global db
- if db!=None:
- db.close()
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
- def clear_video_queue():
- x = threading.Thread(target=gen_video_queue_eng, args=('keepRunning','', '', '','','',''))
- x.start()
- x2 = threading.Thread(target=gen_video_queue, args=('keepRunning','', '', '','','','',''))
- x2.start()
- x3 = threading.Thread(target=gen_video_long_queue, args=('keepRunning','', '', '','','','',''))
- x3.start()
- clear_video_queue()
|