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.
- udata/{frontend → core}/csv.py +1 -1
- udata/core/dataservices/csv.py +1 -1
- udata/core/dataset/api.py +11 -0
- udata/core/dataset/csv.py +1 -1
- udata/core/dataset/tasks.py +1 -2
- udata/core/discussions/csv.py +1 -1
- udata/core/organization/api.py +40 -0
- udata/core/organization/csv.py +1 -1
- udata/core/reuse/csv.py +1 -1
- udata/core/site/api.py +106 -1
- udata/core/tags/csv.py +1 -1
- udata/core/tags/views.py +1 -1
- udata/harvest/csv.py +1 -1
- udata/static/chunks/{10.8ca60413647062717b1e.js → 10.471164b2a9fe15614797.js} +3 -3
- udata/static/chunks/{10.8ca60413647062717b1e.js.map → 10.471164b2a9fe15614797.js.map} +1 -1
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js → 11.83535504cd650ea08f65.js} +3 -3
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js.map → 11.83535504cd650ea08f65.js.map} +1 -1
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.d9c1735d14038b94c17e.js} +2 -2
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.d9c1735d14038b94c17e.js.map} +1 -1
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.81c57c0dedf812e43013.js} +2 -2
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.81c57c0dedf812e43013.js.map} +1 -1
- udata/static/chunks/{19.f03a102365af4315f9db.js → 19.df16abde17a42033a7f8.js} +3 -3
- udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.df16abde17a42033a7f8.js.map} +1 -1
- udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.462bb3029de008497675.js} +2 -2
- udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.462bb3029de008497675.js.map} +1 -1
- udata/static/chunks/{9.033d7e190ca9e226a5d0.js → 9.07515e5187f475bce828.js} +3 -3
- udata/static/chunks/{9.033d7e190ca9e226a5d0.js.map → 9.07515e5187f475bce828.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tests/api/test_organizations_api.py +98 -1
- udata/tests/apiv2/test_datasets.py +16 -0
- udata/tests/frontend/test_csv.py +1 -1
- udata/tests/site/test_site_csv_exports.py +464 -0
- udata/tests/test_tags.py +1 -1
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/METADATA +3 -1
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/RECORD +40 -39
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/LICENSE +0 -0
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/WHEEL +0 -0
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/entry_points.txt +0 -0
- {udata-10.3.2.dev34939.dist-info → udata-10.3.2.dev34982.dist-info}/top_level.txt +0 -0
udata/{frontend → core}/csv.py
RENAMED
|
@@ -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 = {
|
udata/core/dataservices/csv.py
CHANGED
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
|
|
udata/core/dataset/tasks.py
CHANGED
|
@@ -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
|
udata/core/discussions/csv.py
CHANGED
udata/core/organization/api.py
CHANGED
|
@@ -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")
|
udata/core/organization/csv.py
CHANGED
udata/core/reuse/csv.py
CHANGED
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
udata/core/tags/views.py
CHANGED
udata/harvest/csv.py
CHANGED