metube/app/main.py

122 lines
3.5 KiB
Python
Raw Normal View History

2019-11-29 17:31:34 +00:00
#!/usr/bin/env python3
2019-12-03 21:18:14 +00:00
# pylint: disable=no-member,method-hidden
2019-11-29 17:31:34 +00:00
import os
from aiohttp import web
import asyncio
import socketio
import time
import logging
import json
from ytdl import DownloadQueueNotifier, DownloadQueue
log = logging.getLogger('main')
class Config:
_DEFAULTS = {
'DOWNLOAD_DIR': '.',
2019-12-03 21:18:14 +00:00
'URL_PREFIX': '',
2019-11-29 17:31:34 +00:00
}
def __init__(self):
for k, v in self._DEFAULTS.items():
setattr(self, k, os.environ[k] if k in os.environ else v)
2019-12-06 12:16:19 +00:00
if not self.URL_PREFIX.endswith('/'):
self.URL_PREFIX += '/'
2019-11-29 17:31:34 +00:00
config = Config()
class ObjectSerializer(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, object):
return obj.__dict__
else:
return json.JSONEncoder.default(self, obj)
serializer = ObjectSerializer()
app = web.Application()
sio = socketio.AsyncServer()
2019-12-06 12:16:19 +00:00
sio.attach(app, socketio_path=config.URL_PREFIX + 'socket.io')
2019-11-29 17:31:34 +00:00
routes = web.RouteTableDef()
class Notifier(DownloadQueueNotifier):
async def added(self, dl):
await sio.emit('added', serializer.encode(dl))
async def updated(self, dl):
await sio.emit('updated', serializer.encode(dl))
2019-12-03 20:32:07 +00:00
async def completed(self, dl):
await sio.emit('completed', serializer.encode(dl))
async def canceled(self, id):
await sio.emit('canceled', serializer.encode(id))
async def cleared(self, id):
await sio.emit('cleared', serializer.encode(id))
2019-11-29 17:31:34 +00:00
dqueue = DownloadQueue(config, Notifier())
2019-12-03 21:18:14 +00:00
@routes.post(config.URL_PREFIX + 'add')
2019-11-29 17:31:34 +00:00
async def add(request):
post = await request.json()
url = post.get('url')
2019-12-13 20:43:58 +00:00
quality = post.get('quality')
if not url or not quality:
2019-11-29 17:31:34 +00:00
raise web.HTTPBadRequest()
2019-12-13 20:43:58 +00:00
status = await dqueue.add(url, quality)
2019-11-29 17:31:34 +00:00
return web.Response(text=serializer.encode(status))
2019-12-03 21:18:14 +00:00
@routes.post(config.URL_PREFIX + 'delete')
2019-11-29 17:31:34 +00:00
async def delete(request):
post = await request.json()
ids = post.get('ids')
2019-12-03 20:32:07 +00:00
where = post.get('where')
if not ids or where not in ['queue', 'done']:
2019-11-29 17:31:34 +00:00
raise web.HTTPBadRequest()
2019-12-03 20:32:07 +00:00
status = await (dqueue.cancel(ids) if where == 'queue' else dqueue.clear(ids))
2019-11-29 17:31:34 +00:00
return web.Response(text=serializer.encode(status))
@sio.event
async def connect(sid, environ):
2019-12-03 20:32:07 +00:00
await sio.emit('all', serializer.encode(dqueue.get()), to=sid)
2019-11-29 17:31:34 +00:00
2019-12-03 21:18:14 +00:00
@routes.get(config.URL_PREFIX)
2019-11-29 17:31:34 +00:00
def index(request):
return web.FileResponse('ui/dist/metube/index.html')
2019-12-03 21:18:14 +00:00
if config.URL_PREFIX != '/':
@routes.get('/')
def index_redirect_root(request):
return web.HTTPFound(config.URL_PREFIX)
@routes.get(config.URL_PREFIX[:-1])
def index_redirect_dir(request):
return web.HTTPFound(config.URL_PREFIX)
routes.static(config.URL_PREFIX + 'favicon/', 'favicon')
routes.static(config.URL_PREFIX, 'ui/dist/metube')
2019-11-29 17:31:34 +00:00
app.add_routes(routes)
2021-01-26 13:28:03 +00:00
# https://github.com/aio-libs/aiohttp/pull/4615 waiting for release
# @routes.options(config.URL_PREFIX + 'add')
async def add_cors(request):
return web.Response(text=serializer.encode({"status": "ok"}))
app.router.add_route('OPTIONS', config.URL_PREFIX + 'add', add_cors)
async def on_prepare(request, response):
if 'Origin' in request.headers:
response.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
app.on_response_prepare.append(on_prepare)
2019-11-29 17:31:34 +00:00
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
web.run_app(app, port=8081)