udata 9.1.4.dev31168__py2.py3-none-any.whl → 9.1.4.dev31191__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 udata might be problematic. Click here for more details.

@@ -26,6 +26,7 @@ from udata.core.organization.factories import OrganizationFactory
26
26
  from udata.core.organization.models import Member, Organization
27
27
  from udata.core.reuse.factories import ReuseFactory
28
28
  from udata.core.user.factories import UserFactory
29
+ from udata.core.user.models import User
29
30
 
30
31
  log = logging.getLogger(__name__)
31
32
 
@@ -55,22 +56,21 @@ UNWANTED_KEYS: dict[str, list[str]] = {
55
56
  "quality",
56
57
  ],
57
58
  "resource": ["latest", "preview_url", "last_modified"],
58
- "organization": ["members", "page", "uri", "logo_thumbnail"],
59
- "reuse": ["datasets", "image_thumbnail", "page", "uri", "organization", "owner"],
59
+ "organization": ["class", "page", "uri", "logo_thumbnail"],
60
+ "reuse": ["datasets", "image_thumbnail", "page", "uri", "owner"],
60
61
  "community": [
61
62
  "dataset",
62
- "organization",
63
63
  "owner",
64
64
  "latest",
65
65
  "last_modified",
66
66
  "preview_url",
67
67
  ],
