import pickle import codecs import json from django.db import models from django.core import validators as django_validators from pingcap_sso.exceptions import TypeUnsupportedError class SiteSettingDB(models.Model): TYPE_STR = 'str' TYPE_INTEGER = 'integer' TYPE_STR_LIST = 'str_list' DATA_TYPE_CHOCES = ( (TYPE_STR, 'str'), (TYPE_INTEGER, 'integer'), (TYPE_STR_LIST, 'str_list') ) name = models.CharField(max_length=255) value = models.TextField() data_type = models.CharField( max_length=64, choices=DATA_TYPE_CHOCES, default=TYPE_STR) display_at_admin_frontend = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'site_settings' unique_together = ('name', 'data_type') class SiteSettingValue: def __init__(self, name, data_type): self.name = name self.data_type = data_type # SiteSetting.asktug_webhook_secret = 1 # a = SiteSetting.asktug_webhook_secret class MetaSiteSetting(type): REGISTERED_SETTINGS = { 'asktug_post_business_leads_key_words': SiteSettingDB.TYPE_STR_LIST, 'metabase_secret_key': SiteSettingDB.TYPE_STR, 'metabase_site_url': SiteSettingDB.TYPE_STR, 'points_user_redeem_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'business_download_leads_lark_webhook': SiteSettingDB.TYPE_STR, 'asktug_contact_us_lark_webhook': SiteSettingDB.TYPE_STR, 'org_topic_urgency_alert_lark_webhook': SiteSettingDB.TYPE_STR, 'org_topic_urgency_alert_email_address': SiteSettingDB.TYPE_STR, 'asktug_user_action_last_sync_at': SiteSettingDB.TYPE_STR, 'contact_us_emergency_lark_webhook': SiteSettingDB.TYPE_STR, 'contact_us_cooperation_lark_webhook': SiteSettingDB.TYPE_STR, 'contact_us_communication_lark_webhook': SiteSettingDB.TYPE_STR, 'tug_new_application_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'official_new_contact_us_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'official_new_joint_solution_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'company_verification_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'asktug_user_action_for_behavior_track_last_sync_at': SiteSettingDB.TYPE_INTEGER, 'pingcap_staff_resigned_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'community_new_contact_us_notify_lark_webhook': SiteSettingDB.TYPE_STR, 'official_new_partner_compatibility_certification_notify_lark_webhook': SiteSettingDB.TYPE_STR, } def __setattr__(cls, attr, value): data_type = cls.REGISTERED_SETTINGS.get(attr) if not data_type: raise AttributeError(attr) setting, _ = SiteSettingDB.objects.get_or_create(name=attr) setting.value = cls._encode(value, data_type) setting.data_type = data_type setting.save() super(MetaSiteSetting, cls).__setattr__(attr, value) def __getattr__(cls, attr): data_type = cls.REGISTERED_SETTINGS.get(attr) if not data_type: raise AttributeError(attr) try: setting = SiteSettingDB.objects.get( name=attr, data_type=data_type) return cls._parse(setting.value, data_type) except SiteSettingDB.DoesNotExist: return cls._get_default_value_by_type(data_type) def _get_default_value_by_type(cls, data_type): if data_type == SiteSettingDB.TYPE_STR: return '' elif data_type == SiteSettingDB.TYPE_INTEGER: return 0 elif data_type == SiteSettingDB.TYPE_STR_LIST: return [] else: raise Exception('Unsupported data_type: {}'.format(data_type)) def _parse(cls, raw_value, data_type): return json.loads(raw_value) def _encode(cls, raw_value, data_type): return json.dumps(raw_value) class SiteSetting(metaclass=MetaSiteSetting): pass