Skip to content

Commit

Permalink
Merge pull request #23 from Princeton-CDH/presentation-updates
Browse files Browse the repository at this point in the history
updates for djiffy compatibility
  • Loading branch information
rlskoeser authored Aug 12, 2024
2 parents ae3d87a + 02c9ebc commit 224f8d4
Showing 1 changed file with 55 additions and 46 deletions.
101 changes: 55 additions & 46 deletions piffle/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,69 @@ class IIIFException(Exception):
"""Custom exception for IIIF errors"""


def get_iiif_url(url):
"""Wrapper around :meth:`requests.get` to support conditionally
adding an auth tokens or other parameters."""
request_options = {}
# TODO: need some way of configuring hooks for e.g. setting auth tokens
return requests.get(url, **request_options)
class AtDict(addict.Dict):
"""Base attrdict class with handling for fields like @type, @id, etc"""

at_fields = ["type", "id", "context"]

def _key(self, key):
# convert key to @key if in the list of fields that requires it
if key in self.at_fields:
key = "@%s" % key
return key

def __missing__(self, key):
raise KeyError(self._key(key))

def __getattr__(self, key):
try:
# addict getattr just calls getitem
return super().__getattr__(self._key(key))
except KeyError:
# python hasattr checks for attribute error
# translate key error to attribute error,
# since in an attr dict it's kind of both
raise AttributeError

def __getitem__(self, key):
"""
Access a value associated with a key.
"""
val = super().__getitem__(self._key(key))

if key == "seeAlso" and isinstance(val, list) and isinstance(val[0], dict):
return [AtDict(entry) for entry in val]
return val

def __setitem__(self, key, value):
"""
Add a key-value pair to the instance.
"""
return super().__setitem__(self._key(key), value)

def __delitem__(self, key):
"""
Delete a key-value pair
"""
super().__delitem__(self._key(key))


class IIIFPresentation(addict.Dict):
class IIIFPresentation(AtDict):
""":class:`addict.Dict` subclass for read access to IIIF Presentation
content"""

# TODO: document sample use, e.g. @ fields

at_fields = ["type", "id", "context"]

@classmethod
def get_iiif_url(cls, url):
"""Wrapper around :meth:`requests.get` to support conditionally
adding an auth tokens or other parameters."""
request_options = {}
# TODO: need some way of configuring hooks for e.g. setting auth tokens
return requests.get(url, **request_options)

@classmethod
def from_file(cls, path):
"""Initialize :class:`IIIFPresentation` from a file."""
Expand All @@ -41,7 +88,7 @@ def from_url(cls, uri):
:raises: :class:`IIIFException` if URL is not retrieved successfully,
if the response is not JSON content, or if the JSON cannot be parsed.
"""
response = get_iiif_url(uri)
response = cls.get_iiif_url(uri)
if response.status_code == requests.codes.ok:
try:
return cls(response.json())
Expand Down Expand Up @@ -91,44 +138,6 @@ def short_id(cls, uri):
# split on slashes and return the last portion
return uri.split("/")[-1]

def __missing__(self, key):
raise KeyError(self._key(key))

def _key(self, key):
# convert key to @key if in the list of fields that requires it
if key in self.at_fields:
key = "@%s" % key
return key

def __getattr__(self, key):
try:
# addict getattr just calls getitem
return super().__getattr__(self._key(key))
except KeyError:
# python hasattr checks for attribute error
# translate key error to attribute error,
# since in an attr dict it's kind of both
raise AttributeError

def __getitem__(self, key):
"""
Access a value associated with a key.
"""
val = super().__getitem__(self._key(key))
return val

def __setitem__(self, key, value):
"""
Add a key-value pair to the instance.
"""
return super().__setitem__(self._key(key), value)

def __delitem__(self, key):
"""
Delete a key-value pair
"""
super().__delitem__(self._key(key))

@property
def first_label(self):
# label can be a string or list of strings
Expand Down

0 comments on commit 224f8d4

Please sign in to comment.