Skip to content

Commit

Permalink
Merge branch 'release/0.8' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
rlskoeser committed Jun 15, 2022
2 parents ee38eca + 3b86c06 commit 335476b
Show file tree
Hide file tree
Showing 19 changed files with 614 additions and 15 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

0.8
---

* Manifest dynamic properties for license uris and labels are now cached
* Manifest license logic now handles CreativeCommons license URIs.
* Images for rightstatement.org and some CC licenses are now included in static content
* License image path can be generated using the `license_image` property for Manifests with supported licenses

0.7.3
-----

Expand All @@ -12,7 +20,7 @@ Changelog
0.7.2
-----

* Include manifest attribution information in `extra_data` on import
* Include manifest attribution information in ``extra_data`` on import


0.7.1
Expand Down
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ directory::
As of v0.7.3, documentation is automatically built with GitHub Actions
and published using GitHub pages.

Adding license images
^^^^^^^^^^^^^^^^^^^^^

When adding new license image SVG files to this repo, add ``id="licenseimg"`` to
the ``<svg>`` element of each. This allows djiffy users to embed the SVG inline
with a ``<use>`` tag, with its ``href`` attribute pointing to ``#licenseimg``.

If the image will need to be recolored for different backgrounds, as in the
case of the ``rightsstatement_org/`` SVG icons, you can enable this for up to
two tones in each SVG. To do this, set ``fill`` attributes on paths to
``fill="inherit"`` (controlled by the ``fill`` CSS property) or
``fill="currentColor"`` (controlled by the ``color`` CSS property).

License
-------

Expand Down
2 changes: 1 addition & 1 deletion djiffy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
default_app_config = 'djiffy.apps.DjiffyConfig'

__version_info__ = (0, 7, 3, None)
__version_info__ = (0, 8, 0, None)


# Dot-connect all but the last. Last is dash-connected if not None.
Expand Down
68 changes: 58 additions & 10 deletions djiffy/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
from collections import OrderedDict

import json
import os.path

import urllib

# cached property is only available in Python 3.8+
try:
from functools import cached_property
except ImportError:
cached_property = None

from attrdict import AttrMap
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.templatetags.static import static
from django.utils.html import format_html
from jsonfield import JSONField
from piffle import iiif
Expand All @@ -15,6 +24,9 @@
import requests
from requests.exceptions import ConnectionError

# use cached property if python3.8 or greater; fallback to regular property
c_property_if38 = cached_property or property


def get_iiif_url(url):
'''Wrapper around :meth:`requests.get` to support conditionally
Expand Down Expand Up @@ -83,29 +95,64 @@ def admin_thumbnail(self):
return self.thumbnail.admin_thumbnail()
admin_thumbnail.short_description = 'Thumbnail'

@property
@c_property_if38
def logo(self):
'''manifest logo, if there is one'''
return self.extra_data.get('logo', None)

@property
@c_property_if38
def attribution(self):
'''manifest attribution, if there is one'''
return self.extra_data.get('attribution', None)

@property
@c_property_if38
def license(self):
'''manifest license, if there is one'''
return self.extra_data.get('license', None)

@property
@c_property_if38
def license_uri(self):
'''manifest license as :class:`rdflib.URIRef`, if there is a license'''
license = self.license
if license:
# CC uri is also http rather than https
if urllib.parse.urlparse(license).hostname == 'creativecommons.org':
# remove language from url if present
url_parts = license.rstrip("/").split('/')
# url looks like https://creativecommons.org/publicdomain/mark/1.0/deed.de
# if the last part is a language code, remove it
if url_parts[-1].startswith("deed."):
url_parts = url_parts[:-1]
license = "%s/" % '/'.join(url_parts) # URI requires trailing slash
return rdflib.URIRef(license)

@c_property_if38
def rights_statement_id(self):
'''short id for rightstatement.org license'''
if self.license and 'rightsstatements.org' in self.license:
# rightstatement uri is http, not https
if self.license and urllib.parse.urlparse(self.license).hostname == 'rightsstatements.org':
return self.license.rstrip(' /').split('/')[-2]

@c_property_if38
def creativecommons_id(self):
'''short id for creative commons license'''
if self.license and urllib.parse.urlparse(self.license).hostname == 'creativecommons.org':
if "publicdomain/zero/" in self.license:
return "cc-zero"
if "publicdomain/mark/" in self.license:
return "publicdomain"

@c_property_if38
def license_image(self):
'''license image, if we can generate one'''
if self.rights_statement_id:
return static("img/rightsstatements_org/%s.svg" % self.rights_statement_id)
if self.creativecommons_id:
return static("img/creativecommons/%s.svg" % self.creativecommons_id)

_rights_graph = None

# TODO: should use django current language if possible
def license_label(self, lang='en'):
'''Get the text label for the rights license. Uses local
value from edm rights if available; otherwise uses
Expand All @@ -124,10 +171,11 @@ def license_label(self, lang='en'):
# if license is defined and a url
if self.license and urllib.parse.urlparse(self.license).scheme in ['http', 'https']:
self._rights_graph = rdflib.Graph()
url_hostname = urllib.parse.urlparse(self.license).hostname
try:
# rights statement org does content-negotiation for json-jd,
# but rdflib doesn't handle that automatically
if 'rightsstatements.org' in self.license:
if url_hostname == 'rightsstatements.org':
resp = requests.get(self.license,
headers={'Accept': 'application/json'},
allow_redirects=False)
Expand All @@ -136,9 +184,9 @@ def license_label(self, lang='en'):

# creative commons doesn't support content negotiation,
# but you can add rdf to the end of the url
elif 'creativecommons.org' in self.license:
rdf_uri = '/'.join([self.license.rstrip('/'), 'rdf'])
self._rights_graph.parse(rdf_uri)
elif url_hostname == 'creativecommons.org':
# license uri removes language if present and adds trailing slash
self._rights_graph.parse("%srdf" % self.license_uri)

except Exception:
# possible to get an exception when parsing the
Expand All @@ -151,7 +199,7 @@ def license_label(self, lang='en'):
# get the preferred label for this license in the requested language;
# returns a list of label, value; use the first value
if self._rights_graph:
license_uri = rdflib.URIRef(self.license)
license_uri = self.license_uri
preflabel = self._rights_graph.preferredLabel(license_uri,
lang=lang)
if preflabel:
Expand Down
98 changes: 98 additions & 0 deletions djiffy/static/img/creativecommons/cc-zero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 335476b

Please sign in to comment.