This commit is contained in:
grimhilt 2023-09-14 23:21:02 +02:00
parent 17460f937f
commit 88e3f0280d
10 changed files with 145 additions and 36 deletions

View File

@ -3,20 +3,36 @@
# Deployment (from source)
- ``git clone https://github.com/grimhilt/artemio-server.git``
-
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
sudo apt install libjpeg-dev zlib1g-dev
pip install Pillow
sudo apt install libmpv-dev
gunicorn -w 1 -b 0.0.0.0:5500 index:api --access-logfile access.log --error-logfile error.log
# Documentation
## API
/api/login
/api/logout
### Permissions
| Name | Child Of | Description
| --- | --- | ---
CREATE_USER |
CREATE_ROLE |
CREATE_PLAYLIST |
VIEW_PLAYLIST | EDIT_PLAYLIST
OWN_PLAYLIST |
EDIT_PLAYLIST | OWN_PLAYLIST
ACTIVATE_PLAYLIST |
### Playlists (*/api/playlists*)
The user need to be logged in for every routes
*The user need to be logged in for every routes.*
| Method | Endpoint | Permission | Description
| --- | --- | --- | --- |
@ -26,13 +42,24 @@ The user need to be logged in for every routes
| POST | ``/api/playlists/:id`` | EDIT_PLAYLIST | Add file to playlist
| POST | ``/api/playlists/:id/order`` | EDIT_PLAYLIST | Change file order
| POST | ``/api/playlists/:id/seconds`` | EDIT_PLAYLIST | Change display time of a file
| POST | ``/api/playlists/:id/remove_file`` | EDIT_PLAYLIST |
| PUT | ``/api/playlists/:id/update`` | OWN_PLAYLIST |
| POST | ``/api/playlists/:id/remove_file`` | EDIT_PLAYLIST | Remove file from the playlist
| PUT | ``/api/playlists/:id/update`` | OWN_PLAYLIST | Update properties of the playlist
| POST | ``/api/playlists/:id/activate`` | ACTIVATE_PLAYLIST |
| POST | ``/api/playlists/:id/disactivate`` | ACTIVATE_PLAYLIST |
### Users
### Playlists (*/api/playlists*)
*The user need to be logged in for every routes.*
| Method | Endpoint | Permission | Description
| --- | --- | --- | --- |
| GET | ``/api/files`` | EDIT_PLAYLIST | List all existing files
| GET | ``/api/files/:id`` | VIEW_PLAYLIST | Return the file
| POST | ``/api/files/upload`` | EDIT_PLAYLIST | Upload one or multiple files
| DELETE | ``/api/files/:id`` | OWN_PLAYLIST | Delete the file
### Roles
###
### Files

View File

@ -1,13 +1,13 @@
from flask import Blueprint, request, jsonify
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.security import check_password_hash
from flask_login import current_user
from ..models import User, Role
from api.dao.UsersDao import UsersDao
from .. import db
def is_current_admin():
return current_user.as_dict()['roles'][0]['parent_id'] is None
class UserAbl:
@staticmethod
@ -27,30 +27,14 @@ class UserAbl:
if bit == '1' and bit != user_perms[position]:
return jsonify(message="You don't have the permission to give permission(s) you don't have"), 403
# create the user
new_user = User(
login=login,
password=generate_password_hash(password, method='sha256')
)
db.session.add(new_user)
db.session.flush()
# create the permissions for the user
new_role = Role(
name=login,
user_id=new_user.as_dict()['id'],
parent_id=current_user.as_dict()['roles'][0]['id'],
permissions=permissions)
db.session.add(new_role)
new_user.roles.append(new_role)
db.session.flush()
# create user
new_user = UsersDao.create(login, password, permissions, current_user)
db.session.commit()
return jsonify(new_user.as_dict())
@staticmethod
def update(user_id, data):
# todo
return jsonify()
@staticmethod

View File

@ -5,7 +5,7 @@ from ..models import File
from .. import db
files = Blueprint('files', __name__)
FILE_DIR = './data/'
FILE_DIR = '../data/'
@files.route('/files', methods=['POST'])
@login_required

View File

@ -0,0 +1,15 @@
from .. import db
from ..models import User, Role, Playlist, ParentRole
class ParentRoleDao:
def get_children(role_id):
children = db.session.query(ParentRole) \
.filter(ParentRole.parent_id == role_id) \
.all()
return children
def get_parents(role_id):
parents = db.session.query(ParentRole) \
.filter(ParentRole.child_id == role_id) \
.all()
return parents

View File

