NAVWEB and WEBCAL: some minor corrections (#980)

* NAVWEB: set unused media to False by default

Fixes #11496

* Navweb: Center correctly the map in the web page

* Webcal: Dropmenu doesn't work if only one year.

* Navweb: Add notes to updates and delete empty rows

* Navweb: some code cleanup.

* Navweb: remove unused variable

* Narweb: references enhancement on place pages.

* Navweb: convert the years in gregorian cal.

* Narweb: remove unused argument

* Narweb: really solves the pyICU problem

* WEBCAL: missing death symbol
This commit is contained in:
Serge Noiraud 2020-01-17 11:46:40 +01:00 committed by GitHub
parent a2ae7b93fc
commit 763f2738dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 233 additions and 42 deletions

View File

@ -31,7 +31,7 @@ body#FamilyMap {
margin-left: 10px;
margin-right: 10px;
border: solid 4px #000;
margin: 0px auto;
margin: 20px auto;
width: 800px;
height: 400px;
max-width: 90%;

View File

@ -2984,7 +2984,7 @@ class BasePage: # pylint: disable=C1001
gid = self.report.obj_dict[bkref_class][bkref_handle][2]
if role != "":
if self.reference_sort:
role = ""
role = self.birth_death_dates(gid)
elif role[1:2] == ':':
# cal is the original calendar
cal, role = role.split(':')
@ -3012,7 +3012,10 @@ class BasePage: # pylint: disable=C1001
# reset the date to the original calendar
cdate = date.to_calendar(Date.calendar_names[int(cal)])
ldate = self.rlocale.get_date(cdate)
role = " (%s) " % ldate
evtype = self.event_for_date(gid, cdate)
if evtype:
evtype = " " + evtype
role = " (%s) " % (ldate + evtype)
else:
role = " (%s) " % self._(role)
ordered += list_html
@ -3031,6 +3034,45 @@ class BasePage: # pylint: disable=C1001
list_html += Html("a", href=url) + name + role + gid_html
return ordered
def event_for_date(self, gid, date):
"""
return the event type
"""
pers = self.r_db.get_person_from_gramps_id(gid)
if pers:
evt_ref_list = pers.get_event_ref_list()
if evt_ref_list:
for evt_ref in evt_ref_list:
evt = self.r_db.get_event_from_handle(evt_ref.ref)
if evt:
evdate = evt.get_date_object()
# convert date to gregorian
_date = str(evdate.to_calendar("gregorian"))
if _date == str(date):
return self._(str(evt.get_type()))
return ""
def birth_death_dates(self, gid):
"""
return the birth and death date for the person
"""
pers = self.r_db.get_person_from_gramps_id(gid)
if pers:
birth = death = ""
evt_birth = get_birth_or_fallback(self.r_db, pers)
if evt_birth:
birthd = evt_birth.get_date_object()
# convert date to gregorian to avoid strange years
birth = str(birthd.to_calendar("gregorian").get_year())
evt_death = get_death_or_fallback(self.r_db, pers)
if evt_death:
deathd = evt_death.get_date_object()
# convert date to gregorian to avoid strange years
death = str(deathd.to_calendar("gregorian").get_year())
return "(%s-%s)" % (birth, death)
else:
return ""
def display_bkref_list(self, obj_class, obj_handle):
"""
Display a reference list for an object class

View File

@ -31,6 +31,7 @@ from unicodedata import normalize
from collections import defaultdict
from hashlib import md5
import re
import locale # Used only with pyICU
import logging
from xml.sax.saxutils import escape
@ -439,7 +440,10 @@ def sort_places(dbase, handle_list, rlocale=glocale):
for name in temp_list:
if isinstance(name, bytes):
name = name.decode('utf-8')
sorted_lists.append((name, pname_sub[name][0]))
slist = sorted(((sortnames[x], x) for x in pname_sub[name]),
key=lambda x: rlocale.sort_key(x[0]))
for entry in slist:
sorted_lists.append(entry)
return sorted_lists
@ -622,10 +626,29 @@ def first_letter(string, rlocale=glocale):
# no special case
return norm_unicode[0].upper()
def primary_difference(prev_key, new_key, rlocale=glocale):
try:
import PyICU # pylint : disable=wrong-import-position
PRIM_COLL = PyICU.Collator.createInstance(PyICU.Locale(COLLATE_LANG))
PRIM_COLL.setStrength(PRIM_COLL.PRIMARY)
def primary_difference(prev_key, new_key, rlocale=glocale):
"""
The PyICU collation doesn't work if you want to sort in another language
So we use this method to do the work correctly.
Try to use the PyICU collation.
If we generate a report for another language, make sure we use the good
collation sequence
"""
collation = PRIM_COLL
if rlocale.lang != locale.getlocale(locale.LC_COLLATE)[0]:
encoding = rlocale.encoding if rlocale.encoding else "UTF-8"
collate_lang = PyICU.Locale(rlocale.collation+"."+encoding)
collation = PyICU.Collator.createInstance(collate_lang)
return collation.compare(prev_key, new_key) != 0
except:
def primary_difference(prev_key, new_key, rlocale=glocale):
"""
The PyICU collation is not available.
Returns true if there is a primary difference between the two parameters
See http://www.gramps-project.org/bugs/view.php?id=2933#c9317 if

View File

@ -1948,7 +1948,7 @@ class NavWebOptions(MenuReportOptions):
self.__gallery_changed)
self.__unused = BooleanOption(
_("Include unused images and media objects"), True)
_("Include unused images and media objects"), False)
self.__unused.set_help(_('Whether to include unused or unreferenced'
' media objects'))
addopt("unused", self.__unused)

View File

@ -45,9 +45,9 @@ from gramps.plugins.lib.libhtml import Html
#------------------------------------------------
from gramps.plugins.webreport.basepage import BasePage
from gramps.gen.display.place import displayer as _pd
from gramps.plugins.webreport.common import (FULLCLEAR, _EVENTMAP)
from gramps.plugins.webreport.common import (FULLCLEAR, _EVENTMAP, html_escape)
from gramps.gen.lib import (Person, Family, Event, Place, Source, Repository,
Media)
Media, Note, Citation)
from gramps.gen.lib.date import Date
_ = glocale.translation.sgettext
@ -66,6 +66,12 @@ class UpdatesPage(BasePage):
"""
BasePage.__init__(self, report, title)
ldatec = 0
self.inc_repository = self.report.options['inc_repository']
self.inc_families = self.report.options['inc_families']
self.inc_events = self.report.options['inc_events']
self.inc_places = self.report.options['inc_places']
self.inc_sources = self.report.options['inc_sources']
self.inc_gallery = False
output_file, sio = self.report.create_file("updates")
result = self.write_header(self._('New and updated objects'))
@ -93,35 +99,35 @@ class UpdatesPage(BasePage):
if people is not None:
section += people
if self.report.options['inc_families']:
if self.inc_families:
header = self._("Families")
section += Html("h4", header)
families = self.list_people_changed(Family)
if families is not None:
section += families
if self.report.options['inc_events']:
if self.inc_events:
header = self._("Events")
section += Html("h4", header)
events = self.list_people_changed(Event)
if events is not None:
section += events
if self.report.options['inc_places']:
if self.inc_places:
header = self._("Places")
section += Html("h4", header)
places = self.list_people_changed(Place)
if places is not None:
section += places
if self.report.options['inc_sources']:
if self.inc_sources:
header = self._("Sources")
section += Html("h4", header)
sources = self.list_people_changed(Source)
if sources is not None:
section += sources
if self.report.options['inc_repository']:
if self.inc_repository:
header = self._("Repositories")
section += Html("h4", header)
repos = self.list_people_changed(Repository)
@ -130,12 +136,19 @@ class UpdatesPage(BasePage):
if (self.report.options['gallery'] and not
self.report.options['create_thumbs_only']):
self.inc_gallery = True
header = self._("Media")
section += Html("h4", header)
media = self.list_people_changed(Media)
if media is not None:
section += media
header = self._("Notes")
section += Html("h4", header)
events = self.list_notes()
if events is not None:
section += events
# create clear line for proper styling
# create footer section
footer = self.write_footer(ldatec)
@ -145,6 +158,122 @@ class UpdatesPage(BasePage):
# and close the file
self.xhtml_writer(homepage, output_file, sio, ldatec)
def list_notes(self):
"""
List all notes with last change date
"""
nb_items = 0
section = ""
def sort_on_change(handle):
""" sort records based on the last change time """
fct = self.report.database.get_note_from_handle
obj = fct(handle)
timestamp = obj.get_change_time()
return timestamp
note_list = self.report.database.get_note_handles()
obj_list = sorted(note_list, key=sort_on_change, reverse=True)
with Html("table", class_="list", id="list") as section:
for handle in obj_list:
show = False
date = obj = None
obj = self.report.database.get_note_from_handle(handle)
if obj:
text = html_escape(obj.get()[:50])
timestamp = obj.get_change_time()
if timestamp - self.maxdays > 0:
handle_list = set(
self.report.database.find_backlink_handles(
handle,
include_classes=['Person', 'Family', 'Event',
'Place', 'Media', 'Source',
'Citation', 'Repository',
]))
tims = localtime(timestamp)
odat = Date(tims.tm_year, tims.tm_mon, tims.tm_mday)
date = self.rlocale.date_displayer.display(odat)
date += strftime(' %X', tims)
if handle_list:
srbd = self.report.database
srbkref = self.report.bkref_dict
for obj_t, r_handle in handle_list:
if obj_t == 'Person':
if r_handle in srbkref[Person]:
name = self.new_person_link(r_handle)
show = True
elif obj_t == 'Family':
if r_handle in srbkref[Family]:
fam = srbd.get_family_from_handle(
r_handle)
fam = self._("Family")
name = self.family_link(r_handle, fam)
if self.inc_families:
show = True
elif obj_t == 'Place':
if r_handle in srbkref[Place]:
plc = srbd.get_place_from_handle(
r_handle)
plcn = _pd.display(self.report.database,
plc)
name = self.place_link(r_handle, plcn)
if self.inc_places:
show = True
elif obj_t == 'Event':
if r_handle in srbkref[Event]:
evt = srbd.get_event_from_handle(
r_handle)
evtn = self._(evt.get_type().xml_str())
name = self.event_link(r_handle, evtn)
if self.inc_events:
show = True
elif obj_t == 'Media':
if r_handle in srbkref[Media]:
media = srbd.get_media_from_handle(
r_handle)
evtn = media.get_description()
name = self.media_link(r_handle, evtn,
evtn,
usedescr=False)
if self.inc_gallery:
show = True
elif obj_t == 'Citation':
if r_handle in srbkref[Citation]:
cit = srbd.get_event_from_handle(
r_handle)
citsrc = cit.source_handle
evtn = self._("Citation")
name = self.source_link(citsrc, evtn)
if self.inc_sources:
show = True
elif obj_t == 'Source':
if r_handle in srbkref[Source]:
src = srbd.get_source_from_handle(
r_handle)
evtn = src.get_title()
name = self.source_link(r_handle, evtn)
if self.inc_sources:
show = True
elif obj_t == 'Repository':
if r_handle in srbkref[Repository]:
rep = srbd.get_repository_from_handle(
r_handle)
evtn = rep.get_name()
name = self.repository_link(r_handle,
evtn)
if self.inc_repository:
show = True
if show:
row = Html("tr")
section += row
row += Html("td", date, class_="date")
row += Html("td", text)
row += Html("td", name)
nb_items += 1
if nb_items > self.nbr:
break
return section
def list_people_changed(self, object_type):
"""
List all records with last change date
@ -180,8 +309,6 @@ class UpdatesPage(BasePage):
key=sort_on_change, reverse=True)
with Html("table", class_="list", id="list") as section:
for handle in obj_list:
row = Html("tr")
section += row
date = obj = None
name = ""
obj = fct(handle)
@ -236,6 +363,8 @@ class UpdatesPage(BasePage):
odat = Date(tims.tm_year, tims.tm_mon, tims.tm_mday)
date = self.rlocale.date_displayer.display(odat)
date += strftime(' %X', tims)
row = Html("tr")
section += row
row += Html("td", date, class_="date")
row += Html("td", name)
return section

