Commit 5dc776ec authored by Fence's avatar Fence 🌈

init

parents
# 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
# Sphinx documentation
docs/_build/
# PyBuilder
target/
#Ipython Notebook
.ipynb_checkpoints
# pyenv
.python-version
./uploads/*
\ No newline at end of file
from minor import App
app = App()
app.run()
\ No newline at end of file
{
"info": {
"_postman_id": "47133917-aa5d-440f-ba7b-279ab5787a57",
"name": "minor",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "version",
"event": [
{
"listen": "test",
"script": {
"id": "9deba9eb-be72-4b3d-96b7-24ddbe9c8fea",
"type": "text/javascript",
"exec": [
"pm.test(\"correct service\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.name).to.eql(\"minor\");",
"});",
"",
"pm.test(\"correct version\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.version).to.eql(0.1);",
"});"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{url}}/api",
"host": [
"{{url}}"
],
"path": [
"api"
]
}
},
"response": []
},
{
"name": "add_song",
"event": [
{
"listen": "test",
"script": {
"id": "8caf688c-9a93-44a4-9b9d-2d28c32e6678",
"type": "text/javascript",
"exec": [
"pm.test(\"has id\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(_.has(jsonData.data, \"id\")).to.eql(true)",
"});",
"",
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.environment.set(\"song_id\", pm.response.json().data.id);"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"title\": \"bad apple\",\n\t\"artist\": \"nomico\",\n\t\"album_artist\": \"Alstroemeria Records\",\n\t\"album\": \"bad apple EP\",\n\t\"track\": 1,\n\t\"year\": \"2004\"\n}"
},
"url": {
"raw": "{{url}}/api/music/song",
"host": [
"{{url}}"
],
"path": [
"api",
"music",
"song"
]
}
},
"response": []
},
{
"name": "has_no_file",
"event": [
{
"listen": "test",
"script": {
"id": "e832e825-6bf5-4cb5-9098-84ec994431fb",
"type": "text/javascript",
"exec": [
"pm.test(\"Your test name\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.data).to.eql(false);",
"});"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{url}}/api/music/song/{{song_id}}/hasfile",
"host": [
"{{url}}"
],
"path": [
"api",
"music",
"song",
"{{song_id}}",
"hasfile"
]
}
},
"response": []
},
{
"name": "upload_file",
"event": [
{
"listen": "test",
"script": {
"id": "c2c9970c-aed2-4749-b44d-fdbefcfb4aac",
"type": "text/javascript",
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});"
]
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"description": "",
"type": "file"
}
]
},
"url": {
"raw": "{{url}}/api/music/song/{{song_id}}/upload",
"host": [
"{{url}}"
],
"path": [
"api",
"music",
"song",
"{{song_id}}",
"upload"
]
}
},
"response": []
},
{
"name": "has_file",
"event": [
{
"listen": "test",
"script": {
"id": "1148a457-ca05-4bec-ac93-b28cfee05d88",
"type": "text/javascript",
"exec": [
"pm.test(\"Your test name\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.data).to.eql(true);",
"});"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{url}}/api/music/song/{{song_id}}/hasfile",
"host": [
"{{url}}"
],
"path": [
"api",
"music",
"song",
"{{song_id}}",
"hasfile"
]
}
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "33a68747-ae2d-47af-9f30-50d44b2e7f73",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "d93827bd-f864-4759-b07a-360240d23aa4",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "c547da47-7193-43fd-ab64-435731330129",
"key": "url",
"value": "http://127.0.0.1:5000/",
"type": "string",
"description": ""
}
]
}
\ No newline at end of file
from minor.app import App
\ No newline at end of file
from flask import Flask
from flask_mongoengine import MongoEngine
from minor.controller import ApiController, MusicController
class App(object):
def __init__(self):
self._flask = Flask(__name__)
self._flask.config['MONGODB_SETTINGS'] = {'DB': 'testing'}
from minor.model import db
db.init_app(self._flask)
ApiController(self).register(self._flask)
MusicController().register(self._flask)
def run(self):
self._flask.run()
def check_key(self, key):
return key == "sekrit1234"
from minor.controller.api import ApiController
from minor.controller.music import MusicController
\ No newline at end of file
from flask import request, jsonify
from flask_controller import FlaskController, route
from minor import version
from minor.model import MajorInstance
from minor.decorators import json_required
@route("/api")
class ApiController(FlaskController):
def __init__(self, app):
self._app = app
@route("")
def index(self):
v = {"version": version.number, "name": version.name}
return jsonify(v)
@route("/ping")
def ping(self):
return "pong"
@json_required
@route("/register", methods=["POST"])
def register_major(self):
json = request.get_json()
if "key" in json:
if self._app.check_key(json["key"]):
# add the instance the the trusted list
new_instance = MajorInstance(
issuer=json["issuer"], url=json["url"])
new_instance.save()
return jsonify({"code": 200, "message": "ok"}), 200
return jsonify({"code": 400, "message": "bad_request"}), 400
import os
import os.path
from pprint import pprint
from flask import json_available, request, jsonify, Response
from flask_controller import FlaskController, route
from bson import ObjectId
from werkzeug.utils import secure_filename
from minor.decorators import json_required, auth_required
from minor.model import Song
from minor.util import get_ext
@route("/api/music")
class MusicController(FlaskController):
# @auth_required
@route("/listen")
def listen(self, payload=None):
if "song" in payload:
song = Song.objects.get(id=payload["song"])
if song is not None:
filename = "./uploads/" + str(song["_id"]) + ".mp3"
print(filename)
if os.path.isfile(filename):
def generate():
with open(filename, "rb") as fogg:
data = fogg.read(1024)
while data:
yield data
data = fogg.read(1024)
return Response(generate(), mimetype="audio/mp3")
else:
return jsonify({"code": 400, "message": "bad_request"}), 400
# auth_required
@route("/song/<id>")
def song(self, id, payload=None):
song = Song.objects.get(id=id)
if song is not None:
return jsonify({"code": 200, "message": "ok", "data": song}), 200
else:
return jsonify({"code": 400, "message": "bad_request"}), 400
# @auth_required
@route("/song/<id>/hasfile")
def song_has_file(self, id, payload=None):
song = Song.objects.get(id=id)
if song is not None:
filename = "./uploads/" + str(song.id) + ".mp3"
if os.path.isfile(filename):
return jsonify({"code": 200, "message": "ok", "data": True}), 200
else:
return jsonify({"code": 200, "message": "ok", "data": False}), 200
else:
return jsonify({"code": 400, "message": "bad_request"}), 400
# @auth_required
@json_required
@route("/song", methods=["POST"])
def song_post(self, payload=None):
json = request.get_json()
try:
if "album" in json:
song = Song(title=json["title"],
artist=json["artist"],
year=json["year"],
track=json["track"],
album=json["album"],
album_artist=json["album_artist"])
else:
song = Song(title=json["title"],
artist=json["artist"],
year=json["year"]).save()
song.save()
song.reload()
return jsonify({"code": 200,
"message": "ok",
"data": {"id": str(song.id)}}), 200
except KeyError:
return jsonify({"code": 400, "message": "bad_request"}), 400
# @auth_required
@route("/song/<id>/upload", methods=["POST"])
def song_file(self, id, payload=None):
if 'file' in request.files:
file = request.files["file"]
db_song = Song.objects.get(id=id)
if db_song is not None:
if file.filename is not '':
ext = get_ext(file.filename)
if ext is not None:
name = secure_filename(str(db_song.id) + "." + ext)
path = os.path.join("./uploads", name)
file.save(path)
return jsonify({"code": 200, "message": "ok"}), 200
return jsonify({"code": 400, "message": "bad_request"}), 400
import os
import os.path
import json
import jwt
from datetime import datetime, timedelta
import requests
from minor.model import MajorInstance
class CryptoChecker(object):
def __init__(self, db):
self._db = db
def check(self, token):
payload = jwt.decode(token, "", verify=False)
issuer = MajorInstance.objects.get(issuer=payload["iss"])
if issuer is not None:
try:
key = requests.get(issuer["url"] + "/auth/key").text
checked_payload = jwt.decode(token, key)
return checked_payload
except Exception as e:
print(e)
return None
\ No newline at end of file
from functools import wraps
from flask import json_available, jsonify, request
from .crypto_checker import CryptoChecker
def auth_required(f):
@wraps(f)
def decorated_function(self, *args, **kwargs):
auth = request.headers["Authorization"]
if auth is not None:
auth = auth.split(" ")
if auth[0] == "Bearer":
print(auth[1])
payload = CryptoChecker(self._db).check(auth[1])
if payload is not None:
kwargs["payload"] = payload
return f(self, *args, **kwargs)
return jsonify({"code": 401, "message": "unauthorized"}), 401
return decorated_function
def json_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not json_available:
return jsonify({"code": 400, "message": "bad_request"}), 400
return f(*args, **kwargs)
return decorated_function
\ No newline at end of file
from mongoengine import *
from flask_mongoengine import MongoEngine
db = MongoEngine()
class Song(Document):
title = StringField(required=True)
artist = StringField(required=True)
year = StringField(required=True)
track = IntField()
album = StringField()
album_artist = StringField()
class MajorInstance(Document):
issuer = StringField(required=True)
url = URLField(required=True)
\ No newline at end of file
exts = ["mp3", "ogg", "flac"]
def get_ext(filename):
if '.' in filename and filename.rsplit('.', 1)[1].lower() in exts:
return filename.rsplit('.', 1)[1].lower()
else:
return None
number = 0.1
name = "minor"
\ No newline at end of file
docker run --name minor_mongo --restart=always -d -p 27017:27017 mongo
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment