This commit is contained in:
Arti Zirk 2017-05-24 21:17:08 +03:00
commit 929428279c
10 changed files with 208 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
venv/
__pycache__

33
echo360/__init__.py Normal file
View File

@ -0,0 +1,33 @@
import json
from pathlib import Path
import falcon
from .tools import JsonRequest, JsonResponse, error_handler
from .controllers import *
class AboutResource():
def on_get(self, req, resp):
r = {"about": {
"name": "echo360py API",
"version": "1",
"docs": "TODO"
}
}
resp.body = json.dumps(r, indent=4)
app = application = falcon.API(request_type=JsonRequest, response_type=JsonResponse)
app.add_error_handler(ValueError, error_handler)
app.add_route("/", AboutResource())
app.add_route("/Task", TaskResource())
app.add_route("/Tasks", TasksCollection())
app.add_route("/Tasks/{TaskId}", TasksCollection())
app.add_route("/Videos/{VideoUuid}/Streams/{StreamId}", StreamCollection())
FilesStoragePath = Path("files")
FilesStoragePath.mkdir(parents=True, exist_ok=True)
app.add_route("/File/{FileId}", FileCollection(FilesStoragePath))

90
echo360/controllers.py Normal file
View File

@ -0,0 +1,90 @@
from enum import IntEnum
from pathlib import Path
from falcon import HTTPNotFound
class TaskStatus(IntEnum):
Created = 0
Starting = 1
Running = 2
Finished = 3
Error = 4
tasks = [
{
"TaskId":0,
"Progress":0,
"SourceStreamId":0,
"DestinationStreamId":1,
"TaskStatus":TaskStatus.Created
}
]
streams = [
{
"StreamId":0,
"MimeType":"application/x-shockwave-flash",
"Uris":[
{"Uri":"http://10.42.0.1:8080/File/00000000.swf"},
{"Uri":"http://10.42.0.1:8080/File/00015000.swf"},
{"Uri":"http://10.42.0.1:8080/File/00030000.swf"}
]
},
{
"StreamId":1,
"MimeType":"video/x-m4v",
"Uris":[]
}
]
class TaskResource():
def on_get(self, req, resp):
for task in tasks:
if task["TaskStatus"] in (TaskStatus.Created, TaskStatus.Error):
#task["TaskStatus"] = TaskStatus.Starting
resp.json = task
return
else:
raise HTTPNotFound()
class TasksCollection():
def on_get(self, req, resp, TaskId=None):
if TaskId:
TaskId = int(TaskId)
try:
resp.json = tasks[TaskId]
except IndexError:
raise HTTPNotFound()
else:
resp.json = tasks
def on_post(self, req, resp):
task = req.json
tasks.append(task)
class StreamCollection():
def on_get(self, req, resp, VideoUuid, StreamId):
print(VideoUuid, StreamId)
StreamId = int(StreamId)
try:
resp.json = streams[StreamId]
except IndexError:
raise HTTPNotFound()
class FileCollection():
def __init__(self, path):
self.path = path
def on_get(self, req, resp, FileId):
File = Path(FileId).name
File = self.path/File
try:
with File.open("rb") as f:
resp.content_type = "application/octet-stream"
resp.body= f.read()
except FileNotFoundError:
raise HTTPNotFound()

51
echo360/tools.py Normal file
View File

@ -0,0 +1,51 @@
import json
from falcon import Request as FalconRequest
from falcon import Response as FalconResponse
from falcon.errors import HTTPBadRequest, HTTPMissingParam, HTTPError
import falcon.status_codes as status
class JsonRequest(FalconRequest):
#__slots__ = set(FalconRequest.__slots__ + ("_json", "_args"))
@property
def json(self):
if not hasattr(self, "_json"):
if not self.client_accepts_json:
raise falcon.HTTPUnsupportedMediaType(
'This API only supports the JSON formated data')
try:
self._json = json.loads(self.stream.read().decode('utf8'))
except json.decoder.JSONDecodeError as err:
raise HTTPBadRequest("JSONDecodeError", str(err))
return self._json
class JsonResponse(FalconResponse):
#__slots__ = set(FalconRequest.__slots__ + ("_json",))
@property
def json(self):
return self._json
@json.setter
def json(self, value):
self._json = value
self.body = json.dumps(value, indent=4)
def error_handler(ex, req, resp, params):
raise HTTPBadRequest(type(ex).__name__, str(ex))
class TODOException(HTTPError):
def __init__(self, **kwargs):
super(TODOException, self).__init__(status.HTTP_NOT_IMPLEMENTED, **kwargs)
@property
def has_representation(self):
return False

BIN
files/00000000.swf Normal file

Binary file not shown.

BIN
files/00015000.swf Normal file

Binary file not shown.

BIN
files/00030000.swf Normal file

Binary file not shown.

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
falcon

23
uwsgi.ini Normal file
View File

@ -0,0 +1,23 @@
[uwsgi]
plugin=http
plugin=python3
plugin=python
master=true
virtualenv=venv
processes=1
need-app=true
[dev]
ini=:uwsgi
http=:8080
#static-map2=/=../web
#static-index=index.html
mount=/api/v1=wsgi.py
manage-script-name = true
py-autoreload=1
[prod]
ini=:uwsgi
module=echo360
chdir=/srv/http/echo360py/
socket=/run/uwsgi/echo360py

8
wsgi.py Normal file
View File

@ -0,0 +1,8 @@
from echo360 import application
if __name__ == "__main__":
from wsgiref.simple_server import make_server
httpd = make_server('0.0.0.0', 8080, application)
print("Serving on http://0.0.0.0:8080/")
httpd.serve_forever()