Fix Book XML handler to deal with unusual characters in Book name Gramps42 (#536)
* Fix Book XML handler to deal with unusual characters in Book name Fixes #10387 * Fix 'Generate Book' dialog for bad transient parent * Fix Book XML handler for unusual characters in report name Issue #10387
This commit is contained in:
parent
4d68f68742
commit
09bc188a1c
@ -457,79 +457,98 @@ class BookList(object):
|
|||||||
"""
|
"""
|
||||||
Saves the current BookList to the associated file.
|
Saves the current BookList to the associated file.
|
||||||
"""
|
"""
|
||||||
f = open(self.file, "w")
|
with open(self.file, "w", encoding="utf-8") as b_f:
|
||||||
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
b_f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||||
f.write('<booklist>\n')
|
b_f.write('<booklist>\n')
|
||||||
for name in sorted(self.bookmap): # enable a diff of archived copies
|
for name in sorted(self.bookmap): # enable a diff of archived copies
|
||||||
book = self.get_book(name)
|
book = self.get_book(name)
|
||||||
dbname = book.get_dbname()
|
dbname = escape(book.get_dbname())
|
||||||
f.write('<book name="%s" database="%s">\n' % (name, dbname) )
|
b_f.write(' <book name="%s" database="%s">'
|
||||||
for item in book.get_item_list():
|
'\n' % (escape(name), dbname))
|
||||||
f.write(' <item name="%s" trans_name="%s">\n' %
|
for item in book.get_item_list():
|
||||||
(item.get_name(),item.get_translated_name() ) )
|
b_f.write(' <item name="%s" '
|
||||||
options = item.option_class.handler.options_dict
|
'trans_name="%s">\n' % (
|
||||||
for option_name in sorted(options.keys()): # enable a diff
|
item.get_name(),
|
||||||
option_value = options[option_name]
|
item.get_translated_name()))
|
||||||
if isinstance(option_value, (list, tuple)):
|
options = item.option_class.handler.options_dict
|
||||||
f.write(' <option name="%s" value="" '
|
for option_name in sorted(options.keys()): # enable a diff
|
||||||
'length="%d">\n' % (
|
option_value = options[option_name]
|
||||||
escape(option_name),
|
if isinstance(option_value, (list, tuple)):
|
||||||
len(options[option_name]) ) )
|
b_f.write(' <option name="%s" value="" '
|
||||||
for list_index in range(len(option_value)):
|
'length="%d">\n' % (
|
||||||
option_type = type_name(option_value[list_index])
|
escape(option_name),
|
||||||
value = escape(str(option_value[list_index]))
|
len(options[option_name])))
|
||||||
|
for list_index in range(len(option_value)):
|
||||||
|
option_type = type_name(
|
||||||
|
option_value[list_index])
|
||||||
|
value = escape(str(option_value[list_index]))
|
||||||
|
value = value.replace('"', '"')
|
||||||
|
b_f.write(' <listitem number="%d" '
|
||||||
|
'type="%s" value="%s"/>\n' % (
|
||||||
|
list_index,
|
||||||
|
option_type,
|
||||||
|
value))
|
||||||
|
b_f.write(' </option>\n')
|
||||||
|
else:
|
||||||
|
option_type = type_name(option_value)
|
||||||
|
value = escape(str(option_value))
|
||||||
value = value.replace('"', '"')
|
value = value.replace('"', '"')
|
||||||
f.write(' <listitem number="%d" type="%s" '
|
b_f.write(' <option name="%s" type="%s" '
|
||||||
'value="%s"/>\n' % (
|
'value="%s"/>\n' % (
|
||||||
list_index,
|
escape(option_name),
|
||||||
option_type,
|
option_type,
|
||||||
value ) )
|
value))
|
||||||
f.write(' </option>\n')
|
|
||||||
else:
|
|
||||||
option_type = type_name(option_value)
|
|
||||||
value = escape(str(option_value))
|
|
||||||
value = value.replace('"', '"')
|
|
||||||
f.write(' <option name="%s" type="%s" '
|
|
||||||
'value="%s"/>\n' % (
|
|
||||||
escape(option_name),
|
|
||||||
option_type,
|
|
||||||
value) )
|
|
||||||
|
|
||||||
f.write(' <style name="%s"/>\n' % item.get_style_name() )
|
b_f.write(' <style name="%s"/>'
|
||||||
f.write(' </item>\n')
|
'\n' % item.get_style_name())
|
||||||
if book.get_paper_name():
|
b_f.write(' </item>\n')
|
||||||
f.write(' <paper name="%s"/>\n' % book.get_paper_name() )
|
if book.get_paper_name():
|
||||||
if book.get_orientation() is not None: # 0 is legal
|
b_f.write(' <paper name="%s"/>'
|
||||||
f.write(' <orientation value="%s"/>\n' %
|
'\n' % book.get_paper_name())
|
||||||
book.get_orientation() )
|
if book.get_orientation() is not None: # 0 is legal
|
||||||
if book.get_paper_metric() is not None: # 0 is legal
|
b_f.write(' <orientation value="%s"/>'
|
||||||
f.write(' <metric value="%s"/>\n' % book.get_paper_metric() )
|
'\n' % book.get_orientation())
|
||||||
if book.get_custom_paper_size():
|
if book.get_paper_metric() is not None: # 0 is legal
|
||||||
size = book.get_custom_paper_size()
|
b_p_metric = book.get_paper_metric()
|
||||||
f.write(' <size value="%f %f"/>\n' % (size[0], size[1]) )
|
if isinstance(b_p_metric, bool):
|
||||||
if book.get_margins():
|
b_p_metric = int(b_p_metric)
|
||||||
for pos in range(len(book.get_margins())):
|
b_f.write(' <metric value="%s"/>'
|
||||||
f.write(' <margin number="%s" value="%f"/>\n' %
|
'\n' % b_p_metric)
|
||||||
(pos, book.get_margin(pos)) )
|
if book.get_custom_paper_size():
|
||||||
if book.get_format_name():
|
size = book.get_custom_paper_size()
|
||||||
f.write(' <format name="%s"/>\n' % book.get_format_name() )
|
b_f.write(' <size value="%f %f"/>'
|
||||||
if book.get_output():
|
'\n' % (size[0], size[1]))
|
||||||
f.write(' <output name="%s"/>\n' % book.get_output() )
|
if book.get_margins():
|
||||||
f.write('</book>\n')
|
for pos in range(len(book.get_margins())):
|
||||||
|
b_f.write(' <margin number="%s" '
|
||||||
|
'value="%f"/>\n' % (
|
||||||
|
pos, book.get_margin(pos)))
|
||||||
|
if book.get_format_name():
|
||||||
|
b_f.write(' <format name="%s"/>'
|
||||||
|
'\n' % book.get_format_name())
|
||||||
|
if book.get_output():
|
||||||
|
b_f.write(' <output name="%s"/>'
|
||||||
|
'\n' % escape(book.get_output()))
|
||||||
|
b_f.write(' </book>\n')
|
||||||
|
|
||||||
|
b_f.write('</booklist>\n')
|
||||||
|
|
||||||
f.write('</booklist>\n')
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
"""
|
"""
|
||||||
Loads the BookList from the associated file, if it exists.
|
Loads the BookList from the associated file, if it exists.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
p = make_parser()
|
parser = make_parser()
|
||||||
p.setContentHandler(BookParser(self, self.dbase))
|
parser.setContentHandler(BookParser(self, self.dbase))
|
||||||
the_file = open(self.file)
|
# bug 10387; XML should be utf8, but was not previously saved
|
||||||
p.parse(the_file)
|
# that way. So try to read utf8, if fails, try with system
|
||||||
the_file.close()
|
# encoding. Only an issue on non-utf8 systems.
|
||||||
|
try:
|
||||||
|
with open(self.file, encoding="utf-8") as the_file:
|
||||||
|
parser.parse(the_file)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
with open(self.file) as the_file:
|
||||||
|
parser.parse(the_file)
|
||||||
except (IOError, OSError, ValueError, SAXParseException, KeyError,
|
except (IOError, OSError, ValueError, SAXParseException, KeyError,
|
||||||
AttributeError):
|
AttributeError):
|
||||||
pass
|
pass
|
||||||
|
@ -723,7 +723,7 @@ class BookSelector(ManagedWindow):
|
|||||||
"""
|
"""
|
||||||
if self.book.item_list:
|
if self.book.item_list:
|
||||||
BookDialog(self.dbstate, self.uistate,
|
BookDialog(self.dbstate, self.uistate,
|
||||||
self.book, BookOptions)
|
self.book, BookOptions, track=self.track)
|
||||||
else:
|
else:
|
||||||
WarningDialog(_('No items'), _('This book has no items.'),
|
WarningDialog(_('No items'), _('This book has no items.'),
|
||||||
parent=self.window)
|
parent=self.window)
|
||||||
@ -916,14 +916,14 @@ class BookDialog(DocReportDialog):
|
|||||||
Create a dialog selecting target, format, and paper/HTML options.
|
Create a dialog selecting target, format, and paper/HTML options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, dbstate, uistate, book, options):
|
def __init__(self, dbstate, uistate, book, options, track=[]):
|
||||||
self.format_menu = None
|
self.format_menu = None
|
||||||
self.options = options
|
self.options = options
|
||||||
self.is_from_saved_book = False
|
self.is_from_saved_book = False
|
||||||
self.page_html_added = False
|
self.page_html_added = False
|
||||||
self.book = book
|
self.book = book
|
||||||
DocReportDialog.__init__(self, dbstate, uistate, options,
|
DocReportDialog.__init__(self, dbstate, uistate, options,
|
||||||
'book', _("Book"))
|
'book', _("Book"), track=track)
|
||||||
self.options.options_dict['bookname'] = self.book.name
|
self.options.options_dict['bookname'] = self.book.name
|
||||||
self.database = dbstate.db
|
self.database = dbstate.db
|
||||||
|
|
||||||
|
@ -58,16 +58,17 @@ class DocReportDialog(ReportDialog):
|
|||||||
dialogs for docgen derived reports.
|
dialogs for docgen derived reports.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, dbstate, uistate, option_class, name, trans_name):
|
def __init__(self, dbstate, uistate, option_class, name, trans_name,
|
||||||
|
track=[]):
|
||||||
"""Initialize a dialog to request that the user select options
|
"""Initialize a dialog to request that the user select options
|
||||||
for a basic *stand-alone* report."""
|
for a basic *stand-alone* report."""
|
||||||
|
|
||||||
self.style_name = "default"
|
self.style_name = "default"
|
||||||
self.firstpage_added = False
|
self.firstpage_added = False
|
||||||
self.CSS = PLUGMAN.process_plugin_data('WEBSTUFF')
|
self.CSS = PLUGMAN.process_plugin_data('WEBSTUFF')
|
||||||
self.dbname = dbstate.db.get_dbname()
|
self.dbname = dbstate.db.get_dbname()
|
||||||
ReportDialog.__init__(self, dbstate, uistate, option_class,
|
ReportDialog.__init__(self, dbstate, uistate, option_class,
|
||||||
name, trans_name)
|
name, trans_name, track=track)
|
||||||
|
|
||||||
# Allow for post processing of the format frame, since the
|
# Allow for post processing of the format frame, since the
|
||||||
# show_all task calls events that may reset values
|
# show_all task calls events that may reset values
|
||||||
|
Loading…
Reference in New Issue
Block a user