appier 1.33.3__tar.gz → 1.33.5__tar.gz

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.
Files changed (104) hide show
  1. {appier-1.33.3/src/appier.egg-info → appier-1.33.5}/PKG-INFO +1 -1
  2. {appier-1.33.3 → appier-1.33.5}/setup.py +1 -1
  3. {appier-1.33.3 → appier-1.33.5}/src/appier/__init__.py +9 -1
  4. {appier-1.33.3 → appier-1.33.5}/src/appier/base.py +31 -6
  5. {appier-1.33.3 → appier-1.33.5}/src/appier/http.py +1 -1
  6. {appier-1.33.3 → appier-1.33.5}/src/appier/scheduler.py +8 -0
  7. {appier-1.33.3 → appier-1.33.5}/src/appier/structures.py +26 -0
  8. {appier-1.33.3 → appier-1.33.5}/src/appier/test/scheduler.py +27 -0
  9. {appier-1.33.3 → appier-1.33.5}/src/appier/test/structures.py +38 -0
  10. {appier-1.33.3 → appier-1.33.5}/src/appier/util.py +1 -1
  11. {appier-1.33.3 → appier-1.33.5/src/appier.egg-info}/PKG-INFO +1 -1
  12. {appier-1.33.3 → appier-1.33.5}/MANIFEST.in +0 -0
  13. {appier-1.33.3 → appier-1.33.5}/README.rst +0 -0
  14. {appier-1.33.3 → appier-1.33.5}/setup.cfg +0 -0
  15. {appier-1.33.3 → appier-1.33.5}/src/appier/amqp.py +0 -0
  16. {appier-1.33.3 → appier-1.33.5}/src/appier/api.py +0 -0
  17. {appier-1.33.3 → appier-1.33.5}/src/appier/asgi.py +0 -0
  18. {appier-1.33.3 → appier-1.33.5}/src/appier/async_neo.py +0 -0
  19. {appier-1.33.3 → appier-1.33.5}/src/appier/async_old.py +0 -0
  20. {appier-1.33.3 → appier-1.33.5}/src/appier/asynchronous.py +0 -0
  21. {appier-1.33.3 → appier-1.33.5}/src/appier/asynchronous.pyi +0 -0
  22. {appier-1.33.3 → appier-1.33.5}/src/appier/base.pyi +0 -0
  23. {appier-1.33.3 → appier-1.33.5}/src/appier/bus.py +0 -0
  24. {appier-1.33.3 → appier-1.33.5}/src/appier/bus.pyi +0 -0
  25. {appier-1.33.3 → appier-1.33.5}/src/appier/cache.py +0 -0
  26. {appier-1.33.3 → appier-1.33.5}/src/appier/cache.pyi +0 -0
  27. {appier-1.33.3 → appier-1.33.5}/src/appier/common.py +0 -0
  28. {appier-1.33.3 → appier-1.33.5}/src/appier/component.py +0 -0
  29. {appier-1.33.3 → appier-1.33.5}/src/appier/component.pyi +0 -0
  30. {appier-1.33.3 → appier-1.33.5}/src/appier/compress.py +0 -0
  31. {appier-1.33.3 → appier-1.33.5}/src/appier/config.py +0 -0
  32. {appier-1.33.3 → appier-1.33.5}/src/appier/controller.py +0 -0
  33. {appier-1.33.3 → appier-1.33.5}/src/appier/crypt.py +0 -0
  34. {appier-1.33.3 → appier-1.33.5}/src/appier/data.py +0 -0
  35. {appier-1.33.3 → appier-1.33.5}/src/appier/data.pyi +0 -0
  36. {appier-1.33.3 → appier-1.33.5}/src/appier/defines.py +0 -0
  37. {appier-1.33.3 → appier-1.33.5}/src/appier/exceptions.py +0 -0
  38. {appier-1.33.3 → appier-1.33.5}/src/appier/execution.py +0 -0
  39. {appier-1.33.3 → appier-1.33.5}/src/appier/export.py +0 -0
  40. {appier-1.33.3 → appier-1.33.5}/src/appier/extra.py +0 -0
  41. {appier-1.33.3 → appier-1.33.5}/src/appier/extra_neo.py +0 -0
  42. {appier-1.33.3 → appier-1.33.5}/src/appier/extra_old.py +0 -0
  43. {appier-1.33.3 → appier-1.33.5}/src/appier/geo.py +0 -0
  44. {appier-1.33.3 → appier-1.33.5}/src/appier/git.py +0 -0
  45. {appier-1.33.3 → appier-1.33.5}/src/appier/graph.py +0 -0
  46. {appier-1.33.3 → appier-1.33.5}/src/appier/legacy.py +0 -0
  47. {appier-1.33.3 → appier-1.33.5}/src/appier/log.py +0 -0
  48. {appier-1.33.3 → appier-1.33.5}/src/appier/meta.py +0 -0
  49. {appier-1.33.3 → appier-1.33.5}/src/appier/mock.py +0 -0
  50. {appier-1.33.3 → appier-1.33.5}/src/appier/model.py +0 -0
  51. {appier-1.33.3 → appier-1.33.5}/src/appier/model.pyi +0 -0
  52. {appier-1.33.3 → appier-1.33.5}/src/appier/model_a.py +0 -0
  53. {appier-1.33.3 → appier-1.33.5}/src/appier/mongo.py +0 -0
  54. {appier-1.33.3 → appier-1.33.5}/src/appier/observer.py +0 -0
  55. {appier-1.33.3 → appier-1.33.5}/src/appier/part.py +0 -0
  56. {appier-1.33.3 → appier-1.33.5}/src/appier/part.pyi +0 -0
  57. {appier-1.33.3 → appier-1.33.5}/src/appier/preferences.py +0 -0
  58. {appier-1.33.3 → appier-1.33.5}/src/appier/preferences.pyi +0 -0
  59. {appier-1.33.3 → appier-1.33.5}/src/appier/queuing.py +0 -0
  60. {appier-1.33.3 → appier-1.33.5}/src/appier/redisdb.py +0 -0
  61. {appier-1.33.3 → appier-1.33.5}/src/appier/request.py +0 -0
  62. {appier-1.33.3 → appier-1.33.5}/src/appier/res/static/css/base.css +0 -0
  63. {appier-1.33.3 → appier-1.33.5}/src/appier/res/static/images/favicon.ico +0 -0
  64. {appier-1.33.3 → appier-1.33.5}/src/appier/res/static/js/base.js +0 -0
  65. {appier-1.33.3 → appier-1.33.5}/src/appier/res/templates/error.html.tpl +0 -0
  66. {appier-1.33.3 → appier-1.33.5}/src/appier/res/templates/holder.html.tpl +0 -0
  67. {appier-1.33.3 → appier-1.33.5}/src/appier/res/templates/layout.html.tpl +0 -0
  68. {appier-1.33.3 → appier-1.33.5}/src/appier/scheduler.pyi +0 -0
  69. {appier-1.33.3 → appier-1.33.5}/src/appier/serialize.py +0 -0
  70. {appier-1.33.3 → appier-1.33.5}/src/appier/session.py +0 -0
  71. {appier-1.33.3 → appier-1.33.5}/src/appier/session.pyi +0 -0
  72. {appier-1.33.3 → appier-1.33.5}/src/appier/settings.py +0 -0
  73. {appier-1.33.3 → appier-1.33.5}/src/appier/smtp.py +0 -0
  74. {appier-1.33.3 → appier-1.33.5}/src/appier/storage.py +0 -0
  75. {appier-1.33.3 → appier-1.33.5}/src/appier/test/__init__.py +0 -0
  76. {appier-1.33.3 → appier-1.33.5}/src/appier/test/base.py +0 -0
  77. {appier-1.33.3 → appier-1.33.5}/src/appier/test/cache.py +0 -0
  78. {appier-1.33.3 → appier-1.33.5}/src/appier/test/config.py +0 -0
  79. {appier-1.33.3 → appier-1.33.5}/src/appier/test/crypt.py +0 -0
  80. {appier-1.33.3 → appier-1.33.5}/src/appier/test/data.py +0 -0
  81. {appier-1.33.3 → appier-1.33.5}/src/appier/test/exceptions.py +0 -0
  82. {appier-1.33.3 → appier-1.33.5}/src/appier/test/export.py +0 -0
  83. {appier-1.33.3 → appier-1.33.5}/src/appier/test/graph.py +0 -0
  84. {appier-1.33.3 → appier-1.33.5}/src/appier/test/http.py +0 -0
  85. {appier-1.33.3 → appier-1.33.5}/src/appier/test/legacy.py +0 -0
  86. {appier-1.33.3 → appier-1.33.5}/src/appier/test/log.py +0 -0
  87. {appier-1.33.3 → appier-1.33.5}/src/appier/test/mock.py +0 -0
  88. {appier-1.33.3 → appier-1.33.5}/src/appier/test/model.py +0 -0
  89. {appier-1.33.3 → appier-1.33.5}/src/appier/test/part.py +0 -0
  90. {appier-1.33.3 → appier-1.33.5}/src/appier/test/preferences.py +0 -0
  91. {appier-1.33.3 → appier-1.33.5}/src/appier/test/queuing.py +0 -0
  92. {appier-1.33.3 → appier-1.33.5}/src/appier/test/request.py +0 -0
  93. {appier-1.33.3 → appier-1.33.5}/src/appier/test/serialize.py +0 -0
  94. {appier-1.33.3 → appier-1.33.5}/src/appier/test/session.py +0 -0
  95. {appier-1.33.3 → appier-1.33.5}/src/appier/test/smtp.py +0 -0
  96. {appier-1.33.3 → appier-1.33.5}/src/appier/test/typesf.py +0 -0
  97. {appier-1.33.3 → appier-1.33.5}/src/appier/test/util.py +0 -0
  98. {appier-1.33.3 → appier-1.33.5}/src/appier/test/validation.py +0 -0
  99. {appier-1.33.3 → appier-1.33.5}/src/appier/typesf.py +0 -0
  100. {appier-1.33.3 → appier-1.33.5}/src/appier/validation.py +0 -0
  101. {appier-1.33.3 → appier-1.33.5}/src/appier.egg-info/SOURCES.txt +0 -0
  102. {appier-1.33.3 → appier-1.33.5}/src/appier.egg-info/dependency_links.txt +0 -0
  103. {appier-1.33.3 → appier-1.33.5}/src/appier.egg-info/not-zip-safe +0 -0
  104. {appier-1.33.3 → appier-1.33.5}/src/appier.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: appier
