diff --git a/loris/img_info.py b/loris/img_info.py
index c17e591..a3c14ba 100644
--- a/loris/img_info.py
+++ b/loris/img_info.py
@@ -57,7 +57,7 @@ def default(self, obj):
class ImageInfo(JP2Extractor):
'''Info about the image.
- See:
+ See: ,
Slots:
width (int)
@@ -65,9 +65,14 @@ class ImageInfo(JP2Extractor):
scaleFactors [(int)]
sizes [(str)]: the optimal sizes of the image to request
tiles: [{}]
- service (dict): services associated with the image
profile (Profile): Features supported by the server/available for
this image
+ service [{}]: optional - services associated with the image
+ attribution [{}]: optional - text that must be shown when content obtained from the Image API service is
+ displayed or used
+ license []: optional - link to an external resource that describes the license or rights statement under which
+ content obtained from the Image API service may be used
+ logo {}: optional - small image that represents an individual or organization associated with the content
src_img_fp (str): the absolute path on the file system [non IIIF]
src_format (str): the format of the source image file [non IIIF]
@@ -80,27 +85,14 @@ class ImageInfo(JP2Extractor):
'attribution', 'logo', 'license', 'auth_rules',
'src_format', 'src_img_fp', 'color_profile_bytes')
- def __init__(self, app=None, src_img_fp="", src_format="", extra={}):
+ def __init__(self, app=None, src_img_fp="", src_format="", attribution=None, logo=None, license=None, service=None, auth_rules=None):
self.src_img_fp = src_img_fp
self.src_format = src_format
- self.attribution = None
- self.logo = None
- self.license = None
- self.service = {}
- self.auth_rules = extra
-
- # The extraInfo parameter can be used to override specific attributes.
- # If there are extra attributes, drop an error.
- bad_attrs = []
- for (k, v) in extra.get('extraInfo', {}).items():
- try:
- setattr(self, k, v)
- except AttributeError:
- bad_attrs.append(k)
- if bad_attrs:
- raise ImageInfoException(
- "Invalid parameters in extraInfo: %s." % ', '.join(bad_attrs)
- )
+ self.attribution = attribution
+ self.logo = logo
+ self.license = license
+ self.service = service or {}
+ self.auth_rules = auth_rules or {}
# If constructed from JSON, the pixel info will already be processed
if app:
diff --git a/loris/resolver.py b/loris/resolver.py
index 459e694..2170f65 100644
--- a/loris/resolver.py
+++ b/loris/resolver.py
@@ -25,13 +25,13 @@
logger = getLogger(__name__)
-class _AbstractResolver(object):
+class _AbstractResolver:
def __init__(self, config):
self.config = config
if config:
self.auth_rules_ext = self.config.get('auth_rules_ext', 'rules.json')
- self.use_extra_info = self.config.get('use_extra_info', True)
+ self.use_auth_rules = self.config.get('use_auth_rules', False)
def is_resolvable(self, ident):
"""
@@ -65,12 +65,10 @@ def resolve(self, app, ident, base_uri):
cn = self.__class__.__name__
raise NotImplementedError('resolve() not implemented for %s' % (cn,))
- def get_extra_info(self, ident, source_fp):
+ def get_auth_rules(self, ident, source_fp):
"""
- Given the identifier and any resolved source file, find the associated
- extra information to include in info.json, plus any additional authorizer
- specific information. It might end up there after being copied by a
- caching implementation, or live there permanently.
+ Given the identifier and any resolved source file (ie. on the filesystem), grab the associated
+ authentication rules from the filesystem (if they exist).
Args:
ident (str):
@@ -80,11 +78,12 @@ def get_extra_info(self, ident, source_fp):
Returns:
dict: The dict of information to embed in info.json
"""
+ if not self.use_auth_rules:
+ return {}
xjsfp = source_fp.rsplit('.', 1)[0] + "." + self.auth_rules_ext
if exists(xjsfp):
- fh = open(xjsfp)
- xjs = json.load(fh)
- fh.close()
+ with open(xjsfp) as fh:
+ xjs = json.load(fh)
return xjs
else:
return {}
@@ -130,14 +129,13 @@ def is_resolvable(self, ident):
return not self.source_file_path(ident) is None
def resolve(self, app, ident, base_uri):
-
if not self.is_resolvable(ident):
self.raise_404_for_ident(ident)
source_fp = self.source_file_path(ident)
format_ = self.format_from_ident(ident)
- extra = self.get_extra_info(ident, source_fp)
- return ImageInfo(app, source_fp, format_, extra)
+ auth_rules = self.get_auth_rules(ident, source_fp)
+ return ImageInfo(app, source_fp, format_, auth_rules=auth_rules)
class ExtensionNormalizingFSResolver(SimpleFSResolver):
@@ -347,19 +345,19 @@ def copy_to_cache(self, ident):
# These files are < 2k in size, so fetch in one go.
# Assumes that the rules will be next to the image
# cache_dir is image specific, so this is easy
-
- bits = split(source_url)
- fn = bits[1].rsplit('.', 1)[0] + "." + self.auth_rules_ext
- rules_url = bits[0] + '/' + fn
- try:
- resp = requests.get(rules_url)
- if resp.status_code == 200:
- local_rules_fp = join(cache_dir, "loris_cache." + self.auth_rules_ext)
- if not exists(local_rules_fp):
- with open(local_rules_fp, 'w') as fh:
- fh.write(resp.text)
- except requests.exceptions.RequestException:
- pass
+ if self.use_auth_rules:
+ bits = split(source_url)
+ fn = bits[1].rsplit('.', 1)[0] + "." + self.auth_rules_ext
+ rules_url = bits[0] + '/' + fn
+ try:
+ resp = requests.get(rules_url)
+ if resp.status_code == 200:
+ local_rules_fp = join(cache_dir, "loris_cache." + self.auth_rules_ext)
+ if not exists(local_rules_fp):
+ with open(local_rules_fp, 'w') as fh:
+ fh.write(resp.text)
+ except requests.exceptions.RequestException:
+ pass
return local_fp
@@ -368,11 +366,8 @@ def resolve(self, app, ident, base_uri):
if not cached_file_path:
cached_file_path = self.copy_to_cache(ident)
format_ = self.get_format(cached_file_path, None)
- if self.use_extra_info:
- extra = self.get_extra_info(ident, cached_file_path)
- else:
- extra = {}
- return ImageInfo(app, cached_file_path, format_, extra)
+ auth_rules = self.get_auth_rules(ident, cached_file_path)
+ return ImageInfo(app, cached_file_path, format_, auth_rules=auth_rules)
class TemplateHTTPResolver(SimpleHTTPResolver):
@@ -553,5 +548,5 @@ def resolve(self, app, ident, base_uri):
cache_fp = self.cache_file_path(ident)
format_ = self.format_from_ident(ident)
- extra = self.get_extra_info(ident, cache_fp)
- return ImageInfo(app, cache_fp, format_, extra)
+ auth_rules = self.get_auth_rules(ident, cache_fp)
+ return ImageInfo(app, cache_fp, format_, auth_rules=auth_rules)
diff --git a/tests/img_info_t.py b/tests/img_info_t.py
index b4e1390..cc982db 100644
--- a/tests/img_info_t.py
+++ b/tests/img_info_t.py
@@ -262,45 +262,24 @@ def test_info_from_json(self):
self.assertEqual(info.tiles, self.test_jp2_color_tiles)
self.assertEqual(info.sizes, self.test_jp2_color_sizes)
- def test_extrainfo_appears_in_iiif_json(self):
+ def test_rights_licensing_properties_in_iiif_json(self):
info = ImageInfo(
src_img_fp=self.test_jpeg_fp,
src_format=self.test_jpeg_fmt,
- extra={'extraInfo': {
- 'license': 'CC-BY',
- 'logo': 'logo.png',
- 'service': {'@id': 'my_service'},
- 'attribution': 'Author unknown',
- }}
+ license='CC-BY',
+ logo='logo.png',
+ attribution='Author unknown',
)
info.from_image_file()
iiif_json = json.loads(info.to_iiif_json(base_uri='http://localhost/1234'))
assert iiif_json['license'] == 'CC-BY'
assert iiif_json['logo'] == 'logo.png'
- assert iiif_json['service'] == {'@id': 'my_service'}
assert iiif_json['attribution'] == 'Author unknown'
class TestImageInfo:
- def test_extrainfo_can_override_attributes(self):
- info = ImageInfo(extra={'extraInfo': {
- 'license': 'CC-BY',
- 'logo': 'logo.png',
- 'service': {'@id': 'my_service'},
- 'attribution': 'Author unknown',
- }})
- assert info.license == 'CC-BY'
- assert info.logo == 'logo.png'
- assert info.service == {'@id': 'my_service'}
- assert info.attribution == 'Author unknown'
-
- def test_invalid_extra_info_is_imageinfoexception(self):
- with pytest.raises(ImageInfoException) as exc:
- ImageInfo(extra={'extraInfo': {'foo': 'bar', 'baz': 'bat'}})
- assert 'Invalid parameters in extraInfo' in str(exc.value)
-
@pytest.mark.parametrize('src_format', ['', None, 'imgX'])
def test_invalid_src_format_is_error(self, src_format):
info = ImageInfo(src_format=src_format)
diff --git a/tests/resolver_t.py b/tests/resolver_t.py
index fdf46d3..b0345fb 100644
--- a/tests/resolver_t.py
+++ b/tests/resolver_t.py
@@ -107,10 +107,11 @@ def test_get_extra_info(self):
with open(os.path.join(tmp, rules_filename), 'wb') as f:
f.write(json.dumps({'rule': 1}).encode('utf8'))
config = {
- 'src_img_roots' : [tmp]
+ 'src_img_roots' : [tmp],
+ 'use_auth_rules': True
}
resolver = SimpleFSResolver(config=config)
- assert resolver.get_extra_info(ident, source_fp) == {'rule': 1}
+ assert resolver.get_auth_rules(ident, source_fp) == {'rule': 1}
class Test_SourceImageCachingResolver(loris_t.LorisTest):
diff --git a/tests/simple_http_resolver_ut.py b/tests/simple_http_resolver_ut.py
index 6b24617..86ac883 100644
--- a/tests/simple_http_resolver_ut.py
+++ b/tests/simple_http_resolver_ut.py
@@ -174,7 +174,7 @@ def test_config_assigned_to_resolver(self):
'uri_resolvable': True,
'user': 'TestUser',
'pw': 'TestPW',
- 'use_extra_info': False,
+ 'use_auth_rules': True,
}
resolver = SimpleHTTPResolver(config)
@@ -186,7 +186,7 @@ def test_config_assigned_to_resolver(self):
self.assertEqual(resolver.uri_resolvable, True)
self.assertEqual(resolver.user, 'TestUser')
self.assertEqual(resolver.pw, 'TestPW')
- self.assertEqual(resolver.use_extra_info, False)
+ self.assertEqual(resolver.use_auth_rules, True)
def test_barebones_config(self):
config = {
@@ -203,4 +203,4 @@ def test_barebones_config(self):
self.assertEqual(resolver.uri_resolvable, True)
self.assertEqual(resolver.user, None)
self.assertEqual(resolver.pw, None)
- self.assertEqual(resolver.use_extra_info, True)
+ self.assertEqual(resolver.use_auth_rules, False)