models.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. from wtforms import (TextField, IntegerField, FloatField, BooleanField,
  2. SelectField, SelectMultipleField, validators)
  3. from flask.ext.wtf import Form
  4. from flaskbb.extensions import db
  5. class SettingsGroup(db.Model):
  6. __tablename__ = "settingsgroup"
  7. key = db.Column(db.String, primary_key=True)
  8. name = db.Column(db.String, nullable=False)
  9. description = db.Column(db.String, nullable=False)
  10. settings = db.relationship("Setting", lazy="dynamic", backref="group",
  11. cascade="all, delete-orphan")
  12. def save(self):
  13. """Saves a settingsgroup."""
  14. db.session.add(self)
  15. db.session.commit()
  16. def delete(self):
  17. """Deletes a settingsgroup."""
  18. db.session.delete(self)
  19. db.session.commit()
  20. class Setting(db.Model):
  21. __tablename__ = "settings"
  22. key = db.Column(db.String, primary_key=True)
  23. value = db.Column(db.PickleType, nullable=False)
  24. settingsgroup = db.Column(db.String,
  25. db.ForeignKey('settingsgroup.key',
  26. use_alter=True,
  27. name="fk_settingsgroup"),
  28. nullable=False)
  29. # The name (displayed in the form)
  30. name = db.Column(db.String, nullable=False)
  31. # The description (displayed in the form)
  32. description = db.Column(db.String, nullable=False)
  33. # Available types: string, integer, float, boolean, select, selectmultiple
  34. value_type = db.Column(db.String, nullable=False)
  35. # Extra attributes like, validation things (min, max length...)
  36. # For Select*Fields required: choices
  37. extra = db.Column(db.PickleType)
  38. @classmethod
  39. def get_form(cls, group):
  40. """Returns a Form for all settings found in :class:`SettingsGroup`.
  41. :param group: The settingsgroup name. It is used to get the settings
  42. which are in the specified group.
  43. """
  44. class SettingsForm(Form):
  45. pass
  46. # now parse the settings in this group
  47. for setting in group.settings:
  48. field_validators = []
  49. # generate the validators
  50. if "min" in setting.extra:
  51. # Min number validator
  52. if setting.value_type in ("integer", "float"):
  53. field_validators.append(
  54. validators.NumberRange(min=setting.extra["min"])
  55. )
  56. # Min text length validator
  57. elif setting.value_type in ("string"):
  58. field_validators.append(
  59. validators.Length(min=setting.extra["min"])
  60. )
  61. if "max" in setting.extra:
  62. # Max number validator
  63. if setting.value_type in ("integer", "float"):
  64. field_validators.append(
  65. validators.NumberRange(max=setting.extra["max"])
  66. )
  67. # Max text length validator
  68. elif setting.value_type in ("string"):
  69. field_validators.append(
  70. validators.Length(max=setting.extra["max"])
  71. )
  72. # Generate the fields based on value_type
  73. # IntegerField
  74. if setting.value_type == "integer":
  75. setattr(
  76. SettingsForm, setting.key,
  77. IntegerField(setting.name, validators=field_validators,
  78. description=setting.description)
  79. )
  80. # FloatField
  81. elif setting.value_type == "float":
  82. setattr(
  83. SettingsForm, setting.key,
  84. FloatField(setting.name, validators=field_validators,
  85. description=setting.description)
  86. )
  87. # TextField
  88. if setting.value_type == "string":
  89. setattr(
  90. SettingsForm, setting.key,
  91. TextField(setting.name, validators=field_validators,
  92. description=setting.description)
  93. )
  94. # SelectMultipleField
  95. if setting.value_type == "selectmultiple":
  96. setattr(
  97. SettingsForm, setting.key,
  98. SelectMultipleField(
  99. setting.name,
  100. choices=setting.extra['choices'],
  101. description=setting.description
  102. )
  103. )
  104. # SelectField
  105. if setting.value_type == "select":
  106. setattr(
  107. SettingsForm, setting.key,
  108. SelectField(setting.name, choices=setting.extra['choices'],
  109. description=setting.description)
  110. )
  111. # BooleanField
  112. if setting.value_type == "boolean":
  113. setattr(
  114. SettingsForm, setting.key,
  115. BooleanField(setting.name, description=setting.description)
  116. )
  117. return SettingsForm
  118. @classmethod
  119. def get_all(cls):
  120. return cls.query.all()
  121. @classmethod
  122. def update(cls, settings, app=None):
  123. """Updates the current_app's config and stores the changes in the
  124. database.
  125. :param config: A dictionary with configuration items.
  126. """
  127. updated_settings = {}
  128. for key, value in settings.iteritems():
  129. setting = cls.query.filter(Setting.key == key.lower()).first()
  130. setting.value = value
  131. updated_settings[setting.key.upper()] = setting.value
  132. db.session.add(setting)
  133. db.session.commit()
  134. if app is not None:
  135. app.config.update(updated_settings)
  136. @classmethod
  137. def as_dict(cls, from_group=None, upper=False):
  138. """Returns the settings key and value as a dict.
  139. :param from_group: Returns only the settings from the group as a dict.
  140. :param upper: If upper is ``True``, the key will use upper-case
  141. letters. Defaults to ``False``.
  142. """
  143. settings = {}
  144. result = None
  145. if from_group is not None:
  146. result = SettingsGroup.query.filter_by(key=from_group).\
  147. first_or_404()
  148. result = result.settings
  149. else:
  150. result = cls.query.all()
  151. for setting in result:
  152. if upper:
  153. settings[setting.key.upper()] = setting.value
  154. else:
  155. settings[setting.key] = setting.value
  156. return settings
  157. def save(self):
  158. """Saves a setting"""
  159. db.session.add(self)
  160. db.session.commit()
  161. def delete(self):
  162. """Deletes a setting"""
  163. db.session.delete(self)
  164. db.session.commit()