zhongrj
2025-11-24 276323dce9613867abb3f58a4cc2abbfb2fd0dea
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from abc import ABC
from django.core.exceptions import MultipleObjectsReturned, ValidationError
from app.models import PluginDatum
import logging
 
logger = logging.getLogger('app.logger')
 
class DataStore(ABC):
    def __init__(self, namespace, user=None):
        """
        :param namespace: Namespace (typically the plugin's name) to use for this datastore
        :param user: User tied to this datastore. If None, this is a global data store
        """
        self.namespace = namespace
        self.user = user
 
    def db_key(self, key):
        return "{}::{}".format(self.namespace, key)
 
    def get_datum(self, key):
        return PluginDatum.objects.filter(key=self.db_key(key), user=self.user).first()
 
    def set_value(self, type, key, value):
        try:
            return PluginDatum.objects.update_or_create(key=self.db_key(key),
                                                         user=self.user,
                                                         defaults={type + '_value': value})
        except MultipleObjectsReturned:
            # This should never happen
            logger.warning("A plugin data store for the {} plugin returned multiple objects. This is potentially bad. The plugin developer needs to fix this! The data store will not be changed.".format(self.namespace))
            PluginDatum.objects.filter(key=self.db_key(key), user=self.user).delete()
        except ValidationError as e:
            raise InvalidDataStoreValue(e)
 
    def get_value(self, type, key, default=None):
        datum = self.get_datum(key)
        return default if datum is None else getattr(datum, type + '_value')
 
    def get_string(self, key, default=""):
        return self.get_value('string', key, default)
 
    def set_string(self, key, value):
        return self.set_value('string', key, value)
 
    def get_int(self, key, default=0):
        return self.get_value('int', key, default)
 
    def set_int(self, key, value):
        return self.set_value('int', key, value)
 
    def get_float(self, key, default=0.0):
        return self.get_value('float', key, default)
 
    def set_float(self, key, value):
        return self.set_value('float', key, value)
 
    def get_bool(self, key, default=False):
        return self.get_value('bool', key, default)
 
    def set_bool(self, key, value):
        return self.set_value('bool', key, value)
 
    def get_json(self, key, default={}):
        return self.get_value('json', key, default)
 
    def set_json(self, key, value):
        return self.set_value('json', key, value)
 
    def has_key(self, key):
        return self.get_datum(key) is not None
 
    def del_key(self, key):
        datum = self.get_datum(key)
        if datum is not None:
            datum.delete()
            return True
        else:
            return False
 
 
class UserDataStore(DataStore):
    def __init__(self, namespace, user):
        super().__init__(namespace, user)
 
 
class GlobalDataStore(DataStore):
    pass
 
 
class InvalidDataStoreValue(Exception):
    pass