appier 1.31.4__py2.py3-none-any.whl → 1.32.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- appier/__init__.py +333 -52
- appier/amqp.py +29 -30
- appier/api.py +214 -212
- appier/asgi.py +54 -55
- appier/async_neo.py +46 -35
- appier/async_old.py +55 -42
- appier/asynchronous.py +7 -13
- appier/base.py +1762 -1429
- appier/bus.py +51 -52
- appier/cache.py +99 -84
- appier/common.py +9 -11
- appier/component.py +17 -19
- appier/compress.py +25 -28
- appier/config.py +96 -73
- appier/controller.py +9 -15
- appier/crypt.py +25 -21
- appier/data.py +73 -57
- appier/defines.py +191 -226
- appier/exceptions.py +103 -63
- appier/execution.py +94 -88
- appier/export.py +90 -88
- appier/extra.py +6 -13
- appier/extra_neo.py +8 -11
- appier/extra_old.py +18 -16
- appier/geo.py +57 -47
- appier/git.py +101 -90
- appier/graph.py +23 -24
- appier/http.py +520 -398
- appier/legacy.py +373 -180
- appier/log.py +90 -97
- appier/meta.py +42 -42
- appier/mock.py +32 -34
- appier/model.py +793 -681
- appier/model_a.py +208 -183
- appier/mongo.py +183 -107
- appier/observer.py +39 -31
- appier/part.py +23 -24
- appier/preferences.py +44 -47
- appier/queuing.py +78 -96
- appier/redisdb.py +40 -35
- appier/request.py +227 -175
- appier/scheduler.py +13 -18
- appier/serialize.py +37 -31
- appier/session.py +161 -147
- appier/settings.py +2 -11
- appier/smtp.py +53 -49
- appier/storage.py +39 -33
- appier/structures.py +50 -45
- appier/test/__init__.py +2 -11
- appier/test/base.py +111 -108
- appier/test/cache.py +28 -35
- appier/test/config.py +10 -19
- appier/test/crypt.py +3 -12
- appier/test/data.py +3 -12
- appier/test/exceptions.py +8 -17
- appier/test/export.py +16 -33
- appier/test/graph.py +27 -60
- appier/test/http.py +42 -54
- appier/test/legacy.py +20 -30
- appier/test/log.py +14 -35
- appier/test/mock.py +27 -123
- appier/test/model.py +79 -91
- appier/test/part.py +5 -14
- appier/test/preferences.py +5 -13
- appier/test/queuing.py +29 -37
- appier/test/request.py +61 -73
- appier/test/serialize.py +12 -23
- appier/test/session.py +10 -19
- appier/test/smtp.py +8 -14
- appier/test/structures.py +20 -24
- appier/test/typesf.py +14 -28
- appier/test/util.py +480 -438
- appier/typesf.py +251 -171
- appier/util.py +578 -407
- appier/validation.py +280 -143
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/METADATA +6 -1
- appier-1.32.0.dist-info/RECORD +86 -0
- appier-1.31.4.dist-info/RECORD +0 -86
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/LICENSE +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/WHEEL +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/top_level.txt +0 -0
appier/bus.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,16 +22,7 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
@@ -47,12 +38,13 @@ from . import redisdb
|
|
|
47
38
|
from . import component
|
|
48
39
|
from . import exceptions
|
|
49
40
|
|
|
50
|
-
class Bus(component.Component):
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
class Bus(component.Component):
|
|
43
|
+
def __init__(self, name="bus", owner=None, *args, **kwargs):
|
|
44
|
+
component.Component.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
54
45
|
load = kwargs.pop("load", True)
|
|
55
|
-
if load:
|
|
46
|
+
if load:
|
|
47
|
+
self.load(*args, **kwargs)
|
|
56
48
|
|
|
57
49
|
@classmethod
|
|
58
50
|
def new(cls, *args, **kwargs):
|
|
@@ -61,30 +53,33 @@ class Bus(component.Component):
|
|
|
61
53
|
def bind(self, name, method):
|
|
62
54
|
raise exceptions.NotImplementedError()
|
|
63
55
|
|
|
64
|
-
def unbind(self, name, method
|
|
56
|
+
def unbind(self, name, method=None):
|
|
65
57
|
raise exceptions.NotImplementedError()
|
|
66
58
|
|
|
67
59
|
def trigger(self, name, *args, **kwargs):
|
|
68
60
|
raise exceptions.NotImplementedError()
|
|
69
61
|
|
|
70
|
-
class MemoryBus(Bus):
|
|
71
62
|
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
class MemoryBus(Bus):
|
|
64
|
+
def __init__(self, name="memory", owner=None, *args, **kwargs):
|
|
65
|
+
Bus.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
74
66
|
|
|
75
67
|
def bind(self, name, method):
|
|
76
68
|
methods = self._events.get(name, [])
|
|
77
69
|
methods.append(method)
|
|
78
70
|
self._events[name] = methods
|
|
79
71
|
|
|
80
|
-
def unbind(self, name, method
|
|
72
|
+
def unbind(self, name, method=None):
|
|
81
73
|
methods = self._events.get(name, [])
|
|
82
|
-
if method:
|
|
83
|
-
|
|
74
|
+
if method:
|
|
75
|
+
methods.remove(method)
|
|
76
|
+
else:
|
|
77
|
+
del methods[:]
|
|
84
78
|
|
|
85
79
|
def trigger(self, name, *args, **kwargs):
|
|
86
80
|
methods = self._events.get(name, [])
|
|
87
|
-
for method in methods:
|
|
81
|
+
for method in methods:
|
|
82
|
+
method(*args, **kwargs)
|
|
88
83
|
|
|
89
84
|
def _load(self, *args, **kwargs):
|
|
90
85
|
Bus._load(self, *args, **kwargs)
|
|
@@ -96,7 +91,7 @@ class MemoryBus(Bus):
|
|
|
96
91
|
|
|
97
92
|
def _get_state(self):
|
|
98
93
|
state = Bus._get_state(self)
|
|
99
|
-
state.update(_events
|
|
94
|
+
state.update(_events=self._events)
|
|
100
95
|
return state
|
|
101
96
|
|
|
102
97
|
def _set_state(self, state):
|
|
@@ -106,8 +101,8 @@ class MemoryBus(Bus):
|
|
|
106
101
|
for method in methods:
|
|
107
102
|
self.bind(name, method)
|
|
108
103
|
|
|
109
|
-
class RedisBus(Bus):
|
|
110
104
|
|
|
105
|
+
class RedisBus(Bus):
|
|
111
106
|
SERIALIZER = pickle
|
|
112
107
|
""" The serializer to be used for the values contained in
|
|
113
108
|
the bus (used on top of the class) """
|
|
@@ -116,8 +111,8 @@ class RedisBus(Bus):
|
|
|
116
111
|
""" The name of the global channel to which all of the agents
|
|
117
112
|
should be subscribed, for global communication """
|
|
118
113
|
|
|
119
|
-
def __init__(self, name
|
|
120
|
-
Bus.__init__(self, name
|
|
114
|
+
def __init__(self, name="redis", owner=None, *args, **kwargs):
|
|
115
|
+
Bus.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
121
116
|
self._delay = kwargs.pop("delay", True)
|
|
122
117
|
|
|
123
118
|
def bind(self, name, method):
|
|
@@ -127,21 +122,18 @@ class RedisBus(Bus):
|
|
|
127
122
|
channel = self._to_channel(name)
|
|
128
123
|
self._pubsub.subscribe(channel)
|
|
129
124
|
|
|
130
|
-
def unbind(self, name, method
|
|
125
|
+
def unbind(self, name, method=None):
|
|
131
126
|
methods = self._events.get(name, [])
|
|
132
|
-
if method:
|
|
133
|
-
|
|
127
|
+
if method:
|
|
128
|
+
methods.remove(method)
|
|
129
|
+
else:
|
|
130
|
+
del methods[:]
|
|
134
131
|
channel = self._to_channel(name)
|
|
135
132
|
self._pubsub.unsubscribe(channel)
|
|
136
133
|
|
|
137
134
|
def trigger(self, name, *args, **kwargs):
|
|
138
135
|
channel = self._to_channel(name)
|
|
139
|
-
data = self._serializer.dumps(
|
|
140
|
-
dict(
|
|
141
|
-
args = args,
|
|
142
|
-
kwargs = kwargs
|
|
143
|
-
)
|
|
144
|
-
)
|
|
136
|
+
data = self._serializer.dumps(dict(args=args, kwargs=kwargs))
|
|
145
137
|
self._redis.publish(channel, data)
|
|
146
138
|
|
|
147
139
|
def _load(self, *args, **kwargs):
|
|
@@ -150,7 +142,9 @@ class RedisBus(Bus):
|
|
|
150
142
|
self._name = config.conf("BUS_SCOPE", self._name)
|
|
151
143
|
self._name = kwargs.pop("name", self._name)
|
|
152
144
|
self._serializer = kwargs.pop("serializer", self.__class__.SERIALIZER)
|
|
153
|
-
self._global_channel = kwargs.pop(
|
|
145
|
+
self._global_channel = kwargs.pop(
|
|
146
|
+
"global_channel", self.__class__.GLOBAL_CHANNEL
|
|
147
|
+
)
|
|
154
148
|
self._events = dict()
|
|
155
149
|
self._open()
|
|
156
150
|
|
|
@@ -161,7 +155,7 @@ class RedisBus(Bus):
|
|
|
161
155
|
|
|
162
156
|
def _get_state(self):
|
|
163
157
|
state = Bus._get_state(self)
|
|
164
|
-
state.update(_events
|
|
158
|
+
state.update(_events=self._events)
|
|
165
159
|
return state
|
|
166
160
|
|
|
167
161
|
def _set_state(self, state):
|
|
@@ -188,35 +182,40 @@ class RedisBus(Bus):
|
|
|
188
182
|
self._pubsub = None
|
|
189
183
|
self._listener = None
|
|
190
184
|
|
|
191
|
-
def _loop(self, safe
|
|
185
|
+
def _loop(self, safe=True):
|
|
192
186
|
for item in self._pubsub.listen():
|
|
193
187
|
try:
|
|
194
|
-
if not self.loaded:
|
|
195
|
-
|
|
188
|
+
if not self.loaded:
|
|
189
|
+
break
|
|
190
|
+
self._tick(item, safe=safe)
|
|
196
191
|
except Exception as exception:
|
|
197
192
|
self.logger.critical("Unhandled Redis loop exception raised")
|
|
198
193
|
self.logger.error(exception)
|
|
199
194
|
lines = traceback.format_exc().splitlines()
|
|
200
|
-
for line in lines:
|
|
195
|
+
for line in lines:
|
|
196
|
+
self.logger.warning(line)
|
|
201
197
|
|
|
202
|
-
def _tick(self, item, safe
|
|
198
|
+
def _tick(self, item, safe=True):
|
|
203
199
|
channel = item.get("channel", None)
|
|
204
200
|
channel = legacy.str(channel)
|
|
205
201
|
type = item.get("type", None)
|
|
206
202
|
data = item.get("data", None)
|
|
207
|
-
if not type in ("message",):
|
|
208
|
-
|
|
209
|
-
|
|
203
|
+
if not type in ("message",):
|
|
204
|
+
return
|
|
205
|
+
if ":" in channel:
|
|
206
|
+
_prefix, name = channel.split(":", 1)
|
|
207
|
+
else:
|
|
208
|
+
name = channel
|
|
210
209
|
data = self._serializer.loads(data)
|
|
211
210
|
methods = self._events.get(name, []) if self._events else []
|
|
212
211
|
for method in methods:
|
|
213
212
|
if safe:
|
|
214
213
|
self.owner.schedule(
|
|
215
214
|
method,
|
|
216
|
-
args
|
|
217
|
-
kwargs
|
|
218
|
-
timeout
|
|
219
|
-
safe
|
|
215
|
+
args=data["args"],
|
|
216
|
+
kwargs=data["kwargs"],
|
|
217
|
+
timeout=-1,
|
|
218
|
+
safe=True,
|
|
220
219
|
)
|
|
221
220
|
else:
|
|
222
221
|
method(*data["args"], **data["kwargs"])
|
|
@@ -224,10 +223,10 @@ class RedisBus(Bus):
|
|
|
224
223
|
def _to_channel(self, name):
|
|
225
224
|
return self._name + ":" + name
|
|
226
225
|
|
|
227
|
-
class RedisListener(threading.Thread):
|
|
228
226
|
|
|
227
|
+
class RedisListener(threading.Thread):
|
|
229
228
|
def __init__(self, bus):
|
|
230
|
-
threading.Thread.__init__(self, name
|
|
229
|
+
threading.Thread.__init__(self, name="RedisListener")
|
|
231
230
|
self.daemon = True
|
|
232
231
|
self._bus = bus
|
|
233
232
|
|
appier/cache.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,16 +22,7 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
@@ -49,12 +40,13 @@ from . import config
|
|
|
49
40
|
from . import redisdb
|
|
50
41
|
from . import component
|
|
51
42
|
|
|
52
|
-
class Cache(component.Component):
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
class Cache(component.Component):
|
|
45
|
+
def __init__(self, name="cache", owner=None, *args, **kwargs):
|
|
46
|
+
component.Component.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
56
47
|
load = kwargs.pop("load", True)
|
|
57
|
-
if load:
|
|
48
|
+
if load:
|
|
49
|
+
self.load(*args, **kwargs)
|
|
58
50
|
|
|
59
51
|
def __len__(self):
|
|
60
52
|
return self.length()
|
|
@@ -87,9 +79,11 @@ class Cache(component.Component):
|
|
|
87
79
|
def clear(self):
|
|
88
80
|
pass
|
|
89
81
|
|
|
90
|
-
def get(self, key, default
|
|
91
|
-
try:
|
|
92
|
-
|
|
82
|
+
def get(self, key, default=None):
|
|
83
|
+
try:
|
|
84
|
+
return self.get_item(key)
|
|
85
|
+
except KeyError:
|
|
86
|
+
return default
|
|
93
87
|
|
|
94
88
|
def get_item(self, key):
|
|
95
89
|
raise KeyError("not found")
|
|
@@ -97,25 +91,28 @@ class Cache(component.Component):
|
|
|
97
91
|
def set(self, *args, **kwargs):
|
|
98
92
|
return self.set_item(*args, **kwargs)
|
|
99
93
|
|
|
100
|
-
def set_item(self, key, value, expires
|
|
94
|
+
def set_item(self, key, value, expires=None, timeout=None):
|
|
101
95
|
self.mark()
|
|
102
96
|
|
|
103
97
|
def delete_item(self, key):
|
|
104
98
|
self.mark()
|
|
105
99
|
|
|
106
100
|
def contains(self, key):
|
|
107
|
-
try:
|
|
108
|
-
|
|
101
|
+
try:
|
|
102
|
+
self.get_item(key)
|
|
103
|
+
except KeyError:
|
|
104
|
+
return False
|
|
109
105
|
return True
|
|
110
106
|
|
|
111
107
|
def build_value(self, value, expires, timeout):
|
|
112
|
-
if timeout:
|
|
108
|
+
if timeout:
|
|
109
|
+
expires = time.time() + timeout
|
|
113
110
|
return (value, expires)
|
|
114
111
|
|
|
115
|
-
class MemoryCache(Cache):
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
class MemoryCache(Cache):
|
|
114
|
+
def __init__(self, name="memory", owner=None, *args, **kwargs):
|
|
115
|
+
Cache.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
119
116
|
|
|
120
117
|
def length(self):
|
|
121
118
|
return self._data.__len__()
|
|
@@ -130,7 +127,7 @@ class MemoryCache(Cache):
|
|
|
130
127
|
return self.get_item(key)
|
|
131
128
|
return value
|
|
132
129
|
|
|
133
|
-
def set_item(self, key, value, expires
|
|
130
|
+
def set_item(self, key, value, expires=None, timeout=None):
|
|
134
131
|
value = self.build_value(value, expires, timeout)
|
|
135
132
|
return self._data.__setitem__(key, value)
|
|
136
133
|
|
|
@@ -145,23 +142,27 @@ class MemoryCache(Cache):
|
|
|
145
142
|
Cache._unload(self, *args, **kwargs)
|
|
146
143
|
self._data = None
|
|
147
144
|
|
|
148
|
-
class FileCache(Cache):
|
|
149
145
|
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
class FileCache(Cache):
|
|
147
|
+
def __init__(self, name="file", owner=None, *args, **kwargs):
|
|
148
|
+
Cache.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
152
149
|
|
|
153
150
|
def length(self):
|
|
154
|
-
if not os.path.exists(self.base_path):
|
|
151
|
+
if not os.path.exists(self.base_path):
|
|
152
|
+
return 0
|
|
155
153
|
return len(os.listdir(self.base_path))
|
|
156
154
|
|
|
157
155
|
def clear(self):
|
|
158
|
-
if not os.path.exists(self.base_path):
|
|
159
|
-
|
|
156
|
+
if not os.path.exists(self.base_path):
|
|
157
|
+
return
|
|
158
|
+
shutil.rmtree(self.base_path, ignore_errors=True)
|
|
160
159
|
|
|
161
160
|
def get_item(self, key):
|
|
162
161
|
file_path = os.path.join(self.base_path, key)
|
|
163
|
-
if not os.path.exists(file_path):
|
|
164
|
-
|
|
162
|
+
if not os.path.exists(file_path):
|
|
163
|
+
raise KeyError("not found")
|
|
164
|
+
if not os.path.exists(file_path + ".expires"):
|
|
165
|
+
raise KeyError("not found")
|
|
165
166
|
expires = self._read_file(file_path + ".expires")
|
|
166
167
|
expires = int(expires) if expires else None
|
|
167
168
|
if not expires == None and expires < time.time():
|
|
@@ -170,11 +171,11 @@ class FileCache(Cache):
|
|
|
170
171
|
value = self._read_file(file_path)
|
|
171
172
|
return value
|
|
172
173
|
|
|
173
|
-
def set_item(self, key, value, expires
|
|
174
|
+
def set_item(self, key, value, expires=None, timeout=None):
|
|
174
175
|
file_path = os.path.join(self.base_path, key)
|
|
175
176
|
value, expires = self.build_value(value, expires, timeout)
|
|
176
177
|
expires = str(int(expires)) if expires else None
|
|
177
|
-
expires_s = legacy.bytes(expires, force
|
|
178
|
+
expires_s = legacy.bytes(expires, force=True) if expires else b""
|
|
178
179
|
self._write_file(file_path, value)
|
|
179
180
|
self._write_file(file_path + ".expires", expires_s)
|
|
180
181
|
|
|
@@ -190,24 +191,30 @@ class FileCache(Cache):
|
|
|
190
191
|
|
|
191
192
|
def _read_file(self, file_path):
|
|
192
193
|
file = open(file_path, "rb")
|
|
193
|
-
try:
|
|
194
|
-
|
|
194
|
+
try:
|
|
195
|
+
data = file.read()
|
|
196
|
+
finally:
|
|
197
|
+
file.close()
|
|
195
198
|
return data
|
|
196
199
|
|
|
197
200
|
def _write_file(self, file_path, data):
|
|
198
201
|
self._ensure_exists()
|
|
199
202
|
file = open(file_path, "wb")
|
|
200
|
-
try:
|
|
201
|
-
|
|
203
|
+
try:
|
|
204
|
+
file.write(data)
|
|
205
|
+
finally:
|
|
206
|
+
file.close()
|
|
202
207
|
|
|
203
208
|
def _ensure_exists(self):
|
|
204
|
-
if os.path.exists(self.base_path):
|
|
209
|
+
if os.path.exists(self.base_path):
|
|
210
|
+
return
|
|
205
211
|
os.makedirs(self.base_path)
|
|
206
212
|
|
|
207
213
|
def _ensure_path(self):
|
|
208
|
-
if self.base_path:
|
|
214
|
+
if self.base_path:
|
|
215
|
+
return
|
|
209
216
|
app_path = common.base().get_base_path()
|
|
210
|
-
util.verify(not app_path == None, message
|
|
217
|
+
util.verify(not app_path == None, message="No app path available")
|
|
211
218
|
cache_path = os.path.join(app_path, "cache")
|
|
212
219
|
cache_path = config.conf("CACHE_PATH", cache_path)
|
|
213
220
|
cache_path = os.path.expanduser(cache_path)
|
|
@@ -215,40 +222,40 @@ class FileCache(Cache):
|
|
|
215
222
|
cache_path = os.path.normpath(cache_path)
|
|
216
223
|
self.base_path = cache_path
|
|
217
224
|
|
|
218
|
-
class RedisCache(Cache):
|
|
219
225
|
|
|
220
|
-
|
|
221
|
-
|
|
226
|
+
class RedisCache(Cache):
|
|
227
|
+
def __init__(self, name="redis", owner=None, *args, **kwargs):
|
|
228
|
+
Cache.__init__(self, name=name, owner=owner, *args, **kwargs)
|
|
222
229
|
|
|
223
230
|
def length(self):
|
|
224
|
-
if self.hash:
|
|
225
|
-
|
|
231
|
+
if self.hash:
|
|
232
|
+
return self._redis.hlen(self.key)
|
|
233
|
+
else:
|
|
234
|
+
return len(self._redis.keys())
|
|
226
235
|
|
|
227
236
|
def clear(self):
|
|
228
|
-
if self.hash:
|
|
229
|
-
|
|
237
|
+
if self.hash:
|
|
238
|
+
self._redis.delete(self.key)
|
|
239
|
+
else:
|
|
240
|
+
self._redis.flushdb()
|
|
230
241
|
|
|
231
242
|
def get_item(self, key):
|
|
232
|
-
if self.hash:
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
else: return self._set_item(
|
|
243
|
-
key,
|
|
244
|
-
value,
|
|
245
|
-
expires = expires,
|
|
246
|
-
timeout = timeout
|
|
247
|
-
)
|
|
243
|
+
if self.hash:
|
|
244
|
+
return self._get_item_hash(key)
|
|
245
|
+
else:
|
|
246
|
+
return self._get_item(key)
|
|
247
|
+
|
|
248
|
+
def set_item(self, key, value, expires=None, timeout=None):
|
|
249
|
+
if self.hash:
|
|
250
|
+
return self._set_item_hash(key, value, expires=expires, timeout=timeout)
|
|
251
|
+
else:
|
|
252
|
+
return self._set_item(key, value, expires=expires, timeout=timeout)
|
|
248
253
|
|
|
249
254
|
def delete_item(self, key):
|
|
250
|
-
if self.hash:
|
|
251
|
-
|
|
255
|
+
if self.hash:
|
|
256
|
+
self._redis.hdel(self.key, key)
|
|
257
|
+
else:
|
|
258
|
+
self._redis.delete(key)
|
|
252
259
|
|
|
253
260
|
def _load(self, *args, **kwargs):
|
|
254
261
|
Cache._load(self, *args, **kwargs)
|
|
@@ -261,37 +268,45 @@ class RedisCache(Cache):
|
|
|
261
268
|
self._redis = None
|
|
262
269
|
|
|
263
270
|
def _get_item(self, key):
|
|
264
|
-
if not self._redis.exists(key):
|
|
271
|
+
if not self._redis.exists(key):
|
|
272
|
+
raise KeyError("not found")
|
|
265
273
|
return self._redis.get(key)
|
|
266
274
|
|
|
267
275
|
def _get_item_hash(self, key):
|
|
268
|
-
if not self._redis.hexists(self.key, key):
|
|
276
|
+
if not self._redis.hexists(self.key, key):
|
|
277
|
+
raise KeyError("not found")
|
|
269
278
|
return self._redis.hget(self.key, key)
|
|
270
279
|
|
|
271
|
-
def _set_item(self, key, value, expires
|
|
280
|
+
def _set_item(self, key, value, expires=None, timeout=None):
|
|
272
281
|
self._redis.set(key, value)
|
|
273
|
-
if expires:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
282
|
+
if expires:
|
|
283
|
+
timeout = expires - time.time()
|
|
284
|
+
if timeout and timeout > 0:
|
|
285
|
+
self._redis.expire(key, int(timeout))
|
|
286
|
+
elif timeout:
|
|
287
|
+
self._redis.delete(key)
|
|
288
|
+
|
|
289
|
+
def _set_item_hash(self, key, value, expires=None, timeout=None):
|
|
278
290
|
self._redis.hset(self.key, key, value)
|
|
279
|
-
if expires:
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
if expires:
|
|
292
|
+
timeout = expires - time.time()
|
|
293
|
+
if timeout and timeout > 0:
|
|
294
|
+
self._redis.expire(self.key, int(timeout))
|
|
295
|
+
elif timeout:
|
|
296
|
+
self._redis.hdel(self.key, key)
|
|
282
297
|
|
|
283
298
|
@property
|
|
284
|
-
def key(self, prefix
|
|
299
|
+
def key(self, prefix="cache"):
|
|
285
300
|
suffix = self.owner.name_i if self.owner else "global"
|
|
286
301
|
return prefix + ":" + suffix
|
|
287
302
|
|
|
288
|
-
class SerializedCache(object):
|
|
289
303
|
|
|
304
|
+
class SerializedCache(object):
|
|
290
305
|
SERIALIZER = pickle
|
|
291
306
|
""" The serializer to be used for the values contained in
|
|
292
307
|
the session (used on top of the class) """
|
|
293
308
|
|
|
294
|
-
def __init__(self, cache, serializer
|
|
309
|
+
def __init__(self, cache, serializer=None):
|
|
295
310
|
cls = self.__class__
|
|
296
311
|
self._cache = cache
|
|
297
312
|
self._serializer = serializer or cls.SERIALIZER
|
|
@@ -327,6 +342,6 @@ class SerializedCache(object):
|
|
|
327
342
|
value = self._serializer.loads(data)
|
|
328
343
|
return value
|
|
329
344
|
|
|
330
|
-
def set_item(self, key, value, expires
|
|
345
|
+
def set_item(self, key, value, expires=None, timeout=None):
|
|
331
346
|
data = self._serializer.dumps(value)
|
|
332
|
-
return self._cache.set_item(key, data, expires
|
|
347
|
+
return self._cache.set_item(key, data, expires=expires, timeout=timeout)
|
appier/common.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,32 +22,30 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
38
29
|
""" The license for the module """
|
|
39
30
|
|
|
31
|
+
|
|
40
32
|
def base():
|
|
41
33
|
from . import base
|
|
34
|
+
|
|
42
35
|
return base
|
|
43
36
|
|
|
37
|
+
|
|
44
38
|
def model():
|
|
45
39
|
from . import model
|
|
40
|
+
|
|
46
41
|
return model
|
|
47
42
|
|
|
43
|
+
|
|
48
44
|
def util():
|
|
49
45
|
from . import util
|
|
46
|
+
|
|
50
47
|
return util
|
|
51
48
|
|
|
49
|
+
|
|
52
50
|
def is_devel():
|
|
53
51
|
return base().is_devel()
|