diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-06-23 23:18:07 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-06-23 23:18:07 +0200 |
| commit | 3cf70771cb45cc16ec33ffe44e7a1a4799d8f395 (patch) | |
| tree | 55f0edb53141d5f043b486d722f507bfd94abdea /animism-align/cli/app/controllers | |
| parent | 014816dc724c1be60b7dd28d4e608c89b4ed451c (diff) | |
adding web app base
Diffstat (limited to 'animism-align/cli/app/controllers')
18 files changed, 318 insertions, 0 deletions
diff --git a/animism-align/cli/app/controllers/__pycache__/collection_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/collection_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..eb3ea33 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/collection_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..7f7d98d --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/detection_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/detection_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..8868de1 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/detection_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/detection_index_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/detection_index_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..b369829 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/detection_index_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/feature_index_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/feature_index_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..769ca33 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/feature_index_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/graph_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/graph_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..cccd73b --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/graph_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/media_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/media_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..e6dbaee --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/media_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/media_import_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/media_import_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..30497c6 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/media_import_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/modelzoo_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/modelzoo_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..3d493fc --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/modelzoo_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/page_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/page_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..b540b38 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/page_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/search_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/search_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..9cf91ff --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/search_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/socket_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/socket_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..56fce90 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/socket_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/task_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/task_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..6db38eb --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/task_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/tile_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/tile_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..2449ca3 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/tile_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/__pycache__/upload_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/upload_controller.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..ed9da15 --- /dev/null +++ b/animism-align/cli/app/controllers/__pycache__/upload_controller.cpython-37.pyc diff --git a/animism-align/cli/app/controllers/crud_controller.py b/animism-align/cli/app/controllers/crud_controller.py new file mode 100644 index 0000000..595825d --- /dev/null +++ b/animism-align/cli/app/controllers/crud_controller.py @@ -0,0 +1,156 @@ +from flask import request, jsonify +from flask_classful import FlaskView, route +from werkzeug.datastructures import MultiDict + +from app.sql.common import db, Session +from app.server.helpers import parse_search_args, parse_sort_args + +class CrudView(FlaskView): + # to subclass CrudView, specify the model + form: + # model = Collection + # form = CollectionForm + index_all = True + excluded_methods = ['on_index', 'on_show', 'on_create', 'on_update', 'on_destroy'] + default_sort = "id" + default_order = "asc" + + # implement these methods: + def where(self, query, args): + return query + def on_index(self, session, data): + return data + def on_show(self, session, data): + return data + def on_create(self, session, form, item): + pass + def on_update(self, session, form, item): + pass + def on_destroy(self, session, item): + pass + + def index(self): + """ + List all {model}s + """ + session = Session() + if self.index_all: + items = session.query(self.model).all() + else: + offset, limit = parse_search_args(request.args) + sort, order, order_by, order_by_id = parse_sort_args(request.args, self.model, self.default_sort, self.default_order) + query = session.query(self.model) + query = self.where(query, request.args) + if order_by_id is not None: + query = query.order_by(order_by, order_by_id) + else: + query = query.order_by(order_by) + items = query.offset(offset).limit(limit).all() + + res = self.on_index(session, { + 'status': 'ok', + 'res': [ item.toJSON() for item in items ], + }) + session.close() + return jsonify(res) + + def get(self, id: int): + """ + Fetch a single {model}. + """ + session = Session() + item = session.query(self.model).get(id) + if not item: + session.close() + return jsonify({ + 'status': 'error', + 'error': 'item not found' + }) + result = self.on_show(session, { + 'status': 'ok', + 'res': item.toFullJSON() if hasattr(item, 'toFullJSON') else item.toJSON(), + }) + session.close() + return jsonify(result) + + def post(self): + """ + Create a new {model}. + + * JSON params: {jsonparams} + """ + session = Session() + raw_form = MultiDict(request.json) if request.json is not None else request.form + form = self.form(raw_form) + if form.validate(): + item = self.model() + form.populate_obj(item) + self.on_create(session, raw_form, item) + session.add(item) + session.commit() + res = { + 'status': 'ok', + 'res': item.toJSON(), + } + else: + res = { + 'error': 'error', + 'errors': form.errors, + } + session.close() + return jsonify(res) + + def put(self, id: int): + """ + Update a {model}. + + * JSON params: {jsonparams} + """ + session = Session() + item = session.query(self.model).get(id) + if item: + raw_form = MultiDict(request.json) if request.json is not None else request.form + form = self.form(raw_form, obj=item) + # print(item.toJSON()) + if form.validate(): + form.populate_obj(item) + self.on_update(session, raw_form, item) + session.add(item) + session.commit() + res = { + 'status': 'ok', + 'res': item.toJSON(), + } + else: + res = { + 'status': 'error', + 'error': form.errors, + } + else: + res = { + 'status': 'error', + 'error': 'not found', + } + session.close() + return jsonify(res) + + def delete(self, id: int): + """ + Delete a {model}. + """ + session = Session() + item = session.query(self.model).get(id) + if item: + self.on_destroy(session, item) + session.delete(item) + session.commit() + res = { + 'status': 'ok', + 'id': id, + } + else: + res = { + 'status': 'error', + 'error': 'not found', + } + session.close() + return jsonify(res) diff --git a/animism-align/cli/app/controllers/timestamp_controller.py b/animism-align/cli/app/controllers/timestamp_controller.py new file mode 100644 index 0000000..d4cef82 --- /dev/null +++ b/animism-align/cli/app/controllers/timestamp_controller.py @@ -0,0 +1,20 @@ +from flask import request, jsonify, redirect +from flask_classful import route +from werkzeug.datastructures import MultiDict + +from app.sql.common import db, Session +from app.sql.models.graph import Timestamp, TimestampForm +from app.sql.models.page import Page +from app.sql.models.tile import Tile +from app.controllers.crud_controller import CrudView + +class TimestampView(CrudView): + model = Timestamp + form = TimestampForm + default_sort = "start_ts" + + def on_create(self, session, form, item): + item.settings = form['settings'] + + def on_update(self, session, form, item): + item.settings = form['settings'] diff --git a/animism-align/cli/app/controllers/upload_controller.py b/animism-align/cli/app/controllers/upload_controller.py new file mode 100644 index 0000000..86f9f29 --- /dev/null +++ b/animism-align/cli/app/controllers/upload_controller.py @@ -0,0 +1,142 @@ +from flask import request, jsonify +from flask_classful import FlaskView, route +from werkzeug.datastructures import MultiDict +from werkzeug.utils import secure_filename +import os +import numpy as np +from PIL import Image + +from app.settings import app_cfg +from app.sql.common import db, Session +from app.sql.models.upload import Upload +from app.utils.file_utils import sha256_stream, sha256_tree, VALID_IMAGE_EXTS +from app.server.decorators import APIError + +class UploadView(FlaskView): + def index(self): + """ + List all uploaded files. + + * Query string params: offset, limit, sort (id, date), order (asc, desc) + """ + session = Session() + uploads = session.query(Upload).all() + response = { + 'status': 'ok', + 'res': [ upload.toJSON() for upload in uploads ], + } + session.close() + return jsonify(response) + + def get(self, id): + """ + Fetch a single upload. + """ + session = Session() + upload = session.query(Upload).get(id) + response = { + 'status': 'ok', + 'res': upload.toJSON(), + } + session.close() + return jsonify(response) + + def post(self): + """ + Upload a new file. + + * JSON params: username + """ + + try: + username = request.form.get('username') + except: + raise APIError('No username specified') + + param_name = 'image' + if param_name not in request.files: + raise APIError('No file uploaded') + + file = request.files[param_name] + + # get sha256 + sha256 = sha256_stream(file) + _, ext = os.path.splitext(file.filename) + if ext == '.jpeg': + ext = '.jpg' + + # TODO: here check sha256 + # upload = Upload.query.get(id) + + if ext[1:] not in VALID_IMAGE_EXTS: + return jsonify({ 'status': 'error', 'error': 'Not a valid image' }) + + # convert string of image data to uint8 + file.seek(0) + nparr = np.fromstring(file.read(), np.uint8) + + # decode image + try: + im = Image.fromarray(nparr) + except: + return jsonify({ 'status': 'error', 'error': 'Image parse error' }) + + session = Session() + upload = session.query(Upload).filter_by(sha256=sha256).first() + if upload is not None: + print("Already uploaded image") + response = { + 'status': 'ok', + 'notes': 'Image already uploaded', + 'res': upload.toJSON(), + } + session.close() + return jsonify(response) + + uploaded_im_fn = secure_filename(sha256 + ext) + uploaded_im_abspath = os.path.join(app_cfg.DIR_UPLOADS, sha256_tree(sha256)) + uploaded_im_fullpath = os.path.join(uploaded_im_abspath, uploaded_im_fn) + + os.makedirs(uploaded_im_abspath, exist_ok=True) + nparr.tofile(uploaded_im_fullpath) + + upload = Upload(username=username, sha256=sha256, ext=ext) + session.add(upload) + session.commit() + response = { + 'status': 'ok', + 'res': upload.toJSON(), + } + session.close() + return jsonify(response) + + def delete(self, id): + """ + Delete an uploaded file. + """ + session = Session() + upload = session.query(Upload).get(id) + if not upload: + session.close() + return jsonify({ + 'status': 'error', + 'error': 'not found', + }) + + sha256 = upload.sha256 + + uploaded_im_fn = secure_filename(sha256 + upload.ext) + uploaded_im_abspath = os.path.join(app_cfg.DIR_UPLOADS, sha256_tree(sha256)) + uploaded_im_fullpath = os.path.join(uploaded_im_abspath, uploaded_im_fn) + if os.path.exists(uploaded_im_fullpath): + print("Removing " + uploaded_im_fullpath) + os.remove(uploaded_im_fullpath) + + session.delete(upload) + session.commit() + response = { + 'status': 'ok', + 'id': id, + } + session.close() + return jsonify(response) |
