Compare commits

...

2 Commits

Author SHA1 Message Date
Ferdinand Thiessen 27a086a5c0 feat(plugins): Load metadata from entry points / distribution
ci/woodpecker/push/lint Pipeline failed Details
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/pr/lint Pipeline failed Details
ci/woodpecker/pr/test Pipeline was successful Details
2022-02-22 11:07:32 +01:00
Ferdinand Thiessen bc2fb820f0 chore(clean): Fix codestyle of config.py
ci/woodpecker/push/lint Pipeline failed Details
ci/woodpecker/push/test Pipeline was successful Details
2022-02-22 11:07:15 +01:00
13 changed files with 104 additions and 98 deletions

View File

@ -3,4 +3,4 @@ pipeline:
image: python:slim image: python:slim
commands: commands:
- pip install black - pip install black
- black --check --line-length 120 --target-version=py37 . - black --check --line-length 120 --target-version=py39 .

View File

@ -1,10 +1,10 @@
import enum import enum
import pkg_resources
from flask import Flask, current_app from flask import Flask, current_app
from flask_cors import CORS from flask_cors import CORS
from datetime import datetime, date from datetime import datetime, date
from flask.json import JSONEncoder, jsonify from flask.json import JSONEncoder, jsonify
from importlib_metadata import entry_points
from sqlalchemy.exc import OperationalError from sqlalchemy.exc import OperationalError
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
@ -41,18 +41,15 @@ def __load_plugins(app):
logger.debug("Search for plugins") logger.debug("Search for plugins")
app.config["FG_PLUGINS"] = {} app.config["FG_PLUGINS"] = {}
for entry_point in pkg_resources.iter_entry_points("flaschengeist.plugins"): for entry_point in entry_points(group="flaschengeist.plugins"):
logger.debug(f"Found plugin: >{entry_point.name}<") logger.debug(f"Found plugin: {entry_point.name} ({entry_point.dist.version})")
if entry_point.name == config["FLASCHENGEIST"]["auth"] or ( if entry_point.name == config["FLASCHENGEIST"]["auth"] or (
entry_point.name in config and config[entry_point.name].get("enabled", False) entry_point.name in config and config[entry_point.name].get("enabled", False)
): ):
logger.debug(f"Load plugin {entry_point.name}") logger.debug(f"Load plugin {entry_point.name}")
try: try:
plugin = entry_point.load() plugin = entry_point.load()(entry_point, config=config.get(entry_point.name, {}))
if not hasattr(plugin, "name"):
setattr(plugin, "name", entry_point.name)
plugin = plugin(config.get(entry_point.name, {}))
if hasattr(plugin, "blueprint") and plugin.blueprint is not None: if hasattr(plugin, "blueprint") and plugin.blueprint is not None:
app.register_blueprint(plugin.blueprint) app.register_blueprint(plugin.blueprint)
except: except:

View File

