obscreen/src/controller/ContentController.py

301 lines
13 KiB
Python

import json
import os
import time
from flask import Flask, render_template, redirect, request, url_for, send_from_directory, jsonify, abort
from werkzeug.utils import secure_filename
from src.service.ModelStore import ModelStore
from src.model.entity.Content import Content
from src.model.enum.ContentType import ContentType
from src.model.enum.FolderEntity import FolderEntity, FOLDER_ROOT_PATH
from src.interface.ObController import ObController
from src.service.ExternalStorageServer import ExternalStorageServer
from src.util.utils import str_to_enum, get_optional_string
from src.util.UtilFile import randomize_filename
class ContentController(ObController):
def register(self):
self._app.add_url_rule('/slideshow/content', 'slideshow_content_list', self._auth(self.slideshow_content_list), methods=['GET'])
self._app.add_url_rule('/slideshow/content/add', 'slideshow_content_add', self._auth(self.slideshow_content_add), methods=['GET', 'POST'])
self._app.add_url_rule('/slideshow/content/edit/<content_id>', 'slideshow_content_edit', self._auth(self.slideshow_content_edit), methods=['GET'])
self._app.add_url_rule('/slideshow/content/save/<content_id>', 'slideshow_content_save', self._auth(self.slideshow_content_save), methods=['POST'])
self._app.add_url_rule('/slideshow/content/delete', 'slideshow_content_delete', self._auth(self.slideshow_content_delete), methods=['GET'])
self._app.add_url_rule('/slideshow/content/rename', 'slideshow_content_rename', self._auth(self.slideshow_content_rename), methods=['POST'])
self._app.add_url_rule('/slideshow/content/cd', 'slideshow_content_cd', self._auth(self.slideshow_content_cd), methods=['GET'])
self._app.add_url_rule('/slideshow/content/add-folder', 'slideshow_content_folder_add', self._auth(self.slideshow_content_folder_add), methods=['POST'])
self._app.add_url_rule('/slideshow/content/move-folder', 'slideshow_content_folder_move', self._auth(self.slideshow_content_folder_move), methods=['POST'])
self._app.add_url_rule('/slideshow/content/rename-folder', 'slideshow_content_folder_rename', self._auth(self.slideshow_content_folder_rename), methods=['POST'])
self._app.add_url_rule('/slideshow/content/delete-folder', 'slideshow_content_folder_delete', self._auth(self.slideshow_content_folder_delete), methods=['GET'])
self._app.add_url_rule('/slideshow/content/show/<content_id>', 'slideshow_content_show', self._auth(self.slideshow_content_show), methods=['GET'])
self._app.add_url_rule('/slideshow/content/upload-bulk', 'slideshow_content_upload_bulk', self._auth(self.slideshow_content_upload_bulk), methods=['POST'])
self._app.add_url_rule('/slideshow/content/delete-bulk-explr', 'slideshow_content_delete_bulk_explr', self._auth(self.slideshow_content_delete_bulk_explr), methods=['GET'])
def get_working_folder(self):
working_folder_path = request.args.get('path', None)
working_folder = None
if working_folder_path:
working_folder = self._model_store.folder().get_one_by_path(path=working_folder_path, entity=FolderEntity.CONTENT)
if not working_folder:
working_folder_path = self._model_store.variable().get_one_by_name('last_folder_content').as_string()
working_folder = self._model_store.folder().get_one_by_path(path=working_folder_path, entity=FolderEntity.CONTENT)
return working_folder_path, working_folder
def slideshow_content_list(self):
self._model_store.variable().update_by_name('last_pillmenu_slideshow', 'slideshow_content_list')
working_folder_path, working_folder = self.get_working_folder()
slides_with_content = self._model_store.slide().get_all_indexed(attribute='content_id', multiple=True)
return render_template(
'slideshow/contents/list.jinja.html',
foldered_contents=self._model_store.content().get_all_indexed('folder_id', multiple=True),
folders_tree=self._model_store.folder().get_folder_tree(FolderEntity.CONTENT),
slides_with_content=slides_with_content,
working_folder_path=working_folder_path,
working_folder=working_folder,
working_folder_children=self._model_store.folder().get_children(folder=working_folder, entity=FolderEntity.CONTENT, sort='created_at', ascending=False),
enum_content_type=ContentType,
enum_folder_entity=FolderEntity,
chroot_http_external_storage=self.get_external_storage_server().get_directory(),
)
def slideshow_content_add(self):
working_folder_path, working_folder = self.get_working_folder()
route_args = {
"path": working_folder_path,
}
location = request.form['object'] if 'object' in request.form else None
content = self._model_store.content().add_form_raw(
name=request.form['name'],
type=str_to_enum(request.form['type'], ContentType),
request_files=request.files,
upload_dir=self._app.config['UPLOAD_FOLDER'],
location=location,
folder_id=working_folder.id if working_folder else None
)
if not content:
route_args["error"] = 'common_bad_file_type'
return redirect(url_for('slideshow_content_list', **route_args))
def slideshow_content_upload_bulk(self):
working_folder_path, working_folder = self.get_working_folder()
for key in request.files:
files = request.files.getlist(key)
for file in files:
type = ContentType.guess_content_type_file(file.filename)
name = file.filename.rsplit('.', 1)[0]
if type:
self._model_store.content().add_form_raw(
name=name,
type=type,
request_files=file,
upload_dir=self._app.config['UPLOAD_FOLDER'],
folder_id=working_folder.id if working_folder else None
)
return redirect(url_for('slideshow_content_list', path=working_folder_path))
def slideshow_content_edit(self, content_id: int = 0):
content = self._model_store.content().get(content_id)
if not content:
return abort(404)
working_folder_path, working_folder = self.get_working_folder()
return render_template(
'slideshow/contents/edit.jinja.html',
content=content,
working_folder_path=working_folder_path,
working_folder=working_folder,
enum_content_type=ContentType,
chroot_http_external_storage=self.get_external_storage_server().get_directory(),
)
def slideshow_content_save(self, content_id: int = 0):
working_folder_path, working_folder = self.get_working_folder()
content = self._model_store.content().get(content_id)
if not content:
return redirect(url_for('slideshow_content_list', path=working_folder_path))
self._model_store.content().update_form(
id=content.id,
name=request.form['name'],
location=request.form['location'] if 'location' in request.form and request.form['location'] else None
)
self._post_update()
return redirect(url_for('slideshow_content_edit', content_id=content_id, saved=1))
def slideshow_content_delete(self):
working_folder_path, working_folder = self.get_working_folder()
error_tuple = self.delete_content_by_id(request.args.get('id'))
route_args = {
"path": working_folder_path,
}
if error_tuple:
route_args[error_tuple[0]] = error_tuple[1]
return redirect(url_for('slideshow_content_list', **route_args))
def slideshow_content_rename(self):
working_folder_path, working_folder = self.get_working_folder()
self._model_store.content().update_form(
id=request.form['id'],
name=request.form['name'],
)
return redirect(url_for('slideshow_content_list', path=working_folder_path))
def slideshow_content_cd(self):
path = request.args.get('path')
if path == FOLDER_ROOT_PATH:
self._model_store.variable().update_by_name("last_folder_content", FOLDER_ROOT_PATH)
return redirect(url_for('slideshow_content_list', path=FOLDER_ROOT_PATH))
if not path:
return abort(404)
cd_folder = self._model_store.folder().get_one_by_path(
path=path,
entity=FolderEntity.CONTENT
)
if not cd_folder:
return abort(404)
self._model_store.variable().update_by_name("last_folder_content", path)
return redirect(url_for('slideshow_content_list', path=path))
def slideshow_content_folder_add(self):
working_folder_path, working_folder = self.get_working_folder()
self._model_store.folder().add_folder(
entity=FolderEntity.CONTENT,
name=request.form['name'],
working_folder_path=working_folder_path
)
return redirect(url_for('slideshow_content_list', path=working_folder_path))
def slideshow_content_folder_rename(self):
working_folder_path, working_folder = self.get_working_folder()
self._model_store.folder().rename_folder(
folder_id=request.form['id'],
name=request.form['name'],
)
return redirect(url_for('slideshow_content_list', path=working_folder_path))
def slideshow_content_folder_move(self):
working_folder_path, working_folder = self.get_working_folder()
entity_ids = request.form['entity_ids'].split(',')
folder_ids = request.form['folder_ids'].split(',')
for id in entity_ids:
self._model_store.folder().move_to_folder(
entity_id=id,
folder_id=request.form['new_folder_id'],
entity_is_folder=False,
entity=FolderEntity.CONTENT
)
for id in folder_ids:
self._model_store.folder().move_to_folder(
entity_id=id,
folder_id=request.form['new_folder_id'],
entity_is_folder=True,
entity=FolderEntity.CONTENT
)
return redirect(url_for('slideshow_content_list', path=working_folder_path))
def slideshow_content_folder_delete(self):
working_folder_path, working_folder = self.get_working_folder()
error_tuple = self.delete_folder_by_id(request.args.get('id'))
route_args = {
"path": working_folder_path,
}
if error_tuple:
route_args[error_tuple[0]] = error_tuple[1]
return redirect(url_for('slideshow_content_list', **route_args))
def slideshow_content_show(self, content_id: int = 0):
content = self._model_store.content().get(content_id)
if not content:
return abort(404)
return redirect(self._model_store.content().resolve_content_location(content))
def slideshow_content_delete_bulk_explr(self):
working_folder_path, working_folder = self.get_working_folder()
entity_ids = request.args.get('entity_ids', '').split(',')
folder_ids = request.args.get('folder_ids', '').split(',')
route_args_dict = {"path": working_folder_path}
for id in entity_ids:
if id:
error_tuple = self.delete_content_by_id(id)
if error_tuple:
route_args_dict[error_tuple[0]] = error_tuple[1]
for id in folder_ids:
if id:
error_tuple = self.delete_folder_by_id(id)
if error_tuple:
route_args_dict[error_tuple[0]] = error_tuple[1]
return redirect(url_for('slideshow_content_list', **route_args_dict))
def delete_content_by_id(self, id):
content = self._model_store.content().get(id)
if not content:
return None
if self._model_store.slide().count_slides_for_content(content.id) > 0:
return 'referenced_in_slide_error', content.name
self._model_store.content().delete(content.id)
self._post_update()
return None
def delete_folder_by_id(self, id):
folder = self._model_store.folder().get(id)
if not folder:
return None
content_counter = self._model_store.content().count_contents_for_folder(folder.id)
folder_counter = self._model_store.folder().count_subfolders_for_folder(folder.id)
if content_counter > 0 or folder_counter:
return 'folder_not_empty_error', folder.name
self._model_store.folder().delete(id=folder.id)
self._post_update()
return None
def _post_update(self):
pass