diff --git a/app.py b/app.py index cb15b28..299beec 100755 --- a/app.py +++ b/app.py @@ -3,7 +3,7 @@ from flask import Flask, render_template, url_for, redirect, request, g, jsonify, session from depicts import (utils, wdqs, commons, mediawiki, painting, saam, database, dia, rijksmuseum, npg, museodelprado, barnesfoundation, - wd_catalog, relaxed_ssl) + wd_catalog, relaxed_ssl, human) from depicts.pager import Pagination, init_pager from depicts.model import (DepictsItem, DepictsItemAltLabel, Edit, PaintingItem, Language) @@ -203,7 +203,7 @@ def save(item_id): painting_item = PaintingItem.query.get(item_id) if painting_item is None: painting_entity = mediawiki.get_entity_with_cache(f'Q{item_id}') - label = get_entity_label(painting_entity) + label = mediawiki.get_entity_label(painting_entity) painting_item = PaintingItem(item_id=item_id, label=label, entity=painting_entity) database.session.add(painting_item) database.session.commit() @@ -546,6 +546,8 @@ def item_page(item_id): label = None other = get_other(item.entity) + people = human.from_name(label) if label else None + if 'P276' in entity['claims']: location = first_datavalue(entity, 'P276')['id'] institution = other[location] @@ -632,18 +634,11 @@ def item_page(item_id): show_translation_links=show_translation_links, existing_depicts=existing_depicts, image=image, + people=people, other=other, # hits=hits, title=item.display_title) -def get_entity_label(entity): - if 'en' in entity['labels']: - return entity['labels']['en']['value'] - - label_values = {l['value'] for l in entity['labels'].values()} - if len(label_values) == 1: - return list(label_values)[0] - def get_languages(codes): return Language.query.filter(Language.wikimedia_language_code.in_(codes)) @@ -687,7 +682,7 @@ def get_labels(keys, name=None): json.dump({'keys': keys, 'labels': labels}, open(filename, 'w'), indent=2) - return {entity['id']: get_entity_label(entity) for entity in labels} + return {entity['id']: mediawiki.get_entity_label(entity) for entity in labels} def get_other(entity): other_items = set() @@ -744,7 +739,7 @@ def next_page(item_id): image_filename = first_datavalue(entity, 'P18') image = image_with_cache(qid, image_filename, width) - label = get_entity_label(entity) + label = mediawiki.get_entity_label(entity) other = get_other(entity) other_list = [] diff --git a/depicts/human.py b/depicts/human.py new file mode 100644 index 0000000..9409fca --- /dev/null +++ b/depicts/human.py @@ -0,0 +1,59 @@ +from .model import HumanItem +from . import mediawiki +import re + +re_four_digits = re.compile(r'\b\d{4}\b') + +re_iso_date = re.compile(r'\b\d{4}-\d{2}-\d{2}\b') +re_four_and_two = re.compile(r'\b(\d{2})(\d{2})[-–](\d{2})\b') +re_catalog_number = re.compile(r'\b\d{4}[^\d]+\d+[^\d]+\d{4}\b') + +def query(yob, yod): + if yod < yob: + return [] + return HumanItem.query.filter_by(yob=yob, yod=yod).all() + +def get_items_from_name(name): + found = [] + + m = re_four_and_two.search(name) + years = tuple(int(y) for y in re_four_digits.findall(name)) + + print(name) + + yob1, yod1 = None, None + if m: + century = m.group(1) + yob1 = int(century + m.group(2)) + yod1 = int(century + m.group(3)) + + found += query(yob1, yod1) + + if len(years) == 2 and years != (yob1, yod1): + print(years) + found += query(*years) + + return found + +def from_name(name): + candidates = get_items_from_name(name) + lookup = {item.qid: item for item in candidates} + qids = list(lookup.keys()) + + found = [] + for entity in mediawiki.get_entities_with_cache(qids, props='labels|descriptions'): + qid = entity['id'] + item = lookup[qid] + i = { + 'qid': entity['id'], + 'year_of_birth': item.year_of_birth, + 'year_of_death': item.year_of_death, + } + label = mediawiki.get_entity_label(entity) + if label: + i['label'] = label + if 'en' in entity['descriptions']: + i['description'] = entity['descriptions']['en']['value'] + found.append(i) + found.sort(key=lambda i: i['label']) + return found diff --git a/depicts/mediawiki.py b/depicts/mediawiki.py index a3ae224..2bd96f7 100644 --- a/depicts/mediawiki.py +++ b/depicts/mediawiki.py @@ -63,6 +63,16 @@ def get_entity_with_cache(qid, refresh=False): return entity +def get_entities_with_cache(ids, **params): + filename = f'cache/entities_{"_".join(ids)}.json' + if os.path.exists(filename): + entity = json.load(open(filename)) + else: + entity = get_entities(ids, **params) + json.dump(entity, open(filename, 'w'), indent=2) + + return entity + def mediawiki_query(titles, params, site): if not titles: return [] @@ -132,3 +142,11 @@ def get_categories(titles, site): continue title_and_cats.append((i['title'], cats)) return title_and_cats + +def get_entity_label(entity): + if 'en' in entity['labels']: + return entity['labels']['en']['value'] + + label_values = {l['value'] for l in entity['labels'].values()} + if len(label_values) == 1: + return list(label_values)[0] diff --git a/depicts/model.py b/depicts/model.py index a86cce7..6d7a51b 100644 --- a/depicts/model.py +++ b/depicts/model.py @@ -43,6 +43,17 @@ class PaintingItem(Base): entity = Column(postgresql.JSON) qid = column_property('Q' + cast(item_id, String)) +class HumanItem(Base): + __tablename__ = 'human' + item_id = Column(Integer, primary_key=True, autoincrement=False) + year_of_birth = Column(Integer, nullable=False) + year_of_death = Column(Integer, nullable=False) + age_at_death = column_property(year_of_death - year_of_birth) + qid = column_property('Q' + cast(item_id, String)) + + yob = synonym('year_of_birth') + yod = synonym('year_of_death') + class Language(Base): __tablename__ = 'language' item_id = Column(Integer, primary_key=True, autoincrement=False) diff --git a/static/js/item.js b/static/js/item.js index 497eed5..b0ce06e 100644 --- a/static/js/item.js +++ b/static/js/item.js @@ -8,12 +8,18 @@ var app = new Vue({ searchTerms: '', hits: [], new_depicts: [], + people: people, existing_depicts: existing_depicts, }, methods: { remove(index) { this.$delete(this.new_depicts, index); }, + add_person(person) { + var hit = person; + hit['count'] = 0; + this.new_depicts.push(hit); + }, add_depicts(hit) { this.new_depicts.push(hit); this.hits = []; diff --git a/templates/item.html b/templates/item.html index 1633169..dfaad7d 100644 --- a/templates/item.html +++ b/templates/item.html @@ -121,6 +121,16 @@ span.description { color: rgb(96, 96, 96); }

what can you see in this painting?

+
+
These people were born and died in the same years as appears in the title of the painting.
+
+ {{ person.label || '[name missing]' }}, + {{ person.year_of_birth }}-{{ person.year_of_death}} ({{ person.qid }}) + {{ person.description }} + [wikidata] +
+
+
{{ new_depicts.length }} new items to add to painting depicts statement
@@ -178,6 +188,7 @@ span.description { color: rgb(96, 96, 96); }