syncmodels 0.1.312__py2.py3-none-any.whl → 0.1.314__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.
- syncmodels/__init__.py +1 -1
- syncmodels/crawler.py +30 -13
- syncmodels/definitions.py +2 -0
- syncmodels/exceptions.py +4 -0
- syncmodels/helpers/orion.py +2 -1
- syncmodels/logic/browser.py +5 -3
- syncmodels/model/__init__.py +1 -0
- syncmodels/model/model.py +1 -1
- syncmodels/runner.py +5 -0
- syncmodels/storage.py +102 -37
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/METADATA +2 -2
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/RECORD +17 -17
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/AUTHORS.rst +0 -0
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/LICENSE +0 -0
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/WHEEL +0 -0
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/entry_points.txt +0 -0
- {syncmodels-0.1.312.dist-info → syncmodels-0.1.314.dist-info}/top_level.txt +0 -0
syncmodels/__init__.py
CHANGED
syncmodels/crawler.py
CHANGED
@@ -152,7 +152,7 @@ from syncmodels.http import (
|
|
152
152
|
# from syncmodels.registry import iRegistry
|
153
153
|
from syncmodels.auth import iAuthenticator
|
154
154
|
from syncmodels.storage import WaveStorage, Storage
|
155
|
-
from syncmodels.exceptions import NonRecoverable, NonRecoverableAuth, BadData
|
155
|
+
from syncmodels.exceptions import BadLogic, NonRecoverable, NonRecoverableAuth, BadData
|
156
156
|
from syncmodels.syncmodels import SyncModel, COPY
|
157
157
|
from .crud import parse_duri, DEFAULT_DATABASE, DEFAULT_NAMESPACE
|
158
158
|
|
@@ -217,7 +217,7 @@ class iAgent(iRunner):
|
|
217
217
|
include=None,
|
218
218
|
exclude=None,
|
219
219
|
credentials=None,
|
220
|
-
prefix=
|
220
|
+
prefix="",
|
221
221
|
*args,
|
222
222
|
**kw,
|
223
223
|
):
|
@@ -235,9 +235,8 @@ class iAgent(iRunner):
|
|
235
235
|
}
|
236
236
|
|
237
237
|
# prefix template
|
238
|
-
|
239
|
-
|
240
|
-
self.prefix = prefix
|
238
|
+
self.prefix_template = self._compile_template(prefix)
|
239
|
+
self.prefix = prefix
|
241
240
|
|
242
241
|
# config file
|
243
242
|
if not config_path:
|
@@ -268,6 +267,11 @@ class iAgent(iRunner):
|
|
268
267
|
|
269
268
|
return template
|
270
269
|
|
270
|
+
async def start(self):
|
271
|
+
"start runner"
|
272
|
+
await super().start()
|
273
|
+
await self._bootstrap()
|
274
|
+
|
271
275
|
async def _bootstrap(self):
|
272
276
|
"Add the initial tasks to be executed by agent"
|
273
277
|
log.debug(">> [%s] entering bootstrap()", self.name)
|
@@ -403,7 +407,7 @@ class iAgent(iRunner):
|
|
403
407
|
log.debug("+ Task: [%s]: [%s] %s", i, self.name, task)
|
404
408
|
|
405
409
|
# TODO: agp: generalize and provide a better way to save activity records
|
406
|
-
if activity_logger := getattr(self, "activity_logger"):
|
410
|
+
if activity_logger := getattr(self, "activity_logger", None):
|
407
411
|
if activity := task.get(ACTIVITY_LOG_KEY):
|
408
412
|
activity.status = "pending"
|
409
413
|
await activity_logger.update_activity(activity)
|
@@ -766,6 +770,10 @@ class iBot(iAgent):
|
|
766
770
|
# abort responsability chain
|
767
771
|
log.error("Inexpected responsability chain abortion")
|
768
772
|
break
|
773
|
+
except (BadLogic,) as why:
|
774
|
+
# separate to have more fine grain control
|
775
|
+
await self.handle_non_recoverable(why, context)
|
776
|
+
|
769
777
|
except Exception as why:
|
770
778
|
log.error(why)
|
771
779
|
log.error("".join(traceback.format_exception(*sys.exc_info())))
|
@@ -1067,7 +1075,7 @@ class iBot(iAgent):
|
|
1067
1075
|
result = await extract_result(response)
|
1068
1076
|
# result = await response.text()
|
1069
1077
|
log.error(
|
1070
|
-
"[%s] server sent: %s",
|
1078
|
+
"Forbidden [%s] server sent: %s",
|
1071
1079
|
response.status,
|
1072
1080
|
result,
|
1073
1081
|
)
|
@@ -1635,6 +1643,21 @@ class SortPlugin(iPlugin):
|
|
1635
1643
|
kind = context.get(KIND_KEY)
|
1636
1644
|
SortKeyFinder.register(kind, sort_key)
|
1637
1645
|
|
1646
|
+
mapper = self.bot.parent.MAPPERS.get(kind)
|
1647
|
+
if not mapper:
|
1648
|
+
log.error("cant find mapper [%s] in crawler??", kind)
|
1649
|
+
return
|
1650
|
+
|
1651
|
+
# TODO: unify this code (exists sort_key or not exists)
|
1652
|
+
model = mapper.PYDANTIC
|
1653
|
+
item_fields = model.model_fields
|
1654
|
+
reverse = list(set(sort_key).intersection(item_fields))
|
1655
|
+
if not reverse:
|
1656
|
+
log.error("model [%s] has not datetime alike key??", model)
|
1657
|
+
return
|
1658
|
+
|
1659
|
+
context[REVERSE_SORT_KEY] = reverse
|
1660
|
+
|
1638
1661
|
def order(data, accessor):
|
1639
1662
|
result = data
|
1640
1663
|
for key in accessor:
|
@@ -1642,7 +1665,6 @@ class SortPlugin(iPlugin):
|
|
1642
1665
|
result = result[key]
|
1643
1666
|
except Exception as why:
|
1644
1667
|
pass
|
1645
|
-
|
1646
1668
|
return result
|
1647
1669
|
|
1648
1670
|
stream.sort(key=partial(order, accessor=sort_key))
|
@@ -2521,11 +2543,6 @@ class iAsyncCrawler(iCrawler):
|
|
2521
2543
|
# TODO: REVIEW: always is a single value (len==1), why not return waves[0]
|
2522
2544
|
return waves
|
2523
2545
|
|
2524
|
-
async def start(self):
|
2525
|
-
"start runner"
|
2526
|
-
await super().start()
|
2527
|
-
await self._bootstrap()
|
2528
|
-
|
2529
2546
|
async def idle(self):
|
2530
2547
|
"default implementation when loop has nothing to do"
|
2531
2548
|
# check running bots
|
syncmodels/definitions.py
CHANGED
syncmodels/exceptions.py
CHANGED
syncmodels/helpers/orion.py
CHANGED
@@ -117,7 +117,7 @@ class OrionInjector:
|
|
117
117
|
"put",
|
118
118
|
self.target_url
|
119
119
|
# + "/v2/entities/{id}/attrs?options=append,keyValues",
|
120
|
-
+ "/v2/entities/{id}/attrs",
|
120
|
+
+ "/v2/entities/{id}/attrs?type={type}",
|
121
121
|
self.FULL_EXCLUDE,
|
122
122
|
],
|
123
123
|
),
|
@@ -137,6 +137,7 @@ class OrionInjector:
|
|
137
137
|
self.target_url
|
138
138
|
# + "/v2/entities/{id}/attrs?options=append,keyValues",
|
139
139
|
+ "/v2/entities/{id}",
|
140
|
+
# + "/v2/entities/{id}?type={type}", # TODO: avoid posibly 409 if id is used in other fs_pathservice
|
140
141
|
# self.EXCLUDE_ALL,
|
141
142
|
self.FULL_EXCLUDE,
|
142
143
|
],
|
syncmodels/logic/browser.py
CHANGED
@@ -45,7 +45,7 @@ from syncmodels.crud import parse_duri
|
|
45
45
|
from ..definitions import TASK_KEY, KIND_KEY, ORG_URL, DURI, ID_KEY, VOL_DATA
|
46
46
|
from ..session import iSession
|
47
47
|
from ..crawler import iBot
|
48
|
-
from ..crawler import MetaExtractPlugin, PutPlugin, SetURIPlugin
|
48
|
+
from ..crawler import MetaExtractPlugin, PutPlugin, SetURIPlugin, SortPlugin
|
49
49
|
|
50
50
|
from .swarm import SwarmBot, SwarmCrawler, SWARM_REGISTER, SWARM_TASKS
|
51
51
|
from .analyzer import XPathAnalyzer
|
@@ -717,13 +717,15 @@ class BrowserLogicBot(SwarmBot):
|
|
717
717
|
)
|
718
718
|
|
719
719
|
def _add_plugins(self):
|
720
|
-
super()._add_plugins()
|
720
|
+
# super()._add_plugins()
|
721
|
+
# self.plugins.clear()
|
721
722
|
|
722
|
-
self.plugins.clear()
|
723
723
|
# self.add_plugin(HashStreamPlugin())
|
724
724
|
self.add_plugin(MetaExtractPlugin(geojson=False))
|
725
725
|
self.add_plugin(PutPlugin())
|
726
726
|
self.add_plugin(SetURIPlugin())
|
727
|
+
# self.add_plugin(SortPlugin())
|
728
|
+
|
727
729
|
# self.add_plugin(RenameKeys())
|
728
730
|
# self.add_plugin(UnwrapResponse())
|
729
731
|
# self.add_plugin(RegExtractor())
|
syncmodels/model/__init__.py
CHANGED
syncmodels/model/model.py
CHANGED
@@ -23,7 +23,7 @@ from typing_extensions import Annotated
|
|
23
23
|
from pydantic import BaseModel as _BaseModel
|
24
24
|
from pydantic import Field
|
25
25
|
from pydantic import PlainSerializer, BeforeValidator
|
26
|
-
from pydantic.functional_validators import field_validator
|
26
|
+
from pydantic.functional_validators import field_validator, model_validator
|
27
27
|
|
28
28
|
# from pydantic.dataclasses import dataclass
|
29
29
|
|
syncmodels/runner.py
CHANGED
@@ -62,7 +62,9 @@ class iRunner:
|
|
62
62
|
self.t0 = 0
|
63
63
|
self.t1 = 0
|
64
64
|
self.nice = 600
|
65
|
+
self.clock = 0
|
65
66
|
|
67
|
+
self.hooks = []
|
66
68
|
self.stop_when_empty = stop_when_empty
|
67
69
|
|
68
70
|
self._wip = []
|
@@ -160,6 +162,9 @@ class iRunner:
|
|
160
162
|
if not func:
|
161
163
|
func = getattr(self, task[FUNC_KEY]) # let fail with AttributeError
|
162
164
|
await func(**task)
|
165
|
+
self.clock += 1
|
166
|
+
for hook in self.hooks:
|
167
|
+
await hook(**task)
|
163
168
|
|
164
169
|
async def idle(self):
|
165
170
|
"default implementation when loop has nothing to do"
|
syncmodels/storage.py
CHANGED
@@ -9,7 +9,7 @@ import time
|
|
9
9
|
import sys
|
10
10
|
import traceback
|
11
11
|
from typing import List
|
12
|
-
from datetime import timedelta
|
12
|
+
from datetime import timedelta, datetime
|
13
13
|
import pytz
|
14
14
|
from multiprocessing import Process
|
15
15
|
import random
|
@@ -26,7 +26,13 @@ from surrealist import Surreal as Surrealist
|
|
26
26
|
|
27
27
|
from agptools.logs import logger
|
28
28
|
from agptools.helpers import parse_uri, build_uri, DATE, tf
|
29
|
-
from agptools.containers import
|
29
|
+
from agptools.containers import (
|
30
|
+
merge as merge_dict,
|
31
|
+
build_dict,
|
32
|
+
json_compatible,
|
33
|
+
Walk,
|
34
|
+
CWalk,
|
35
|
+
)
|
30
36
|
|
31
37
|
from syncmodels.definitions import (
|
32
38
|
REVERSE_SORT_KEY,
|
@@ -40,6 +46,13 @@ from syncmodels.http import (
|
|
40
46
|
# USER_AGENT,
|
41
47
|
APPLICATION_JSON,
|
42
48
|
)
|
49
|
+
from syncmodels.exceptions import (
|
50
|
+
SyncModelException,
|
51
|
+
BadLogic,
|
52
|
+
NonRecoverable,
|
53
|
+
NonRecoverableAuth,
|
54
|
+
BadData,
|
55
|
+
)
|
43
56
|
|
44
57
|
from .helpers.importers import JSONVerter
|
45
58
|
|
@@ -72,6 +85,7 @@ from .definitions import (
|
|
72
85
|
SORT_KEY,
|
73
86
|
LIMIT_KEY,
|
74
87
|
WAVE_LAST_KEY,
|
88
|
+
COMPARISON_PATTERNS,
|
75
89
|
)
|
76
90
|
from .crud import (
|
77
91
|
DEFAULT_DATABASE,
|
@@ -120,6 +134,12 @@ UTC_TZ = pytz.timezone("UTC")
|
|
120
134
|
|
121
135
|
|
122
136
|
# REGEXP_FQUI = re.compile(r"((?P<ns>[^/]*?)/)?(?P<table>[^:]+):(?P<uid>.*)$")
|
137
|
+
|
138
|
+
|
139
|
+
def comparable_struct(data, patterns):
|
140
|
+
wdata = Walk(data)
|
141
|
+
|
142
|
+
|
123
143
|
def split_fqui(fqid):
|
124
144
|
"try to split FQUID into table and uid"
|
125
145
|
try:
|
@@ -129,6 +149,20 @@ def split_fqui(fqid):
|
|
129
149
|
return fqid, None
|
130
150
|
|
131
151
|
|
152
|
+
def normalize_payload(data, keys):
|
153
|
+
for key in set(keys or []).intersection(data):
|
154
|
+
value = DATE(data[key])
|
155
|
+
if isinstance(value, datetime):
|
156
|
+
if not value.tzinfo:
|
157
|
+
value = pytz.utc.localize(value)
|
158
|
+
value = value.astimezone(UTC_TZ)
|
159
|
+
value = value.strftime("%Y-%m-%dT%H:%M:%SZ")
|
160
|
+
|
161
|
+
data[key] = value
|
162
|
+
|
163
|
+
return data
|
164
|
+
|
165
|
+
|
132
166
|
# ---------------------------------------------------------
|
133
167
|
# Data Store / Ignore Policies
|
134
168
|
# ---------------------------------------------------------
|
@@ -763,7 +797,7 @@ class WaveStorage(iWaves, iStorage):
|
|
763
797
|
|
764
798
|
2. if the object has been inserted in `tube` then:
|
765
799
|
- create / update Snapshot
|
766
|
-
-
|
800
|
+
- create / update Wave info with original the original query data
|
767
801
|
|
768
802
|
|
769
803
|
e: exists
|
@@ -804,8 +838,8 @@ class WaveStorage(iWaves, iStorage):
|
|
804
838
|
if model := kw.get(MODEL_KEY):
|
805
839
|
self.register_metadata(uri, {"model": model})
|
806
840
|
|
807
|
-
sort_keys = kw.get(SORT_KEY
|
808
|
-
reverse_sort_keys = kw.get(REVERSE_SORT_KEY
|
841
|
+
sort_keys = kw.get(SORT_KEY) or []
|
842
|
+
reverse_sort_keys = kw.get(REVERSE_SORT_KEY) or []
|
809
843
|
sort_kw_presence = all([kw.get(_) for _ in sort_keys])
|
810
844
|
sort_data_presence = all([data.get(_) for _ in reverse_sort_keys])
|
811
845
|
|
@@ -830,7 +864,7 @@ class WaveStorage(iWaves, iStorage):
|
|
830
864
|
# stream = [kw]
|
831
865
|
if not (sort_keys := SortKeyFinder.find_sort_key(stream=stream)):
|
832
866
|
kind = kw.get(KIND_KEY)
|
833
|
-
sort_keys = kw[SORT_KEY] = SortKeyFinder.get(kind)
|
867
|
+
sort_keys = kw[SORT_KEY] = SortKeyFinder.get(kind) or []
|
834
868
|
|
835
869
|
kw[SORT_KEY] = sort_keys
|
836
870
|
log.debug("[%s] found: %s as sort_keys", uri, sort_keys)
|
@@ -853,8 +887,11 @@ class WaveStorage(iWaves, iStorage):
|
|
853
887
|
# now
|
854
888
|
# ['2005-06-01T00:00:00.000+02:00']
|
855
889
|
# [datetime.datetime(2005, 6, 1, 0, 0, tzinfo=tzoffset(None, 7200))]
|
890
|
+
|
891
|
+
normalize_payload(data, sort_keys)
|
892
|
+
|
856
893
|
monotonic = data.setdefault(MONOTONIC_KEY, monotonic_wave())
|
857
|
-
for monotonic_key in set(sort_keys
|
894
|
+
for monotonic_key in set(sort_keys).intersection(data):
|
858
895
|
monotonic_value = DATE(data[monotonic_key])
|
859
896
|
|
860
897
|
# seconds
|
@@ -868,7 +905,6 @@ class WaveStorage(iWaves, iStorage):
|
|
868
905
|
since_value = pytz.utc.localize(since_value)
|
869
906
|
since_value = since_value.astimezone(UTC_TZ)
|
870
907
|
since_value = since_value.strftime("%Y-%m-%dT%H:%M:%SZ")
|
871
|
-
|
872
908
|
break
|
873
909
|
else:
|
874
910
|
monotonic_key = MONOTONIC_KEY # ??
|
@@ -878,8 +914,8 @@ class WaveStorage(iWaves, iStorage):
|
|
878
914
|
|
879
915
|
query = f"{namespace}://{database}/{thing}"
|
880
916
|
|
881
|
-
|
882
|
-
data_sort_blueprint =
|
917
|
+
data_sort_blueprint = build_dict(data, sort_keys)
|
918
|
+
# data_sort_blueprint = build_comparisson_dict(data, reverse_sort_keys)
|
883
919
|
blueprint = {
|
884
920
|
MONOTONIC_SINCE_KEY: monotonic_key,
|
885
921
|
MONOTONIC_SINCE_VALUE: since_value,
|
@@ -890,7 +926,7 @@ class WaveStorage(iWaves, iStorage):
|
|
890
926
|
LIMIT_KEY, 50 # TODO: agp: set in definition?
|
891
927
|
), # TODO: this is temporal, ideally None
|
892
928
|
ORG_KEY: uid,
|
893
|
-
**data_sort_blueprint, # implies sv = True
|
929
|
+
# **data_sort_blueprint, # implies sv = True
|
894
930
|
}
|
895
931
|
# TODO: LIMIT 1 ?
|
896
932
|
|
@@ -904,8 +940,6 @@ class WaveStorage(iWaves, iStorage):
|
|
904
940
|
sort_keys,
|
905
941
|
MASK,
|
906
942
|
)
|
907
|
-
# existing = await self.storage.query(query, **blueprint)
|
908
|
-
# N = len(existing)
|
909
943
|
|
910
944
|
# TODO: agp: cache and get behaviour from database?
|
911
945
|
if not (behavior := self.behavior_uri.get(query)):
|
@@ -922,64 +956,93 @@ class WaveStorage(iWaves, iStorage):
|
|
922
956
|
self.behavior_uri[query] = behavior
|
923
957
|
|
924
958
|
t0 = time.time()
|
925
|
-
|
959
|
+
# search the same data
|
960
|
+
# TODO: update blueprint
|
961
|
+
blueprint = {
|
962
|
+
# MONOTONIC_SINCE_KEY: monotonic_key,
|
963
|
+
# MONOTONIC_SINCE_VALUE: since_value,
|
964
|
+
# MONOTONIC_SINCE_OPERATOR: ">=",
|
965
|
+
# ORDER_KEY: monotonic_key,
|
966
|
+
# DIRECTION_KEY: DIRECTION_DESC,
|
967
|
+
LIMIT_KEY: kw.get(
|
968
|
+
LIMIT_KEY, 50 # TODO: agp: set in definition?
|
969
|
+
), # TODO: this is temporal, ideally None
|
970
|
+
ORG_KEY: uid,
|
971
|
+
**data_sort_blueprint, # implies sv = True
|
972
|
+
}
|
973
|
+
identical = await self.storage.query(
|
974
|
+
query,
|
975
|
+
**blueprint,
|
976
|
+
# **data_sort_bp,
|
977
|
+
)
|
978
|
+
# TODO: try to create only a single query
|
979
|
+
# TODO: review different structures case
|
980
|
+
similar = await self.storage.query(
|
926
981
|
query,
|
927
982
|
**blueprint,
|
928
983
|
# **data_sort_bp,
|
929
984
|
)
|
930
985
|
t1 = time.time()
|
931
986
|
_elapsed = t1 - t0
|
932
|
-
|
933
|
-
|
987
|
+
existing = identical + similar
|
988
|
+
N = len(existing)
|
989
|
+
log.debug(
|
990
|
+
"[%s] found [%s] similar records in %s secs",
|
991
|
+
blueprint,
|
992
|
+
N,
|
993
|
+
_elapsed,
|
994
|
+
)
|
995
|
+
if data_sort_blueprint and N > 1:
|
934
996
|
if behavior & ALLOW_DUPLICATED_ITEMS:
|
935
997
|
log.debug(
|
936
998
|
"tube [%s] has multiples records: [%s] records, but ALLOW_SAME_DATE_DIFFERENT_VALUES is defined",
|
937
999
|
uid,
|
938
|
-
|
1000
|
+
N,
|
939
1001
|
)
|
940
|
-
|
1002
|
+
existing.clear()
|
941
1003
|
else:
|
942
1004
|
log.debug(
|
943
1005
|
"tube has multiples records: [%s] = %s records, must just 1 and sort_key is defined by: [%s]",
|
944
1006
|
uid,
|
945
|
-
|
1007
|
+
N,
|
946
1008
|
data_sort_blueprint,
|
947
1009
|
)
|
948
1010
|
|
949
1011
|
push = True
|
950
|
-
|
1012
|
+
patterns = kw.get(COMPARISON_PATTERNS)
|
1013
|
+
if patterns:
|
1014
|
+
wdata = CWalk(data, include=patterns, exclude=MASK)
|
1015
|
+
if not wdata:
|
1016
|
+
log.warning("patterns don't get any data")
|
1017
|
+
raise BadLogic(data)
|
1018
|
+
else:
|
1019
|
+
patterns = [r".*"]
|
1020
|
+
wdata = CWalk(data, include=patterns, exclude=MASK)
|
1021
|
+
for exists in existing:
|
1022
|
+
wexists = CWalk(exists, include=patterns, exclude=MASK)
|
951
1023
|
existing_sort_blueprint = build_dict(exists, reverse_sort_keys)
|
952
|
-
|
953
|
-
# check if stream provide an old-echo item
|
954
|
-
# sort_keys must exists in both data
|
955
|
-
old_echo = [
|
956
|
-
old_echo.append(data[_] < exists[_]) if _ in exists else False
|
957
|
-
]
|
958
|
-
if any(old_echo):
|
959
|
-
log.warning(
|
960
|
-
"provider give old data again, preserving storage value and ignore this old_echo"
|
961
|
-
)
|
962
|
-
push = False
|
963
|
-
break
|
1024
|
+
# existing_sort_blueprint = build_comparisson_dict(exists, reverse_sort_keys)
|
964
1025
|
|
965
1026
|
same_sort_key = existing_sort_blueprint == data_sort_blueprint
|
966
1027
|
|
967
1028
|
# check if we must "duplicate" data inside tube
|
968
|
-
keys0 = set(exists).difference(MASK)
|
969
|
-
keys1 = set(data).difference(MASK)
|
1029
|
+
# keys0 = set(exists).difference(MASK)
|
1030
|
+
# keys1 = set(data).difference(MASK)
|
1031
|
+
keys0 = set(wexists)
|
1032
|
+
keys1 = set(wdata)
|
970
1033
|
same_structure = keys0 == keys1
|
971
1034
|
|
972
1035
|
same_values = False
|
973
1036
|
if same_sort_key and same_structure:
|
974
1037
|
for key in keys0:
|
975
|
-
if
|
1038
|
+
if wexists[key] != wdata[key]:
|
976
1039
|
log.debug(
|
977
1040
|
"[%s].[%s].[%s]: %s != %s",
|
978
1041
|
uid,
|
979
1042
|
data_sort_blueprint,
|
980
1043
|
key,
|
981
|
-
|
982
|
-
|
1044
|
+
wexists[key],
|
1045
|
+
wdata[key],
|
983
1046
|
)
|
984
1047
|
break
|
985
1048
|
else:
|
@@ -1206,6 +1269,8 @@ class WaveStorage(iWaves, iStorage):
|
|
1206
1269
|
return all([res0, res1, res2])
|
1207
1270
|
else:
|
1208
1271
|
return True
|
1272
|
+
except SyncModelException as why:
|
1273
|
+
raise why
|
1209
1274
|
except Exception as why: # pragma: nocover
|
1210
1275
|
log.error(why)
|
1211
1276
|
log.error("".join(traceback.format_exception(*sys.exc_info())))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: syncmodels
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.314
|
4
4
|
Summary: Synchronizable Models
|
5
5
|
Home-page: https://github.com/asterio.gonzalez/syncmodels
|
6
6
|
Author: Asterio Gonzalez
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Requires-Python: >=3.6
|
19
19
|
License-File: LICENSE
|
20
20
|
License-File: AUTHORS.rst
|
21
|
-
Requires-Dist: agptools>=0.1.
|
21
|
+
Requires-Dist: agptools>=0.1.314
|
22
22
|
Requires-Dist: aiocache
|
23
23
|
Requires-Dist: aiohttp
|
24
24
|
Requires-Dist: Click
|
@@ -1,17 +1,17 @@
|
|
1
|
-
syncmodels/__init__.py,sha256=
|
1
|
+
syncmodels/__init__.py,sha256=G_3tlPvmtf1CQaauaKV6PoulB_iHJ43bVbH_1q_p8aI,142
|
2
2
|
syncmodels/context.py,sha256=k1Gs_ip9BfyRFpyRnzqYvRDKo0sYBqJsh6z9sWln9oE,451
|
3
|
-
syncmodels/crawler.py,sha256=
|
3
|
+
syncmodels/crawler.py,sha256=U6F0QlzmxkReCB6X2Xbxmm2rRn99GEX005dG7AFl8xE,94430
|
4
4
|
syncmodels/crud.py,sha256=viHBwzczcjNyFiLxL7VGYSbWJW5VjU8AvKaPufBMP7M,15303
|
5
|
-
syncmodels/definitions.py,sha256=
|
6
|
-
syncmodels/exceptions.py,sha256=
|
5
|
+
syncmodels/definitions.py,sha256=dTMxcwcIeYQthZCZXNQmaO1SolWY-WhafASyl91xTo0,5455
|
6
|
+
syncmodels/exceptions.py,sha256=ZLAwu19cs2UN2Sv3jaLnixT_jRI7T42TfyutCkUsuIk,685
|
7
7
|
syncmodels/geofactory.py,sha256=1FkrdEn0QA0O4_lSUAwjqXH2dmlQWi32AkntnG4AEQY,10372
|
8
8
|
syncmodels/http.py,sha256=FFVT3QJJgur2dv1Q_7l9ZsWN8z6_gUjOT9hJff1ZAqk,3335
|
9
9
|
syncmodels/parallel.py,sha256=Ll8HmyFF9v9fIofqqSgfhyTlklvb77mTtNdG5Y9lqdQ,7145
|
10
10
|
syncmodels/registry.py,sha256=YaQtgbSwa0je1MpCcVHALI3_b85vrddyOlhsnrUcKZs,8224
|
11
11
|
syncmodels/requests.py,sha256=wWoC5hPDm1iBM_zrlyKRauzhXgdKR3pT5RqyC-5UZhQ,538
|
12
|
-
syncmodels/runner.py,sha256=
|
12
|
+
syncmodels/runner.py,sha256=IHDKuQ3yJ1DN9wktMiIrerPepYX61tc3AzbFfuUqEFw,5454
|
13
13
|
syncmodels/schema.py,sha256=uinUt8Asq_x7xa6MKWVXNyoWO6gKocjGPppjimaXzEU,2492
|
14
|
-
syncmodels/storage.py,sha256
|
14
|
+
syncmodels/storage.py,sha256=-kdXuPjkHBPauoXTWcmwK4jmH9hr2X1JFERqluznL1Q,71513
|
15
15
|
syncmodels/syncmodels.py,sha256=EzSC4C75V4wJDmsLLbp8YUVwqA6A16KCNW8nB-MqPcs,10567
|
16
16
|
syncmodels/timequeue.py,sha256=YRd3ULRaIhoszaBsYhfr0epMqAbL6-NwVEtScjUYttM,595
|
17
17
|
syncmodels/wave.py,sha256=Gra22BLiA9z2nF-6diXpjAc4GZv9nebmyvHxdAfXec4,7764
|
@@ -32,22 +32,22 @@ syncmodels/helpers/geojson.py,sha256=9VZjdEw19fLS_Q9topapUOPGxRg2D4GOqm2tlx11W7M
|
|
32
32
|
syncmodels/helpers/importers.py,sha256=KImR9pQu4ir6EI6Ipta0q3RWloFT_VTJi67kM0lZsKQ,3919
|
33
33
|
syncmodels/helpers/loaders.py,sha256=aus0aRcbU1vVa_zWo42aX6uV3B0fQ0aQpkTWlR9xGLA,4325
|
34
34
|
syncmodels/helpers/models.py,sha256=c_ATzmiw5mVY1IGnwmyhjIuu5d2idHU-XeRigZSMkOQ,719
|
35
|
-
syncmodels/helpers/orion.py,sha256=
|
35
|
+
syncmodels/helpers/orion.py,sha256=Lblk4OGRNidYl1-2lZKUPXyvuR1hXip7FHloXLtU-XA,30717
|
36
36
|
syncmodels/helpers/surreal.py,sha256=zoWtGm5oAxwvgJNq_NTpKOHN3h9FNObhFDLuiBOl1YY,10050
|
37
37
|
syncmodels/helpers/units.py,sha256=g50m5DQrAyP_qpDRa4LCEA5Rz2UZUmlIixfWG_ddw9I,3571
|
38
38
|
syncmodels/logic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
syncmodels/logic/activity_logger.py,sha256=8wjvgRwaNbibYWGgl-trovSS70yNkoCTlb-AIx3aZEE,14053
|
40
40
|
syncmodels/logic/analyzer.py,sha256=7JDIvZIiDVgdABaaRk7TEbzOFM6HAH3RaSsIDmL4QVE,12291
|
41
|
-
syncmodels/logic/browser.py,sha256=
|
41
|
+
syncmodels/logic/browser.py,sha256=KqvOLPAl2p5EBol7FK-XYvOXeDnu0h9Dz7xfagKTheM,84768
|
42
42
|
syncmodels/logic/swarm.py,sha256=eRBVlNAOzzWKFGCb7LGLx2aj7yQlTY1OwLoeSEllvXY,17207
|
43
43
|
syncmodels/mapper/__init__.py,sha256=jS82LFr9zzyqXBz82tSw04vDowhTpKxhg_W2XvhUlt0,129
|
44
44
|
syncmodels/mapper/fiware.py,sha256=auszPmhCS46z_68MXjksrQAFUfctjbVrVdBvOpOkMj8,523
|
45
45
|
syncmodels/mapper/mapper.py,sha256=SphMhr59bbTWWxnvitonURk3lSPDerGqUTs5-P-Tjlg,17397
|
46
|
-
syncmodels/model/__init__.py,sha256=
|
46
|
+
syncmodels/model/__init__.py,sha256=mD6fpRvBOl7i98pqqwpB2NKlviyD-G8iRXqufjU-9z8,148
|
47
47
|
syncmodels/model/activity.py,sha256=tKzc9zc_5Sx549yTdaTYkfnLnbEsEmzpu53BHstqvFQ,4592
|
48
48
|
syncmodels/model/geofilters.py,sha256=YxZZPk60MvzrBslOrpJec_Er1aTWGg1wgYrXPovrpP8,9284
|
49
49
|
syncmodels/model/geojson.py,sha256=BsW3phXHBGeaIOyOZg7U8bRYKKerAEgNjCl8EnBS2Dg,8329
|
50
|
-
syncmodels/model/model.py,sha256=
|
50
|
+
syncmodels/model/model.py,sha256=c8fAvGZ8_oXYQbdNixltRFhWjY3zYE1Y7MTLXIjbpac,11558
|
51
51
|
syncmodels/model/swarm.py,sha256=0QMc1iyiuW5goLLQGFTIky3dJcc5BfuBPHtVbn7iRK4,1266
|
52
52
|
syncmodels/model/schema_org/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
53
|
syncmodels/model/schema_org/aboutpage.py,sha256=_sqPMc7LxGWNSHwkvTB6OZZAfEovgHltisp6AAz2t9Y,452
|
@@ -302,10 +302,10 @@ syncmodels/session/postgresql.py,sha256=ZMIu1Rv93pKfvFlovFBmWArzlrT2xaQWNYGZT_LW
|
|
302
302
|
syncmodels/session/sql.py,sha256=bD7zXRrEKKJmqY2UoibWENuWb5zHrrU72F3_dYbS6LY,6569
|
303
303
|
syncmodels/session/sqlite.py,sha256=nCDjopLiBpX1F10qkKoARM7JrVdIpJ1WdGOduFVxaiA,2080
|
304
304
|
syncmodels/source/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
305
|
-
syncmodels-0.1.
|
306
|
-
syncmodels-0.1.
|
307
|
-
syncmodels-0.1.
|
308
|
-
syncmodels-0.1.
|
309
|
-
syncmodels-0.1.
|
310
|
-
syncmodels-0.1.
|
311
|
-
syncmodels-0.1.
|
305
|
+
syncmodels-0.1.314.dist-info/AUTHORS.rst,sha256=3ZPoqg8Aav8DSYKd0fwcwn4_5HwSiMLart0E5Un00-U,168
|
306
|
+
syncmodels-0.1.314.dist-info/LICENSE,sha256=uzMOYtIiUsnsD0xHJR7aJWJ4v_bvan0kTnvufy5eNoA,1075
|
307
|
+
syncmodels-0.1.314.dist-info/METADATA,sha256=59uo0tcMb8sXzIoBOlGNPUdyivZA7wIhkYj1hXZ1sMU,2700
|
308
|
+
syncmodels-0.1.314.dist-info/WHEEL,sha256=SrDKpSbFN1G94qcmBqS9nyHcDMp9cUS9OC06hC0G3G0,109
|
309
|
+
syncmodels-0.1.314.dist-info/entry_points.txt,sha256=dMnigjZsHMxTwXiiZyBZdBbMYE0-hY3L5cG15EcDAzw,51
|
310
|
+
syncmodels-0.1.314.dist-info/top_level.txt,sha256=2DfQ9NuAhKMjY3BvQGVBA7GfqTm7EoHNbaehSUiqiHQ,11
|
311
|
+
syncmodels-0.1.314.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|