models.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.plugins.models
  4. ~~~~~~~~~~~~~~~~~~~~~~~
  5. This module provides registration and a basic DB backed key-value
  6. store for plugins.
  7. :copyright: (c) 2017 by the FlaskBB Team.
  8. :license: BSD, see LICENSE for more details.
  9. """
  10. from sqlalchemy import UniqueConstraint
  11. from sqlalchemy.orm.collections import attribute_mapped_collection
  12. from flaskbb._compat import itervalues
  13. from flaskbb.extensions import db
  14. from flaskbb.utils.database import CRUDMixin
  15. from flaskbb.utils.forms import generate_settings_form, SettingsValueTypes
  16. class PluginStore(CRUDMixin, db.Model):
  17. id = db.Column(db.Integer, primary_key=True)
  18. key = db.Column(db.Unicode(255), nullable=False)
  19. value = db.Column(db.PickleType, nullable=False)
  20. # Available types: string, integer, float, boolean, select, selectmultiple
  21. value_type = db.Column(db.Enum(SettingsValueTypes), nullable=False)
  22. # Extra attributes like, validation things (min, max length...)
  23. # For Select*Fields required: choices
  24. extra = db.Column(db.PickleType, nullable=True)
  25. plugin_id = db.Column(db.Integer, db.ForeignKey('plugin_registry.id'))
  26. # Display stuff
  27. name = db.Column(db.Unicode(255), nullable=False)
  28. description = db.Column(db.Text, nullable=True)
  29. __table_args__ = (
  30. UniqueConstraint('key', 'plugin_id', name='plugin_kv_uniq'),
  31. )
  32. def __repr__(self):
  33. return '<PluginSetting plugin={} key={} value={}>'.format(
  34. self.plugin.name, self.key, self.value
  35. )
  36. class PluginRegistry(CRUDMixin, db.Model):
  37. id = db.Column(db.Integer, primary_key=True)
  38. name = db.Column(db.Unicode(255), unique=True, nullable=False)
  39. enabled = db.Column(db.Boolean, default=True)
  40. values = db.relationship(
  41. 'PluginStore',
  42. collection_class=attribute_mapped_collection('key'),
  43. cascade='all, delete-orphan',
  44. backref='plugin'
  45. )
  46. @property
  47. def settings(self):
  48. return {kv.key: kv.value for kv in itervalues(self.values)}
  49. def get_settings_form(self):
  50. """Generates a settings form based on the settings."""
  51. return generate_settings_form(self.values.values())()
  52. def update_settings(self, settings):
  53. """Updates the given settings of the plugin.
  54. :param settings: A dictionary containing setting items.
  55. """
  56. pluginstore = PluginStore.query.filter(
  57. PluginStore.key.in_(settings.keys())
  58. ).all()
  59. setting_list = []
  60. for pluginsetting in pluginstore:
  61. pluginsetting.value = settings[pluginsetting.key]
  62. setting_list.append(pluginsetting)
  63. db.session.add_all(setting_list)
  64. db.session.commit()
  65. def add_settings(self, settings):
  66. """Adds the given settings to the plugin.
  67. :param settings: A dictionary containing setting items.
  68. """
  69. plugin_settings = []
  70. for key in settings:
  71. pluginstore = PluginStore()
  72. pluginstore.key = key
  73. pluginstore.value = settings[key]['value']
  74. pluginstore.value_type = settings[key]['value_type']
  75. pluginstore.extra = settings[key]['extra']
  76. pluginstore.name = settings[key]['name']
  77. pluginstore.description = settings[key]['description']
  78. pluginstore.plugin = self
  79. plugin_settings.append(pluginstore)
  80. db.session.add_all(plugin_settings)
  81. db.session.commit()
  82. def __repr__(self):
  83. return '<Plugin name={} enabled={}>'.format(self.name, self.enabled)