models.py 4.4 KB

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