Example #1
0
    def handle_places(self, data):
        base_uri = self.helper.make_proj_uri('PLACE', '')
        for loc in data.get('locations', []):
            l = loc.get('location')
            if l:
                current = parse_location_name(l,
                                              uri_base=self.helper.proj_prefix)
                place_data = self.helper.make_place(current, base_uri=base_uri)
                data['places'].append(place_data)
                note = loc.get('location_note')
                if note:
                    note = vocab.Note(ident='', content=note)
                    data['referred_to_by'].append(note)
                date = loc.get('location_date')
                if date:
                    note = vocab.BibliographyStatement(
                        ident='', content=f'Residence in {l} ({date})')
                    data['referred_to_by'].append(note)

            address = loc.get('address')
            if address:
                contact = model.Identifier(ident='', content=address)
                contact_data = add_crom_data(data={}, what=contact)
                data['contact_point'].append(contact_data)
                note = loc.get('address_note')
                if note:
                    note = vocab.Note(ident='', content=note)
                    data['referred_to_by'].append(note)
                date = loc.get('address_date')
                if date:
                    note = vocab.BibliographyStatement(
                        ident='', content=f'Address at {l} ({date})')
                    data['referred_to_by'].append(note)
Example #2
0
    def populate_destruction_events(self,
                                    data: dict,
                                    note,
                                    *,
                                    type_map,
                                    location=None):
        destruction_types_map = type_map
        hmo = get_crom_object(data)
        title = data.get('title')
        short_title = truncate_with_ellipsis(title, 100) or title

        r = re.compile(
            r'[Dd]estroyed(?: (?:by|during) (\w+))?(?: in (\d{4})[.]?)?')
        m = r.search(note)
        if m:
            method = m.group(1)
            year = m.group(2)
            # The destruction URI is just the object URI with a suffix. When URIs are
            # reconciled during prev/post sale rewriting, this will allow us to also reconcile
            # the URIs for the destructions (of which there should only be one per object)
            dest_uri = hmo.id + '-Destruction'

            d = model.Destruction(ident=dest_uri,
                                  label=f'Destruction of “{short_title}”')
            d.referred_to_by = vocab.Note(ident='', content=note)
            if year is not None:
                begin, end = date_cleaner(year)
                ts = timespan_from_outer_bounds(begin, end)
                ts.identified_by = model.Name(ident='', content=year)
                d.timespan = ts

            if method:
                with suppress(KeyError, AttributeError):
                    type_name = destruction_types_map[method.lower()]
                    otype = vocab.instances[type_name]
                    event = model.Event(
                        label=
                        f'{method.capitalize()} event causing the destruction of “{short_title}”'
                    )
                    event.classified_as = otype
                    d.caused_by = event
                    data['_events'].append(add_crom_data(data={}, what=event))

            if location:
                current = parse_location_name(
                    location, uri_base=self.helper.uid_tag_prefix)
                # The place URI used for destruction events is based on the object URI with
                # a suffix. When URIs are reconciled during prev/post sale rewriting, this
                # will allow us to also reconcile the URIs for the places of destruction
                # (of which there should only be one hierarchy per object)
                base_uri = hmo.id + '-Destruction-Place,'
                place_data = self.helper.make_place(current, base_uri=base_uri)
                place = get_crom_object(place_data)
                if place:
                    data['_locations'].append(place_data)
                    d.took_place_at = place

            hmo.destroyed_by = d
Example #3
0
	def handle_places(self, data):
		locations = {l.strip() for l in data.get('location', '').split(';')} - {''}
		base_uri = self.helper.make_proj_uri('PLACE', '')
		for l in locations:
			current = parse_location_name(l, uri_base=self.helper.proj_prefix)
			place_data = self.helper.make_place(current, base_uri=base_uri)
			data['places'].append(place_data)

		addresses = {l.strip() for l in data.get('address', '').split(';')} - {''}
		for address in addresses:
			contact = model.Identifier(ident='', content=address)
			contact_data = add_crom_data(data={}, what=contact)
			data['contact_point'].append(contact_data)
