dalia_dif 0.0.16__py3-none-any.whl → 0.0.18__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.
- dalia_dif/cli.py +17 -2
- dalia_dif/dif13/community/__init__.py +47 -13
- dalia_dif/dif13/community/dalia_communities.csv +1 -1
- dalia_dif/dif13/reader.py +27 -6
- dalia_dif/version.py +1 -1
- {dalia_dif-0.0.16.dist-info → dalia_dif-0.0.18.dist-info}/METADATA +2 -2
- {dalia_dif-0.0.16.dist-info → dalia_dif-0.0.18.dist-info}/RECORD +10 -10
- {dalia_dif-0.0.16.dist-info → dalia_dif-0.0.18.dist-info}/WHEEL +2 -2
- {dalia_dif-0.0.16.dist-info → dalia_dif-0.0.18.dist-info}/entry_points.txt +0 -0
- {dalia_dif-0.0.16.dist-info → dalia_dif-0.0.18.dist-info}/licenses/LICENSE +0 -0
dalia_dif/cli.py
CHANGED
|
@@ -17,10 +17,20 @@ def main() -> None:
|
|
|
17
17
|
|
|
18
18
|
@main.command()
|
|
19
19
|
@click.option("--dif-version", type=click.Choice(["1.3"]), default="1.3")
|
|
20
|
+
@click.option("--ignore-missing-description", is_flag=True)
|
|
21
|
+
@click.option("--communities-path", type=Path)
|
|
20
22
|
@click.argument("location")
|
|
21
|
-
def validate(
|
|
23
|
+
def validate(
|
|
24
|
+
location: str, dif_version: str, ignore_missing_description: bool, communities_path: Path | None
|
|
25
|
+
) -> None:
|
|
22
26
|
"""Validate a local/remote file or local folder of DIF-encoded CSVs."""
|
|
23
27
|
from dalia_dif.dif13 import read_dif13
|
|
28
|
+
from dalia_dif.dif13.community import get_communities_dict
|
|
29
|
+
|
|
30
|
+
if communities_path is not None:
|
|
31
|
+
community_dict = get_communities_dict(communities_path)
|
|
32
|
+
else:
|
|
33
|
+
community_dict = {}
|
|
24
34
|
|
|
25
35
|
fail = False
|
|
26
36
|
p = Path(location)
|
|
@@ -31,7 +41,12 @@ def validate(location: str, dif_version: str) -> None:
|
|
|
31
41
|
for path in p.glob("*.csv"):
|
|
32
42
|
click.secho(f"\n> {path.relative_to(p)}", fg="green")
|
|
33
43
|
errors: list[str] = []
|
|
34
|
-
read_dif13(
|
|
44
|
+
read_dif13(
|
|
45
|
+
path,
|
|
46
|
+
error_accumulator=errors,
|
|
47
|
+
ignore_missing_description=ignore_missing_description,
|
|
48
|
+
custom_community_dict=community_dict,
|
|
49
|
+
)
|
|
35
50
|
if errors:
|
|
36
51
|
fail = True
|
|
37
52
|
for error in errors:
|
|
@@ -3,35 +3,69 @@
|
|
|
3
3
|
import csv
|
|
4
4
|
from collections import Counter
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
from typing import Any, TypeAlias
|
|
7
|
+
|
|
8
|
+
from pydantic import UUID4, AnyHttpUrl, BaseModel, Field
|
|
6
9
|
|
|
7
10
|
HERE = Path(__file__).parent.resolve()
|
|
8
11
|
COMMUNITIES_PATH = HERE / "dalia_communities.csv"
|
|
9
12
|
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
class Community(BaseModel):
|
|
15
|
+
"""A data model for communities."""
|
|
16
|
+
|
|
17
|
+
uuid: UUID4
|
|
18
|
+
title: str
|
|
19
|
+
ror: str | None = None
|
|
20
|
+
website: AnyHttpUrl | None = None
|
|
21
|
+
synonyms: list[str] = Field(default_factory=list)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _process(row: dict[str, Any]) -> Community:
|
|
25
|
+
if synonyms_raw := row.pop("synonyms"):
|
|
26
|
+
row["synonyms"] = [s.strip() for s in synonyms_raw.split("|")]
|
|
27
|
+
return Community.model_validate({k: v for k, v in row.items() if v})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def read_communities(path: Path) -> list[Community]:
|
|
31
|
+
"""Read communities."""
|
|
32
|
+
with open(path, newline="") as csvfile:
|
|
33
|
+
return [_process(row) for row in csv.DictReader(csvfile)]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
CommunityDict: TypeAlias = dict[str, str]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_communities_dict(path: Path) -> CommunityDict:
|
|
40
|
+
"""Get a mapping from names/synonyms to UUID strings."""
|
|
12
41
|
rv = {}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
rv[synonym] = row["ID"]
|
|
42
|
+
for community in read_communities(path):
|
|
43
|
+
rv[community.title] = str(community.uuid)
|
|
44
|
+
for synonym in community.synonyms:
|
|
45
|
+
rv[synonym] = str(community.uuid)
|
|
18
46
|
return rv
|
|
19
47
|
|
|
20
48
|
|
|
21
|
-
|
|
49
|
+
def _read_mapping() -> dict[str, str]:
|
|
50
|
+
rv = {}
|
|
51
|
+
for community in read_communities(COMMUNITIES_PATH):
|
|
52
|
+
rv[community.title] = str(community.uuid)
|
|
53
|
+
for synonym in community.synonyms:
|
|
54
|
+
rv[synonym] = str(community.uuid)
|
|
55
|
+
return rv
|
|
56
|
+
|
|
22
57
|
|
|
23
|
-
|
|
58
|
+
LOOKUP_DICT_COMMUNITIES: CommunityDict = get_communities_dict(COMMUNITIES_PATH)
|
|
24
59
|
|
|
25
60
|
MISSING_COMMUNITIES: Counter[str] = Counter()
|
|
26
61
|
|
|
27
62
|
|
|
28
63
|
def get_community_labels() -> dict[str, str]:
|
|
29
64
|
"""Get community labels."""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
65
|
+
return {
|
|
66
|
+
str(community.uuid): COMMUNITY_RELABELS.get(community.title, community.title)
|
|
67
|
+
for community in read_communities(COMMUNITIES_PATH)
|
|
68
|
+
}
|
|
35
69
|
|
|
36
70
|
|
|
37
71
|
COMMUNITY_RELABELS = {
|
dalia_dif/dif13/reader.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
import re
|
|
7
|
-
from collections import Counter
|
|
7
|
+
from collections import ChainMap, Counter
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import TextIO
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ from pystow.utils import safe_open_dict_reader
|
|
|
17
17
|
from rdflib import URIRef
|
|
18
18
|
from tqdm import tqdm
|
|
19
19
|
|
|
20
|
-
from .community import LOOKUP_DICT_COMMUNITIES
|
|
20
|
+
from .community import LOOKUP_DICT_COMMUNITIES, CommunityDict
|
|
21
21
|
from .model import (
|
|
22
22
|
AuthorDIF13,
|
|
23
23
|
EducationalResourceDIF13,
|
|
@@ -101,6 +101,8 @@ def read_dif13(
|
|
|
101
101
|
*,
|
|
102
102
|
error_accumulator: list[str] | None = None,
|
|
103
103
|
converter: curies.Converter | None = None,
|
|
104
|
+
ignore_missing_description: bool = False,
|
|
105
|
+
custom_community_dict: CommunityDict | None = None,
|
|
104
106
|
) -> list[EducationalResourceDIF13]:
|
|
105
107
|
"""Parse DALIA records."""
|
|
106
108
|
if isinstance(path, str) and (path.startswith("http://") or path.startswith("https://")):
|
|
@@ -132,7 +134,13 @@ def read_dif13(
|
|
|
132
134
|
for idx, record in enumerate(reader, start=2)
|
|
133
135
|
if (
|
|
134
136
|
oer := parse_dif13_row(
|
|
135
|
-
file_name,
|
|
137
|
+
file_name,
|
|
138
|
+
idx,
|
|
139
|
+
record,
|
|
140
|
+
error_accumulator=error_accumulator,
|
|
141
|
+
converter=converter,
|
|
142
|
+
ignore_missing_description=ignore_missing_description,
|
|
143
|
+
custom_community_dict=custom_community_dict,
|
|
136
144
|
)
|
|
137
145
|
)
|
|
138
146
|
is not None
|
|
@@ -157,13 +165,19 @@ def parse_dif13_row( # noqa:C901
|
|
|
157
165
|
future: bool = False,
|
|
158
166
|
error_accumulator: list[str] | None = None,
|
|
159
167
|
converter: curies.Converter | None = None,
|
|
168
|
+
ignore_missing_description: bool = False,
|
|
169
|
+
custom_community_dict: CommunityDict | None = None,
|
|
160
170
|
) -> EducationalResourceDIF13 | None:
|
|
161
171
|
"""Convert a row in a DALIA curation file to a resource, or return none if unable."""
|
|
162
172
|
if isinstance(file_name, Path):
|
|
163
173
|
file_name = file_name.name
|
|
164
174
|
|
|
165
175
|
supporting_communities, recommending_communities = _process_communities(
|
|
166
|
-
file_name,
|
|
176
|
+
file_name,
|
|
177
|
+
idx,
|
|
178
|
+
row,
|
|
179
|
+
error_accumulator=error_accumulator,
|
|
180
|
+
custom_community_dict=custom_community_dict,
|
|
167
181
|
)
|
|
168
182
|
|
|
169
183
|
external_uris = _pop_split(row, "Link")
|
|
@@ -193,7 +207,12 @@ def parse_dif13_row( # noqa:C901
|
|
|
193
207
|
|
|
194
208
|
description = row.pop("Description").strip()
|
|
195
209
|
if not description:
|
|
196
|
-
_log(
|
|
210
|
+
_log(
|
|
211
|
+
file_name,
|
|
212
|
+
idx,
|
|
213
|
+
"no description given",
|
|
214
|
+
error_accumulator=None if ignore_missing_description else error_accumulator,
|
|
215
|
+
)
|
|
197
216
|
return None
|
|
198
217
|
|
|
199
218
|
try:
|
|
@@ -461,8 +480,10 @@ def _process_communities(
|
|
|
461
480
|
row: dict[str, str],
|
|
462
481
|
*,
|
|
463
482
|
error_accumulator: list[str] | None = None,
|
|
483
|
+
custom_community_dict: CommunityDict | None = None,
|
|
464
484
|
) -> tuple[list[URIRef], list[URIRef]]:
|
|
465
485
|
supporting, recommending = [], []
|
|
486
|
+
community_dict = ChainMap(custom_community_dict or {}, LOOKUP_DICT_COMMUNITIES)
|
|
466
487
|
for community in _pop_split(row, "Community"):
|
|
467
488
|
match = COMMUNITY_RELATION_RE.search(community)
|
|
468
489
|
if not match:
|
|
@@ -477,7 +498,7 @@ def _process_communities(
|
|
|
477
498
|
name = match.group("name").strip()
|
|
478
499
|
relation = match.group("relation")
|
|
479
500
|
|
|
480
|
-
community_uuid =
|
|
501
|
+
community_uuid = community_dict.get(name, None)
|
|
481
502
|
if not community_uuid:
|
|
482
503
|
if not MISSING_COMMUNITIES[name]:
|
|
483
504
|
_log(
|
dalia_dif/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dalia_dif
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.18
|
|
4
4
|
Summary: Tools for DALIA's data model for open educational resources
|
|
5
5
|
Keywords: snekpack,cookiecutter,open educational resources,educational resources,training
|
|
6
6
|
Author: Charles Tapley Hoyt
|
|
@@ -39,9 +39,9 @@ Maintainer: Charles Tapley Hoyt
|
|
|
39
39
|
Maintainer-email: Charles Tapley Hoyt <cthoyt@gmail.com>
|
|
40
40
|
Requires-Python: >=3.10
|
|
41
41
|
Project-URL: Bug Tracker, https://github.com/data-literacy-alliance/dalia-dif/issues
|
|
42
|
-
Project-URL: Documentation, https://dalia-dif.readthedocs.io
|
|
43
42
|
Project-URL: Homepage, https://github.com/data-literacy-alliance/dalia-dif
|
|
44
43
|
Project-URL: Repository, https://github.com/data-literacy-alliance/dalia-dif.git
|
|
44
|
+
Project-URL: Documentation, https://dalia-dif.readthedocs.io
|
|
45
45
|
Provides-Extra: export
|
|
46
46
|
Provides-Extra: fti
|
|
47
47
|
Description-Content-Type: text/markdown
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
dalia_dif/.DS_Store,sha256=MtnD5ThzFbk9R7gZVWNniR_qnre6YMJscVWWkkQW8AM,6148
|
|
2
2
|
dalia_dif/__init__.py,sha256=uyO7jo0cu-99M2a87I7XeOH6c9ZPqRH46YgTdfXLOWg,66
|
|
3
3
|
dalia_dif/__main__.py,sha256=dlPNI11KSS49DY4SoTA1l8gQZr6iR9N1JJsySTjicUg,126
|
|
4
|
-
dalia_dif/cli.py,sha256=
|
|
4
|
+
dalia_dif/cli.py,sha256=yvV0YeBSJ9cGlmcsuTaVqGw6-zokjLvoQ8xYHjPzoq8,3504
|
|
5
5
|
dalia_dif/dif13/__init__.py,sha256=tMaSW0hhnuO_Mt8CM_d0cTT6j_FSTGFY99crUawWa4w,457
|
|
6
|
-
dalia_dif/dif13/community/__init__.py,sha256=
|
|
7
|
-
dalia_dif/dif13/community/dalia_communities.csv,sha256=
|
|
6
|
+
dalia_dif/dif13/community/__init__.py,sha256=IwHOubp6bc6peW2vVgaYuA7JNJ07py60bUZowKDttvs,2107
|
|
7
|
+
dalia_dif/dif13/community/dalia_communities.csv,sha256=Dg4rGox0ykZ-2HFFgVF8hDZIxcX2VgeKUle2W4PHD0c,6193
|
|
8
8
|
dalia_dif/dif13/constants.py,sha256=NLNutj5AYok_WY1t1iE01dOCKK2eCnkezzN4TUgT-SA,6797
|
|
9
9
|
dalia_dif/dif13/export/__init__.py,sha256=-HXO3x8soeYPFg5vIggJcZihGbyeVn_DO42cqWwNAuA,28
|
|
10
10
|
dalia_dif/dif13/export/charts.py,sha256=8cXrq2UMnQUFi_Bda5L5sbZJRu2DnfUftj8zPe5c8ik,13695
|
|
@@ -17,7 +17,7 @@ dalia_dif/dif13/model.py,sha256=GIfzAnT0Blh7Qe-wk3w_lxZld-B4VbfH2ahyaDdpuR4,6935
|
|
|
17
17
|
dalia_dif/dif13/picklists.py,sha256=FapSFANJZ_u432RtGyOq7v8FpKfR4X9C7n3bAAXbrNI,4933
|
|
18
18
|
dalia_dif/dif13/predicates.py,sha256=rrWVPMnMPvMelS4i2hOEWGhL11t-KR8yRrDArhGvYPE,1700
|
|
19
19
|
dalia_dif/dif13/rdf.py,sha256=ZPdGB1hM2zNuxe6gidNwOn0LJB00Zs-mj2fHOYNm_qU,5908
|
|
20
|
-
dalia_dif/dif13/reader.py,sha256=
|
|
20
|
+
dalia_dif/dif13/reader.py,sha256=SinQMN_cimwihpsM3kJwom-MD8Om_WPTTi5Bo5EOKxQ,17611
|
|
21
21
|
dalia_dif/dif13/utils.py,sha256=-r5ezhD7AkaJUAsUtZl1sHG_P76fz2Q_ULXgXLyDNII,814
|
|
22
22
|
dalia_dif/namespace/__init__.py,sha256=kJGpIXZzeUdVhM_Pj465XlMkVqMB2Uc9aAZeFKQp5IQ,3105
|
|
23
23
|
dalia_dif/namespace/bibframe_lite_relation.py,sha256=2trFP98s1wCPUfiAjHg-EK09yjWXC6ePLNJIVqgZvd8,255
|
|
@@ -31,9 +31,9 @@ dalia_dif/namespace/modalia.py,sha256=pSL-G9ib0E--Jwrbu9PvMMRjMe2FzzxoSjEv-0ank2
|
|
|
31
31
|
dalia_dif/namespace/rec.py,sha256=c2Ce5IEhnM_BcZJUCXiMQEZ2GLFcC_76hfkKE16-zLc,241
|
|
32
32
|
dalia_dif/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
33
33
|
dalia_dif/utils.py,sha256=AA19Bw0vv8-ODZzDy_VR57WwndRccaQIepVS8tvodDo,761
|
|
34
|
-
dalia_dif/version.py,sha256=
|
|
35
|
-
dalia_dif-0.0.
|
|
36
|
-
dalia_dif-0.0.
|
|
37
|
-
dalia_dif-0.0.
|
|
38
|
-
dalia_dif-0.0.
|
|
39
|
-
dalia_dif-0.0.
|
|
34
|
+
dalia_dif/version.py,sha256=7L891_Jrr5liLFWnZMCce8I-vBl683ocjoLsHlmjYGY,962
|
|
35
|
+
dalia_dif-0.0.18.dist-info/licenses/LICENSE,sha256=S-DsND478R_VQyGmtXbVYW67fRiJj3QfY8UXIJ4zvLI,1076
|
|
36
|
+
dalia_dif-0.0.18.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
|
|
37
|
+
dalia_dif-0.0.18.dist-info/entry_points.txt,sha256=GmBz8JVyUD6m4v2QIxa7gm3sHIVNjTl5KTPP7L3FCGI,50
|
|
38
|
+
dalia_dif-0.0.18.dist-info/METADATA,sha256=rqYxck75cMrF7PtSj4xMR9NeaPe9YySdUEVrW8Cs4Sw,17760
|
|
39
|
+
dalia_dif-0.0.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|