Compare commits
1 Commits
e4c552af01
...
12b0bf55f8
Author | SHA1 | Date |
---|---|---|
Ferdinand Thiessen | 12b0bf55f8 |
|
@ -17,3 +17,5 @@ matrix:
|
|||
PYTHON:
|
||||
- 3.10
|
||||
- 3.9
|
||||
- 3.8
|
||||
- 3.7
|
||||
|
|
19
README.md
19
README.md
|
@ -7,29 +7,20 @@ This is the backend of the Flaschengeist.
|
|||
### Requirements
|
||||
- `mysql` or `mariadb`
|
||||
- maybe `libmariadb` development files[1]
|
||||
- python 3.9+
|
||||
- pip 21.0+
|
||||
- python 3.7+
|
||||
|
||||
*[1] By default Flaschengeist uses mysql as database backend, if you are on Windows Flaschengeist uses `PyMySQL`, but on
|
||||
[1] By default Flaschengeist uses mysql as database backend, if you are on Windows Flaschengeist uses `PyMySQL`, but on
|
||||
Linux / Mac the faster `mysqlclient` is used, if it is not already installed installing from pypi requires the
|
||||
development files for `libmariadb` to be present on your system.*
|
||||
development files for `libmariadb` to be present on your system.
|
||||
|
||||
### Install python files
|
||||
It is recommended to upgrade pip to the latest version before installing:
|
||||
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
Default installation with *mariadb*/*mysql* support:
|
||||
|
||||
pip3 install --user ".[mysql]"
|
||||
|
||||
pip3 install --user .
|
||||
or with ldap support
|
||||
|
||||
pip3 install --user ".[ldap]"
|
||||
|
||||
or if you want to also run the tests:
|
||||
|
||||
pip3 install --user ".[ldap,tests]"
|
||||
pip3 install --user ".[ldap,test]"
|
||||
|
||||
You will also need a MySQL driver, recommended drivers are
|
||||
- `mysqlclient`
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
"""Controller for Plugin logic
|
||||
|
||||
Used by plugins for setting and notification functionality.
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
from ..database import db
|
||||
from ..models.setting import _PluginSetting
|
||||
from ..models.notification import Notification
|
||||
|
||||
|
||||
def get_setting(plugin_id: str, name: str, **kwargs):
|
||||
"""Get plugin setting from database
|
||||
|
||||
Args:
|
||||
plugin_id: ID of the plugin
|
||||
name: string identifying the setting
|
||||
default: Default value
|
||||
Returns:
|
||||
Value stored in database (native python)
|
||||
Raises:
|
||||
`KeyError` if no such setting exists in the database
|
||||
"""
|
||||
try:
|
||||
setting = (
|
||||
_PluginSetting.query.filter(_PluginSetting.plugin == plugin_id).filter(_PluginSetting.name == name).one()
|
||||
)
|
||||
return setting.value
|
||||
except sqlalchemy.orm.exc.NoResultFound:
|
||||
if "default" in kwargs:
|
||||
return kwargs["default"]
|
||||
else:
|
||||
raise KeyError
|
||||
|
||||
|
||||
def set_setting(plugin_id: str, name: str, value):
|
||||
"""Save setting in database
|
||||
|
||||
Args:
|
||||
plugin_id: ID of the plugin
|
||||
name: String identifying the setting
|
||||
value: Value to be stored
|
||||
"""
|
||||
setting = (
|
||||
_PluginSetting.query.filter(_PluginSetting.plugin == plugin_id)
|
||||
.filter(_PluginSetting.name == name)
|
||||
.one_or_none()
|
||||
)
|
||||
if setting is not None:
|
||||
if value is None:
|
||||
db.session.delete(setting)
|
||||
else:
|
||||
setting.value = value
|
||||
else:
|
||||
db.session.add(_PluginSetting(plugin=plugin_id, name=name, value=value))
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def notify(plugin_id: str, user, text: str, data=None):
|
||||
"""Create a new notification for an user
|
||||
|
||||
Args:
|
||||
plugin_id: ID of the plugin
|
||||
user: `flaschengeist.models.user.User` to notify
|
||||
text: Visibile notification text
|
||||
data: Optional data passed to the notificaton
|
||||
Returns:
|
||||
ID of the created `flaschengeist.models.notification.Notification`
|
||||
|
||||
Hint: use the data for frontend actions.
|
||||
"""
|
||||
if not user.deleted:
|
||||
n = Notification(text=text, data=data, plugin=plugin_id, user_=user)
|
||||
db.session.add(n)
|
||||
db.session.commit()
|
||||
return n.id
|
|
@ -1,9 +1,13 @@
|
|||
from flask import Blueprint
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from flask import Blueprint
|
||||
from werkzeug.datastructures import FileStorage
|
||||
from werkzeug.exceptions import MethodNotAllowed, NotFound
|
||||
|
||||
from flaschengeist.database import db
|
||||
from flaschengeist.controller import imageController
|
||||
from flaschengeist.models.notification import Notification
|
||||
from flaschengeist.models.user import _Avatar, User
|
||||
from flaschengeist.models.setting import _PluginSetting
|
||||
from flaschengeist.utils.hook import HookBefore, HookAfter
|
||||
|
||||
plugins_installed = HookAfter("plugins.installed")
|
||||
|
@ -129,9 +133,18 @@ class Plugin(PluginMetadata):
|
|||
Raises:
|
||||
`KeyError` if no such setting exists in the database
|
||||
"""
|
||||
from ..controller import pluginController
|
||||
|
||||
return pluginController.get_setting(self.id)
|
||||
try:
|
||||
setting = (
|
||||
_PluginSetting.query.filter(_PluginSetting.plugin == self.name)
|
||||
.filter(_PluginSetting.name == name)
|
||||
.one()
|
||||
)
|
||||
return setting.value
|
||||
except sqlalchemy.orm.exc.NoResultFound:
|
||||
if "default" in kwargs:
|
||||
return kwargs["default"]
|
||||
else:
|
||||
raise KeyError
|
||||
|
||||
def set_setting(self, name: str, value):
|
||||
"""Save setting in database
|
||||
|
@ -140,9 +153,19 @@ class Plugin(PluginMetadata):
|
|||
name: String identifying the setting
|
||||
value: Value to be stored
|
||||
"""
|
||||
from ..controller import pluginController
|
||||
|
||||
return pluginController.set_setting(self.id, name, value)
|
||||
setting = (
|
||||
_PluginSetting.query.filter(_PluginSetting.plugin == self.name)
|
||||
.filter(_PluginSetting.name == name)
|
||||
.one_or_none()
|
||||
)
|
||||
if setting is not None:
|
||||
if value is None:
|
||||
db.session.delete(setting)
|
||||
else:
|
||||
setting.value = value
|
||||
else:
|
||||
db.session.add(_PluginSetting(plugin=self.name, name=name, value=value))
|
||||
db.session.commit()
|
||||
|
||||
def notify(self, user, text: str, data=None):
|
||||
"""Create a new notification for an user
|
||||
|
@ -156,9 +179,11 @@ class Plugin(PluginMetadata):
|
|||
|
||||
Hint: use the data for frontend actions.
|
||||
"""
|
||||
from ..controller import pluginController
|
||||
|
||||
return pluginController.notify(self.id, user, text, data)
|
||||
if not user.deleted:
|
||||
n = Notification(text=text, data=data, plugin=self.id, user_=user)
|
||||
db.session.add(n)
|
||||
db.session.commit()
|
||||
return n.id
|
||||
|
||||
def serialize(self):
|
||||
"""Serialize a plugin into a dict
|
||||
|
@ -258,10 +283,6 @@ class AuthPlugin(Plugin):
|
|||
MethodNotAllowed: If not supported by Backend
|
||||
Any valid HTTP exception
|
||||
"""
|
||||
# By default save the image to the avatar,
|
||||
# deleting would happen by unsetting it
|
||||
from ..controller import imageController
|
||||
|
||||
user.avatar_ = imageController.upload_image(file)
|
||||
|
||||
def delete_avatar(self, user: User):
|
||||
|
|
Loading…
Reference in New Issue