Example #4
0
    def populate_destruction_events(self,
                                    data: dict,
                                    note,
                                    *,
                                    type_map,
                                    location=None):
        destruction_types_map = type_map
        hmo = get_crom_object(data)
        title = data.get('title')
        short_title = truncate_with_ellipsis(title, 100) or title

        r = re.compile(
            r'[Dd]estroyed(?: (?:by|during) (\w+))?(?: in (\d{4})[.]?)?')
        m = r.search(note)
        if m:
            method = m.group(1)
            year = m.group(2)
            dest_id = hmo.id + '-Destr'
            d = model.Destruction(ident=dest_id,
                                  label=f'Destruction of “{short_title}”')
            d.referred_to_by = vocab.Note(ident='', content=note)
            if year is not None:
                begin, end = date_cleaner(year)
                ts = timespan_from_outer_bounds(begin, end)
                ts.identified_by = model.Name(ident='', content=year)
                d.timespan = ts

            if method:
                with suppress(KeyError, AttributeError):
                    type_name = destruction_types_map[method.lower()]
                    otype = vocab.instances[type_name]
                    event = model.Event(
                        label=
                        f'{method.capitalize()} event causing the destruction of “{short_title}”'
                    )
                    event.classified_as = otype
                    d.caused_by = event
                    data['_events'].append(add_crom_data(data={}, what=event))

            if location:
                current = parse_location_name(
                    location, uri_base=self.helper.uid_tag_prefix)
                base_uri = hmo.id + '-Place,'
                place_data = self.helper.make_place(current, base_uri=base_uri)
                place = get_crom_object(place_data)
                if place:
                    data['_locations'].append(place_data)
                    d.took_place_at = place

            hmo.destroyed_by = d
Example #5
0
    def model_sojourn(self, data, loc):
        base_uri = self.helper.make_proj_uri('PLACE', '')
        cb = data.get('corporate_body', False)
        sojourn_type = vocab.Establishment if cb else vocab.Residing
        sdata = {
            'type': sojourn_type,
            'referred_to_by': [],
        }

        verbatim_date = loc.get('address_date')
        if verbatim_date:
            date_range = date_cleaner(verbatim_date)
            if date_range:
                begin, end = date_range
                ts = timespan_from_outer_bounds(*date_range)
                ts.identified_by = model.Name(ident='', content=verbatim_date)
                sdata['timespan'] = add_crom_data(
                    {
                        'address_date': verbatim_date,
                        'begin': begin,
                        'end': end
                    }, ts)

        current = None
        l = loc.get('location')
        if l:
            current = parse_location_name(l, uri_base=self.helper.proj_prefix)
        address = loc.get('address')
        if address:
            current = {
                'name': address,
                'part_of': current,
                'type': 'address',
            }

        for k in ('address_note', 'location_note'):
            note = loc.get(k)
            if note:
                sdata['referred_to_by'].append(
                    vocab.Note(ident='', content=note))

        if current:
            place_data = self.helper.make_place(current, base_uri=base_uri)
            data['_places'].append(place_data)
            sdata['place'] = place_data
        return sdata
Example #6
0
    def _populate_object_present_location(self, data: dict, now_key,
                                          destruction_types_map):
        hmo = get_crom_object(data)
        location = data.get('present_location')
        if location:
            loc = location.get('geog')
            note = location.get('note')
            if loc:
                if 'destroyed ' in loc.lower():
                    self.populate_destruction_events(
                        data, loc, type_map=destruction_types_map)
                elif isinstance(note, str) and 'destroyed ' in note.lower():
                    # the object was destroyed, so any "present location" data is actually
                    # an indication of the location of destruction.
                    self.populate_destruction_events(
                        data,
                        note,
                        type_map=destruction_types_map,
                        location=loc)
                else:
                    # TODO: if `parse_location_name` fails, still preserve the location string somehow
                    current = parse_location_name(
                        loc, uri_base=self.helper.uid_tag_prefix)
                    inst = location.get('inst')
                    if inst:
                        owner_data = {
                            'label': f'{inst} ({loc})',
                            'identifiers':
                            [model.Name(ident='', content=inst)]
                        }
                        ulan = None
                        with suppress(ValueError, TypeError):
                            ulan = int(location.get('insi'))
                        if ulan:
                            owner_data['ulan'] = ulan
                            owner_data['uri'] = self.helper.make_proj_uri(
                                'ORG', 'ULAN', ulan)
                        else:
                            owner_data['uri'] = self.helper.make_proj_uri(
                                'ORG', 'NAME', inst, 'PLACE', loc)
                    else:
                        owner_data = {
                            'label':
                            '(Anonymous organization)',
                            'uri':
                            self.helper.make_proj_uri('ORG', 'CURR-OWN',
                                                      *now_key),
                        }

                    if note:
                        owner_data['note'] = note

                    base_uri = hmo.id + '-Place,'
                    place_data = self.helper.make_place(current,
                                                        base_uri=base_uri)
                    place = get_crom_object(place_data)

                    make_la_org = pipeline.linkedart.MakeLinkedArtOrganization(
                    )
                    owner_data = make_la_org(owner_data)
                    owner = get_crom_object(owner_data)

                    acc = location.get('acc')
                    if acc:
                        acc_number = vocab.AccessionNumber(ident='',
                                                           content=acc)
                        hmo.identified_by = acc_number
                        assignment = model.AttributeAssignment(ident='')
                        assignment.carried_out_by = owner
                        acc_number.assigned_by = assignment

                    owner.residence = place
                    data['_locations'].append(place_data)
                    data['_final_org'] = owner_data
            else:
                pass  # there is no present location place string
