Skip to content

Commit

Permalink
Merge pull request #42 from quaternionmedia/magnussens
Browse files Browse the repository at this point in the history
Magnussens: form to render workflow
  • Loading branch information
mrharpo authored Mar 22, 2021
2 parents f489bf1 + 09f2317 commit fc97749
Show file tree
Hide file tree
Showing 20 changed files with 554 additions and 35 deletions.
5 changes: 5 additions & 0 deletions .email
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
EMAIL_SERVER=femail.harpo.me
EMAIL_PORT=587
EMAIL_USERNAME=alfred@quaternion.media
EMAIL_PASSWORD=""
EMAIL_SENDTO=""
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ api/data
*.png
*.jpg
*.edl

.email
10 changes: 8 additions & 2 deletions alfred
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ elif [ $1 = "log" -o $1 = "logs" -o $1 = "l" ]; then

elif [ $1 = "worker" -o $1 = "w" ]; then
shift
celery worker --workdir api -A tasks:renderer -l debug -b pyamqp://192.168.192.13 --result-backend rpc://

# . operator used in place of source
. ./.cred
celery -A tasks:renderer --workdir api/ -b pyamqp://$1 --result-backend rpc:// worker
elif [ $1 = "dump" ]; then
shift
DATE=`date "+%Y-%m-%d-%H%M%S"`
Expand All @@ -96,4 +97,9 @@ elif [ $1 = "restore" ]; then
docker container cp $1 alfred_db_1:/$1
docker-compose exec db sh -c "mongorestore --gzip --db alfred --archive=/$1 --drop"

elif [ $1 = "reload" ]; then
shift
# reload otto
docker-compose -f docker-compose.yml -f dev.yml up -d --build api

fi
2 changes: 2 additions & 0 deletions api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ RUN apk add g++ wget libffi-dev openssl-dev jpeg-dev cairo cairo-dev imagemagick

COPY requirements.txt /
RUN pip install -Ur /requirements.txt
COPY otto/requirements.txt /
RUN pip install numpy gizeh pillow
RUN pip install -Ur /requirements.txt
RUN pip install celery google-cloud-storage
RUN pip uninstall amqplib
RUN pip install librabbitmq
Expand Down
6 changes: 6 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@
CELERY_BACKEND = environ.get('CELERY_BACKEND')

BUCKET_NAME = environ.get('ALFRED_BUCKET_NAME', 'tower-renders')

EMAIL_USERNAME = environ.get('EMAIL_USERNAME')
EMAIL_PASSWORD = environ.get('EMAIL_PASSWORD')
EMAIL_SERVER = environ.get('EMAIL_SERVER')
EMAIL_PORT = environ.get('EMAIL_PORT')
EMAIL_SENDTO = environ.get('EMAIL_SENDTO')
21 changes: 21 additions & 0 deletions api/emailer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from smtplib import SMTP
from email.message import EmailMessage
import config

def sendMail(message, subject):
try:
msg = EmailMessage()
msg.set_content(message)
msg['Subject'] = subject
msg['From'] = config.EMAIL_USERNAME
msg['To'] = config.EMAIL_SENDTO
s=SMTP(config.EMAIL_SERVER, config.EMAIL_PORT)
s.set_debuglevel(1)
s.starttls()
s.login(config.EMAIL_USERNAME, config.EMAIL_PASSWORD)
s.send_message(msg)
s.quit()
return True
except Exception as e:
print('error sending email', e)
return False
41 changes: 24 additions & 17 deletions api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from math import floor
from config import BUCKET_NAME
from bucket import generate_signed_url
from emailer import sendMail

def seconds(t):
return sum(x * round(float(s), 2) for x, s in zip([3600, 60, 1], t.split(":")))
Expand Down Expand Up @@ -81,7 +82,7 @@ def updateProgress(id, progress):
# REST Routing :
# TODO: as it grows length -> breakout file into suporting files as needed, e.g. dbm'database manager', util'utiliy', etc.
app = FastAPI()
app.mount('/otto', ottoApi)
app.include_router(ottoApi, prefix='/otto', dependencies=[Depends(get_current_active_user)])

@app.on_event("startup")
async def seedDb():
Expand Down Expand Up @@ -123,27 +124,25 @@ async def download_file(filename: str):


