示例#1
0
	def test_procurement_boundary(self):
		vocab.add_linked_art_boundary_check()
		a = model.Activity()
		p = vocab.ProvenanceEntry()
		a.caused = p
		js = factory.toJSON(a)
		self.assertTrue(not 'classified_as' in js['caused'][0])		
示例#2
0
    def related_procurement(self,
                            hmo,
                            tx_label_args,
                            current_tx=None,
                            current_ts=None,
                            buyer=None,
                            seller=None,
                            previous=False,
                            ident=None,
                            make_label=None):
        '''
		Returns a new `vocab.ProvenanceEntry` object (and related acquisition) that is temporally
		related to the supplied procurement and associated data. The new procurement is for
		the given object, and has the given buyer and seller (both optional).

		If the `previous` flag is `True`, the new procurement is occurs before `current_tx`,
		and if the timespan `current_ts` is given, has temporal data to that effect. If
		`previous` is `False`, this relationship is reversed.
		
		The `make_label` argument, if supplied, is used as a function to generate the
		label for the provenance entry. Its arguments (generated in `handle_prev_post_owner`)
		are:
		
		  * helper: the helper object for the current pipeline
		  * sale_type: the sale type passed to `handle_prev_post_owner` (e.g. "Auction")
		  * transaction: the transaction type being handled (e.g. "Sold")
		  * rel: a string describing the relationship between this provenance entry and the object (e.g. "leading to the previous ownership of")
		  * N trailing arguments used that are the contents of the `lot_object_key` tuple passed to `handle_prev_post_owner`
		'''
        def _make_label_default(helper, sale_type, transaction, rel, *args):
            strs = [str(x) for x in args]
            return ', '.join(strs)

        if make_label is None:
            make_label = _make_label_default

        tx = vocab.ProvenanceEntry(ident=ident)
        tx_label = make_label(*tx_label_args)
        tx._label = tx_label
        tx.identified_by = model.Name(ident='', content=tx_label)

        if current_tx:
            if previous:
                tx.ends_before_the_start_of = current_tx
            else:
                tx.starts_after_the_end_of = current_tx
        modifier_label = 'Previous' if previous else 'Subsequent'
        try:
            pacq = model.Acquisition(
                ident='',
                label=f'{modifier_label} Acquisition of: “{hmo._label}”')
            pxfer = model.TransferOfCustody(
                ident='',
                label=f'{modifier_label} Transfer of Custody of: “{hmo._label}”'
            )
        except AttributeError:
            pacq = model.Acquisition(ident='',
                                     label=f'{modifier_label} Acquisition')
            pxfer = model.TransferOfCustody(
                ident='', label=f'{modifier_label} Transfer of Custody')
        pacq.transferred_title_of = hmo
        pxfer.transferred_custody_of = hmo
        if buyer:
            pacq.transferred_title_to = buyer
            pxfer.transferred_custody_to = buyer
        if seller:
            pacq.transferred_title_from = seller
            pxfer.transferred_custody_from = seller

        tx.part = pacq
        tx.part = pxfer
        if current_ts:
            if previous:
                pacq.timespan = timespan_before(current_ts)
            else:
                pacq.timespan = timespan_after(current_ts)
        return tx, pacq