@ -31,7 +31,7 @@ class PlaylistDao:
.first()
return has_role_to_view
def has_role_view_d(playlist_id, user_id):
def has_role_edit_d(playlist_id, user_id):
has_role_to_edit = db.session.query(Playlist) \
.filter(
Playlist.edit.any(

31
src/api/dao/RolesDao.py Normal file
View File

@ -0,0 +1,31 @@
from .. import db
from ..models import User, Role, Playlist, ParentRole
from .ParentRoleDao import ParentRoleDao
class RolesDao:
def create(name, user_id, parent_id, permissions):
new_role = Role(
name=name,
user_id=user_id,
parent_id=parent_id,
permissions=permissions)
db.session.add(new_role)
# get all parents
parents = ParentRoleDao.get_parents(parent_id)
parent_ids = [parent_id]
for parent in parents:
parent_ids.append(parent.as_dict()['parent_id'])
# add all parents
for id in parent_ids:
parent_role = ParentRole(
parent_id=id,
child_id=user_id
)
db.session.add(parent_role)
db.session.flush()
return new_role

View File

@ -1,7 +1,32 @@
from .. import db
from werkzeug.security import generate_password_hash, check_password_hash
from ..models import User, Role, Playlist
from .RolesDao import RolesDao
class UsersDao:
def create(login, password, permissions, current_user):
# create the user
new_user = User(
login=login,
password=generate_password_hash(password, method='sha256')
)
db.session.add(new_user)
db.session.flush()
# create role for the user
new_role = RolesDao.create(
name=login,
user_id=new_user.as_dict()['id'],
parent_id=current_user.as_dict()['roles'][0]['id'],
permissions=permissions)
new_user.roles.append(new_role)
db.session.flush()
return new_user
def has_role_view_q(user_id):
has_role_to_view = db.session.query(User) \
.filter(User.id == user_id) \
@ -23,6 +48,7 @@ class UsersDao:
return has_role_to_edit
def playlists(user_id):
# todo recursion on user parenting
playlists = db.session.query(Playlist) \
.filter(
# all playlist where user can view

View File

@ -55,16 +55,36 @@ class UserRole(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
role_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)
class ParentRole(db.Model):
__tablename__ = 'ParentRole'
parent_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)
child_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
class Role(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), default=None)
permissions = db.Column(db.Integer, default=0)
parent_id = db.Column(db.Integer, db.ForeignKey('role.id'), default=None)
children = db.relationship('Role', secondary="ParentRole",
primaryjoin=id == ParentRole.parent_id,
secondaryjoin=id == ParentRole.child_id,
backref='parents')
users = db.relationship('User', secondary='UserRole', back_populates='roles')
playlists_view = db.relationship('Playlist', secondary='PlaylistView', back_populates='view')
playlists_edit = db.relationship('Playlist', secondary='PlaylistEdit', back_populates='edit')
def as_full_dict(self):
res = self.as_dict()
res['parents'] = [parent.as_dict() for parent in self.parents]
res['children'] = [child.as_dict() for child in self.children]
return res
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
@ -76,7 +96,7 @@ class User(db.Model, UserMixin):
def as_dict(self):
res = self.as_dict_unsafe()
res['roles'] = [role.as_dict() for role in self.roles]
res['roles'] = [role.as_full_dict() for role in self.roles]
del res['password']
return res

View File

@ -1,12 +1,16 @@
from api import create_api
from screen.ScreenManager import ScreenManager
#api = create_api()
#screen_manager = ScreenManager().getInstance()
api = create_api()
screen_manager = ScreenManager().getInstance()
if __name__ == '__main__':
#api.run(host="0.0.0.0", port=5500, debug=True)
#api.run(host="0.0.0.0", port=5500)
#api.run()
api.run(host="0.0.0.0", port=5500)
def test():
from screen.SlideShow import SlideShow
import tkinter as tk
import mpv

View File

@ -7,6 +7,8 @@ import imageio
import vlc
import mpv
DATA_DIR = "../data/"
class SlideShow:
def __init__(self, root, files):
print(files)
@ -62,7 +64,7 @@ class MediaFactory:
def image_player(self):
print("image player")
path = './data/' + self.file['name']
path = DATA_DIR + self.file['name']
image = Image.open(path)
image = self.parent.resize_full_screen(image)
@ -78,7 +80,7 @@ class VideoPlayer:
def __init__(self, parent, file):
self.file = file
self.parent = parent
self.path = './data/' + self.file['name']
self.path = DATA_DIR + self.file['name']
#self.mpv_instance = mpv.MPV(wid=str(self.parent.canvas.winfo_id()))
instance = vlc.Instance()
player = instance.media_player_new()