@ -1,6 +1,7 @@
import pkg_resources from importlib_metadata import Distribution, EntryPoint
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from werkzeug.exceptions import MethodNotAllowed, NotFound from werkzeug.exceptions import MethodNotAllowed, NotFound
from flaschengeist.models.user import _Avatar, User from flaschengeist.models.user import _Avatar, User
from flaschengeist.utils.hook import HookBefore, HookAfter from flaschengeist.utils.hook import HookBefore, HookAfter
@ -45,31 +46,43 @@ Args:
class Plugin: class Plugin:
"""Base class for all Plugins """Base class for all Plugins
If your class uses custom models add a static property called ``models``"""
blueprint = None # You have to override If your class uses custom models add a static property called ``models``.
"""Override with a `flask.blueprint` if the plugin uses custom routes""" """
permissions = [] # You have to override
"""Override to add custom permissions used by the plugin name: str
"""Name of the plugin, loaded from EntryPoint"""
version: str
"""Version of the plugin, loaded from Distribution"""
dist: Distribution
"""Distribution of this plugin"""
blueprint = None
"""Optional `flask.blueprint` if the plugin uses custom routes"""
permissions: list[str] = []
"""Optional list of custom permissions used by the plugin
A good style is to name the permissions with a prefix related to the plugin name, A good style is to name the permissions with a prefix related to the plugin name,
to prevent clashes with other plugins. E. g. instead of *delete* use *plugin_delete*. to prevent clashes with other plugins. E. g. instead of *delete* use *plugin_delete*.
""" """
id = "dev.flaschengeist.plugin" # You have to override
"""Override with the unique ID of the plugin (Hint: FQN)"""
name = "plugin" # You have to override
"""Override with human readable name of the plugin"""
models = None # You have to override
"""Override with models module"""
migrations_path = None # Override this with the location of your db migrations directory
"""Override with path to migration files, if custome db tables are used"""
def __init__(self, config=None): models = None
"""Optional module containing the SQLAlchemy models used by the plugin"""
migrations_path = None
"""Optional location of the path to migration files, required if custome db tables are used"""
def __init__(self, entry_point: EntryPoint, config=None):
"""Constructor called by create_app """Constructor called by create_app
Args: Args:
config: Dict configuration containing the plugin section config: Dict configuration containing the plugin section
""" """
self.version = pkg_resources.get_distribution(self.__module__.split(".")[0]).version self.version = entry_point.dist.version
self.name = entry_point.name
self.dist = entry_point.dist
def install(self): def install(self):
"""Installation routine """Installation routine
@ -91,7 +104,7 @@ class Plugin:
""" """
from ..controller import pluginController from ..controller import pluginController
return pluginController.get_setting(self.id) return pluginController.get_setting(self.id, name, **kwargs)
def set_setting(self, name: str, value): def set_setting(self, name: str, value):
"""Save setting in database """Save setting in database

View File