示例#3
0
    def __call__(self, data, non_auctions, event_properties,
                 problematic_records, transaction_types):
        '''Add modeling data for the auction of a lot of objects.'''
        self.helper.copy_source_information(data['_object'], data)

        auction_houses_data = event_properties['auction_houses']

        auction_locations = event_properties['auction_locations']
        auction_data = data['auction_of_lot']
        try:
            lot_object_key = object_key(auction_data)
        except Exception as e:
            warnings.warn(
                f'Failed to compute lot object key from data {auction_data} ({e})'
            )
            pprint.pprint({k: v
                           for k, v in data.items() if v != ''},
                          stream=sys.stderr)
            raise
        cno, lno, date = lot_object_key
        sale_type = non_auctions.get(cno, 'Auction')

        ask_price = data.get('ask_price', {}).get('ask_price')
        if ask_price:
            # if there is an asking price/currency, it's a direct sale, not an auction;
            # filter these out from subsequent modeling of auction lots.
            warnings.warn(
                f'Skipping {cno} {lno} because it asserts an asking price')
            return

        if sale_type != 'Auction':
            # the records in this sales catalog do not represent auction sales, so the
            # price data should not be asserted as a sale price, but instead as an
            # asking price.
            with suppress(KeyError):
                prices = data['price']
                del data['price']
                if prices:
                    price_data = prices[0]
                    price = get_crom_object(price_data)
                    if price:
                        ma = vocab.add_classification(price, vocab.AskingPrice)
                        data['ask_price'] = add_crom_data(price_data, ma)

        shared_lot_number = self.helper.shared_lot_number_from_lno(lno)
        uid, uri = self.helper.shared_lot_number_ids(cno, lno, date)
        sale_data = {'uid': uid, 'uri': uri}

        lot = self.helper.sale_for_sale_type(sale_type, lot_object_key)
        data['lot_object_id'] = f'{cno} {lno} ({date})'

        if 'link_to_pdf' in auction_data:
            url = auction_data['link_to_pdf']
            page = vocab.WebPage(ident=url, label=url)
            lot.referred_to_by = page

        for problem_key, problem in problematic_records.get('lots', []):
            # TODO: this is inefficient, but will probably be OK so long as the number
            #       of problematic records is small. We do it this way because we can't
            #       represent a tuple directly as a JSON dict key, and we don't want to
            #       have to do post-processing on the services JSON files after loading.
            if tuple(problem_key) == lot_object_key:
                note = model.LinguisticObject(ident='', content=problem)
                problem_classification = model.Type(
                    ident=self.helper.problematic_record_uri,
                    label='Problematic Record')
                problem_classification.classified_as = vocab.instances[
                    "brief text"]
                note.classified_as = problem_classification
                lot.referred_to_by = note

        cite_content = []
        if data.get('transaction_so'):
            cite_content.append(data['transaction_so'])
        if data.get('transaction_cite'):
            cite_content.append(data['transaction_cite'])
        if cite_content:
            content = ', '.join(cite_content)
            cite = vocab.BibliographyStatement(
                ident='', content=content, label='Source of transaction type')
            cite.identified_by = model.Name(
                ident='', content='Source of transaction type')
            lot.referred_to_by = cite

        transaction = data.get('transaction')
        SOLD = transaction_types['sold']
        WITHDRAWN = transaction_types['withdrawn']
        self.set_lot_objects(lot, cno, lno, sale_data['uri'], data, sale_type)
        auction, _, _ = self.helper.sale_event_for_catalog_number(
            cno, sale_type)
        if transaction not in WITHDRAWN:
            lot.part_of = auction
            event_dates = event_properties['auction_dates'].get(cno)

            auction_houses = [
                get_crom_object(self.helper.add_auction_house_data(h.copy()))
                for h in auction_houses_data.get(cno, [])
            ]

            self.set_lot_auction_houses(lot, cno, auction_houses)
            self.set_lot_location(lot, cno, auction_locations)
            self.set_lot_date(lot, auction_data, event_dates)
            self.set_lot_notes(lot, auction_data, sale_type)

            tx_uri = self.helper.transaction_uri_for_lot(auction_data, data)
            lots = self.helper.lots_in_transaction(auction_data, data)
            tx = vocab.ProvenanceEntry(ident=tx_uri)
            tx_label = prov_entry_label(self.helper, sale_type, transaction,
                                        'of', cno, lots, date)
            tx._label = tx_label
            tx.identified_by = model.Name(ident='', content=tx_label)
            tx.caused_by = lot
            tx_data = {'uri': tx_uri}

            if transaction in SOLD:
                if sale_type == 'Auction':
                    # the records in this sales catalog represent auction sales, so the
                    # price data for a sale should be asserted as a hammer price.
                    with suppress(KeyError):
                        prices = data['price']
                        if prices:
                            price_data = prices[0]
                            price = get_crom_object(price_data)
                            if price:
                                vocab.add_classification(
                                    price, vocab.HammerPrice)

                multi = self.helper.transaction_contains_multiple_lots(
                    auction_data, data)
                if multi:
                    tx_data['multi_lot_tx'] = lots

            with suppress(AttributeError):
                tx_data['_date'] = lot.timespan
            data['_prov_entry_data'] = add_crom_data(data=tx_data, what=tx)

            data['_event_causing_prov_entry'] = add_crom_data(data=sale_data,
                                                              what=lot)
        yield data