Skip to content

Commit ef87125

Browse files
committed
PR updates
1 parent f238420 commit ef87125

File tree

2 files changed

+100
-56
lines changed

2 files changed

+100
-56
lines changed

dsaps/models.py

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import collections
12
import csv
23
import datetime
34
from functools import partial
@@ -78,7 +79,7 @@ def filtered_item_search(self, key, string, query_type,
7879
return item_links
7980

8081
def get_id_from_handle(self, handle):
81-
"""Posts a collection to a specified community."""
82+
"""Retrieves UUID for an object based on its handle."""
8283
endpoint = f'{self.url}/handle/{handle}'
8384
rec_obj = requests.get(endpoint, headers=self.header,
8485
cookies=self.cookies).json()
@@ -124,26 +125,29 @@ def post_items_to_coll(self, coll_id, coll_metadata, file_dict,
124125

125126
def post_bitstreams_to_item(self, item_id, file_identifier, file_dict,
126127
ingest_type):
127-
"""Posts bitstreams to a specified item."""
128-
for k, v in file_dict.items():
129-
bitstreams = []
130-
if k.startswith(file_identifier):
131-
bitstreams.append(k)
132-
bitstreams.sort()
133-
for bitstream in bitstreams:
134-
bitstream_path = file_dict[bitstream]
135-
file_name = os.path.basename(bitstream_path)
136-
if ingest_type == 'local':
137-
data = open(bitstream_path, 'rb')
138-
elif ingest_type == 'remote':
139-
data = requests.get(bitstream_path)
140-
endpoint = (f'{self.url}/items/{item_id}'
141-
+ f'/bitstreams?name={file_name}')
142-
header_upload = {'accept': 'application/json'}
143-
bit_id = requests.post(endpoint, headers=header_upload,
144-
cookies=self.cookies, data=data).json()
145-
bit_id = bit_id['uuid']
146-
yield bit_id
128+
"""Post a sorted set of bitstreams to a specified item."""
129+
file_dict = collections.OrderedDict(sorted(file_dict.items()))
130+
for bitstream, v in file_dict.items():
131+
bit_id = self.post_bitstream(item_id, file_identifier, file_dict,
132+
ingest_type, bitstream)
133+
yield bit_id
134+
135+
def post_bitstream(self, item_id, file_identifier, file_dict, ingest_type,
136+
bitstream):
137+
"""Post a bitstream to a specified item."""
138+
bitstream_path = file_dict[bitstream]
139+
file_name = os.path.basename(bitstream_path)
140+
if ingest_type == 'local':
141+
data = open(bitstream_path, 'rb')
142+
elif ingest_type == 'remote':
143+
data = requests.get(bitstream_path)
144+
endpoint = (f'{self.url}/items/{item_id}'
145+
+ f'/bitstreams?name={file_name}')
146+
header_upload = {'accept': 'application/json'}
147+
bit_id = requests.post(endpoint, headers=header_upload,
148+
cookies=self.cookies, data=data).json()
149+
bit_id = bit_id['uuid']
150+
return bit_id
147151

148152
def _pop_inst(self, class_type, rec_obj):
149153
"""Populate class instance with data from record."""
@@ -224,38 +228,29 @@ def elapsed_time(start_time, label):
224228
logger.info(f'{label} : {td}')
225229

226230

227-
def metadata_csv(row, key, field, language=None, delimiter=''):
228-
"""Create metadata element from CSV."""
231+
def metadata_elems_from_row(row, key, field, language=None, delimiter=''):
232+
"""Create a metadata element from a CSV row."""
229233
metadata_elems = []
230234
if row[field] != '':
231-
if delimiter != '' and delimiter in row[field]:
235+
if delimiter:
232236
values = row[field].split(delimiter)
233-
for value in values:
234-
if language is not None:
235-
metadata_elem = {'key': key, 'language': language, 'value':
236-
value}
237-
metadata_elems.append(metadata_elem)
238-
else:
239-
metadata_elem = {'key': key, 'value': value}
240-
metadata_elems.append(metadata_elem)
241237
else:
242-
value = row[field]
243-
if language is not None:
244-
metadata_elem = {'key': key, 'language': language, 'value':
245-
value}
246-
else:
247-
metadata_elem = {'key': key, 'value': value}
248-
metadata_elems.append(metadata_elem)
238+
values = [row[field]]
239+
for value in values:
240+
metadata_elem = {'key': key, 'language': language, 'value':
241+
value}
242+
metadata_elems.append({k: v for k, v in metadata_elem.items()
243+
if v is not None})
249244
return metadata_elems
250245

251246

252247
def create_metadata_rec(mapping_dict, row, metadata_rec):
253-
"""Create metadata record from CSV."""
248+
"""Create metadata record from a series of metadata elements."""
254249
for k, v in mapping_dict.items():
255250
if len(v) == 3:
256-
metadata_elems = metadata_csv(row, k, v[0], v[1], v[2])
251+
metadata_elems = metadata_elems_from_row(row, k, v[0], v[1], v[2])
257252
else:
258-
metadata_elems = metadata_csv(row, k, v[0])
253+
metadata_elems = metadata_elems_from_row(row, k, v[0])
259254
for metadata_elem in metadata_elems:
260255
metadata_rec.append(metadata_elem)
261256
return metadata_rec

tests/test_models.py

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@ def client():
1515

1616

1717
@pytest.fixture
18-
def sample_content(tmp_path):
18+
def sample_content_1(tmp_path):
1919
content = 'test'
2020
dir = tmp_path / 'sub'
2121
dir.mkdir()
22-
sample_content = dir / '123.pdf'
22+
sample_content = dir / '123_1.pdf'
23+
sample_content.write_text(content)
24+
return sample_content
25+
26+
27+
@pytest.fixture
28+
def sample_content_2(tmp_path):
29+
content = 'test'
30+
dir = tmp_path / 'sub'
31+
sample_content = dir / '123_2.pdf'
2332
sample_content.write_text(content)
2433
return sample_content
2534

@@ -88,7 +97,7 @@ def test_post_coll_to_comm(client):
8897
assert coll_id == '5678'
8998

9099

91-
def test_post_items_to_coll(client, sample_content):
100+
def test_post_items_to_coll(client, sample_content_1):
92101
"""Test post_items_to_coll method."""
93102
with requests_mock.Mocker() as m:
94103
coll_metadata = [{"metadata": [
@@ -101,10 +110,10 @@ def test_post_items_to_coll(client, sample_content):
101110
"value": "repo/0/ao/123"}]}]
102111
coll_id = '789'
103112
ingest_type = 'local'
104-
file_dict = {'123': sample_content}
113+
file_dict = {'123': sample_content_1}
105114
item_json = {'uuid': 'a1b2', 'handle': '1111.1/1111'}
106115
m.post('mock://example.com/collections/789/items', json=item_json)
107-
url = 'mock://example.com/items/a1b2/bitstreams?name=123.pdf'
116+
url = 'mock://example.com/items/a1b2/bitstreams?name=123_1.pdf'
108117
b_json = {'uuid': 'c3d4'}
109118
m.post(url, json=b_json)
110119
item_ids = client.post_items_to_coll(coll_id, coll_metadata, file_dict,
@@ -113,20 +122,42 @@ def test_post_items_to_coll(client, sample_content):
113122
assert 'a1b2' == item_id
114123

115124

116-
def test_post_bitstreams_to_item(client, sample_content):
125+
def test_post_bitstreams_to_item(client, sample_content_1, sample_content_2):
117126
"""Test post_bitstreams_to_item method."""
118127
with requests_mock.Mocker() as m:
119128
item_id = 'a1b2'
120129
ingest_type = 'local'
121130
file_identifier = '123'
122-
file_dict = {'123': sample_content}
123-
b_json = {'uuid': 'c3d4'}
124-
url = 'mock://example.com/items/a1b2/bitstreams?name=123.pdf'
125-
m.post(url, json=b_json)
131+
file_dict = {'123_2': sample_content_2, '123_1': sample_content_1}
132+
b_json_1 = {'uuid': 'c3d4'}
133+
url_1 = 'mock://example.com/items/a1b2/bitstreams?name=123_1.pdf'
134+
m.post(url_1, json=b_json_1)
135+
b_json_2 = {'uuid': 'e5f6'}
136+
url_2 = 'mock://example.com/items/a1b2/bitstreams?name=123_2.pdf'
137+
m.post(url_2, json=b_json_2)
126138
bit_ids = client.post_bitstreams_to_item(item_id, file_identifier,
127139
file_dict, ingest_type)
140+
bit_ids_output = []
128141
for bit_id in bit_ids:
129-
assert 'c3d4' == bit_id
142+
bit_ids_output.append(bit_id)
143+
assert bit_ids_output[0] == 'c3d4'
144+
assert bit_ids_output[1] == 'e5f6'
145+
146+
147+
def test_post_bitstream(client, sample_content_1):
148+
"""Test post_bitstream method."""
149+
with requests_mock.Mocker() as m:
150+
item_id = 'a1b2'
151+
ingest_type = 'local'
152+
file_identifier = '123'
153+
file_dict = {'123': sample_content_1}
154+
b_json = {'uuid': 'c3d4'}
155+
url = 'mock://example.com/items/a1b2/bitstreams?name=123_1.pdf'
156+
bitstream = '123'
157+
m.post(url, json=b_json)
158+
bit_id = client.post_bitstream(item_id, file_identifier, file_dict,
159+
ingest_type, bitstream)
160+
assert 'c3d4' == bit_id
130161

131162

132163
def test__pop_inst(client):
@@ -169,12 +200,30 @@ def test_build_file_dict_remote():
169200
# assert False
170201

171202

172-
def test_metadata_csv():
173-
"""Test metadata_csv function."""
203+
def test_metadata_elems_from_row():
204+
"""Test metadata_elems_from_row function."""
174205
row = {'title': 'Test title'}
175-
metadata_elem = models.metadata_csv(row, 'dc.title', 'title', 'en_US')
206+
metadata_elem = models.metadata_elems_from_row(row, 'dc.title', 'title',
207+
'en_US')
176208
assert metadata_elem[0]['key'] == 'dc.title'
177209
assert metadata_elem[0]['value'] == 'Test title'
210+
assert metadata_elem[0]['language'] == 'en_US'
211+
metadata_elem = models.metadata_elems_from_row(row, 'dc.title', 'title')
212+
assert metadata_elem[0]['key'] == 'dc.title'
213+
assert metadata_elem[0]['value'] == 'Test title'
214+
assert 'language' not in metadata_elem[0]
215+
row = {'title': ''}
216+
metadata_elem = models.metadata_elems_from_row(row, 'dc.title', 'title')
217+
assert metadata_elem == []
218+
row = {'title': 'Test title 1|Test title 2'}
219+
metadata_elem = models.metadata_elems_from_row(row, 'dc.title', 'title',
220+
'en_US', '|')
221+
assert metadata_elem[0]['key'] == 'dc.title'
222+
assert metadata_elem[0]['value'] == 'Test title 1'
223+
assert metadata_elem[0]['language'] == 'en_US'
224+
assert metadata_elem[1]['key'] == 'dc.title'
225+
assert metadata_elem[1]['value'] == 'Test title 2'
226+
assert metadata_elem[1]['language'] == 'en_US'
178227

179228

180229
# def test_create_ingest_report():

0 commit comments

Comments
 (0)