-
Notifications
You must be signed in to change notification settings - Fork 167
/
base.py
135 lines (90 loc) · 2.88 KB
/
base.py
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from plugin.core.helpers.variable import to_tuple
from plugin.models import db
import apsw
import inspect
import logging
import peewee
log = logging.getLogger(__name__)
class Method(object):
def __init__(self, manager, *args, **kwargs):
self.manager = manager
@property
def model(self):
return self.manager.model
class Get(Method):
def __call__(self, *query, **kwargs):
obj = self.model.get(*query, **kwargs)
if obj:
obj._created = False
return obj
def all(self):
return self.model.select()
def by_id(self, id):
return self(self.model.id == id)
def or_create(self, *query, **kwargs):
try:
return self.manager.create(**kwargs)
except (apsw.ConstraintError, peewee.IntegrityError), ex:
log.debug('or_create() - ex: %r', ex)
return self(*query)
def where(self, *query):
return self.model.select().where(*query)
class Create(Method):
def __call__(self, **kwargs):
if not self.model:
raise Exception('Manager %r has no "model" attribute defined' % self.manager)
with db.transaction():
obj = self.model.create(**kwargs)
if obj:
# Set flag
obj._created = True
return obj
class Update(Method):
keys = []
def __call__(self, obj, data, save=True):
changed = False
for key, value in data.items():
if not hasattr(obj, key):
raise KeyError('%r has no key %r' % (obj, key))
if getattr(obj, key) == value:
continue
changed = True
setattr(obj, key, value)
if not changed:
return False
if save:
obj.save()
return True
def from_dict(self, obj, changes, save=True):
if not changes:
return False
# Resolve `account`
if inspect.isfunction(obj):
obj = obj()
# Update `TraktAccount`
data = {}
for key in self.keys:
if key not in changes:
continue
data[key] = changes[key]
if data and not self(obj, data, save=save):
log.debug('Unable to update %r (nothing changed?)', obj)
return True
class ManagerMeta(type):
def __init__(cls, name, bases, attributes):
super(ManagerMeta, cls).__init__(name, bases, attributes)
if '__metaclass__' in attributes:
return
# Construct manager methods
for key in ['get', 'create', 'update']:
value = getattr(cls, key)
if not value or not inspect.isclass(value):
continue
# Construct method
setattr(cls, key, value(cls))
class Manager(object):
__metaclass__ = ManagerMeta
create = Create
get = Get
update = Update
model = None