Example #7
0
    def handle_prev_post_owner(self,
                               data,
                               hmo,
                               tx_data,
                               sale_type,
                               lot_object_key,
                               owner_record,
                               record_id,
                               rev,
                               ts=None,
                               make_label=None):
        current_tx = get_crom_object(tx_data)
        sales_record = get_crom_object(data['_record'])
        if rev:
            rel = f'leading to the previous ownership of'
            source_label = 'Source of information on history of the object prior to the current sale.'
        else:
            rel = f'leading to the subsequent ownership of'
            source_label = 'Source of information on history of the object after the current sale.'
        owner_record.update({
            'pi_record_no':
            data['pi_record_no'],
            'ulan':
            owner_record.get('ulan', owner_record.get('own_ulan')),
        })
        self.add_person(owner_record,
                        record=sales_record,
                        relative_id=record_id,
                        role='artist')
        owner = get_crom_object(owner_record)

        # TODO: handle other fields of owner_record: own_auth_d, own_auth_q, own_ques, own_so

        if owner_record.get('own_auth_l'):
            loc = owner_record['own_auth_l']
            current = parse_location_name(loc,
                                          uri_base=self.helper.uid_tag_prefix)
            place_data = self.helper.make_place(current)
            place = get_crom_object(place_data)
            owner.residence = place
            data['_owner_locations'].append(place_data)

        if owner_record.get('own_auth_p'):
            content = owner_record['own_auth_p']
            owner.referred_to_by = vocab.Note(ident='', content=content)

        data.setdefault('_other_owners', [])
        data['_other_owners'].append(owner_record)

        # The Provenance Entry URI must not share a prefix with the object URI, otherwise
        # we run the rist of provenance entries being accidentally merged during URI
        # reconciliation as part of the prev/post sale rewriting.
        tx_uri = self.helper.prepend_uri_key(hmo.id, f'PROV-{record_id}')
        tx_label_args = tuple([self.helper, sale_type, 'Sold', rel] +
                              list(lot_object_key))
        tx, _ = self.related_procurement(hmo,
                                         tx_label_args,
                                         current_tx,
                                         ts,
                                         buyer=owner,
                                         previous=rev,
                                         ident=tx_uri,
                                         make_label=make_label)
        if owner_record.get('own_auth_e'):
            content = owner_record['own_auth_e']
            tx.referred_to_by = vocab.Note(ident='', content=content)

        own_info_source = owner_record.get('own_so')
        if own_info_source:
            note = vocab.SourceStatement(ident='',
                                         content=own_info_source,
                                         label=source_label)
            tx.referred_to_by = note

        ptx_data = tx_data.copy()
        data['_prov_entries'].append(add_crom_data(data=ptx_data, what=tx))
