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 flask import Flask, render_template, url_for, redirect, request, g, jsonify, session
from depicts import (utils, wdqs, commons, mediawiki, painting, saam, database, from depicts import (utils, wdqs, commons, mediawiki, painting, saam, database,
dia, rijksmuseum, npg, museodelprado, barnesfoundation, dia, rijksmuseum, npg, museodelprado, barnesfoundation,
wd_catalog, relaxed_ssl) wd_catalog, relaxed_ssl, human)
from depicts.pager import Pagination, init_pager from depicts.pager import Pagination, init_pager
from depicts.model import (DepictsItem, DepictsItemAltLabel, Edit, PaintingItem, from depicts.model import (DepictsItem, DepictsItemAltLabel, Edit, PaintingItem,
Language) Language)
@ -203,7 +203,7 @@ def save(item_id):
painting_item = PaintingItem.query.get(item_id) painting_item = PaintingItem.query.get(item_id)
if painting_item is None: if painting_item is None:
painting_entity = mediawiki.get_entity_with_cache(f'Q{item_id}') 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) painting_item = PaintingItem(item_id=item_id, label=label, entity=painting_entity)
database.session.add(painting_item) database.session.add(painting_item)
database.session.commit() database.session.commit()
@ -546,6 +546,8 @@ def item_page(item_id):
label = None label = None
other = get_other(item.entity) other = get_other(item.entity)
people = human.from_name(label) if label else None
if 'P276' in entity['claims']: if 'P276' in entity['claims']:
location = first_datavalue(entity, 'P276')['id'] location = first_datavalue(entity, 'P276')['id']
institution = other[location] institution = other[location]
@ -632,18 +634,11 @@ def item_page(item_id):
show_translation_links=show_translation_links, show_translation_links=show_translation_links,
existing_depicts=existing_depicts, existing_depicts=existing_depicts,
image=image, image=image,
people=people,
other=other, other=other,
# hits=hits, # hits=hits,
title=item.display_title) 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): def get_languages(codes):
return Language.query.filter(Language.wikimedia_language_code.in_(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}, json.dump({'keys': keys, 'labels': labels},
open(filename, 'w'), indent=2) 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): def get_other(entity):
other_items = set() other_items = set()
@ -744,7 +739,7 @@ def next_page(item_id):
image_filename = first_datavalue(entity, 'P18') image_filename = first_datavalue(entity, 'P18')
image = image_with_cache(qid, image_filename, width) image = image_with_cache(qid, image_filename, width)
label = get_entity_label(entity) label = mediawiki.get_entity_label(entity)
other = get_other(entity) other = get_other(entity)
other_list = [] 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 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): def mediawiki_query(titles, params, site):
if not titles: if not titles:
return [] return []
@ -132,3 +142,11 @@ def get_categories(titles, site):
continue continue
title_and_cats.append((i['title'], cats)) title_and_cats.append((i['title'], cats))
return title_and_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) entity = Column(postgresql.JSON)
qid = column_property('Q' + cast(item_id, String)) 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): class Language(Base):
__tablename__ = 'language' __tablename__ = 'language'
item_id = Column(Integer, primary_key=True, autoincrement=False) item_id = Column(Integer, primary_key=True, autoincrement=False)

View file

@ -8,12 +8,18 @@ var app = new Vue({
searchTerms: '', searchTerms: '',
hits: [], hits: [],
new_depicts: [], new_depicts: [],
people: people,
existing_depicts: existing_depicts, existing_depicts: existing_depicts,
}, },
methods: { methods: {
remove(index) { remove(index) {
this.$delete(this.new_depicts, index); this.$delete(this.new_depicts, index);
}, },
add_person(person) {
var hit = person;
hit['count'] = 0;
this.new_depicts.push(hit);
},
add_depicts(hit) { add_depicts(hit) {
this.new_depicts.push(hit); this.new_depicts.push(hit);
this.hits = []; this.hits = [];

View file

@ -121,6 +121,16 @@ span.description { color: rgb(96, 96, 96); }
<h3>what can you see in this painting?</h3> <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 v-if="new_depicts.length">
<div>{{ new_depicts.length }} new items to add to painting depicts statement</div> <div>{{ new_depicts.length }} new items to add to painting depicts statement</div>
</div> </div>
@ -178,6 +188,7 @@ span.description { color: rgb(96, 96, 96); }
<script> <script>
var lookup_url = {{ url_for('depicts_lookup') | tojson }}; var lookup_url = {{ url_for('depicts_lookup') | tojson }};
var existing_depicts = {{ existing_depicts | tojson }}; var existing_depicts = {{ existing_depicts | tojson }};
var people = {{ people | tojson }};
</script> </script>
<script src="{{ url_for('static', filename='vue/vue.js') }}"></script> <script src="{{ url_for('static', filename='vue/vue.js') }}"></script>
<script src="{{ url_for('static', filename='js/item.js') }}"></script> <script src="{{ url_for('static', filename='js/item.js') }}"></script>