View File

@ -63,6 +63,7 @@ from gramps.gen.plug.menu import (BooleanOption, NumberOption, StringOption,
from gramps.gen.utils.config import get_researcher
from gramps.gen.utils.alive import probably_alive
from gramps.gen.utils.db import get_death_or_fallback
from gramps.gen.utils.symbols import Symbols
from gramps.gen.datehandler import displayer as _dd
from gramps.gen.display.name import displayer as _nd
@ -464,19 +465,13 @@ class WebCalReport(Report):
"if (x.className === \"nav\") { x.className += \""
" responsive\"; } else { x.className = \"nav\"; }"
" }</script>")
if self.multiyear:
head += menuscript
# begin header section
if self.multiyear:
headerdiv = Html("div", id='header') + (
Html("<a href=\"javascript:void(0);\" class=\"navIcon\""
" onclick=\"navFunction()\">&#8801;</a>")) + (
Html("h1", html_escape(title),
id="SiteTitle", inline=True))
else:
headerdiv = Html("div", id='header') + (
Html("h1", html_escape(title),
Html("<button href=\"javascript:void(0);\" class=\"navIcon\""
" onclick=\"navFunction()\">&#8801;</button>")) + (
Html("h1", self.title_text,
id="SiteTitle", inline=True))
body += headerdiv
@ -2168,12 +2163,14 @@ def get_day_list(event_date, holiday_list, bday_anniv_list, rlocale=glocale):
#age_str.format(precision=1, as_age=False, dlocale=rlocale)
age_str = age_str.format(precision=1, as_age=False, dlocale=rlocale)
symbols = Symbols()
death_idx = symbols.DEATH_SYMBOL_SHADOWED_LATIN_CROSS
death_symbol = symbols.get_death_symbol_for_char(death_idx)
# a birthday
if event == 'Birthday':
if age_at_death is not None:
death_symbol = "&#10014;" # latin cross for html code
trans_date = trans_text("Died %(death_date)s.")
translated_date = rlocale.get_date(dead_event_date)
mess = trans_date % {'death_date' : translated_date}
@ -2194,7 +2191,7 @@ def get_day_list(event_date, holiday_list, bday_anniv_list, rlocale=glocale):
# a death
if event == 'Death':
txt_str = (text + ', <em>'
txt_str = (text + ', ' + death_symbol + ' <em>'
+ (_('%s since death') % str(age_str) if nyears
else _('death'))
+ '</em>')