Add rest api

This commit is contained in:
Arti Zirk 2016-11-01 22:26:29 +02:00
parent 1b731f5f2f
commit efaea4141c
8 changed files with 291 additions and 0 deletions

90
.gitignore vendored Normal file
View File

@ -0,0 +1,90 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
.venv/
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject

20
api/README.md Normal file
View File

@ -0,0 +1,20 @@
# API Karu Media
This is a api writen in python for Karu Media storage server
# How to set it up?
First you need Python 3.4 or newer and latest uwsgi installed in your system
For Debian you have to install those pacakges
sudo apt-get install python3 python3-pip python3-venv uwsgi uwsgi-plugin-python3 python3-uwsgidecorators
And then you can just run those commands
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
And you can run it like so
uwsgi --ini uwsgi.ini:dev

33
api/karumedia/__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": "Karu Media API",
"version": "1",
"docs": "TODO"
}
}
r.update({"endpoints":[
{"url":"/",
"description":"About this API"}
]})
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())
path = Path("/home/arti/Videod")
app.add_route("/movies", MoviesCollection(path))
app.add_route("/movies/{movie}", MoviesResource(path))

View File

@ -0,0 +1,71 @@
import re
import json
from falcon import HTTPInternalServerError, HTTP_201
from .tools import TODOException
movie_name_and_year = re.compile("(.*)\((.*)\)")
class BaseResource():
def __init__(self, path):
self.path = path
class MoviesCollection(BaseResource):
def on_get(self, req, resp):
movie_paths = [p for p in (self.path / 'Filmid').iterdir() if p.is_dir()]
movies = []
for movie_path in movie_paths:
if not (movie_path / "metadata.json").exists():
match = movie_name_and_year.match(movie_path.name)
if not match:
mobj = {
"title":movie_path.name,
"title_english":movie_path.name,
"title_long":movie_path.name,
"state":"ok"
}
else:
movie_name, movie_year = match.groups()
mobj = {
"title":movie_name,
"title_english":movie_name,
"title_long":movie_path.name,
"year":movie_year,
"state": "ok"
}
movies.append(mobj)
continue
with (movie_path / "metadata.json").open() as f:
metadata = json.loads(f.read())
mobj = {
"title":metadata["title"],
"title_english":metadata["title"],
"title_long":movie_path.name,
"year":metadata["year"],
"runtime": int(metadata["runtime"]) // 100,
"imdb_code": metadata["imdb_id"],
"rating": metadata["rating"],
"summary": metadata["plot_outline"],
"synopsis": metadata["plot_outline"],
"mpa_rating": metadata["certification"],
"genres": metadata["genres"],
"state": "ok"
}
if metadata["plots"]:
mobj["description_full"] = metadata["plots"][0]
movies.append(mobj)
jobj = {"data":{
"limit":len(movies),
"count":len(movies),
"movies":movies,
"page_number":1
},
"status": "ok",
"status_message": "query was successful"
}
resp.json = jobj
class MoviesResource(BaseResource):
def on_get(self, req, resp, movie):
resp.json = [{"path": self.path, "movie":movie}]

52
api/karumedia/tools.py Normal file
View File

@ -0,0 +1,52 @@
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

1
api/requirements.txt Normal file
View File

@ -0,0 +1 @@
falcon

23
api/uwsgi.ini Normal file
View File

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

1
api/wsgi.py Normal file
View File

@ -0,0 +1 @@
from karumedia import application