@app.post('/render')
async def queueRender(prog: BackgroundTasks, edl: Edl, project: str, width: int = 1920, height: int = 1080):
async def queueRender(prog: BackgroundTasks, project: str, width: int = 1920, height: int = 1080, edl: Edl = Body(...), user: User = Depends(get_current_active_user)):
ts = timestr()
duration = sum(c['duration'] for c in edl.edl)
filename = f'{project}_{width}x{height}_{duration}s_{ts}.mp4'
media = db.projects.find_one({'name': project}, ['form'])['form']['media']
id = db.renders.insert_one({
filename = f'{project}_{width}x{height}_{edl.duration}s_{ts}.mp4'
render = {
'user': user.username,
'project': project,
'filename': filename,
'duration': duration,
'duration': edl.duration,
'resolution': (width, height),
'media': media,
'edl': edl.edl,
'progress': 0,
'started': ts,
'link': join('https://storage.googleapis.com/', BUCKET_NAME, filename),
}
).inserted_id
proj = db.projects.find_one({'name': project}, ['form'])['form']
print('rendering!', filename, proj)
media = [ download(m) for m in proj['media'] ]
task = renderRemote.delay(edl=edl.edl, media=media, audio=download(proj['audio'][0]), filename=filename, moviesize=(width, height))
# media = db.projects.find_one({'name': project}, ['form'])['form']['media']
id = db.renders.insert_one(render).inserted_id
print('rendering!', render)
# media = [ download(m) for m in proj['media'] ]
task = renderRemote.delay(edl=edl.edl, filename=filename, moviesize=(width, height))
def updateRenderProgress(progress):
r = progress.get('result')
# print('updating progress', r)
Expand Down Expand Up @@ -187,10 +186,11 @@ def pauseRender(user: User = Depends(get_current_active_user)):
@app.put('/renders/{render}/cancel')
def cancelRender(render: str, user: User = Depends(get_current_active_user)):
# cancel selected render
res = db.renders.delete_one({'filename': render})
if res.deleted_count:
print('deleted render', render, res, res.deleted_count)
return res.deleted_count
res = db.renders.find_one_and_delete({'filename': render})
if res:
print('deleted render', render, res)
db.deleted.insert_one(res)
return
else:
return HTTPException(status_code=406, detail='no such entry in database')

Expand Down Expand Up @@ -298,6 +298,13 @@ async def saveFile(file, location='data'):
with open(join(location, file.filename), 'wb') as f:
f.write(data)

@app.post('/report')
async def reportIssue(name: str, issue: str = Body(...)):
if not sendMail(issue, name):
print('error reporting issue with ', name, issue)
raise HTTPException(status_code=500, detail='error sending email')


app.include_router(auth)
app.include_router(users)

Expand Down
2 changes: 1 addition & 1 deletion api/otto
2 changes: 2 additions & 0 deletions api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ tinydb
pyjwt
passlib[bcrypt]
pymongo
celery
google-cloud-storage
6 changes: 3 additions & 3 deletions api/tasks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from celery import Celery
from otto.render import renderEdl
from otto.render import renderMultitrack
import config
from logger import CeleryLogger
from os.path import join
Expand All @@ -9,8 +9,8 @@


@renderer.task(bind=True)
def renderRemote(self, edl, media, audio, filename, moviesize):
def renderRemote(self, edl, filename, audio=None, moviesize=(1920,1080)):
log = CeleryLogger(self)
renderEdl(edl, media, audio, join('videos', filename), moviesize, log)
renderMultitrack(edl, audio, join('videos', filename), moviesize, log)
upload(filename, directory='videos')
self.update_state(state='PROGRESS', meta={'status': 'uploaded'})
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ services:
- CELERY_BACKEND=rpc://
- DB_URL=mongodb://db:27017
- GOOGLE_APPLICATION_CREDENTIALS=/cred.json

env_file:
- .email

db:
image: mongo:bionic
Expand Down
72 changes: 72 additions & 0 deletions website/src/Components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import m from 'mithril'
import { Menu } from './Menu'

export function Form() {
return {
view: vnode => {
return m('form', vnode.attrs, vnode.children)
}
}
}

export function TextBox() {
return {
view: vnode => {
return [
m('label.formlabel', {for: vnode.attrs.name}, vnode.attrs.text),
m('textarea', vnode.attrs),
m('br')
]
}
}
}
export function Button() {
return {
view: vnode => {
return m('input.button', vnode.attrs, vnode.children)
}
}
}

export function Img() {
return {
view: vnode => {
return m('img', vnode.attrs, vnode.children)
}
}
}

export function Selector() {
return {
view: vnode => {
return [
m('label.formlabel', { for: vnode.attrs.name }, vnode.attrs.text),
m('select', vnode.attrs, vnode.children.map(c => {
return m('option', {value: c}, c)
})),
m('br'),
]
}
}
}


export function Section() {
return {
view: vnode => {
return m('section', vnode.attrs, vnode.children)
}
}
}

export function Layout() {
return {
view: vnode => {
return [
m(Menu),
m(Section, vnode.attrs, vnode.children)
]
}
}
}

Loading

0 comments on commit fc97749

Please sign in to comment.