Show people with the birth/death on item page

This commit is contained in:
Edward Betts 2019-10-08 11:11:15 +01:00
parent 96a03a0abe
commit 077cdcfeb2
6 changed files with 112 additions and 12 deletions

19
app.py
View file

@ -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 = []

59
depicts/human.py Normal file
View file

@ -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

View file

@ -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]

View file

@ -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)

View file

@ -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 = [];

View file

@ -121,6 +121,16 @@ span.description { color: rgb(96, 96, 96); }
<h3>what can you see in this painting?</h3>
<div v-if="people.length">
<div>These people were born and died in the same years as appears in the title of the painting.</div>
<div v-for="person in people">
<a href="#" @click.prevent="add_person(person)">{{ person.label || '[name missing]' }}</a>,
{{ person.year_of_birth }}-{{ person.year_of_death}} ({{ person.qid }})
<span v-if="person.description" class="description">{{ person.description }}</span>
<a :href="'https://www.wikidata.org/wiki/' + person.qid">[wikidata]</a>
</div>
</div>
<div v-if="new_depicts.length">
<div>{{ new_depicts.length }} new items to add to painting depicts statement</div>
</div>
@ -178,6 +188,7 @@ span.description { color: rgb(96, 96, 96); }
<script>
var lookup_url = {{ url_for('depicts_lookup') | tojson }};
var existing_depicts = {{ existing_depicts | tojson }};
var people = {{ people | tojson }};
</script>
<script src="{{ url_for('static', filename='vue/vue.js') }}"></script>
<script src="{{ url_for('static', filename='js/item.js') }}"></script>