def get_provider(self, obj: SolrResult) -> Optional[List]: """ If a URI for the organization is not provided, we will not show any information about the organization. :param obj: A Solr record. :return: A 'provider' block. """ uri: Optional[str] = obj.get("institution_uri_s", None) if not uri: return None org_name: Optional[str] = obj.get("holding_institution_s", None) org_homepage: Optional[str] = obj.get("institution_homepage_sni", None) provider_block: List = [{ "id": uri, "type": "Agent", "label": { "en": [org_name] }, "homepage": { "id": org_homepage, "type": "Text", "label": { "en": [org_name] }, "format": "text/html" }, }] return provider_block
def get_nav_date(self, obj: SolrResult) -> Optional[str]: year: Optional[int] = obj.get('start_date_i') or obj.get('end_date_i') if year is None: return None return f"{year}-01-01T00:00:00Z"
def get_object(self, obj: SolrResult) -> Dict: req = self.context.get('request') cfg = self.context.get('config') manifest_tmpl: str = cfg['templates']['manifest_id_tmpl'] mfid = get_identifier(req, obj.get('id'), manifest_tmpl) label: str = obj.get("full_shelfmark_s") return {"id": mfid, "type": "Manifest", "name": label}
def get_sid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') range_tmpl: str = cfg['templates']['range_id_tmpl'] identifier: str = obj.get("object_id") range_id: str = obj.get("work_id") return get_identifier(req, identifier, range_tmpl, range_id=range_id)
def get_attribution(self, obj: SolrResult) -> str: rights: str = obj.get("access_rights_sni", "") terms: str = obj.get("use_terms_sni", "") # If there is both rights and terms, will separate them with semicolon. # If there is only one, will join the empty string and then strip it off for display. attrb: str = ". ".join([rights, terms]).strip(". ") # The previous line would strip the final period. Put it back in. return f"{attrb}."
def get_mid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') manifest_id: str = obj.get('id') manifest_id_tmpl: str = cfg['templates']['manifest_id_tmpl'] return get_identifier(req, manifest_id, manifest_id_tmpl)
def get_manifests(self, obj: SolrResult) -> Optional[List]: coll_id: str = obj.get('collection_id') req = self.context.get('request') cfg = self.context.get('config') manager: SolrManager = SolrManager(SolrConnection) # The 'All' collection is for every object in the collection, so we # don't need to restrict it by collection. if coll_id == 'all': fq = ["type:object"] else: fq = ["type:object", f"all_collections_id_sm:{coll_id}"] sort: str = "institution_label_s asc, shelfmark_sort_ans asc" rows: int = 100 fl = ["id", "title_s", "full_shelfmark_s", "thumbnail_id"] manager.search("*:*", fq=fq, sort=sort, fl=fl, rows=rows) if manager.hits == 0: return None return CollectionManifest(manager.results, many=True, context={ 'request': req, 'config': cfg }).data
def get_collections(self, obj: SolrResult) -> Optional[List]: coll_id: str = obj.get('collection_id') req = self.context.get('request') cfg = self.context.get('config') manager: SolrManager = SolrManager(SolrConnection) fq: List = ["type:collection", f"parent_collection_id:{coll_id}"] fl: List = [ 'id', 'name_s', 'description_s', 'collection_id', 'parent_collection_id' ] sort: str = "name_s asc" rows: int = 100 manager.search("*:*", fq=fq, fl=fl, sort=sort, rows=rows) if manager.hits == 0: return None return CollectionCollection(manager.results, many=True, context={ 'request': req, 'config': cfg }).data
def get_homepage(self, obj: SolrResult) -> List: req = self.context.get('request') cfg = self.context.get('config') tmpl: str = cfg['templates']['digital_bodleian_permalink_tmpl'] uuid: str = obj.get("id") conn: SolrManager = SolrManager(SolrConnection) fq: List = ['type:link', f"object_id:{uuid}"] conn.search("*:*", fq=fq) links: List = [{ 'id': get_identifier(req, uuid, tmpl), 'type': "Text", "label": { "en": ["View on Digital Bodleian"] }, "format": "text/html", "language": ["en"] }] if conn.hits > 0: for r in conn.results: links.append({ 'id': r.get('target_s'), 'type': "Text", "label": { "en": [r.get('label_s')] }, "format": "text/html", "language": ["en"] }) return links
def get_cid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') tmpl: str = cfg['templates']['collection_id_tmpl'] cid: str = obj.get('collection_id') return get_identifier(req, cid, tmpl)
def get_id(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') activity_create_id_tmpl: str = cfg['templates'][ 'activitystream_create_id_tmpl'] return get_identifier(req, obj.get('id'), activity_create_id_tmpl)
def get_behaviour(self, obj: SolrResult) -> List: vtype = obj.get('viewing_type_s') if vtype and vtype in ["map", "sheet", "binding", "photo"]: return ["individuals"] return ["paged"]
def get_within(self, obj: SolrResult) -> Optional[List]: """ When requested directly, give a within parameter to point back to the parent manuscript. """ direct_request: bool = self.context.get('direct_request') if not direct_request: return None req = self.context.get('request') cfg = self.context.get('config') manifest_tmpl: str = cfg['templates']['manifest_id_tmpl'] wid: str = get_identifier(req, obj.get('object_id'), manifest_tmpl) # get object shelfmark for the label fq = [f'id:"{obj.get("object_id")}"', 'type:object'] fl = ['full_shelfmark_s'] res = SolrConnection.search(q='*:*', fq=fq, fl=fl, rows=1) if res.hits == 0: return None object_record = res.docs[0] return [{ "@id": wid, "@type": "Manifest", "label": object_record.get('full_shelfmark_s') }]
def get_rendering(self, obj: SolrResult) -> Optional[Dict]: # Talbot manifests are a bit different, so exclude their metadata if 'talbot' in obj.get('all_collections_id_sm', []): # type: ignore return None req = self.context.get('request') cfg = self.context.get('config') tmpl = cfg['templates']['digital_bodleian_permalink_tmpl'] ident: str = get_identifier(req, obj.get('id'), tmpl) return { "@id": ident, "label": "View on Digital Bodleian", "format": "text/html" }
def v3_metadata_block(obj: SolrResult, field_config: Optional[Dict[str, str]] = None) -> Optional[List[Dict]]: """ A helper method for returning a IIIF Prezi3 metadata block. The main difference between this and the previous version is that all labels will come with a language value and be rendered as a list of values instead of a singleton. :param obj: A dictionary object containing metadata values :param field_config: A dictionary of solr fields to manifest fields. Defaults to the one for manifest level metadata :return: A list of Metadata labels and values to be embedded in a manifest. """ if not field_config: field_config = FIELD_CONFIG metadata: List = [] for field, label in field_config.items(): val = obj.get(field, None) if not val: continue if isinstance(val, list): fval = [{"label": {"en": [label]}, "value": {"en": val}}] else: fval = [{"label": {"en": [label]}, "value": {"en": [val]}}] metadata += fval return metadata or None
def get_items(self, obj: SolrResult) -> Optional[List]: req = self.context.get('request') cfg = self.context.get('config') obj_id: str = obj.get('id') # Check if the canvases have annotations. We don't actually # need to retrieve them, just get the number of hits. has_annotations_res = SolrConnection.search( "*:*", fq=["type:annotationpage", f"object_id:{obj_id}"], rows=0) has_annotations = has_annotations_res.hits > 0 manager: SolrManager = SolrManager(SolrConnection) fq: List = ["type:surface", f"object_id:{obj_id}"] sort: str = "sort_i asc" fl: List = [ "*,[child parentFilter=type:surface childFilter=type:image]" ] rows: int = 100 manager.search("*:*", fq=fq, fl=fl, sort=sort, rows=rows) if manager.hits == 0: return None return Canvas(manager.results, context={ "request": req, "config": cfg, "has_annotations": has_annotations }, many=True).data
def v2_metadata_block(obj: SolrResult, field_config: Optional[Dict[str, str]] = None) -> Optional[List[Dict]]: """ A helper method for constructing the manifest metadata block. Separated from the main manifest constructor to hide a lot of messy configuration and implementation. :param obj: A dictionary object containing values for metadata :param field_config: A dictionary of solr fields to manifest fields. Defaults to the one for manifest level metadata :return: A dictionary suitable for use in the IIIF metadata block. """ if not field_config: field_config = FIELD_CONFIG metadata: List = [] for field, label in field_config.items(): val = obj.get(field, None) if not val: continue if isinstance(val, list): fval = [{"label": label, "value": v} for v in val] else: fval = [{"label": label, "value": val}] metadata += fval return metadata or None
def get_images(self, obj: SolrResult) -> List[Dict]: return ImageAnnotation(obj.get("_childDocuments_"), context={ "request": self.context.get('request'), "config": self.context.get('config') }, many=True).data
def get_service(self, obj: SolrResult) -> Dict: req = self.context.get('request') cfg = self.context.get('config') image_tmpl = cfg['templates']['image_id_tmpl'] identifier = re.sub(IMAGE_ID_SUB, "", obj.get("id")) image_id = get_identifier(req, identifier, image_tmpl) return {"type": "ImageService2", "profile": "level1", "id": image_id}
def get_cid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') canvas_tmpl = cfg['templates']['canvas_id_tmpl'] # Surfaces have the suffix "_surface" in Solr. Strip it off for this identifier canvas_id = re.sub(SURFACE_ID_SUB, "", obj.get("id")) return get_identifier(req, canvas_id, canvas_tmpl)
def get_required_statement(self, obj: SolrResult) -> Dict: return { "label": { "en": ["Terms of Use"] }, "value": { "en": [obj.get("use_terms_sni", None)] } }
def get_iid(self, obj: SolrResult) -> str: cfg = self.context.get('config') req = self.context.get('request') image_tmpl = cfg['templates']['image_id_tmpl'] # Images have the suffix "_image" in Solr. identifier = re.sub(IMAGE_ID_SUB, "", obj.get("id")) return get_identifier(req, identifier, image_tmpl) # type: ignore
def get_metadata(self, obj: SolrResult) -> Optional[List[Dict]]: # Talbot manifests are a bit different, so exclude their metadata if 'talbot' in obj.get('all_collections_id_sm', []): # type: ignore return None req = self.context.get('request') cfg = self.context.get('config') tmpl: str = cfg['templates']['digital_bodleian_permalink_tmpl'] ident: str = get_identifier(req, obj.get('id'), tmpl) val: str = '<span><a href="{0}">View on Digital Bodleian</a></span>'.format( ident) metadata: List = [{"label": "Homepage", "value": val}] metadata += get_links(obj, 2) metadata += v2_metadata_block(obj) return metadata
def get_aid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') annotation_tmpl: str = cfg['templates']['annotation_id_tmpl'] # The substitution here is only needed for image annotations, but won't affect other annotations annotation_id: str = re.sub(IMAGE_ID_SUB, "", obj.get("id")) return get_identifier(req, annotation_id, annotation_tmpl)
def get_ranges(self, obj: SolrResult) -> Optional[List]: hierarchy = self.context.get('hierarchy') wk_id = obj.get("work_id") # If the work ID is not in the hierarchy, it contains # a list of canvases; return None. if wk_id not in hierarchy: return None return hierarchy[wk_id]
def get_aid(self, obj: SolrResult) -> str: req = self.context.get('request') cfg = self.context.get('config') annopage_tmpl: str = cfg['templates']['annopage_id_tmpl'] # Surfaces have the suffix "_surface" in Solr. Strip it off for this identifier # this isn't necessary for annotationpage ids, but also won't affect them annopage_id: str = re.sub(SURFACE_ID_SUB, "", obj.get("id")) return get_identifier(req, annopage_id, annopage_tmpl)
def get_width(self, obj: SolrResult) -> int: """ Width and Height are not stored on the canvas, but on the child documents. Assume that the first child document, if there is one, contains the width/height for the canvas. """ if "_childDocuments_" not in obj: return 0 return obj.get('_childDocuments_')[0]['width_i']
def get_height(self, obj: SolrResult) -> int: """ See the comment for width above. :param obj: A Solr result :return: An integer representing the height of the canvas. """ if "_childDocuments_" not in obj: return 0 return obj.get("_childDocuments_")[0]['height_i']
def get_canvases(self, obj: SolrResult) -> Optional[List]: hierarchy = self.context.get('hierarchy') wk_id = obj.get("work_id") # If the work id is in the hierarchy, this contains # a list of ranges; return None. if wk_id in hierarchy: return None req = self.context.get('request') cfg = self.context.get('config') surfaces: List = obj.get('surfaces_sm') canvas_tmpl: str = cfg['templates']['canvas_id_tmpl'] ret: List = [] for s in surfaces: ret.append( get_identifier(req, re.sub(SURFACE_ID_SUB, "", s), canvas_tmpl)) return ret
def get_viewing_hint(self, obj: SolrResult) -> str: """ The viewing types are controlled in the silo indexer; returns 'paged' by default :param obj: :return: """ vtype: str = obj.get('viewing_type_s') if vtype and vtype in ["map", "sheet", "binding", "photo"]: return "individuals" return "paged"