@ -17,8 +17,8 @@ from flaschengeist.plugins import AuthPlugin, before_role_updated
class AuthLDAP(AuthPlugin): class AuthLDAP(AuthPlugin):
def __init__(self, config): def __init__(self, entry_point, config):
super().__init__() super().__init__(entry_point)
app.config.update( app.config.update(
LDAP_SERVER=config.get("host", "localhost"), LDAP_SERVER=config.get("host", "localhost"),
LDAP_PORT=config.get("port", 389), LDAP_PORT=config.get("port", 389),

View File

@ -56,16 +56,15 @@ def service_debit():
class BalancePlugin(Plugin): class BalancePlugin(Plugin):
name = "balance"
id = "dev.flaschengeist.balance"
blueprint = Blueprint(name, __name__)
permissions = permissions.permissions permissions = permissions.permissions
plugin: "BalancePlugin" = LocalProxy(lambda: current_app.config["FG_PLUGINS"][BalancePlugin.name]) plugin: "BalancePlugin" = LocalProxy(lambda: current_app.config["FG_PLUGINS"][BalancePlugin.name])
models = models models = models
def __init__(self, config): def __init__(self, entry_point, config):
super(BalancePlugin, self).__init__(config) super(BalancePlugin, self).__init__(entry_point, config)
from . import routes from .routes import blueprint
self.blueprint = blueprint
@plugins_loaded @plugins_loaded
def post_loaded(*args, **kwargs): def post_loaded(*args, **kwargs):

View File

@ -1,6 +1,6 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from werkzeug.exceptions import Forbidden, BadRequest from werkzeug.exceptions import Forbidden, BadRequest
from flask import request, jsonify from flask import Blueprint, request, jsonify
from flaschengeist.utils import HTTP from flaschengeist.utils import HTTP
from flaschengeist.models.session import Session from flaschengeist.models.session import Session
@ -18,7 +18,10 @@ def str2bool(string: str):
raise ValueError raise ValueError
@BalancePlugin.blueprint.route("/users/<userid>/balance/shortcuts", methods=["GET", "PUT"]) blueprint = Blueprint("balance", __package__)
@blueprint.route("/users/<userid>/balance/shortcuts", methods=["GET", "PUT"])
@login_required() @login_required()
def get_shortcuts(userid, current_session: Session): def get_shortcuts(userid, current_session: Session):
"""Get balance shortcuts of an user """Get balance shortcuts of an user
@ -50,7 +53,7 @@ def get_shortcuts(userid, current_session: Session):
return HTTP.no_content() return HTTP.no_content()
@BalancePlugin.blueprint.route("/users/<userid>/balance/limit", methods=["GET"]) @blueprint.route("/users/<userid>/balance/limit", methods=["GET"])
@login_required() @login_required()
def get_limit(userid, current_session: Session): def get_limit(userid, current_session: Session):
"""Get limit of an user """Get limit of an user
@ -73,7 +76,7 @@ def get_limit(userid, current_session: Session):
return {"limit": balance_controller.get_limit(user)} return {"limit": balance_controller.get_limit(user)}
@BalancePlugin.blueprint.route("/users/<userid>/balance/limit", methods=["PUT"]) @blueprint.route("/users/<userid>/balance/limit", methods=["PUT"])
@login_required(permissions.SET_LIMIT) @login_required(permissions.SET_LIMIT)
def set_limit(userid, current_session: Session): def set_limit(userid, current_session: Session):
"""Set the limit of an user """Set the limit of an user
@ -99,7 +102,7 @@ def set_limit(userid, current_session: Session):
return HTTP.no_content() return HTTP.no_content()
@BalancePlugin.blueprint.route("/users/balance/limit", methods=["GET", "PUT"]) @blueprint.route("/users/balance/limit", methods=["GET", "PUT"])
@login_required(permission=permissions.SET_LIMIT) @login_required(permission=permissions.SET_LIMIT)
def limits(current_session: Session): def limits(current_session: Session):
"""Get, Modify limit of all users """Get, Modify limit of all users
@ -124,7 +127,7 @@ def limits(current_session: Session):
return HTTP.no_content() return HTTP.no_content()
@BalancePlugin.blueprint.route("/users/<userid>/balance", methods=["GET"]) @blueprint.route("/users/<userid>/balance", methods=["GET"])
@login_required(permission=permissions.SHOW) @login_required(permission=permissions.SHOW)
def get_balance(userid, current_session: Session): def get_balance(userid, current_session: Session):
"""Get balance of user, optionally filtered """Get balance of user, optionally filtered
@ -162,7 +165,7 @@ def get_balance(userid, current_session: Session):
return {"credit": balance[0], "debit": balance[1], "balance": balance[2]} return {"credit": balance[0], "debit": balance[1], "balance": balance[2]}
@BalancePlugin.blueprint.route("/users/<userid>/balance/transactions", methods=["GET"]) @blueprint.route("/users/<userid>/balance/transactions", methods=["GET"])
@login_required(permission=permissions.SHOW) @login_required(permission=permissions.SHOW)
def get_transactions(userid, current_session: Session): def get_transactions(userid, current_session: Session):
"""Get transactions of user, optionally filtered """Get transactions of user, optionally filtered
@ -223,7 +226,7 @@ def get_transactions(userid, current_session: Session):
return {"transactions": transactions, "count": count} return {"transactions": transactions, "count": count}
@BalancePlugin.blueprint.route("/users/<userid>/balance", methods=["PUT"]) @blueprint.route("/users/<userid>/balance", methods=["PUT"])
@login_required() @login_required()
def change_balance(userid, current_session: Session): def change_balance(userid, current_session: Session):
"""Change balance of an user """Change balance of an user
@ -272,7 +275,7 @@ def change_balance(userid, current_session: Session):
raise Forbidden raise Forbidden
@BalancePlugin.blueprint.route("/balance/<int:transaction_id>", methods=["DELETE"]) @blueprint.route("/balance/<int:transaction_id>", methods=["DELETE"])
@login_required() @login_required()
def reverse_transaction(transaction_id, current_session: Session): def reverse_transaction(transaction_id, current_session: Session):
"""Reverse a transaction """Reverse a transaction
@ -297,7 +300,7 @@ def reverse_transaction(transaction_id, current_session: Session):
raise Forbidden raise Forbidden
@BalancePlugin.blueprint.route("/balance", methods=["GET"]) @blueprint.route("/balance", methods=["GET"])
@login_required(permission=permissions.SHOW_OTHER) @login_required(permission=permissions.SHOW_OTHER)
def get_balances(current_session: Session): def get_balances(current_session: Session):
"""Get all balances """Get all balances

View File

@ -12,8 +12,8 @@ from . import Plugin
class MailMessagePlugin(Plugin): class MailMessagePlugin(Plugin):
def __init__(self, config): def __init__(self, entry_point, config):
super().__init__() super().__init__(entry_point)
self.server = config["SERVER"] self.server = config["SERVER"]
self.port = config["PORT"] self.port = config["PORT"]
self.user = config["USER"] self.user = config["USER"]

View File

@ -15,21 +15,23 @@ from . import models
from . import pricelist_controller, permissions from . import pricelist_controller, permissions
blueprint = Blueprint("pricelist", __name__, url_prefix="/pricelist")
class PriceListPlugin(Plugin): class PriceListPlugin(Plugin):
name = "pricelist"
permissions = permissions.permissions permissions = permissions.permissions
blueprint = Blueprint(name, __name__, url_prefix="/pricelist")
plugin = LocalProxy(lambda: current_app.config["FG_PLUGINS"][PriceListPlugin.name]) plugin = LocalProxy(lambda: current_app.config["FG_PLUGINS"][PriceListPlugin.name])
models = models models = models
def __init__(self, cfg): def __init__(self, entry_point, config=None):
super().__init__(cfg) super().__init__(entry_point, config)
self.blueprint = blueprint
config = {"discount": 0} config = {"discount": 0}
config.update(cfg) config.update(config)
@PriceListPlugin.blueprint.route("/drink-types", methods=["GET"]) @blueprint.route("/drink-types", methods=["GET"])
@PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["GET"]) @blueprint.route("/drink-types/<int:identifier>", methods=["GET"])
def get_drink_types(identifier=None): def get_drink_types(identifier=None):
"""Get DrinkType(s) """Get DrinkType(s)
@ -49,7 +51,7 @@ def get_drink_types(identifier=None):
return jsonify(result) return jsonify(result)
@PriceListPlugin.blueprint.route("/drink-types", methods=["POST"]) @blueprint.route("/drink-types", methods=["POST"])
@login_required(permission=permissions.CREATE_TYPE) @login_required(permission=permissions.CREATE_TYPE)
def new_drink_type(current_session): def new_drink_type(current_session):
"""Create new DrinkType """Create new DrinkType
@ -71,7 +73,7 @@ def new_drink_type(current_session):
return jsonify(drink_type) return jsonify(drink_type)
@PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["PUT"]) @blueprint.route("/drink-types/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_TYPE) @login_required(permission=permissions.EDIT_TYPE)
def update_drink_type(identifier, current_session): def update_drink_type(identifier, current_session):
"""Modify DrinkType """Modify DrinkType
@ -94,7 +96,7 @@ def update_drink_type(identifier, current_session):
return jsonify(drink_type) return jsonify(drink_type)
@PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["DELETE"]) @blueprint.route("/drink-types/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_TYPE) @login_required(permission=permissions.DELETE_TYPE)
def delete_drink_type(identifier, current_session): def delete_drink_type(identifier, current_session):
"""Delete DrinkType """Delete DrinkType
@ -112,8 +114,8 @@ def delete_drink_type(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/tags", methods=["GET"]) @blueprint.route("/tags", methods=["GET"])
@PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["GET"]) @blueprint.route("/tags/<int:identifier>", methods=["GET"])
def get_tags(identifier=None): def get_tags(identifier=None):
"""Get Tag(s) """Get Tag(s)
@ -133,7 +135,7 @@ def get_tags(identifier=None):
return jsonify(result) return jsonify(result)
@PriceListPlugin.blueprint.route("/tags", methods=["POST"]) @blueprint.route("/tags", methods=["POST"])
@login_required(permission=permissions.CREATE_TAG) @login_required(permission=permissions.CREATE_TAG)
def new_tag(current_session): def new_tag(current_session):
"""Create Tag """Create Tag
@ -153,7 +155,7 @@ def new_tag(current_session):
return jsonify(drink_type) return jsonify(drink_type)
@PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["PUT"]) @blueprint.route("/tags/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_TAG) @login_required(permission=permissions.EDIT_TAG)
def update_tag(identifier, current_session): def update_tag(identifier, current_session):
"""Modify Tag """Modify Tag
@ -174,7 +176,7 @@ def update_tag(identifier, current_session):
return jsonify(tag) return jsonify(tag)
@PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["DELETE"]) @blueprint.route("/tags/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_TAG) @login_required(permission=permissions.DELETE_TAG)
def delete_tag(identifier, current_session): def delete_tag(identifier, current_session):
"""Delete Tag """Delete Tag
@ -192,8 +194,8 @@ def delete_tag(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/drinks", methods=["GET"]) @blueprint.route("/drinks", methods=["GET"])
@PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["GET"]) @blueprint.route("/drinks/<int:identifier>", methods=["GET"])
def get_drinks(identifier=None): def get_drinks(identifier=None):
"""Get Drink(s) """Get Drink(s)
@ -249,7 +251,7 @@ def get_drinks(identifier=None):
return jsonify({"drinks": drinks, "count": count}) return jsonify({"drinks": drinks, "count": count})
@PriceListPlugin.blueprint.route("/list", methods=["GET"]) @blueprint.route("/list", methods=["GET"])
def get_pricelist(): def get_pricelist():
"""Get Priclist """Get Priclist
Route: ``/pricelist/list`` | Method: ``GET`` Route: ``/pricelist/list`` | Method: ``GET``
@ -298,7 +300,7 @@ def get_pricelist():
return jsonify({"pricelist": pricelist, "count": count}) return jsonify({"pricelist": pricelist, "count": count})
@PriceListPlugin.blueprint.route("/drinks/search/<string:name>", methods=["GET"]) @blueprint.route("/drinks/search/<string:name>", methods=["GET"])
def search_drinks(name): def search_drinks(name):
"""Search Drink """Search Drink
@ -319,7 +321,7 @@ def search_drinks(name):
return jsonify(pricelist_controller.get_drinks(name, public=public)) return jsonify(pricelist_controller.get_drinks(name, public=public))
@PriceListPlugin.blueprint.route("/drinks", methods=["POST"]) @blueprint.route("/drinks", methods=["POST"])
@login_required(permission=permissions.CREATE) @login_required(permission=permissions.CREATE)
def create_drink(current_session): def create_drink(current_session):
"""Create Drink """Create Drink
@ -371,7 +373,7 @@ def create_drink(current_session):
return jsonify(pricelist_controller.set_drink(data)) return jsonify(pricelist_controller.set_drink(data))
@PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["PUT"]) @blueprint.route("/drinks/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT) @login_required(permission=permissions.EDIT)
def update_drink(identifier, current_session): def update_drink(identifier, current_session):
"""Modify Drink """Modify Drink
@ -425,7 +427,7 @@ def update_drink(identifier, current_session):
return jsonify(pricelist_controller.update_drink(identifier, data)) return jsonify(pricelist_controller.update_drink(identifier, data))
@PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["DELETE"]) @blueprint.route("/drinks/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE) @login_required(permission=permissions.DELETE)
def delete_drink(identifier, current_session): def delete_drink(identifier, current_session):
"""Delete Drink """Delete Drink
@ -443,7 +445,7 @@ def delete_drink(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/prices/<int:identifier>", methods=["DELETE"]) @blueprint.route("/prices/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_PRICE) @login_required(permission=permissions.DELETE_PRICE)
def delete_price(identifier, current_session): def delete_price(identifier, current_session):
"""Delete Price """Delete Price
@ -461,7 +463,7 @@ def delete_price(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/volumes/<int:identifier>", methods=["DELETE"]) @blueprint.route("/volumes/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_VOLUME) @login_required(permission=permissions.DELETE_VOLUME)
def delete_volume(identifier, current_session): def delete_volume(identifier, current_session):
"""Delete DrinkPriceVolume """Delete DrinkPriceVolume
@ -479,7 +481,7 @@ def delete_volume(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/ingredients/extraIngredients", methods=["GET"]) @blueprint.route("/ingredients/extraIngredients", methods=["GET"])
@login_required() @login_required()
def get_extra_ingredients(current_session): def get_extra_ingredients(current_session):
"""Get ExtraIngredients """Get ExtraIngredients
@ -495,7 +497,7 @@ def get_extra_ingredients(current_session):
return jsonify(pricelist_controller.get_extra_ingredients()) return jsonify(pricelist_controller.get_extra_ingredients())
@PriceListPlugin.blueprint.route("/ingredients/<int:identifier>", methods=["DELETE"]) @blueprint.route("/ingredients/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_INGREDIENTS_DRINK) @login_required(permission=permissions.DELETE_INGREDIENTS_DRINK)
def delete_ingredient(identifier, current_session): def delete_ingredient(identifier, current_session):
"""Delete Ingredient """Delete Ingredient
@ -513,7 +515,7 @@ def delete_ingredient(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/ingredients/extraIngredients", methods=["POST"]) @blueprint.route("/ingredients/extraIngredients", methods=["POST"])
@login_required(permission=permissions.EDIT_INGREDIENTS) @login_required(permission=permissions.EDIT_INGREDIENTS)
def set_extra_ingredient(current_session): def set_extra_ingredient(current_session):
"""Create ExtraIngredient """Create ExtraIngredient
@ -532,7 +534,7 @@ def set_extra_ingredient(current_session):
return jsonify(pricelist_controller.set_extra_ingredient(data)) return jsonify(pricelist_controller.set_extra_ingredient(data))
@PriceListPlugin.blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["PUT"]) @blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_INGREDIENTS) @login_required(permission=permissions.EDIT_INGREDIENTS)
def update_extra_ingredient(identifier, current_session): def update_extra_ingredient(identifier, current_session):
"""Modify ExtraIngredient """Modify ExtraIngredient
@ -552,7 +554,7 @@ def update_extra_ingredient(identifier, current_session):
return jsonify(pricelist_controller.update_extra_ingredient(identifier, data)) return jsonify(pricelist_controller.update_extra_ingredient(identifier, data))
@PriceListPlugin.blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["DELETE"]) @blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_INGREDIENTS) @login_required(permission=permissions.DELETE_INGREDIENTS)
def delete_extra_ingredient(identifier, current_session): def delete_extra_ingredient(identifier, current_session):
"""Delete ExtraIngredient """Delete ExtraIngredient
@ -570,7 +572,7 @@ def delete_extra_ingredient(identifier, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/settings/min_prices", methods=["GET"]) @blueprint.route("/settings/min_prices", methods=["GET"])
@login_required() @login_required()
def get_pricelist_settings_min_prices(current_session): def get_pricelist_settings_min_prices(current_session):
"""Get MinPrices """Get MinPrices
@ -591,7 +593,7 @@ def get_pricelist_settings_min_prices(current_session):
return jsonify(min_prices) return jsonify(min_prices)
@PriceListPlugin.blueprint.route("/settings/min_prices", methods=["POST"]) @blueprint.route("/settings/min_prices", methods=["POST"])
@login_required(permission=permissions.EDIT_MIN_PRICES) @login_required(permission=permissions.EDIT_MIN_PRICES)
def post_pricelist_settings_min_prices(current_session): def post_pricelist_settings_min_prices(current_session):
"""Create MinPrices """Create MinPrices
@ -614,7 +616,7 @@ def post_pricelist_settings_min_prices(current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/users/<userid>/pricecalc_columns", methods=["GET", "PUT"]) @blueprint.route("/users/<userid>/pricecalc_columns", methods=["GET", "PUT"])
@login_required() @login_required()
def get_columns(userid, current_session): def get_columns(userid, current_session):
"""Get pricecalc_columns of an user """Get pricecalc_columns of an user
@ -646,7 +648,7 @@ def get_columns(userid, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/users/<userid>/pricecalc_columns_order", methods=["GET", "PUT"]) @blueprint.route("/users/<userid>/pricecalc_columns_order", methods=["GET", "PUT"])
@login_required() @login_required()
def get_columns_order(userid, current_session): def get_columns_order(userid, current_session):
"""Get pricecalc_columns_order of an user """Get pricecalc_columns_order of an user
@ -677,7 +679,7 @@ def get_columns_order(userid, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/users/<userid>/pricelist", methods=["GET", "PUT"]) @blueprint.route("/users/<userid>/pricelist", methods=["GET", "PUT"])
@login_required() @login_required()
def get_priclist_setting(userid, current_session): def get_priclist_setting(userid, current_session):
"""Get pricelistsetting of an user """Get pricelistsetting of an user
@ -710,7 +712,7 @@ def get_priclist_setting(userid, current_session):
return no_content() return no_content()
@PriceListPlugin.blueprint.route("/drinks/<int:identifier>/picture", methods=["POST", "DELETE"]) @blueprint.route("/drinks/<int:identifier>/picture", methods=["POST", "DELETE"])
@login_required(permission=permissions.EDIT) @login_required(permission=permissions.EDIT)
def set_picture(identifier, current_session): def set_picture(identifier, current_session):
"""Get, Create, Delete Drink Picture """Get, Create, Delete Drink Picture
@ -737,7 +739,7 @@ def set_picture(identifier, current_session):
raise BadRequest raise BadRequest
@PriceListPlugin.blueprint.route("/drinks/<int:identifier>/picture", methods=["GET"]) @blueprint.route("/drinks/<int:identifier>/picture", methods=["GET"])
# @headers({"Cache-Control": "private, must-revalidate"}) # @headers({"Cache-Control": "private, must-revalidate"})
def _get_picture(identifier): def _get_picture(identifier):
"""Get Picture """Get Picture

View File

@ -16,8 +16,7 @@ from . import permissions
class RolesPlugin(Plugin): class RolesPlugin(Plugin):
name = "roles" blueprint = Blueprint("roles", __name__)
blueprint = Blueprint(name, __name__)
permissions = permissions.permissions permissions = permissions.permissions

View File

@ -1,6 +1,5 @@
import pkg_resources
from datetime import datetime, timedelta
from flask import Blueprint from flask import Blueprint
from datetime import datetime, timedelta
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.utils.HTTP import no_content from flaschengeist.utils.HTTP import no_content
@ -40,15 +39,9 @@ def scheduled(id: str, replace=False, **kwargs):
class SchedulerPlugin(Plugin): class SchedulerPlugin(Plugin):
id = "dev.flaschengeist.scheduler" def __init__(self, entry_point, config=None):
name = "scheduler" super().__init__(entry_point, config)
blueprint = Blueprint(name, __name__) self.blueprint = Blueprint(self.name, __name__)
def __init__(self, config=None):
"""Constructor called by create_app
Args:
config: Dict configuration containing the plugin section
"""
def __view_func(): def __view_func():
self.run_tasks() self.run_tasks()
@ -60,7 +53,6 @@ class SchedulerPlugin(Plugin):
except: except:
logger.error("Error while executing scheduled tasks!", exc_info=True) logger.error("Error while executing scheduled tasks!", exc_info=True)
self.version = pkg_resources.get_distribution(self.__module__.split(".")[0]).version
cron = None if config is None else config.get("cron", "passive_web").lower() cron = None if config is None else config.get("cron", "passive_web").lower()
if cron is None or cron == "passive_web": if cron is None or cron == "passive_web":

View File

@ -18,8 +18,7 @@ from flaschengeist.utils.datetime import from_iso_format
class UsersPlugin(Plugin): class UsersPlugin(Plugin):
name = "users" blueprint = Blueprint("users", __name__)
blueprint = Blueprint(name, __name__)
permissions = permissions.permissions permissions = permissions.permissions

View File

@ -26,6 +26,8 @@ install_requires =
Pillow>=8.4.0 Pillow>=8.4.0
flask_cors flask_cors
flask_sqlalchemy>=2.5 flask_sqlalchemy>=2.5
# Importlib requirement can be dropped when python requirement is >= 3.10
importlib_metadata>=4.3
sqlalchemy>=1.4.26 sqlalchemy>=1.4.26
toml toml
werkzeug werkzeug