68
- "discussion": ["subject", "user", "url", "class"],
69
- "message": ["posted_by"],
68
+ "discussion": ["subject", "url", "class"],
69
+ "user": ["uri", "page", "class", "avatar_thumbnail", "email"],
70
+ "posted_by": ["uri", "page", "class", "avatar_thumbnail", "email"],
70
71
  "dataservice": [
71
72
  "datasets",
72
73
  "license",
73
- "organization",
74
74
  "owner",
75
75
  "self_api_url",
76
76
  "self_web_url",
@@ -80,6 +80,8 @@ UNWANTED_KEYS: dict[str, list[str]] = {
80
80
 
81
81
  def remove_unwanted_keys(obj: dict, filter_type: str) -> dict:
82
82
  """Remove UNWANTED_KEYS from a dict."""
83
+ if filter_type not in UNWANTED_KEYS:
84
+ return obj
83
85
  for unwanted_key in UNWANTED_KEYS[filter_type]:
84
86
  if unwanted_key in obj:
85
87
  del obj[unwanted_key]
@@ -150,6 +152,29 @@ def generate_fixtures_file(data_source: str, results_filename: str) -> None:
150
152
  print(f"Fixtures saved to file {results_filename}")
151
153
 
152
154
 
155
+ def get_or_create(data, key, model, factory):
156
+ """Try getting the object. If it doesn't exist yet, create it with the provided factory."""
157
+ if key not in data or data[key] is None:
158
+ return
159
+ data[key] = remove_unwanted_keys(data[key], key)
160
+ obj = model.objects(id=data[key]["id"]).first()
161
+ if not obj:
162
+ obj = factory(**data[key])
163
+ return obj
164
+
165
+
166
+ def get_or_create_organization(data):
167
+ return get_or_create(data, "organization", Organization, OrganizationFactory)
168
+
169
+
170
+ def get_or_create_owner(data):
171
+ return get_or_create(data, "owner", User, UserFactory)
172
+
173
+
174
+ def get_or_create_user(data):
175
+ return get_or_create(data, "user", User, UserFactory)
176
+
177
+
153
178
  @cli.command()
154
179
  @click.argument("source", default=DEFAULT_FIXTURE_FILE)
155
180
  def import_fixtures(source):
@@ -165,52 +190,45 @@ def import_fixtures(source):
165
190
  user = UserFactory()
166
191
  dataset = fixture["dataset"]
167
192
  dataset = remove_unwanted_keys(dataset, "dataset")
168
- if not fixture["organization"]:
169
- dataset = DatasetFactory(**dataset, owner=user)
170
- else:
171
- org = Organization.objects(id=fixture["organization"]["id"]).first()
172
- if not org:
173
- organization = fixture["organization"]
174
- organization = remove_unwanted_keys(organization, "organization")
175
- org = OrganizationFactory(**organization, members=[Member(user=user)])
193
+ if fixture["organization"]:
194
+ organization = fixture["organization"]
195
+ organization["members"] = [
196
+ Member(user=get_or_create_user(member), role=member["role"])
197
+ for member in organization["members"]
198
+ ]
199
+ fixture["organization"] = organization
200
+ org = get_or_create_organization(fixture)
176
201
  dataset = DatasetFactory(**dataset, organization=org)
202
+ else:
203
+ dataset = DatasetFactory(**dataset, owner=user)
177
204
  for resource in fixture["resources"]:
178
205
  resource = remove_unwanted_keys(resource, "resource")
179
206
  res = ResourceFactory(**resource)
180
207
  dataset.add_resource(res)
181
208
  for reuse in fixture["reuses"]:
182
209
  reuse = remove_unwanted_keys(reuse, "reuse")
183
- ReuseFactory(**reuse, datasets=[dataset], owner=user)
210
+ reuse["owner"] = get_or_create_owner(reuse)
211
+ reuse["organization"] = get_or_create_organization(reuse)
212
+ ReuseFactory(**reuse, datasets=[dataset])
184
213
  for community in fixture["community_resources"]:
185
214
  community = remove_unwanted_keys(community, "community")
186
- CommunityResourceFactory(**community, dataset=dataset, owner=user)
215
+ community["owner"] = get_or_create_owner(community)
216
+ community["organization"] = get_or_create_organization(community)
217
+ CommunityResourceFactory(**community, dataset=dataset)
187
218
  for discussion in fixture["discussions"]:
188
219
  discussion = remove_unwanted_keys(discussion, "discussion")
189
- messages = discussion.pop("discussion")
190
- for message in messages:
191
- message = remove_unwanted_keys(message, "message")
192
- DiscussionFactory(
193
- **discussion,
194
- subject=dataset,
195
- user=user,
196
- discussion=[
197
- MessageDiscussionFactory(**message, posted_by=user) for message in messages
198
- ],
199
- )
220
+ discussion["closed_by"] = get_or_create(discussion, "closed_by", User, UserFactory)
221
+ for message in discussion["discussion"]:
222
+ message["posted_by"] = get_or_create(message, "posted_by", User, UserFactory)
223
+ discussion["discussion"] = [
224
+ MessageDiscussionFactory(**message) for message in discussion["discussion"]
225
+ ]
226
+ discussion["user"] = get_or_create_user(discussion)
227
+ DiscussionFactory(**discussion, subject=dataset)
200
228
  for dataservice in fixture["dataservices"]:
201
229
  dataservice = remove_unwanted_keys(dataservice, "dataservice")
202
- if not dataservice["contact_point"]:
203
- DataserviceFactory(**dataservice, datasets=[dataset], organization=org)
204
- else:
205
- contact_point = ContactPoint.objects(
206
- id=dataservice["contact_point"]["id"]
207
- ).first()
208
- if not contact_point:
209
- contact_point = ContactPointFactory(**dataservice["contact_point"])
210
- dataservice.pop("contact_point")
211
- DataserviceFactory(
212
- **dataservice,
213
- datasets=[dataset],
214
- organization=org,
215
- contact_point=contact_point,
216
- )
230
+ dataservice["contact_point"] = get_or_create(
231
+ dataservice, "contact_point", ContactPoint, ContactPointFactory
232
+ )
233
+ dataservice["organization"] = get_or_create_organization(dataservice)
234
+ DataserviceFactory(**dataservice, datasets=[dataset])
@@ -27,21 +27,28 @@ class FixturesTest:
27
27
  """Test generating fixtures from the current env, then importing them back."""
28
28
  assert models.Dataset.objects.count() == 0 # Start with a clean slate.
29
29
  user = UserFactory()
30
- org = OrganizationFactory(**{}, members=[Member(user=user)])
30
+ admin = UserFactory()
31
+ org = OrganizationFactory(
32
+ members=[Member(user=user, role="editor"), Member(user=admin, role="admin")]
33
+ )
31
34
  # Set the same slug we're 'exporting' from the FIXTURE_DATASET_SLUG config, see the
32
35
  # @pytest.mark.options above.
33
- dataset = DatasetFactory(**{}, slug="some-test-dataset-slug", organization=org)
34
- res = ResourceFactory(**{})
36
+ dataset = DatasetFactory(slug="some-test-dataset-slug", organization=org)
37
+ res = ResourceFactory()
35
38
  dataset.add_resource(res)
36
- ReuseFactory(**{}, datasets=[dataset], owner=user)
37
- CommunityResourceFactory(**{}, dataset=dataset, owner=user)
39
+ ReuseFactory(datasets=[dataset], owner=user)
40
+ CommunityResourceFactory(dataset=dataset, owner=user)
38
41
  DiscussionFactory(
39
42
  **{},
40
43
  subject=dataset,
41
44
  user=user,
42
- discussion=[MessageDiscussionFactory(**{}, posted_by=user)],
45
+ discussion=[
46
+ MessageDiscussionFactory(posted_by=user),
47
+ MessageDiscussionFactory(posted_by=admin),
48
+ ],
49
+ closed_by=admin,
43
50
  )
44
- DataserviceFactory(**{}, datasets=[dataset])
51
+ DataserviceFactory(datasets=[dataset], organization=org)
45
52
 
46
53
  with NamedTemporaryFile(mode="w+", delete=True) as fixtures_fd:
47
54
  # Get the fixtures from the local instance.
@@ -69,13 +76,25 @@ class FixturesTest:
69
76
  # Then load them in the database to make sure they're correct.
70
77
  result = cli("import-fixtures", fixtures_fd.name)
71
78
  assert models.Organization.objects(slug=org.slug).count() > 0
79
+ result_org = models.Organization.objects.get(slug=org.slug)
80
+ assert result_org.members[0].user.id == user.id
81
+ assert result_org.members[0].role == "editor"
82
+ assert result_org.members[1].user.id == admin.id
83
+ assert result_org.members[1].role == "admin"
72
84
  assert models.Dataset.objects.count() > 0
73
85
  assert models.Discussion.objects.count() > 0
86
+ result_discussion = models.Discussion.objects.first()
87
+ assert result_discussion.user.id == user.id
88
+ assert result_discussion.closed_by.id == admin.id
89
+ assert len(result_discussion.discussion) == 2
90
+ assert result_discussion.discussion[0].posted_by.id == user.id
91
+ assert result_discussion.discussion[1].posted_by.id == admin.id
74
92
  assert models.CommunityResource.objects.count() > 0
75
93
  assert models.User.objects.count() > 0
76
94
  assert models.Dataservice.objects.count() > 0
77
95
  # Make sure we also import the dataservice organization
78
- assert models.Dataservice.objects(organization__exists=True).count() > 0
96
+ result_dataservice = models.Dataservice.objects.first()
97
+ assert result_dataservice.organization == org
79
98
 
80
99
  def test_import_fixtures_from_default_file(self, cli):
81
100
  """Test importing fixtures from udata.commands.fixture.DEFAULT_FIXTURE_FILE."""
@@ -13,7 +13,7 @@ class TagsAPITest:
13
13
  def test_suggest_tags_api(self, api):
14
14
  """It should suggest tags"""
15
15
  for i in range(3):
16
- tags = [faker.word(), faker.word(), "test", "test-{0}".format(i)]
16
+ tags = [faker.tag(), faker.tag(), "test", "test-{0}".format(i)]
17
17
  ReuseFactory(tags=tags, visible=True)
18
18
  DatasetFactory(tags=tags, visible=True)
19
19
 
@@ -33,7 +33,7 @@ class TagsAPITest:
33
33
  def test_suggest_tags_api_with_unicode(self, api):
34
34
  """It should suggest tags"""
35
35
  for i in range(3):
36
- tags = [faker.word(), faker.word(), "testé", "testé-{0}".format(i)]
36
+ tags = [faker.tag(), faker.tag(), "testé", "testé-{0}".format(i)]
37
37
  ReuseFactory(tags=tags, visible=True)
38
38
  DatasetFactory(tags=tags, visible=True)
39
39
 
udata/utils.py CHANGED
@@ -18,6 +18,8 @@ from faker.providers import BaseProvider
18
18
  from faker.providers.lorem.la import Provider as LoremProvider
19
19
  from flask import abort
20
20
 
21
+ from udata import tags
22
+
21
23
 
22
24
  def get_by(lst, field, value):
23
25
  """Find an object in a list given a field value"""
@@ -277,6 +279,16 @@ PROVIDERS.remove("faker.providers.lorem")
277
279
  faker = Faker("fr_FR") # Use a unicode/utf-8 based locale
278
280
 
279
281
 
282
+ def tag() -> str:
283
+ fake_tag: str = faker.word()
284
+ while len(fake_tag) < tags.MIN_TAG_LENGTH:
285
+ fake_tag = faker.word()
286
+ return fake_tag
287
+
288
+
289
+ faker.tag = tag
290
+
291
+
280
292
  def faker_provider(provider):
281
293
  faker.add_provider(provider)
282
294
  factory.Faker.add_provider(provider)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: udata
3
- Version: 9.1.4.dev31168
3
+ Version: 9.1.4.dev31191
4
4
  Summary: Open data portal
5
5
  Home-page: https://github.com/opendatateam/udata
6
6
  Author: Opendata Team
@@ -146,6 +146,7 @@ It is collectively taken care of by members of the
146
146
  - Fix circular import error [#3128](https://github.com/opendatateam/udata/pull/3128)
147
147
  - Add an option to specify the port when using `inv serve` [#3123](https://github.com/opendatateam/udata/pull/3123)
148
148
  - Add a new `related_to` filter parameter to the activities API endpoint [#3127](https://github.com/opendatateam/udata/pull/3127)
149
+ - Properly import the `Discussion.closed_by` from the fixtures [#3125](https://github.com/opendatateam/udata/pull/3125)
149
150
 
150
151
  ## 9.1.3 (2024-08-01)
151
152
 
@@ -20,7 +20,7 @@ udata/tasks.py,sha256=hLdmHV7ozeq803BRjU6X3DT3oVsZrV1beQILpbjsfQI,4978
20
20
  udata/terms.md,sha256=nFx978tUQ3vTEv6POykXaZvcQ5e_gcvmO4ZgcfbSWXo,187
21
21
  udata/tracking.py,sha256=WOcqA1RlHN8EPFuEc2kNau54mec4-pvi-wUFrMXevzg,345
22
22
  udata/uris.py,sha256=Nxy-kvj46FhRDNW7sebFI-X7nFJEP5ViwgGQvAHmBW0,3561
23
- udata/utils.py,sha256=AbPqkgtdjuQScOCoTcZl3eDiEmU0p-agr1lqvEJwaS0,8661
23
+ udata/utils.py,sha256=a-iwHhbCgghIu0vi-D4-s8iHQSaXK6QwxGNGuksCm9w,8855
24
24
  udata/worker.py,sha256=K-Wafye5-uXP4kQlffRKws2J9YbJ6m6n2QjcVsY8Nsg,118
25
25
  udata/wsgi.py,sha256=MY8en9K9eDluvJYUxTdzqSDoYaDgCVZ69ZcUvxAvgqA,77
26
26
  udata/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -42,7 +42,7 @@ udata/commands/__init__.py,sha256=Won_rW_hIU9TA3o4oNe6kI46l1fnDBM_oW0Hc1XS9F8,77
42
42
  udata/commands/cache.py,sha256=bLdrf_fCWFYX9ULlL2ADsZRwijkI4pArsJxfx24OivM,341
43
43
  udata/commands/db.py,sha256=x5ui77hoT-JcECneBhhXZtpH4g65gaj7SyeM0bnORhA,14694
44
44
  udata/commands/dcat.py,sha256=L1J1AxQCmMDmwdxzugQNfy4VZQYf1rI1wPhSdUaMB5E,3419
45
- udata/commands/fixtures.py,sha256=FPJhABW1UFx_vLqnklZHJFY6GtFtv8BIaqK9zDXKsKY,8423
45
+ udata/commands/fixtures.py,sha256=37vzviUStMiPwuuctpjVkB2wbJl_xvCwABDQHqTwg8I,9157
46
46
  udata/commands/images.py,sha256=0rVojLik5DYgJ6W4uNEfMP2g2QUU2V761tj3z6lo8no,2050
47
47
  udata/commands/info.py,sha256=A5WMo3_N_rlt3cySVJrZqKWrbIowX97ZLKMIFQE5178,1545
48
48
  udata/commands/init.py,sha256=8CpH8MklzPkpxczs43lFM5ZNrHCJRbUtzHapgYNHs7M,1520
@@ -52,7 +52,7 @@ udata/commands/static.py,sha256=OUYPAR1giaPk52DK-v-nQYUSx-YQ4cF7YXLt1t5wtBU,2199
52
52
  udata/commands/test.py,sha256=0snHTDolowQK-DmAKnhF_mBuDOBMApAbEc35GEiwH0M,893
53
53
  udata/commands/worker.py,sha256=bjXQGCwkbZxkcxLMPA2Lr0nkNjXLpGNDMkkQXjwBLPI,3976
54
54
  udata/commands/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- udata/commands/tests/test_fixtures.py,sha256=kFwqWA3Ha0mnCR5EE5aPz6jv3hfPheuwOMYkOvvBKyU,4120
55
+ udata/commands/tests/test_fixtures.py,sha256=ZDps7ao6r86SV1Gv0Aftq4Ly1sdDnrUQGMNUz6LMTIo,5012
56
56
  udata/core/__init__.py,sha256=O7C9WWCXiLWnWPnPbFRszWhOmvRQiI4gD-5qkWvPGRo,385
57
57
  udata/core/owned.py,sha256=UEg5tp-ZunzC2avCdholpqibDIUZgFBsXS7BEcdnBy0,4567
58
58
  udata/core/activity/__init__.py,sha256=OaiFyq7HB4xL4SuMPD1N8IFNpntwx9ZayVzelciOieI,298
@@ -610,7 +610,7 @@ udata/tests/api/test_organizations_api.py,sha256=YcO2fWELdmPD4Oc8h5MTrLI-Gfbx16R
610
610
  udata/tests/api/test_reports_api.py,sha256=fCSz9NwMXBs6cxdXBVVI6y564AtovmZYw3xkgxQ9KE8,6217
611
611
  udata/tests/api/test_reuses_api.py,sha256=yDF7fssG4km6MfzBbBTrPaQ_Ay3E8W9OglSG_RHxlYk,18710
612
612
  udata/tests/api/test_swagger.py,sha256=eE6La9qdTYTIUFevRVPJgtj17Jq_8uOlsDwzCNR0LL8,760
613
- udata/tests/api/test_tags_api.py,sha256=wQR67DeRQvLn8fvgwUMpnT135xamo2fNSSqhEMm0v-g,2429
613
+ udata/tests/api/test_tags_api.py,sha256=36zEBgthVEn6pctJ0kDgPmEaUr-iqRAHeZRcRG2LEXQ,2425
614
614
  udata/tests/api/test_topics_api.py,sha256=s4pqHTWl3ly8HQd2YmVclHFrjrf0212u5iDSOTSBbZg,9375
615
615
  udata/tests/api/test_transfer_api.py,sha256=5cp4-O-nxkxDibsVbsG2lZ2qAsTBX2BpoMPTm8bvT8k,3085
616
616
  udata/tests/api/test_user_api.py,sha256=Xtme7l_15rHjTqSzjxNLv5Q8I_T5_eY2rIgzuNVJlRk,14357
@@ -697,9 +697,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=WpPzAqVd2Onv_kz45ULUySKPLrpjcc
697
697
  udata/translations/pt/LC_MESSAGES/udata.po,sha256=18Op9RUITewoDRewlOdYzzq6gjsf1lsvepACV1d7zxs,44976
698
698
  udata/translations/sr/LC_MESSAGES/udata.mo,sha256=NIYRNhVoETZUvIvWm3cCW7DtMBAnS2vXzZjMF5ZzD_c,28500
699
699
  udata/translations/sr/LC_MESSAGES/udata.po,sha256=rQB-4V4WJ7bURj6g2j653vItr5TMHadcLQxec7_fDmg,51545
700
- udata-9.1.4.dev31168.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
701
- udata-9.1.4.dev31168.dist-info/METADATA,sha256=YZ2NedcM5hDUSpvuREmEnsk_Fr0O4r5Ftx1CXTD_eI0,129017
702
- udata-9.1.4.dev31168.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
703
- udata-9.1.4.dev31168.dist-info/entry_points.txt,sha256=3SKiqVy4HUqxf6iWspgMqH8d88Htk6KoLbG1BU-UddQ,451
704
- udata-9.1.4.dev31168.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
705
- udata-9.1.4.dev31168.dist-info/RECORD,,
700
+ udata-9.1.4.dev31191.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
701
+ udata-9.1.4.dev31191.dist-info/METADATA,sha256=hdGyZDlTnaExRiHPp-q6h0P-JeYSyTN8AJIHpysI_tg,129137
702
+ udata-9.1.4.dev31191.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
703
+ udata-9.1.4.dev31191.dist-info/entry_points.txt,sha256=3SKiqVy4HUqxf6iWspgMqH8d88Htk6KoLbG1BU-UddQ,451
704
+ udata-9.1.4.dev31191.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
705
+ udata-9.1.4.dev31191.dist-info/RECORD,,