morango 0.8.2__py2.py3-none-any.whl → 0.8.4__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.
Potentially problematic release.
This version of morango might be problematic. Click here for more details.
- morango/__init__.py +1 -1
- morango/models/core.py +6 -1
- morango/models/fields/crypto.py +18 -1
- morango/registry.py +22 -15
- morango/sync/operations.py +1 -1
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/METADATA +2 -2
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/RECORD +11 -11
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/WHEEL +1 -1
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/AUTHORS.md +0 -0
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/LICENSE +0 -0
- {morango-0.8.2.dist-info → morango-0.8.4.dist-info}/top_level.txt +0 -0
morango/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.8.
|
|
1
|
+
__version__ = "0.8.4"
|
morango/models/core.py
CHANGED
|
@@ -473,7 +473,7 @@ class Store(AbstractStore):
|
|
|
473
473
|
# imports core models.
|
|
474
474
|
from morango.sync.utils import mute_signals
|
|
475
475
|
with mute_signals(signals.post_delete):
|
|
476
|
-
klass_model.
|
|
476
|
+
klass_model.syncing_objects.filter(id=self.id).delete()
|
|
477
477
|
return None, deferred_fks
|
|
478
478
|
else:
|
|
479
479
|
# load model into memory
|
|
@@ -806,6 +806,11 @@ class SyncableModel(UUIDModelMixin):
|
|
|
806
806
|
|
|
807
807
|
objects = SyncableModelManager()
|
|
808
808
|
|
|
809
|
+
# Add a special syncing_objects queryset to every SyncableModel for use in syncing operations.
|
|
810
|
+
# This means that we still deal with the entire set of objects when syncing, even if the default
|
|
811
|
+
# model manager has been overridden to filter the queryset.
|
|
812
|
+
syncing_objects = SyncableModelManager()
|
|
813
|
+
|
|
809
814
|
class Meta:
|
|
810
815
|
abstract = True
|
|
811
816
|
|
morango/models/fields/crypto.py
CHANGED
|
@@ -6,6 +6,7 @@ desirability/efficiency from left to right). We have a base ``Key`` class which
|
|
|
6
6
|
"""
|
|
7
7
|
import hashlib
|
|
8
8
|
import re
|
|
9
|
+
import sys
|
|
9
10
|
|
|
10
11
|
import rsa as PYRSA
|
|
11
12
|
from django.db import models
|
|
@@ -20,6 +21,16 @@ except ImportError:
|
|
|
20
21
|
M2CRYPTO_EXISTS = False
|
|
21
22
|
|
|
22
23
|
try:
|
|
24
|
+
# Pre-empt the PanicException that importing cryptography can cause
|
|
25
|
+
# when we are using a non-compatible version of cffi on Python 3.13
|
|
26
|
+
# this happens because of static depdendency bundling in Kolibri
|
|
27
|
+
import cffi
|
|
28
|
+
|
|
29
|
+
if sys.version_info > (3, 13):
|
|
30
|
+
if hasattr(cffi, "__version_info__"):
|
|
31
|
+
if cffi.__version_info__ < (1, 17, 1):
|
|
32
|
+
raise ImportError
|
|
33
|
+
|
|
23
34
|
from cryptography.hazmat.backends import default_backend
|
|
24
35
|
from cryptography import exceptions as crypto_exceptions
|
|
25
36
|
|
|
@@ -39,7 +50,13 @@ try:
|
|
|
39
50
|
CRYPTOGRAPHY_EXISTS = True
|
|
40
51
|
except ImportError:
|
|
41
52
|
CRYPTOGRAPHY_EXISTS = False
|
|
42
|
-
|
|
53
|
+
except BaseException as e:
|
|
54
|
+
# Still catch PanicExceptions just in case.
|
|
55
|
+
if "Python API call failed" in str(e):
|
|
56
|
+
CRYPTOGRAPHY_EXISTS = False
|
|
57
|
+
else:
|
|
58
|
+
# Otherwise raise the error again to avoid silently catching other errors
|
|
59
|
+
raise
|
|
43
60
|
|
|
44
61
|
from base64 import encodebytes as b64encode, decodebytes as b64decode
|
|
45
62
|
|
morango/registry.py
CHANGED
|
@@ -35,6 +35,24 @@ def _multiple_self_ref_fk_check(class_model):
|
|
|
35
35
|
return False
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def _check_manager(name, objects):
|
|
39
|
+
from morango.models.manager import SyncableModelManager
|
|
40
|
+
from morango.models.query import SyncableModelQuerySet
|
|
41
|
+
# syncable model checks
|
|
42
|
+
if not isinstance(objects, SyncableModelManager):
|
|
43
|
+
raise InvalidMorangoModelConfiguration(
|
|
44
|
+
"Manager for {} must inherit from SyncableModelManager.".format(
|
|
45
|
+
name
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
if not isinstance(objects.none(), SyncableModelQuerySet):
|
|
49
|
+
raise InvalidMorangoModelConfiguration(
|
|
50
|
+
"Queryset for {} model must inherit from SyncableModelQuerySet.".format(
|
|
51
|
+
name
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
38
56
|
class SyncableModelRegistry(object):
|
|
39
57
|
def __init__(self):
|
|
40
58
|
self.profile_models = {}
|
|
@@ -98,8 +116,6 @@ class SyncableModelRegistry(object):
|
|
|
98
116
|
|
|
99
117
|
import django.apps
|
|
100
118
|
from morango.models.core import SyncableModel
|
|
101
|
-
from morango.models.manager import SyncableModelManager
|
|
102
|
-
from morango.models.query import SyncableModelQuerySet
|
|
103
119
|
|
|
104
120
|
model_list = []
|
|
105
121
|
for model in django.apps.apps.get_models():
|
|
@@ -110,19 +126,10 @@ class SyncableModelRegistry(object):
|
|
|
110
126
|
raise InvalidMorangoModelConfiguration(
|
|
111
127
|
"Syncing models with more than 1 self referential ForeignKey is not supported."
|
|
112
128
|
)
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
name
|
|
118
|
-
)
|
|
119
|
-
)
|
|
120
|
-
if not isinstance(model.objects.none(), SyncableModelQuerySet):
|
|
121
|
-
raise InvalidMorangoModelConfiguration(
|
|
122
|
-
"Queryset for {} model must inherit from SyncableModelQuerySet.".format(
|
|
123
|
-
name
|
|
124
|
-
)
|
|
125
|
-
)
|
|
129
|
+
# Check both the objects and the syncing_objects querysets.
|
|
130
|
+
_check_manager(name, model.objects)
|
|
131
|
+
_check_manager(name, model.syncing_objects)
|
|
132
|
+
|
|
126
133
|
if model._meta.many_to_many:
|
|
127
134
|
raise UnsupportedFieldType(
|
|
128
135
|
"{} model with a ManyToManyField is not supported in morango."
|
morango/sync/operations.py
CHANGED
|
@@ -145,7 +145,7 @@ def _serialize_into_store(profile, filter=None):
|
|
|
145
145
|
for model in syncable_models.get_models(profile):
|
|
146
146
|
new_store_records = []
|
|
147
147
|
new_rmc_records = []
|
|
148
|
-
klass_queryset = model.
|
|
148
|
+
klass_queryset = model.syncing_objects.filter(_morango_dirty_bit=True)
|
|
149
149
|
if prefix_condition:
|
|
150
150
|
klass_queryset = klass_queryset.filter(prefix_condition)
|
|
151
151
|
store_records_dict = Store.objects.in_bulk(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: morango
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.4
|
|
4
4
|
Summary: Pure Python sqlite-based Django DB replication engine.
|
|
5
5
|
Home-page: https://github.com/learningequality/morango
|
|
6
6
|
Author: Learning Equality
|
|
@@ -26,7 +26,7 @@ License-File: LICENSE
|
|
|
26
26
|
License-File: AUTHORS.md
|
|
27
27
|
Requires-Dist: django<4,>=3
|
|
28
28
|
Requires-Dist: django-mptt>0.10.0
|
|
29
|
-
Requires-Dist: rsa<
|
|
29
|
+
Requires-Dist: rsa<4.10
|
|
30
30
|
Requires-Dist: djangorestframework>3.10
|
|
31
31
|
Requires-Dist: django-ipware==4.0.2
|
|
32
32
|
Requires-Dist: requests
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
morango/__init__.py,sha256=
|
|
1
|
+
morango/__init__.py,sha256=jhHEJFZWhkQDemoZMomBYq-RNrKXknYzUaeIU9A6XsI,22
|
|
2
2
|
morango/apps.py,sha256=bs_LaTt1038Oh0OOWqaZKpF8rL9cg8rqW4hftIILPw8,559
|
|
3
3
|
morango/errors.py,sha256=okjt7FqSHIf3x9SmnmoW6aqNJ_g7Ye3Fx7tuQSNUYEI,1223
|
|
4
4
|
morango/proquint.py,sha256=YRjgceaYD_wDE8R-21AK5m6MSzbarIBP_kDxJ_gHsbQ,3679
|
|
5
|
-
morango/registry.py,sha256=
|
|
5
|
+
morango/registry.py,sha256=LcHyrNqcqSBAEHJDMS0pinKKzkxRTZjxEyAeZhtrKgo,9480
|
|
6
6
|
morango/urls.py,sha256=pIjnq01BUNxnC0BucRXMr_0H366U5l88k65r67JtHK8,131
|
|
7
7
|
morango/utils.py,sha256=psppzkIjlrmWI2bq2a1wGW0f_0VhdszYleLbm4C4aAs,3652
|
|
8
8
|
morango/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -50,19 +50,19 @@ morango/migrations/0024_auto_20240129_1757.py,sha256=Buy1T4PiTFo8zP7p2HY-3gmiJur
|
|
|
50
50
|
morango/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
51
|
morango/models/__init__.py,sha256=ws6VwRPs7iKLRfFSuRpUESTZlGEmSk0Nv61chh-Gn2Q,1722
|
|
52
52
|
morango/models/certificates.py,sha256=XVq6tKOwLZjq2hw0j5hrBQGsm5H-GSPZ5ZVOg9An9Hw,15110
|
|
53
|
-
morango/models/core.py,sha256
|
|
53
|
+
morango/models/core.py,sha256=-yZ01bS0nXNV0BL_wTHEc4x-7Hh_69hn3MyUunGK2SU,39080
|
|
54
54
|
morango/models/fsic_utils.py,sha256=B9RM-uPZFvEXWbsPeeit5qA21gKGpA0NkKCLFIdNI_0,7130
|
|
55
55
|
morango/models/manager.py,sha256=fzzX7k8qV5W5dMBb0ASOBNRJRpvQZbEG1hgyuMtzt4g,163
|
|
56
56
|
morango/models/query.py,sha256=eHcf9PYYEDShN6lRng7Ow9RJwNFPdKI1hDbVUXeyl9U,869
|
|
57
57
|
morango/models/signals.py,sha256=R17Fqddbg2AgAVnH4oZPrDQMWi94R2XsLmnUbrgKS2I,478
|
|
58
58
|
morango/models/utils.py,sha256=8J138TR3FkslovfUWkLLEpODieFtmHKne7Lm1I8iPXk,6588
|
|
59
59
|
morango/models/fields/__init__.py,sha256=dzxg8-_v3irXkPnyCsiVDur0gG0RJfKzFcshjL6Y-9s,225
|
|
60
|
-
morango/models/fields/crypto.py,sha256=
|
|
60
|
+
morango/models/fields/crypto.py,sha256=Q_y7s-UpFEz9zXFaAkEDOmqwx4b19F7wbTafpd_XPp4,14509
|
|
61
61
|
morango/models/fields/uuids.py,sha256=w7M8KlA8oLPascq14tcor89V92IGxx2XtdweS-0lF6A,4275
|
|
62
62
|
morango/sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
morango/sync/context.py,sha256=_gqfE-RfTIn0UMKFeI2snIJEGCbmR_NRl-Ts5u35B7Q,17815
|
|
64
64
|
morango/sync/controller.py,sha256=rcibQcq579hneUef2p41Ze4OCysLI7rVz6FCFIfYiVA,11575
|
|
65
|
-
morango/sync/operations.py,sha256=
|
|
65
|
+
morango/sync/operations.py,sha256=ErZ-W4MiCUVl_vn0pFi8DWGgT1C9wOAH4AagCMdLBOs,69502
|
|
66
66
|
morango/sync/session.py,sha256=9CTLhpEPM8q1M_b2HHxouZbzm7vBJoImoqPWqdodgII,3853
|
|
67
67
|
morango/sync/syncsession.py,sha256=82TzwxNOH4QSR41mbRWAHWlZOAF_XxaWIRk6EXIWj1o,25292
|
|
68
68
|
morango/sync/utils.py,sha256=BrG8CYVmaAhRNa_HYuPCYSnncskSsW_ig0Cf7xsY2mo,8792
|
|
@@ -71,9 +71,9 @@ morango/sync/backends/base.py,sha256=zQP5hOB2Qw0qv0G00LXFHl2GQ3b0bheyujdNVl5rT-8
|
|
|
71
71
|
morango/sync/backends/postgres.py,sha256=N0IeXN67AkdQKlD20b8LQZ1ocdarapL8pqu8FQAc6lM,19850
|
|
72
72
|
morango/sync/backends/sqlite.py,sha256=vg7kWFIF346-NjVwexYfjYbrrOyzzvcCmk5uUkqhabw,12850
|
|
73
73
|
morango/sync/backends/utils.py,sha256=UvyYByzRenOwtDvLPO_1wIOE8Yr88FnuAM2c4VSk7uQ,5145
|
|
74
|
-
morango-0.8.
|
|
75
|
-
morango-0.8.
|
|
76
|
-
morango-0.8.
|
|
77
|
-
morango-0.8.
|
|
78
|
-
morango-0.8.
|
|
79
|
-
morango-0.8.
|
|
74
|
+
morango-0.8.4.dist-info/AUTHORS.md,sha256=9Ussd3Fq3RPjHyQT_3AyGss5jiVbn858WQuIBOi1ajI,276
|
|
75
|
+
morango-0.8.4.dist-info/LICENSE,sha256=RkI6MjmrrTKa3aoPAVyk9QdeLZclcrKds6FH3phRSRU,1074
|
|
76
|
+
morango-0.8.4.dist-info/METADATA,sha256=gdnV3KotcdrkSTIoAX8GVij3As1tpxaDYzf0Cg1lALU,2585
|
|
77
|
+
morango-0.8.4.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
|
|
78
|
+
morango-0.8.4.dist-info/top_level.txt,sha256=pzREWN0EeEq3yHDRast9XI081Ow_rtcm7WV0ZQTlIPY,8
|
|
79
|
+
morango-0.8.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|