udata 10.3.2.dev34939__py2.py3-none-any.whl → 10.3.2.dev34982__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.

Files changed (40) hide show
  1. udata/{frontend → core}/csv.py +1 -1
  2. udata/core/dataservices/csv.py +1 -1
  3. udata/core/dataset/api.py +11 -0
  4. udata/core/dataset/csv.py +1 -1
  5. udata/core/dataset/tasks.py +1 -2
  6. udata/core/discussions/csv.py +1 -1
  7. udata/core/organization/api.py +40 -0
  8. udata/core/organization/csv.py +1 -1
  9. udata/core/reuse/csv.py +1 -1
  10. udata/core/site/api.py +106 -1
  11. udata/core/tags/csv.py +1 -1
  12. udata/core/tags/views.py +1 -1
  13. udata/harvest/csv.py +1 -1
  14. udata/static/chunks/{10.8ca60413647062717b1e.js → 10.471164b2a9fe15614797.js} +3 -3
  15. udata/static/chunks/{10.8ca60413647062717b1e.js.map → 10.471164b2a9fe15614797.js.map} +1 -1
  16. udata/static/chunks/{11.b6f741fcc366abfad9c4.js → 11.83535504cd650ea08f65.js} +3 -3
  17. udata/static/chunks/{11.b6f741fcc366abfad9c4.js.map → 11.83535504cd650ea08f65.js.map} +1 -1
  18. udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.d9c1735d14038b94c17e.js} +2 -2
  19. udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.d9c1735d14038b94c17e.js.map} +1 -1
  20. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.81c57c0dedf812e43013.js} +2 -2
  21. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.81c57c0dedf812e43013.js.map} +1 -1
  22. udata/static/chunks/{19.f03a102365af4315f9db.js → 19.df16abde17a42033a7f8.js} +3 -3
  23. udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.df16abde17a42033a7f8.js.map} +1 -1
  24. udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.462bb3029de008497675.js} +2 -2
  25. udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.462bb3029de008497675.js.map} +1 -1
  26. udata/static/chunks/{9.033d7e190ca9e226a5d0.js → 9.07515e5187f475bce828.js} +3 -3
  27. udata/static/chunks/{9.033d7e190ca9e226a5d0.js.map → 9.07515e5187f475bce828.js.map} +1 -1
  28. udata/static/common.js +1 -1
  29. udata/static/common.js.map +1 -1
  30. udata/tests/api/test_organizations_api.py +98 -1
  31. udata/tests/apiv2/test_datasets.py +16 -0
  32. udata/tests/frontend/test_csv.py +1 -1
  33. udata/tests/site/test_site_csv_exports.py +464 -0
  34. udata/tests/test_tags.py +1 -1
  35. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/METADATA +3 -1
  36. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/RECORD +40 -39
  37. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/LICENSE +0 -0
  38. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/WHEEL +0 -0
  39. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/entry_points.txt +0 -0
  40. {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/top_level.txt +0 -0
@@ -240,7 +240,7 @@ def stream(queryset_or_adapter, basename=None):
240
240
  cls = _adapters.get(queryset_or_adapter._document)
241
241
  adapter = cls(queryset_or_adapter)
242
242
  else:
243
- raise ValueError("Unsupported object type")
243
+ raise ValueError(f"Unsupported object type {queryset_or_adapter}")
244
244
 
245
245
  timestamp = datetime.utcnow().strftime("%Y-%m-%d-%H-%M")
246
246
  headers = {
@@ -1,4 +1,4 @@
1
- from udata.frontend import csv
1
+ from udata.core import csv
2
2
 
3
3
  from .models import Dataservice
4
4
 
udata/core/dataset/api.py CHANGED
@@ -38,6 +38,7 @@ from udata.core.dataservices.models import Dataservice
38
38
  from udata.core.dataset.models import CHECKSUM_TYPES
39
39
  from udata.core.followers.api import FollowAPI
40
40
  from udata.core.organization.models import Organization
41
+ from udata.core.reuse.models import Reuse
41
42
  from udata.core.storages.api import handle_upload, upload_parser
42
43
  from udata.core.topic.models import Topic
43
44
  from udata.linkchecker.checker import check_resource
@@ -122,6 +123,7 @@ class DatasetApiParser(ModelApiParser):
122
123
  self.parser.add_argument("topic", type=str, location="args")
123
124
  self.parser.add_argument("credit", type=str, location="args")
124
125
  self.parser.add_argument("dataservice", type=str, location="args")
126
+ self.parser.add_argument("reuse", type=str, location="args")
125
127
  self.parser.add_argument(
126
128
  "archived",
127
129
  type=boolean,
@@ -200,6 +202,15 @@ class DatasetApiParser(ModelApiParser):
200
202
  pass
201
203
  else:
202
204
  datasets = datasets.filter(id__in=[d.id for d in dataservice.datasets])
205
+ if args.get("reuse"):
206
+ if not ObjectId.is_valid(args["reuse"]):
207
+ api.abort(400, "Reuse arg must be an identifier")
208
+ try:
209
+ reuse = Reuse.objects.get(id=args["reuse"])
210
+ except Reuse.DoesNotExist:
211
+ pass
212
+ else:
213
+ datasets = datasets.filter(id__in=[d.id for d in reuse.datasets])
203
214
  if args.get("archived") is not None:
204
215
  if current_user.is_anonymous:
205
216
  abort(401)
udata/core/dataset/csv.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # for backwards compatibility (see https://github.com/opendatateam/udata/pull/3152)
2
2
  import json
3
3
 
4
+ from udata.core import csv
4
5
  from udata.core.discussions.csv import DiscussionCsvAdapter # noqa: F401
5
- from udata.frontend import csv
6
6
 
7
7
  from .models import Dataset, Resource
8
8
 
@@ -9,9 +9,8 @@ from mongoengine import ValidationError
9
9
 
10
10
  from udata import mail
11
11
  from udata import models as udata_models
12
- from udata.core import storages
12
+ from udata.core import csv, storages
13
13
  from udata.core.dataservices.models import Dataservice
14
- from udata.frontend import csv
15
14
  from udata.harvest.models import HarvestJob
16
15
  from udata.i18n import lazy_gettext as _
17
16
  from udata.models import Activity, Discussion, Follow, Organization, Topic, Transfer, db
@@ -1,4 +1,4 @@
1
- from udata.frontend import csv
1
+ from udata.core import csv
2
2
 
3
3
  from .models import Discussion
4
4
 
@@ -1,3 +1,4 @@
1
+ import itertools
1
2
  from datetime import datetime
2
3
 
3
4
  from flask import make_response, redirect, request, url_for
@@ -6,6 +7,7 @@ from mongoengine.queryset.visitor import Q
6
7
  from udata.api import API, api, errors
7
8
  from udata.api.parsers import ModelApiParser
8
9
  from udata.auth import admin_permission, current_user
10
+ from udata.core import csv
9
11
  from udata.core.badges import api as badges_api
10
12
  from udata.core.badges.fields import badge_fields
11
13
  from udata.core.contact_point.api import ContactPointApiParser
@@ -13,8 +15,10 @@ from udata.core.contact_point.api_fields import contact_point_page_fields
13
15
  from udata.core.dataservices.models import Dataservice
14
16
  from udata.core.dataset.api import DatasetApiParser
15
17
  from udata.core.dataset.api_fields import dataset_page_fields
18
+ from udata.core.dataset.csv import DatasetCsvAdapter, ResourcesCsvAdapter
16
19
  from udata.core.dataset.models import Dataset
17
20
  from udata.core.discussions.api import discussion_fields
21
+ from udata.core.discussions.csv import DiscussionCsvAdapter
18
22
  from udata.core.discussions.models import Discussion
19
23
  from udata.core.followers.api import FollowAPI
20
24
  from udata.core.reuse.models import Reuse
@@ -164,6 +168,42 @@ class OrganizationAPI(API):
164
168
  return "", 204
165
169
 
166
170
 
171
+ @ns.route("/<org:org>/datasets.csv", endpoint="organization_datasets_csv", doc=common_doc)
172
+ @api.response(404, "Organization not found")
173
+ @api.response(410, "Organization has been deleted")
174
+ class DatasetsCsvAPI(API):
175
+ def get(self, org):
176
+ datasets = Dataset.objects(organization=str(org.id)).visible()
177
+ adapter = DatasetCsvAdapter(datasets)
178
+ return csv.stream(adapter, "{0}-datasets".format(org.slug))
179
+
180
+
181
+ @ns.route("/<org:org>/discussions.csv", endpoint="organization_discussions_csv", doc=common_doc)
182
+ @api.response(404, "Organization not found")
183
+ @api.response(410, "Organization has been deleted")
184
+ class DiscussionsCsvAPI(API):
185
+ def get(self, org):
186
+ datasets = Dataset.objects.filter(organization=str(org.id))
187
+ discussions = [Discussion.objects.filter(subject=dataset) for dataset in datasets]
188
+ # Turns a list of lists into a flat list.
189
+ adapter = DiscussionCsvAdapter(itertools.chain(*discussions))
190
+ return csv.stream(adapter, "{0}-discussions".format(org.slug))
191
+
192
+
193
+ @ns.route(
194
+ "/<org:org>/datasets-resources.csv",
195
+ endpoint="organization_datasets_resources_csv",
196
+ doc=common_doc,
197
+ )
198
+ @api.response(404, "Organization not found")
199
+ @api.response(410, "Organization has been deleted")
200
+ class DatasetsResourcesCsvAPI(API):
201
+ def get(self, org):
202
+ datasets = Dataset.objects(organization=str(org.id)).visible()
203
+ adapter = ResourcesCsvAdapter(datasets)
204
+ return csv.stream(adapter, "{0}-datasets-resources".format(org.slug))
205
+
206
+
167
207
  @ns.route("/<org:org>/catalog", endpoint="organization_rdf", doc=common_doc)
168
208
  @api.response(404, "Organization not found")
169
209
  @api.response(410, "Organization has been deleted")
@@ -1,5 +1,5 @@
1
+ from udata.core import csv
1
2
  from udata.core.dataset.models import Dataset
2
- from udata.frontend import csv
3
3
 
4
4
  from .models import Organization
5
5
 
udata/core/reuse/csv.py CHANGED
@@ -1,4 +1,4 @@
1
- from udata.frontend import csv
1
+ from udata.core import csv
2
2
 
3
3
  from .models import Reuse
4
4
 
udata/core/site/api.py CHANGED
@@ -1,10 +1,23 @@
1
1
  from bson import ObjectId
2
- from flask import json, make_response, redirect, request, url_for
2
+ from flask import current_app, json, make_response, redirect, request, url_for
3
3
 
4
4
  from udata.api import API, api, fields
5
5
  from udata.auth import admin_permission
6
+ from udata.core import csv
7
+ from udata.core.dataservices.csv import DataserviceCsvAdapter
6
8
  from udata.core.dataservices.models import Dataservice
9
+ from udata.core.dataset.api import DatasetApiParser
7
10
  from udata.core.dataset.api_fields import dataset_fields
11
+ from udata.core.dataset.csv import ResourcesCsvAdapter
12
+ from udata.core.dataset.search import DatasetSearch
13
+ from udata.core.dataset.tasks import get_queryset as get_csv_queryset
14
+ from udata.core.organization.api import OrgApiParser
15
+ from udata.core.organization.csv import OrganizationCsvAdapter
16
+ from udata.core.organization.models import Organization
17
+ from udata.core.reuse.api import ReuseApiParser
18
+ from udata.core.reuse.csv import ReuseCsvAdapter
19
+ from udata.harvest.csv import HarvestSourceCsvAdapter
20
+ from udata.harvest.models import HarvestSource
8
21
  from udata.models import Dataset, Reuse
9
22
  from udata.rdf import CONTEXT, RDF_EXTENSIONS, graph_response, negociate_content
10
23
  from udata.utils import multi_to_dict
@@ -114,9 +127,101 @@ class SiteRdfCatalogFormat(API):
114
127
  return make_response(*graph_response(catalog, format))
115
128
 
116
129
 
130
+ @api.route("/site/datasets.csv", endpoint="site_datasets_csv")
131
+ class SiteDatasetsCsv(API):
132
+ def get(self):
133
+ # redirect to EXPORT_CSV dataset if feature is enabled and no filter is set
134
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
135
+ if not request.args and "dataset" in exported_models:
136
+ return redirect(get_export_url("dataset"))
137
+ search_parser = DatasetSearch.as_request_parser(store_missing=False)
138
+ params = search_parser.parse_args()
139
+ params["facets"] = False
140
+ datasets = DatasetApiParser.parse_filters(get_csv_queryset(Dataset), params)
141
+ adapter = csv.get_adapter(Dataset)
142
+ return csv.stream(adapter(datasets), "datasets")
143
+
144
+
145
+ @api.route("/site/resources.csv", endpoint="site_datasets_resources_csv")
146
+ class SiteResourcesCsv(API):
147
+ def get(self):
148
+ # redirect to EXPORT_CSV dataset if feature is enabled and no filter is set
149
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
150
+ if not request.args and "resource" in exported_models:
151
+ return redirect(get_export_url("resource"))
152
+ search_parser = DatasetSearch.as_request_parser(store_missing=False)
153
+ params = search_parser.parse_args()
154
+ params["facets"] = False
155
+ datasets = DatasetApiParser.parse_filters(get_csv_queryset(Dataset), params)
156
+ return csv.stream(ResourcesCsvAdapter(datasets), "resources")
157
+
158
+
159
+ @api.route("/site/organizations.csv", endpoint="site_organizations_csv")
160
+ class SiteOrganizationsCsv(API):
161
+ def get(self):
162
+ params = multi_to_dict(request.args)
163
+ # redirect to EXPORT_CSV dataset if feature is enabled and no filter is set
164
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
165
+ if not params and "organization" in exported_models:
166
+ return redirect(get_export_url("organization"))
167
+ params["facets"] = False
168
+ organizations = OrgApiParser.parse_filters(get_csv_queryset(Organization), params)
169
+ return csv.stream(OrganizationCsvAdapter(organizations), "organizations")
170
+
171
+
172
+ @api.route("/site/reuses.csv", endpoint="site_reuses_csv")
173
+ class SiteReusesCsv(API):
174
+ def get(self):
175
+ params = multi_to_dict(request.args)
176
+ # redirect to EXPORT_CSV dataset if feature is enabled and no filter is set
177
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
178
+ if not params and "reuse" in exported_models:
179
+ return redirect(get_export_url("reuse"))
180
+ params["facets"] = False
181
+ reuses = ReuseApiParser.parse_filters(get_csv_queryset(Reuse), params)
182
+ return csv.stream(ReuseCsvAdapter(reuses), "reuses")
183
+
184
+
185
+ @api.route("/site/dataservices.csv", endpoint="site_dataservices_csv")
186
+ class SiteDataservicesCsv(API):
187
+ def get(self):
188
+ params = multi_to_dict(request.args)
189
+ # redirect to EXPORT_CSV dataset if feature is enabled and no filter is set
190
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
191
+ if not params and "dataservice" in exported_models:
192
+ return redirect(get_export_url("dataservice"))
193
+ params["facets"] = False
194
+ dataservices = Dataservice.apply_sort_filters(get_csv_queryset(Dataservice))
195
+ return csv.stream(DataserviceCsvAdapter(dataservices), "dataservices")
196
+
197
+
198
+ @api.route("/site/harvests.csv", endpoint="site_harvests_csv")
199
+ class SiteHarvestsCsv(API):
200
+ def get(self):
201
+ # redirect to EXPORT_CSV dataset if feature is enabled
202
+ exported_models = current_app.config.get("EXPORT_CSV_MODELS", [])
203
+ if "harvest" in exported_models:
204
+ return redirect(get_export_url("harvest"))
205
+ adapter = HarvestSourceCsvAdapter(get_csv_queryset(HarvestSource).order_by("created_at"))
206
+ return csv.stream(adapter, "harvest")
207
+
208
+
117
209
  @api.route("/site/context.jsonld", endpoint="site_jsonld_context")
118
210
  class SiteJsonLdContext(API):
119
211
  def get(self):
120
212
  response = make_response(json.dumps(CONTEXT))
121
213
  response.headers["Content-Type"] = "application/ld+json"
122
214
  return response
215
+
216
+
217
+ def get_export_url(model):
218
+ did = current_app.config["EXPORT_CSV_DATASET_ID"]
219
+ dataset = Dataset.objects.get_or_404(id=did)
220
+ resource = None
221
+ for r in dataset.resources:
222
+ if r.extras.get("csv-export:model", "") == model:
223
+ resource = r
224
+ break
225
+ if not resource:
226
+ api.abort(404)
227
+ return resource.url
udata/core/tags/csv.py CHANGED
@@ -1,4 +1,4 @@
1
- from udata.frontend import csv
1
+ from udata.core import csv
2
2
 
3
3
  from .models import Tag
4
4
 
udata/core/tags/views.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
 
3
- from udata.frontend import csv
3
+ from udata.core import csv
4
4
  from udata.i18n import I18nBlueprint
5
5
 
6
6
  from .csv import TagCsvAdapter
udata/harvest/csv.py CHANGED
@@ -1,4 +1,4 @@
1
- from udata.frontend import csv
1
+ from udata.core import csv
2
2
 
3
3
  from .models import HarvestSource
4
4