Show people with the birth/death on item page
This commit is contained in:
parent
96a03a0abe
commit
077cdcfeb2
19
app.py
19
app.py
|
@ -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
59
depicts/human.py
Normal 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
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 = [];
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue