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/component.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"
|
|
@@ -42,6 +33,7 @@ import logging
|
|
|
42
33
|
from . import util
|
|
43
34
|
from . import common
|
|
44
35
|
|
|
36
|
+
|
|
45
37
|
class Component(object):
|
|
46
38
|
"""
|
|
47
39
|
Top level component class to be used as an abstract definition
|
|
@@ -51,7 +43,7 @@ class Component(object):
|
|
|
51
43
|
component should behave and the life-cycle stages for it.
|
|
52
44
|
"""
|
|
53
45
|
|
|
54
|
-
def __init__(self, name
|
|
46
|
+
def __init__(self, name="component", owner=None, *args, **kwargs):
|
|
55
47
|
object.__init__(self)
|
|
56
48
|
self.id = util.gen_token()
|
|
57
49
|
self.name = name
|
|
@@ -59,12 +51,14 @@ class Component(object):
|
|
|
59
51
|
self.loaded = False
|
|
60
52
|
|
|
61
53
|
def load(self, *args, **kwargs):
|
|
62
|
-
if self.is_loaded:
|
|
54
|
+
if self.is_loaded:
|
|
55
|
+
return
|
|
63
56
|
self._load(*args, **kwargs)
|
|
64
57
|
return self
|
|
65
58
|
|
|
66
59
|
def unload(self, *args, **kwargs):
|
|
67
|
-
if not self.is_loaded:
|
|
60
|
+
if not self.is_loaded:
|
|
61
|
+
return
|
|
68
62
|
self._unload(*args, **kwargs)
|
|
69
63
|
return self
|
|
70
64
|
|
|
@@ -72,10 +66,12 @@ class Component(object):
|
|
|
72
66
|
set_state = kwargs.get("set_state", True)
|
|
73
67
|
owner = self.owner
|
|
74
68
|
state = self.get_state()
|
|
75
|
-
if self.is_loaded:
|
|
69
|
+
if self.is_loaded:
|
|
70
|
+
self.unload()
|
|
76
71
|
self.owner = owner
|
|
77
72
|
self.load()
|
|
78
|
-
if set_state:
|
|
73
|
+
if set_state:
|
|
74
|
+
self.set_state(state)
|
|
79
75
|
|
|
80
76
|
def get_state(self):
|
|
81
77
|
return self._get_state()
|
|
@@ -85,8 +81,10 @@ class Component(object):
|
|
|
85
81
|
|
|
86
82
|
@property
|
|
87
83
|
def logger(self):
|
|
88
|
-
if self.owner:
|
|
89
|
-
|
|
84
|
+
if self.owner:
|
|
85
|
+
return self.owner.logger
|
|
86
|
+
else:
|
|
87
|
+
return logging.getLogger()
|
|
90
88
|
|
|
91
89
|
@property
|
|
92
90
|
def is_loaded(self):
|
|
@@ -100,7 +98,7 @@ class Component(object):
|
|
|
100
98
|
self.loaded = False
|
|
101
99
|
|
|
102
100
|
def _get_state(self):
|
|
103
|
-
return dict(owner
|
|
101
|
+
return dict(owner=self.owner)
|
|
104
102
|
|
|
105
103
|
def _set_state(self, state):
|
|
106
104
|
self.owner = state.get("owner", None)
|
appier/compress.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"
|
|
@@ -42,40 +33,42 @@ import os
|
|
|
42
33
|
from . import legacy
|
|
43
34
|
from . import exceptions
|
|
44
35
|
|
|
45
|
-
class Compress(object):
|
|
46
36
|
|
|
37
|
+
class Compress(object):
|
|
47
38
|
def __init__(self):
|
|
48
39
|
self._load_compress()
|
|
49
40
|
|
|
50
41
|
def load_jsmin(self):
|
|
51
|
-
try:
|
|
52
|
-
|
|
42
|
+
try:
|
|
43
|
+
import jsmin
|
|
44
|
+
except ImportError:
|
|
45
|
+
self.jsmin = None
|
|
46
|
+
return
|
|
53
47
|
self.jsmin = jsmin
|
|
54
48
|
|
|
55
49
|
def type_jpeg(self):
|
|
56
50
|
return "image/jpeg"
|
|
57
51
|
|
|
58
|
-
def compress(self, file_path, modified
|
|
52
|
+
def compress(self, file_path, modified=None, method=None):
|
|
59
53
|
# retrieves the modification data from the requested file and
|
|
60
54
|
# uses it to construct the complete (cache) key to be used in
|
|
61
55
|
# cache try, in case there's a match returns the new file
|
|
62
56
|
modified = modified or os.path.getmtime(file_path)
|
|
63
57
|
key = "%s:%s" % (method, file_path)
|
|
64
58
|
result = self.try_cache(key, modified)
|
|
65
|
-
if result:
|
|
59
|
+
if result:
|
|
60
|
+
return (len(result), legacy.BytesIO(result))
|
|
66
61
|
|
|
67
62
|
# in case there's no provided method a proper not found exception
|
|
68
63
|
# should be raised so that the end user is notified about the non
|
|
69
64
|
# existence of such unset compressor (as expected)
|
|
70
|
-
if method == None:
|
|
71
|
-
message
|
|
72
|
-
)
|
|
65
|
+
if method == None:
|
|
66
|
+
raise exceptions.NotFoundError(message="Compressor is not defined")
|
|
73
67
|
|
|
74
68
|
# in case the compress string is defined, tries to find the proper
|
|
75
69
|
# compress method and in case it's not found raises an exception
|
|
76
|
-
if not hasattr(self, "compress_" + method):
|
|
77
|
-
message
|
|
78
|
-
)
|
|
70
|
+
if not hasattr(self, "compress_" + method):
|
|
71
|
+
raise exceptions.NotFoundError(message="Compressor '%s' not found" % method)
|
|
79
72
|
|
|
80
73
|
# retrieves the proper compressor method for the requested compress
|
|
81
74
|
# technique, this should be used in a dynamic way enforcing some
|
|
@@ -85,8 +78,10 @@ class Compress(object):
|
|
|
85
78
|
# opens the requested file and reads the complete set of information
|
|
86
79
|
# from it closing the file object after the operation is complete
|
|
87
80
|
file = open(file_path, "rb")
|
|
88
|
-
try:
|
|
89
|
-
|
|
81
|
+
try:
|
|
82
|
+
data = file.read()
|
|
83
|
+
finally:
|
|
84
|
+
file.close()
|
|
90
85
|
|
|
91
86
|
# runs the compressing operation using the target compressor and uses
|
|
92
87
|
# the resulting (compressed) data as the value to be returned
|
|
@@ -103,20 +98,22 @@ class Compress(object):
|
|
|
103
98
|
return (result_size, result_file)
|
|
104
99
|
|
|
105
100
|
def compress_jpeg(self, file_path):
|
|
106
|
-
if self.jinja:
|
|
101
|
+
if self.jinja:
|
|
102
|
+
return self.compress_jpeg_pil(file_path)
|
|
107
103
|
return self.compress_fallback(file_path)
|
|
108
104
|
|
|
109
|
-
def compress_jpeg_pil(self, data, quality
|
|
105
|
+
def compress_jpeg_pil(self, data, quality=80):
|
|
110
106
|
input = legacy.BytesIO(data)
|
|
111
107
|
output = legacy.BytesIO()
|
|
112
108
|
image = self.pil.Image.open(input)
|
|
113
|
-
image.save(output, format
|
|
109
|
+
image.save(output, format="jpeg", quality=quality, optimize=True)
|
|
114
110
|
output.seek(0, os.SEEK_SET)
|
|
115
111
|
data = output.read()
|
|
116
112
|
return data
|
|
117
113
|
|
|
118
114
|
def compress_js(self, data):
|
|
119
|
-
if self.jsmin:
|
|
115
|
+
if self.jsmin:
|
|
116
|
+
return self.compress_js_jsmin(data)
|
|
120
117
|
return self.compress_fallback(data)
|
|
121
118
|
|
|
122
119
|
def compress_js_jsmin(self, data):
|
appier/config.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"
|
|
@@ -60,19 +51,15 @@ IMPORT_NAMES = ("$import", "$include", "$IMPORT", "$INCLUDE")
|
|
|
60
51
|
name that references a list of include files to be loaded """
|
|
61
52
|
|
|
62
53
|
CASTS = {
|
|
63
|
-
bool
|
|
64
|
-
list
|
|
65
|
-
tuple
|
|
54
|
+
bool: lambda v: v if isinstance(v, bool) else v in ("1", "true", "True"),
|
|
55
|
+
list: lambda v: v if isinstance(v, list) else v.split(";") if v else [],
|
|
56
|
+
tuple: lambda v: v if isinstance(v, tuple) else tuple(v.split(";") if v else []),
|
|
66
57
|
}
|
|
67
58
|
""" The map containing the various cast method
|
|
68
59
|
operation associated with the various data types,
|
|
69
60
|
they provide a different type of casting strategy """
|
|
70
61
|
|
|
71
|
-
ENV_ENCODINGS = (
|
|
72
|
-
"utf-8",
|
|
73
|
-
sys.getdefaultencoding(),
|
|
74
|
-
sys.getfilesystemencoding()
|
|
75
|
-
)
|
|
62
|
+
ENV_ENCODINGS = ("utf-8", sys.getdefaultencoding(), sys.getfilesystemencoding())
|
|
76
63
|
""" The sequence of encodings that are going to
|
|
77
64
|
be used to try to decode possible byte based strings
|
|
78
65
|
for the various environment variable values """
|
|
@@ -95,7 +82,8 @@ be set on the initial loading of the ".home" file """
|
|
|
95
82
|
if not isinstance(__builtins__, dict):
|
|
96
83
|
__builtins__ = __builtins__.__dict__
|
|
97
84
|
|
|
98
|
-
|
|
85
|
+
|
|
86
|
+
def conf(name, default=None, cast=None, ctx=None):
|
|
99
87
|
"""
|
|
100
88
|
Retrieves the configuration value for the provided value
|
|
101
89
|
defaulting to the provided default value in case no value
|
|
@@ -125,42 +113,53 @@ def conf(name, default = None, cast = None, ctx = None):
|
|
|
125
113
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
126
114
|
cast = _cast_r(cast)
|
|
127
115
|
value = configs.get(name, default)
|
|
128
|
-
if cast and not value == None:
|
|
116
|
+
if cast and not value == None:
|
|
117
|
+
value = cast(value)
|
|
129
118
|
return value
|
|
130
119
|
|
|
131
|
-
|
|
120
|
+
|
|
121
|
+
def conf_prefix(prefix, ctx=None):
|
|
132
122
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
133
123
|
configs_prefix = dict()
|
|
134
124
|
for name, value in configs.items():
|
|
135
|
-
if not name.startswith(prefix):
|
|
125
|
+
if not name.startswith(prefix):
|
|
126
|
+
continue
|
|
136
127
|
configs_prefix[name] = value
|
|
137
128
|
return configs_prefix
|
|
138
129
|
|
|
139
|
-
|
|
130
|
+
|
|
131
|
+
def conf_suffix(suffix, ctx=None):
|
|
140
132
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
141
133
|
configs_suffix = dict()
|
|
142
134
|
for name, value in configs.items():
|
|
143
|
-
if not name.endswith(suffix):
|
|
135
|
+
if not name.endswith(suffix):
|
|
136
|
+
continue
|
|
144
137
|
configs_suffix[name] = value
|
|
145
138
|
return configs_suffix
|
|
146
139
|
|
|
147
|
-
|
|
140
|
+
|
|
141
|
+
def conf_s(name, value, ctx=None):
|
|
148
142
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
149
143
|
configs[name] = value
|
|
150
144
|
|
|
151
|
-
|
|
145
|
+
|
|
146
|
+
def conf_r(name, ctx=None):
|
|
152
147
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
153
|
-
if not name in configs:
|
|
148
|
+
if not name in configs:
|
|
149
|
+
return
|
|
154
150
|
del configs[name]
|
|
155
151
|
|
|
156
|
-
|
|
152
|
+
|
|
153
|
+
def conf_d(ctx=None):
|
|
157
154
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
158
155
|
return configs
|
|
159
156
|
|
|
157
|
+
|
|
160
158
|
def conf_ctx():
|
|
161
|
-
return dict(configs
|
|
159
|
+
return dict(configs=dict(), config_f=dict())
|
|
160
|
+
|
|
162
161
|
|
|
163
|
-
def load(names
|
|
162
|
+
def load(names=(FILE_NAME,), path=None, encoding="utf-8", ctx=None):
|
|
164
163
|
paths = []
|
|
165
164
|
homes = get_homes()
|
|
166
165
|
for home in homes:
|
|
@@ -172,43 +171,54 @@ def load(names = (FILE_NAME,), path = None, encoding = "utf-8", ctx = None):
|
|
|
172
171
|
paths.append(path)
|
|
173
172
|
for path in paths:
|
|
174
173
|
for name in names:
|
|
175
|
-
load_file(name
|
|
176
|
-
load_env(ctx
|
|
174
|
+
load_file(name=name, path=path, encoding=encoding, ctx=ctx)
|
|
175
|
+
load_env(ctx=ctx)
|
|
177
176
|
|
|
178
|
-
|
|
177
|
+
|
|
178
|
+
def load_file(name=FILE_NAME, path=None, encoding="utf-8", ctx=None):
|
|
179
179
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
180
180
|
config_f = ctx["config_f"] if ctx else CONFIG_F
|
|
181
181
|
|
|
182
|
-
if path:
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
if path:
|
|
183
|
+
path = os.path.normpath(path)
|
|
184
|
+
if path:
|
|
185
|
+
file_path = os.path.join(path, name)
|
|
186
|
+
else:
|
|
187
|
+
file_path = name
|
|
185
188
|
|
|
186
189
|
file_path = os.path.abspath(file_path)
|
|
187
190
|
file_path = os.path.normpath(file_path)
|
|
188
191
|
base_path = os.path.dirname(file_path)
|
|
189
192
|
|
|
190
193
|
exists = os.path.exists(file_path)
|
|
191
|
-
if not exists:
|
|
194
|
+
if not exists:
|
|
195
|
+
return
|
|
192
196
|
|
|
193
197
|
exists = file_path in config_f
|
|
194
|
-
if exists:
|
|
198
|
+
if exists:
|
|
199
|
+
config_f.remove(file_path)
|
|
195
200
|
config_f.append(file_path)
|
|
196
201
|
|
|
197
202
|
file = open(file_path, "rb")
|
|
198
|
-
try:
|
|
199
|
-
|
|
200
|
-
|
|
203
|
+
try:
|
|
204
|
+
data = file.read()
|
|
205
|
+
finally:
|
|
206
|
+
file.close()
|
|
207
|
+
if not data:
|
|
208
|
+
return
|
|
201
209
|
|
|
202
210
|
data = data.decode(encoding)
|
|
203
211
|
data_j = json.loads(data)
|
|
204
212
|
|
|
205
|
-
_load_includes(base_path, data_j, encoding
|
|
213
|
+
_load_includes(base_path, data_j, encoding=encoding)
|
|
206
214
|
|
|
207
215
|
for key, value in data_j.items():
|
|
208
|
-
if not _is_valid(key):
|
|
216
|
+
if not _is_valid(key):
|
|
217
|
+
continue
|
|
209
218
|
configs[key] = value
|
|
210
219
|
|
|
211
|
-
|
|
220
|
+
|
|
221
|
+
def load_env(ctx=None):
|
|
212
222
|
configs = ctx["configs"] if ctx else CONFIGS
|
|
213
223
|
|
|
214
224
|
config = dict(os.environ)
|
|
@@ -218,28 +228,31 @@ def load_env(ctx = None):
|
|
|
218
228
|
_load_includes(home, config)
|
|
219
229
|
|
|
220
230
|
for key, value in legacy.iteritems(config):
|
|
221
|
-
if not _is_valid(key):
|
|
231
|
+
if not _is_valid(key):
|
|
232
|
+
continue
|
|
222
233
|
configs[key] = value
|
|
223
234
|
is_bytes = legacy.is_bytes(value)
|
|
224
|
-
if not is_bytes:
|
|
235
|
+
if not is_bytes:
|
|
236
|
+
continue
|
|
225
237
|
for encoding in ENV_ENCODINGS:
|
|
226
|
-
try:
|
|
227
|
-
|
|
228
|
-
|
|
238
|
+
try:
|
|
239
|
+
value = value.decode(encoding)
|
|
240
|
+
except UnicodeDecodeError:
|
|
241
|
+
pass
|
|
242
|
+
else:
|
|
243
|
+
break
|
|
229
244
|
configs[key] = value
|
|
230
245
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
default = "~",
|
|
234
|
-
encoding = "utf-8",
|
|
235
|
-
force_default = False
|
|
236
|
-
):
|
|
246
|
+
|
|
247
|
+
def get_homes(file_path=HOME_FILE, default="~", encoding="utf-8", force_default=False):
|
|
237
248
|
global HOMES
|
|
238
|
-
if HOMES:
|
|
249
|
+
if HOMES:
|
|
250
|
+
return HOMES
|
|
239
251
|
|
|
240
252
|
HOMES = os.environ.get("HOMES", None)
|
|
241
253
|
HOMES = HOMES.split(";") if HOMES else HOMES
|
|
242
|
-
if not HOMES == None:
|
|
254
|
+
if not HOMES == None:
|
|
255
|
+
return HOMES
|
|
243
256
|
|
|
244
257
|
default = os.path.expanduser(default)
|
|
245
258
|
default = os.path.abspath(default)
|
|
@@ -249,13 +262,17 @@ def get_homes(
|
|
|
249
262
|
file_path = os.path.expanduser(file_path)
|
|
250
263
|
file_path = os.path.normpath(file_path)
|
|
251
264
|
exists = os.path.exists(file_path)
|
|
252
|
-
if not exists:
|
|
265
|
+
if not exists:
|
|
266
|
+
return HOMES
|
|
253
267
|
|
|
254
|
-
if not force_default:
|
|
268
|
+
if not force_default:
|
|
269
|
+
del HOMES[:]
|
|
255
270
|
|
|
256
271
|
file = open(file_path, "rb")
|
|
257
|
-
try:
|
|
258
|
-
|
|
272
|
+
try:
|
|
273
|
+
data = file.read()
|
|
274
|
+
finally:
|
|
275
|
+
file.close()
|
|
259
276
|
|
|
260
277
|
data = data.decode("utf-8")
|
|
261
278
|
data = data.strip()
|
|
@@ -264,7 +281,8 @@ def get_homes(
|
|
|
264
281
|
|
|
265
282
|
for path in paths:
|
|
266
283
|
path = path.strip()
|
|
267
|
-
if not path:
|
|
284
|
+
if not path:
|
|
285
|
+
continue
|
|
268
286
|
path = os.path.expanduser(path)
|
|
269
287
|
path = os.path.abspath(path)
|
|
270
288
|
path = os.path.normpath(path)
|
|
@@ -272,13 +290,17 @@ def get_homes(
|
|
|
272
290
|
|
|
273
291
|
return HOMES
|
|
274
292
|
|
|
293
|
+
|
|
275
294
|
def _cast_r(cast):
|
|
276
295
|
is_string = type(cast) in legacy.STRINGS
|
|
277
|
-
if is_string:
|
|
278
|
-
|
|
296
|
+
if is_string:
|
|
297
|
+
cast = __builtins__.get(cast, None)
|
|
298
|
+
if not cast:
|
|
299
|
+
return None
|
|
279
300
|
return CASTS.get(cast, cast)
|
|
280
301
|
|
|
281
|
-
|
|
302
|
+
|
|
303
|
+
def _load_includes(base_path, config, encoding="utf-8"):
|
|
282
304
|
includes = ()
|
|
283
305
|
|
|
284
306
|
for alias in IMPORT_NAMES:
|
|
@@ -288,16 +310,15 @@ def _load_includes(base_path, config, encoding = "utf-8"):
|
|
|
288
310
|
includes = includes.split(";")
|
|
289
311
|
|
|
290
312
|
for include in includes:
|
|
291
|
-
load_file(
|
|
292
|
-
|
|
293
|
-
path = base_path,
|
|
294
|
-
encoding = encoding
|
|
295
|
-
)
|
|
313
|
+
load_file(name=include, path=base_path, encoding=encoding)
|
|
314
|
+
|
|
296
315
|
|
|
297
316
|
def _is_valid(key):
|
|
298
|
-
if key in IMPORT_NAMES:
|
|
317
|
+
if key in IMPORT_NAMES:
|
|
318
|
+
return False
|
|
299
319
|
return True
|
|
300
320
|
|
|
321
|
+
|
|
301
322
|
def _is_devel():
|
|
302
323
|
"""
|
|
303
324
|
Simple debug/development level detection mechanism to be
|
|
@@ -315,6 +336,7 @@ def _is_devel():
|
|
|
315
336
|
|
|
316
337
|
return conf("LEVEL", "INFO") in ("DEBUG",)
|
|
317
338
|
|
|
339
|
+
|
|
318
340
|
def _is_secure():
|
|
319
341
|
"""
|
|
320
342
|
Simple secure variable that should be overriden only under
|
|
@@ -327,6 +349,7 @@ def _is_secure():
|
|
|
327
349
|
secured type level of traceability.
|
|
328
350
|
"""
|
|
329
351
|
|
|
330
|
-
return conf("SECURE", True, cast
|
|
352
|
+
return conf("SECURE", True, cast=bool)
|
|
353
|
+
|
|
331
354
|
|
|
332
355
|
load()
|
appier/controller.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"
|
|
@@ -41,6 +32,7 @@ from . import meta
|
|
|
41
32
|
from . import legacy
|
|
42
33
|
from . import observer
|
|
43
34
|
|
|
35
|
+
|
|
44
36
|
class Controller(legacy.with_meta(meta.Indexed, observer.Observable)):
|
|
45
37
|
"""
|
|
46
38
|
Top level abstract controller class from which all the
|
|
@@ -62,12 +54,14 @@ class Controller(legacy.with_meta(meta.Indexed, observer.Observable)):
|
|
|
62
54
|
return getattr(self.owner, name)
|
|
63
55
|
raise AttributeError("'%s' not found" % name)
|
|
64
56
|
|
|
65
|
-
def register(self, lazy
|
|
66
|
-
if lazy:
|
|
57
|
+
def register(self, lazy=False):
|
|
58
|
+
if lazy:
|
|
59
|
+
return
|
|
67
60
|
self.setup()
|
|
68
61
|
|
|
69
|
-
def unregister(self, lazy
|
|
70
|
-
if lazy:
|
|
62
|
+
def unregister(self, lazy=False):
|
|
63
|
+
if lazy:
|
|
64
|
+
return
|
|
71
65
|
self.teardown()
|
|
72
66
|
|
|
73
67
|
def setup(self):
|