3
- Version: 1.33.3
3
+ Version: 1.33.5
4
4
  Summary: Appier Framework
5
5
  Home-page: http://appier.hive.pt
6
6
  Author: Hive Solutions Lda.
@@ -44,7 +44,7 @@ def read_file(path):
44
44
 
45
45
  setuptools.setup(
46
46
  name="appier",
47
- version="1.33.3",
47
+ version="1.33.5",
48
48
  author="Hive Solutions Lda.",
49
49
  author_email="development@hive.pt",
50
50
  description="Appier Framework",
@@ -291,7 +291,15 @@ from .smtp import (
291
291
  header,
292
292
  )
293
293
  from .storage import StorageEngine, BaseEngine, FsEngine
294
- from .structures import OrderedDict, LazyDict, LazyValue, GeneratorFile, lazy_dict, lazy
294
+ from .structures import (
295
+ OrderedDict,
296
+ LazyDict,
297
+ LazyValue,
298
+ GeneratorFile,
299
+ LimitedSizeDict,
300
+ lazy_dict,
301
+ lazy,
302
+ )
295
303
  from .typesf import (
296
304
  AbstractType,
297
305
  Type,
@@ -94,7 +94,7 @@ NAME = "appier"
94
94
  """ The name to be used to describe the framework while working
95
95
  on its own environment, this is just a descriptive value """
96
96
 
97
- VERSION = "1.33.3"
97
+ VERSION = "1.33.5"
98
98
  """ The version of the framework that is currently installed
99
99
  this value may be used for debugging/diagnostic purposes """
100
100
 
@@ -4207,6 +4207,35 @@ class App(
4207
4207
  )
4208
4208
  line = line.decode(encoding, "ignore") if legacy.is_bytes(line) else line
4209
4209
 
4210
+ # runs the template for the path, so that it's possible to better
4211
+ # understand the origin of the path execution
4212
+ path_f = template % (path, lineno, context)
4213
+
4214
+ # in case the path to the file does not exists, then there's nothing
4215
+ # remaining to be done in terms of specific stack format
4216
+ if not path or not os.path.exists(path):
4217
+ # creates the "file-less" item dictionary to be used to a certain
4218
+ # degree of debuggability
4219
+ item_d = dict(
4220
+ id=id,
4221
+ path=path,
4222
+ path_f=path_f,
4223
+ line=line,
4224
+ lineno=lineno,
4225
+ context=context,
4226
+ lines=[],
4227
+ lines_b=[],
4228
+ )
4229
+ cls._extended_handle(item_d)
4230
+
4231
+ # adds the newly created formatted item to the list of formatted
4232
+ # items to be returned at the end of the method execution
4233
+ formatted.append(item_d)
4234
+
4235
+ # continues the loop as this is not a valid file and no
4236
+ # further information can be retrieved
4237
+ continue
4238
+
4210
4239
  # opens the current file in stack trace and reads the complete
4211
4240
  # contents from it so that the target lines may be read
4212
4241
  file = open(path, "rb")
@@ -4220,7 +4249,7 @@ class App(
4220
4249
  contents_d = contents.decode(encoding, "ignore")
4221
4250
 
4222
4251
  # generates a new random identifier for the current stack item
4223
- # this is going to be used to identify it univocally
4252
+ # this is going to be used to identify it uniquely
4224
4253
  id = str(uuid.uuid4())
4225
4254
 
4226
4255
  # normalizes the currently extracted path by ensuring that it's
@@ -4259,10 +4288,6 @@ class App(
4259
4288
  # directly print the complete set of lines in the structure
4260
4289
  lines_b = legacy.u("\n").join((line["line"] for line in lines))
4261
4290
 
4262
- # runs the template for the path, so that it's possible to better
4263
- # understand the origin of the path execution
4264
- path_f = template % (path, lineno, context)
4265
-
4266
4291
  # creates the dictionary that contains the complete set of information
4267
4292
  # about the current line in the stack and then runs the pipeline of
4268
4293
  # operation in it to properly process it
@@ -1120,7 +1120,7 @@ def _quote(values, plus=False, safe="/"):
1120
1120
 
1121
1121
  final = dict()
1122
1122
 
1123
- for key, value in values.items():
1123
+ for key, value in values:
1124
1124
  key = method(key, safe=safe)
1125
1125
  value = method(value[0], safe=safe)
1126
1126
  final[key] = value
@@ -187,6 +187,14 @@ class SchedulerTask(object):
187
187
  self.date = SchedulerDate.from_cron(cron)
188
188
  self._enabled = True
189
189
 
190
+ def __eq__(self, other):
191
+ if isinstance(other, self.__class__):
192
+ return True
193
+ return False
194
+
195
+ def __lt__(self, other):
196
+ return False
197
+
190
198
  def enable(self):
191
199
  self._enabled = True
192
200
 
@@ -29,6 +29,7 @@ __license__ = "Apache License, Version 2.0"
29
29
  """ The license for the module """
30
30
 
31
31
  import os
32
+ import collections
32
33
 
33
34
 
34
35
  class OrderedDict(dict):
@@ -280,5 +281,30 @@ class GeneratorFile(object):
280
281
  self._generator.close()
281
282
 
282
283
 
284
+ class LimitedSizeDict(dict):
285
+ """
286
+ Size limited dictionary that removes the oldest item
287
+ once the maximum size is reached.
288
+
289
+ Useful for caching purposes where the cache should have
290
+ a limited size and the oldest items should be removed
291
+ once the maximum size is reached, constrains memory usage.
292
+ """
293
+
294
+ def __init__(self, max_size=128):
295
+ dict.__init__(self)
296
+ self.max_size = max_size
297
+ self._order = collections.deque()
298
+
299
+ def __setitem__(self, key, value):
300
+ if key in self:
301
+ self._order.remove(key)
302
+ elif len(self) >= self.max_size:
303
+ oldest_key = self._order.popleft()
304
+ del self[oldest_key]
305
+ dict.__setitem__(self, key, value)
306
+ self._order.append(key)
307
+
308
+
283
309
  lazy_dict = LazyDict
284
310
  lazy = LazyValue
@@ -134,6 +134,33 @@ class CronSchedulerTest(unittest.TestCase):
134
134
  scheduler.next_run(), datetime.datetime(2013, 4, 10, hour=0, minute=11)
135
135
  )
136
136
 
137
+ def test_duplicate(self):
138
+ state = dict(value=0)
139
+
140
+ def increment():
141
+ state["value"] += 1
142
+
143
+ scheduler = appier.CronScheduler(None)
144
+ task1 = scheduler.schedule(
145
+ lambda: increment(),
146
+ appier.SchedulerDate(minutes=11, days_of_month=10, days_of_week=2),
147
+ now=datetime.datetime(2013, 1, 1, hour=1, minute=1),
148
+ )
149
+ task2 = scheduler.schedule(
150
+ lambda: increment(),
151
+ appier.SchedulerDate(minutes=11, days_of_month=10, days_of_week=2),
152
+ now=datetime.datetime(2013, 1, 1, hour=1, minute=1),
153
+ )
154
+ self.assertNotEqual(task1, None)
155
+ self.assertNotEqual(task2, None)
156
+ self.assertEqual(isinstance(task1, appier.SchedulerTask), True)
157
+ self.assertEqual(isinstance(task2, appier.SchedulerTask), True)
158
+ self.assertEqual(task1.enabled, True)
159
+ self.assertEqual(task2.enabled, True)
160
+ self.assertEqual(
161
+ scheduler.next_run(), datetime.datetime(2013, 4, 10, hour=0, minute=11)
162
+ )
163
+
137
164
 
138
165
  class SchedulerDateTest(unittest.TestCase):
139
166
 
@@ -220,3 +220,41 @@ class LazyDictTest(unittest.TestCase):
220
220
  self.assertEqual(struct["first"], 1)
221
221
  self.assertEqual(isinstance(struct.__getitem__("second", True), int), True)
222
222
  self.assertEqual(struct["second"], 2)
223
+
224
+
225
+ class LimitedSizeDictTest(unittest.TestCase):
226
+ def setUp(self):
227
+ self.dict_size = 1024
228
+ self.limited_dict = appier.LimitedSizeDict(self.dict_size)
229
+
230
+ def test_add_single_item(self):
231
+ self.limited_dict["first"] = "first_value"
232
+ self.assertIn("first", self.limited_dict)
233
+ self.assertEqual(self.limited_dict["first"], "first_value")
234
+
235
+ def test_exceeding_size_limit(self):
236
+ for index in range(self.dict_size + 1):
237
+ self.limited_dict["key_%d" % index] = "value_%d" % index
238
+ self.assertNotIn("key_0", self.limited_dict)
239
+ self.assertIn("key_%d" % self.dict_size, self.limited_dict)
240
+
241
+ def test_maintaining_order(self):
242
+ for index in range(self.dict_size):
243
+ self.limited_dict["key_%d" % index] = "value_%d" % index
244
+ self.limited_dict["new_key"] = "new_value"
245
+ self.assertNotIn("key_0", self.limited_dict)
246
+ self.assertIn("new_key", self.limited_dict)
247
+ self.assertEqual(self.limited_dict["new_key"], "new_value")
248
+
249
+ def test_update_existing_key(self):
250
+ self.limited_dict["first"] = "first_value"
251
+ self.limited_dict["first"] = "second_value"
252
+ self.assertEqual(self.limited_dict["first"], "second_value")
253
+ self.assertEqual(len(self.limited_dict), 1)
254
+
255
+ def test_repr(self):
256
+ self.limited_dict["first"] = "first_value"
257
+ self.limited_dict["second"] = "second_value"
258
+ repr_str = repr(self.limited_dict)
259
+ self.assertIn("'first': 'first_value'", repr_str)
260
+ self.assertIn("'second': 'second_value'", repr_str)
@@ -503,7 +503,7 @@ def install_pip(package, delayed=False, isolated=True, user=None):
503
503
  result = pip_main(args)
504
504
  if result == 0:
505
505
  return
506
- raise exceptions.OperationalError(message="pip error")
506
+ raise exceptions.OperationalError(message="pip error, exit code (%d)" % result)
507
507
 
508
508
 
509
509
  def install_pip_s(package, delayed=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: appier
3
- Version: 1.33.3
3
+ Version: 1.33.5
4
4
  Summary: Appier Framework
5
5
  Home-page: http://appier.hive.pt
6
6
  Author: Hive Solutions Lda.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes