Skip to content

Commit dddbd5f

Browse files
committed
BF+ENH: set dist-restrictions metadata correctly
1 parent b01c62d commit dddbd5f

File tree

4 files changed

+93
-3
lines changed

4 files changed

+93
-3
lines changed

heudiconv/external/dlad.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import inspect
12
import os
3+
24
import os.path as op
35
import logging
46
from glob import glob
@@ -155,7 +157,12 @@ def mark_sensitive(ds, path_glob):
155157
paths = glob(op.join(ds.path, path_glob))
156158
if not paths:
157159
return
158-
ds.repo.set_metadata(
160+
lgr.debug("Marking %d files with distribution-restrictions field",
161+
len(paths))
162+
# set_metadata can be a bloody generator
163+
res = ds.repo.set_metadata(
159164
paths,
160-
init=[('distribution-restrictions', 'sensitive')],
161-
recursive=True)
165+
init=dict([('distribution-restrictions', 'sensitive')]),
166+
recursive=True)
167+
if inspect.isgenerator(res):
168+
res = list(res)

heudiconv/external/tests/__init__.py

Whitespace-only changes.

heudiconv/external/tests/test_dlad.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from ..dlad import mark_sensitive
2+
from datalad.api import Dataset
3+
from ...utils import create_tree
4+
5+
6+
def test_mark_sensitive(tmpdir):
7+
ds = Dataset(str(tmpdir)).create(force=True)
8+
create_tree(
9+
str(tmpdir),
10+
{
11+
'f1': 'd1',
12+
'f2': 'd2',
13+
'g1': 'd3',
14+
'g2': 'd1',
15+
}
16+
)
17+
ds.add('.')
18+
mark_sensitive(ds, 'f*')
19+
all_meta = dict(ds.repo.get_metadata('.'))
20+
target_rec = {'distribution-restrictions': ['sensitive']}
21+
# g2 since the same content
22+
assert not all_meta.pop('g1', None) # nothing or empty record
23+
assert all_meta == {'f1': target_rec, 'f2': target_rec, 'g2': target_rec}

heudiconv/utils.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,63 @@ def clear_temp_dicoms(item_dicoms):
388388
def file_md5sum(filename):
389389
with open(filename, 'rb') as f:
390390
return hashlib.md5(f.read()).hexdigest()
391+
392+
393+
# Borrowed from DataLad (MIT license), with "archives" functionality commented
394+
# out
395+
class File(object):
396+
"""Helper for a file entry in the create_tree/@with_tree
397+
398+
It allows to define additional settings for entries
399+
"""
400+
def __init__(self, name, executable=False):
401+
"""
402+
403+
Parameters
404+
----------
405+
name : str
406+
Name of the file
407+
executable: bool, optional
408+
Make it executable
409+
"""
410+
self.name = name
411+
self.executable = executable
412+
413+
def __str__(self):
414+
return self.name
415+
416+
417+
def create_tree(path, tree, archives_leading_dir=True):
418+
"""Given a list of tuples (name, load) or a dict create such a tree
419+
420+
if load is a tuple or a dict itself -- that would create either a subtree
421+
or an archive with that content and place it into the tree if name ends
422+
with .tar.gz
423+
"""
424+
lgr.log(5, "Creating a tree under %s", path)
425+
if not op.exists(path):
426+
os.makedirs(path)
427+
428+
if isinstance(tree, dict):
429+
tree = tree.items()
430+
431+
for file_, load in tree:
432+
if isinstance(file_, File):
433+
executable = file_.executable
434+
name = file_.name
435+
else:
436+
executable = False
437+
name = file_
438+
full_name = op.join(path, name)
439+
if isinstance(load, (tuple, list, dict)):
440+
# if name.endswith('.tar.gz') or name.endswith('.tar') or name.endswith('.zip'):
441+
# create_tree_archive(path, name, load, archives_leading_dir=archives_leading_dir)
442+
# else:
443+
create_tree(full_name, load, archives_leading_dir=archives_leading_dir)
444+
else:
445+
with open(full_name, 'w') as f:
446+
if sys.version_info[0] == 2 and not isinstance(load, str):
447+
load = load.encode('utf-8')
448+
f.write(load)
449+
if executable:
450+
os.chmod(full_name, os.stat(full_name).st_mode | stat.S_IEXEC)

0 commit comments

Comments
 (0)