Example #8
0
    def _populate_object_present_location(self, data: dict, now_key,
                                          destruction_types_map):
        hmo = get_crom_object(data)
        location = data.get('present_location')
        if location:
            loc = location.get('geog')
            note = location.get('note')

            # in these two if blocks, the object was destroyed, so any "present location"
            # data is actually an indication of the location of destruction.
            if isinstance(loc, str) and 'destroyed ' in loc.lower():
                self.populate_destruction_events(
                    data, loc, type_map=destruction_types_map)
                loc = None
            elif isinstance(note, str) and 'destroyed ' in note.lower():
                self.populate_destruction_events(
                    data, note, type_map=destruction_types_map, location=loc)
                note = None

            if loc:
                # TODO: if `parse_location_name` fails, still preserve the location string somehow
                current = parse_location_name(
                    loc, uri_base=self.helper.uid_tag_prefix)
                inst = location.get('inst')
                if inst:
                    owner_data = {
                        'label': f'{inst} ({loc})',
                        'identifiers': [model.Name(ident='', content=inst)]
                    }
                    ulan = None
                    with suppress(ValueError, TypeError):
                        ulan = int(location.get('insi'))
                    if ulan:
                        owner_data['ulan'] = ulan
                        owner_data['uri'] = self.helper.make_proj_uri(
                            'ORG', 'ULAN', ulan)
                    else:
                        owner_data['uri'] = self.helper.make_proj_uri(
                            'ORG', 'NAME', inst, 'PLACE', loc)
                else:
                    owner_data = {
                        'label':
                        '(Anonymous organization)',
                        'uri':
                        self.helper.make_proj_uri('ORG', 'CURR-OWN', *now_key),
                    }

                if note:
                    owner_data['note'] = note

                # It's conceivable that there could be more than one "present location"
                # for an object that is reconciled based on prev/post sale rewriting.
                # Therefore, the place URI must not share a prefix with the object URI,
                # otherwise all such places are liable to be merged during URI
                # reconciliation as part of the prev/post sale rewriting.
                base_uri = self.helper.prepend_uri_key(hmo.id, 'PLACE')
                place_data = self.helper.make_place(current, base_uri=base_uri)
                place = get_crom_object(place_data)

                make_la_org = pipeline.linkedart.MakeLinkedArtOrganization()
                owner_data = make_la_org(owner_data)
                owner = get_crom_object(owner_data)

                acc = location.get('acc')
                if acc:
                    acc_number = vocab.AccessionNumber(ident='', content=acc)
                    hmo.identified_by = acc_number
                    assignment = model.AttributeAssignment(ident='')
                    assignment.carried_out_by = owner
                    acc_number.assigned_by = assignment

                owner.residence = place
                data['_locations'].append(place_data)
                data['_final_org'] = owner_data
            else:
                pass  # there is no present location place string
Example #9
0
    def handle_prev_post_owner(self,
                               data,
                               hmo,
                               tx_data,
                               sale_type,
                               lot_object_key,
                               owner_record,
                               record_id,
                               rev,
                               ts=None,
                               make_label=None):
        current_tx = get_crom_object(tx_data)
        sales_record = get_crom_object(data['_record'])
        if rev:
            rel = f'leading to the previous ownership of'
            source_label = 'Source of information on history of the object prior to the current sale.'
        else:
            rel = f'leading to the subsequent ownership of'
            source_label = 'Source of information on history of the object after the current sale.'
        owner_record.update({
            'pi_record_no':
            data['pi_record_no'],
            'ulan':
            owner_record.get('ulan', owner_record.get('own_ulan')),
            'auth_name':
            owner_record.get('auth_name', owner_record.get('own_auth')),
            'name':
            owner_record.get('name', owner_record.get('own')),
        })
        self.add_person(owner_record,
                        record=sales_record,
                        relative_id=record_id,
                        role='artist')
        owner = get_crom_object(owner_record)

        # TODO: handle other fields of owner_record: own_auth_d, own_auth_q, own_ques, own_so

        if owner_record.get('own_auth_l'):
            loc = owner_record['own_auth_l']
            current = parse_location_name(loc,
                                          uri_base=self.helper.uid_tag_prefix)
            place_data = self.helper.make_place(current)
            place = get_crom_object(place_data)
            owner.residence = place
            data['_owner_locations'].append(place_data)

        data.setdefault('_other_owners', [])
        data['_other_owners'].append(owner_record)

        tx_uri = hmo.id + f'-{record_id}-Prov'
        tx_label_args = tuple([self.helper, sale_type, 'Sold', rel] +
                              list(lot_object_key))
        tx, _ = self.related_procurement(hmo,
                                         tx_label_args,
                                         current_tx,
                                         ts,
                                         buyer=owner,
                                         previous=rev,
                                         ident=tx_uri,
                                         make_label=make_label)

        own_info_source = owner_record.get('own_so')
        if own_info_source:
            note = vocab.SourceStatement(ident='',
                                         content=own_info_source,
                                         label=source_label)
            tx.referred_to_by = note

        ptx_data = tx_data.copy()
        data['_prov_entries'].append(add_crom_data(data=ptx_data, what=tx))