Skip to content

Commit 85a27ca

Browse files
authored
Merge pull request #14 from MITLibraries/misc-refactoring
get id from handle and misc refactoring
2 parents 59fc7a6 + ef87125 commit 85a27ca

File tree

6 files changed

+160
-100
lines changed

6 files changed

+160
-100
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: python
22
python:
3-
- "3.7"
3+
- "3.8"
44
install:
55
- pipenv install --dev
66
script:

Pipfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ requests-mock = "*"
1010
[packages]
1111
requests = "*"
1212
structlog = "*"
13-
attr = "*"
13+
attrs = "*"
1414
click = "*"
1515
lxml = "*"
1616

1717
[requires]
18-
python_version = "3.7"
18+
python_version = "3.8"
1919

2020
[scripts]
2121
dsaps = "python -c \"from dsaps.cli import main; main()\""

dsaps/cli.py

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
@click.pass_context
2525
def main(ctx, url, email, password):
2626
ctx.obj = {}
27+
if os.path.isdir('logs') is False:
28+
os.mkdir('logs')
2729
dt = datetime.datetime.utcnow().isoformat(timespec='seconds')
2830
log_suffix = f'{dt}.log'
2931
structlog.configure(processors=[
@@ -47,31 +49,6 @@ def main(ctx, url, email, password):
4749
ctx.obj['start_time'] = start_time
4850

4951

50-
@click.group()
51-
def aux():
52-
pass
53-
54-
55-
@main.command()
56-
@click.option('-f', '--field', prompt='Enter the field to be searched',
57-
help='The field to search.')
58-
@click.option('-s', '--string', prompt='Enter the string',
59-
help='The field to search.')
60-
@click.option('-t', '--search_type', prompt='Enter the type of search',
61-
help='The type of search.',
62-
type=click.Choice(['exists', 'doesnt_exist', 'equals',
63-
'not_equals', 'contains', 'doesnt_contain']),
64-
default='contains')
65-
@click.pass_context
66-
def search(ctx, field, string, search_type):
67-
# Temp function for testing
68-
client = ctx.obj['client']
69-
start_time = ctx.obj['start_time']
70-
item_links = client.filtered_item_search(field, string, search_type)
71-
logger.info(item_links)
72-
models.elapsed_time(start_time, 'Elapsed time')
73-
74-
7552
@main.command()
7653
@click.option('-c', '--comm_handle', prompt='Enter the community handle',
7754
help='The handle of the community in which to create the ,'
@@ -111,7 +88,7 @@ def newcoll(ctx, comm_handle, coll_name, metadata, file_path, file_type,
11188
models.elapsed_time(start_time, 'Total runtime:')
11289

11390

114-
@aux.command()
91+
@main.command()
11592
@click.option('-m', '--metadata_csv', prompt='Enter the metadata CSV file',
11693
help='The path of the CSV file of metadata.')
11794
@click.option('-f', '--file_path', prompt='Enter the path',
@@ -150,7 +127,7 @@ def reconcile(metadata_csv, file_path, file_type):
150127
models.create_csv_from_list(metadata_matches, 'metadata_matches.csv')
151128

152129

153-
@aux.command()
130+
@main.command()
154131
@click.option('-m', '--metadata_csv', prompt='Enter the metadata CSV file',
155132
help='The path of the CSV file of metadata.')
156133
def metadatajson(metadata_csv):
@@ -190,7 +167,5 @@ def metadatajson(metadata_csv):
190167
json.dump(metadata_group, f)
191168

192169

193-
cli = click.CommandCollection(sources=[main, aux])
194-
195170
if __name__ == '__main__':
196-
cli()
171+
main()

dsaps/models.py

Lines changed: 51 additions & 31 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
@@ -77,6 +78,13 @@ def filtered_item_search(self, key, string, query_type,
7778
offset = offset + 200
7879
return item_links
7980

81+
def get_id_from_handle(self, handle):
82+
"""Retrieves UUID for an object based on its handle."""
83+
endpoint = f'{self.url}/handle/{handle}'
84+
rec_obj = requests.get(endpoint, headers=self.header,
85+
cookies=self.cookies).json()
86+
return rec_obj['uuid']
87+
8088
def post_coll_to_comm(self, comm_handle, coll_name):
8189
"""Posts a collection to a specified community."""
8290
endpoint = f'{self.url}/handle/{comm_handle}'
@@ -117,22 +125,29 @@ def post_items_to_coll(self, coll_id, coll_metadata, file_dict,
117125

118126
def post_bitstreams_to_item(self, item_id, file_identifier, file_dict,
119127
ingest_type):
120-
"""Posts bitstreams to a specified item."""
121-
for k, v in file_dict.items():
122-
if k.startswith(file_identifier):
123-
bitstream = file_dict[k]
124-
file_name = os.path.basename(bitstream)
125-
if ingest_type == 'local':
126-
data = open(bitstream, 'rb')
127-
elif ingest_type == 'remote':
128-
data = requests.get(bitstream)
129-
endpoint = (f'{self.url}/items/{item_id}'
130-
+ f'/bitstreams?name={file_name}')
131-
header_upload = {'accept': 'application/json'}
132-
bit_id = requests.post(endpoint, headers=header_upload,
133-
cookies=self.cookies, data=data).json()
134-
bit_id = bit_id['uuid']
135-
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
136151

137152
def _pop_inst(self, class_type, rec_obj):
138153
"""Populate class instance with data from record."""
@@ -192,7 +207,7 @@ def build_file_dict_remote(directory_url, file_type, file_dict):
192207
"""Build list of files in a remote directory."""
193208
response = requests.get(directory_url)
194209
links = html.fromstring(response.content).iterlinks()
195-
for link in [l for l in links if l[2].endswith(file_type)]:
210+
for link in [i for i in links if i[2].endswith(file_type)]:
196211
file_identifier = link[2].replace(f'.{file_type}', '')
197212
file_dict[file_identifier] = f'{directory_url}{link[2]}'
198213
return file_dict
@@ -213,24 +228,29 @@ def elapsed_time(start_time, label):
213228
logger.info(f'{label} : {td}')
214229

215230

216-
def metadata_csv(row, key, field, language=None):
217-
"""Create metadata element from CSV."""
218-
value = row[field]
219-
if language is not None:
220-
metadata_elem = {'key': key, 'language': language, 'value':
221-
value}
222-
else:
223-
metadata_elem = {'key': key, 'value': value}
224-
return metadata_elem
231+
def metadata_elems_from_row(row, key, field, language=None, delimiter=''):
232+
"""Create a metadata element from a CSV row."""
233+
metadata_elems = []
234+
if row[field] != '':
235+
if delimiter:
236+
values = row[field].split(delimiter)
237+
else:
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})
244+
return metadata_elems
225245

226246

227247
def create_metadata_rec(mapping_dict, row, metadata_rec):
228-
"""Create metadata record from CSV."""
248+
"""Create metadata record from a series of metadata elements."""
229249
for k, v in mapping_dict.items():
230-
if len(v) == 2:
231-
metadata_elem = metadata_csv(row, k, v[0], v[1])
250+
if len(v) == 3:
251+
metadata_elems = metadata_elems_from_row(row, k, v[0], v[1], v[2])
232252
else:
233-
metadata_elem = metadata_csv(row, k, v[0])
234-
if metadata_elem['value'] != '':
253+
metadata_elems = metadata_elems_from_row(row, k, v[0])
254+
for metadata_elem in metadata_elems:
235255
metadata_rec.append(metadata_elem)
236256
return metadata_rec

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from setuptools import setup, find_packages
22

33
setup(
4-
name='DSpace API Python Scripts',
4+
name='dsaps',
55
version='1.0.0',
66
description='',
77
packages=find_packages(exclude=['tests']),
@@ -10,7 +10,7 @@
1010
install_requires=[
1111
'requests',
1212
'structlog',
13-
'attr',
13+
'attrs',
1414
'click',
1515
'lxml',
1616
],
@@ -19,5 +19,5 @@
1919
'dsaps=dsaps.cli:main',
2020
]
2121
},
22-
python_requires='>=3.7.1',
22+
python_requires='>=3.8',
2323
)

0 commit comments

Comments
 (0)