models.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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.ext.associationproxy import association_proxy
  12. from sqlalchemy.orm.collections import attribute_mapped_collection
  13. from flaskbb.extensions import db
  14. from flaskbb.utils.database import CRUDMixin
  15. from flaskbb.utils.forms import generate_settings_form
  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. # Enum?
  21. # Available types: string, integer, float, boolean, select, selectmultiple
  22. value_type = db.Column(db.Unicode(20), nullable=False)
  23. # Extra attributes like, validation things (min, max length...)
  24. # For Select*Fields required: choices
  25. extra = db.Column(db.PickleType, nullable=True)
  26. plugin_id = db.Column(db.Integer, db.ForeignKey('plugin_registry.id'))
  27. # Display stuff
  28. name = db.Column(db.Unicode(255), nullable=False)
  29. description = db.Column(db.Text, nullable=True)
  30. __table_args__ = (
  31. UniqueConstraint('key', 'plugin_id', name='plugin_kv_uniq'),
  32. )
  33. def __repr__(self):
  34. return '<PluginSetting plugin={} key={} value={}>'.format(
  35. self.plugin.name, self.key, self.value
  36. )
  37. class PluginRegistry(CRUDMixin, db.Model):
  38. id = db.Column(db.Integer, primary_key=True)
  39. name = db.Column(db.Unicode(255), unique=True, nullable=False)
  40. enabled = db.Column(db.Boolean, default=True)
  41. values = db.relationship(
  42. 'PluginStore',
  43. collection_class=attribute_mapped_collection('key'),
  44. cascade='all, delete-orphan',
  45. backref='plugin'
  46. )
  47. settings = association_proxy(
  48. 'values', 'value', creator=lambda k, v: PluginStore(key=k, value=v)
  49. )
  50. def get_settings_form(self):
  51. return generate_settings_form(self.values.values())()
  52. def add_settings(self, settings):
  53. plugin_settings = []
  54. for key in settings:
  55. pluginstore = PluginStore()
  56. pluginstore.key = key
  57. pluginstore.value = settings[key]['value']
  58. pluginstore.value_type = settings[key]['value_type']
  59. pluginstore.extra = settings[key]['extra']
  60. pluginstore.name = settings[key]['name']
  61. pluginstore.description = settings[key]['description']
  62. pluginstore.plugin = self
  63. plugin_settings.append(pluginstore)
  64. db.session.add_all(plugin_settings)
  65. db.session.commit()
  66. def __repr__(self):
  67. return '<Plugin name={} enabled={}>'.format(self.name, self.enabled)