models.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.management.models
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~
  5. This module contains all management related models.
  6. :copyright: (c) 2014 by the FlaskBB Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. import logging
  10. from flask_wtf import FlaskForm
  11. from flaskbb._compat import iteritems, text_type
  12. from flaskbb.extensions import cache, db
  13. from flaskbb.utils.database import CRUDMixin
  14. from flaskbb.utils.forms import SettingValueType, generate_settings_form
  15. from wtforms import (BooleanField, FloatField, IntegerField, SelectField,
  16. SelectMultipleField, TextField, validators)
  17. logger = logging.getLogger(__name__)
  18. class SettingsGroup(db.Model, CRUDMixin):
  19. __tablename__ = "settingsgroup"
  20. key = db.Column(db.String(255), primary_key=True)
  21. name = db.Column(db.String(255), nullable=False)
  22. description = db.Column(db.Text, nullable=False)
  23. settings = db.relationship("Setting", lazy="dynamic", backref="group",
  24. cascade="all, delete-orphan")
  25. def __repr__(self):
  26. return "<{} {}>".format(self.__class__.__name__, self.key)
  27. class Setting(db.Model, CRUDMixin):
  28. __tablename__ = "settings"
  29. key = db.Column(db.String(255), primary_key=True)
  30. value = db.Column(db.PickleType, nullable=False)
  31. settingsgroup = db.Column(db.String(255),
  32. db.ForeignKey('settingsgroup.key',
  33. use_alter=True,
  34. name="fk_settingsgroup"),
  35. nullable=False)
  36. # The name (displayed in the form)
  37. name = db.Column(db.String(200), nullable=False)
  38. # The description (displayed in the form)
  39. description = db.Column(db.Text, nullable=False)
  40. # Available types: string, integer, float, boolean, select, selectmultiple
  41. value_type = db.Column(db.Enum(SettingValueType), nullable=False)
  42. # Extra attributes like, validation things (min, max length...)
  43. # For Select*Fields required: choices
  44. extra = db.Column(db.PickleType)
  45. @classmethod
  46. def get_form(cls, group):
  47. """Returns a Form for all settings found in :class:`SettingsGroup`.
  48. :param group: The settingsgroup name. It is used to get the settings
  49. which are in the specified group.
  50. """
  51. return generate_settings_form(settings=group.settings)
  52. @classmethod
  53. def get_all(cls):
  54. return cls.query.all()
  55. @classmethod
  56. def update(cls, settings, app=None):
  57. """Updates the cache and stores the changes in the
  58. database.
  59. :param settings: A dictionary with setting items.
  60. """
  61. # update the database
  62. for key, value in iteritems(settings):
  63. setting = cls.query.filter(Setting.key == key.lower()).first()
  64. setting.value = value
  65. db.session.add(setting)
  66. db.session.commit()
  67. cls.invalidate_cache()
  68. @classmethod
  69. def get_settings(cls, from_group=None):
  70. """This will return all settings with the key as the key for the dict
  71. and the values are packed again in a dict which contains
  72. the remaining attributes.
  73. :param from_group: Optionally - Returns only the settings from a group.
  74. """
  75. result = None
  76. if from_group is not None:
  77. result = from_group.settings
  78. else:
  79. result = cls.query.all()
  80. settings = {}
  81. for setting in result:
  82. settings[setting.key] = setting.value
  83. return settings
  84. @classmethod
  85. @cache.cached(key_prefix="settings")
  86. def as_dict(cls, from_group=None, upper=True):
  87. """Returns all settings as a dict. This method is cached. If you want
  88. to invalidate the cache, simply execute ``self.invalidate_cache()``.
  89. :param from_group: Returns only the settings from the group as a dict.
  90. :param upper: If upper is ``True``, the key will use upper-case
  91. letters. Defaults to ``False``.
  92. """
  93. settings = {}
  94. result = None
  95. if from_group is not None:
  96. result = SettingsGroup.query.filter_by(key=from_group).\
  97. first_or_404()
  98. result = result.settings
  99. else:
  100. result = cls.query.all()
  101. for setting in result:
  102. if upper:
  103. setting_key = setting.key.upper()
  104. else:
  105. setting_key = setting.key
  106. settings[setting_key] = setting.value
  107. return settings
  108. @classmethod
  109. def invalidate_cache(cls):
  110. """Invalidates this objects cached metadata."""
  111. cache.delete_memoized(cls.as_dict, cls)