forked from openlp/openlp
Bug #882819 - recover v1.x theme file names from XML info
This commit is contained in:
parent
ebcf7a5dd2
commit
0c06569dc5
@ -41,7 +41,7 @@ class Ui_FileRenameDialog(object):
|
|||||||
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
|
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
|
||||||
self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
|
self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
|
||||||
self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
|
self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
|
||||||
QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self))
|
QtCore.QRegExp(r'[^/\\?*|<>\[\]":+%]+'), self))
|
||||||
self.fileNameEdit.setObjectName(u'fileNameEdit')
|
self.fileNameEdit.setObjectName(u'fileNameEdit')
|
||||||
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
|
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
|
||||||
self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)
|
self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)
|
||||||
|
@ -43,8 +43,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
|||||||
context_menu_action, context_menu_separator, find_and_set_in_combo_box
|
context_menu_action, context_menu_separator, find_and_set_in_combo_box
|
||||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||||
from openlp.core.ui.printserviceform import PrintServiceForm
|
from openlp.core.ui.printserviceform import PrintServiceForm
|
||||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
from openlp.core.utils import AppLocation, delete_file, split_filename
|
||||||
split_filename
|
|
||||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||||
|
|
||||||
class ServiceManagerList(QtGui.QTreeWidget):
|
class ServiceManagerList(QtGui.QTreeWidget):
|
||||||
@ -635,8 +634,11 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
try:
|
try:
|
||||||
zip = zipfile.ZipFile(fileName)
|
zip = zipfile.ZipFile(fileName)
|
||||||
for zipinfo in zip.infolist():
|
for zipinfo in zip.infolist():
|
||||||
ucsfile = file_is_unicode(zipinfo.filename)
|
try:
|
||||||
if not ucsfile:
|
ucsfile = zipinfo.filename.decode(u'utf-8')
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Filename "%s" is not valid UTF-8' %
|
||||||
|
zipinfo.filename.decode(u'utf-8', u'replace'))
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
message=translate('OpenLP.ServiceManager',
|
message=translate('OpenLP.ServiceManager',
|
||||||
'File is not a valid service.\n'
|
'File is not a valid service.\n'
|
||||||
|
@ -30,6 +30,7 @@ import zipfile
|
|||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
import locale
|
import locale
|
||||||
|
import re
|
||||||
|
|
||||||
from xml.etree.ElementTree import ElementTree, XML
|
from xml.etree.ElementTree import ElementTree, XML
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
@ -43,8 +44,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
|||||||
context_menu_action, context_menu_separator
|
context_menu_action, context_menu_separator
|
||||||
from openlp.core.theme import Theme
|
from openlp.core.theme import Theme
|
||||||
from openlp.core.ui import FileRenameForm, ThemeForm
|
from openlp.core.ui import FileRenameForm, ThemeForm
|
||||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
|
||||||
get_filesystem_encoding
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -147,6 +147,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
check_directory_exists(self.thumbPath)
|
check_directory_exists(self.thumbPath)
|
||||||
self.themeForm.path = self.path
|
self.themeForm.path = self.path
|
||||||
self.oldBackgroundImage = None
|
self.oldBackgroundImage = None
|
||||||
|
self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
|
||||||
# Last little bits of setting up
|
# Last little bits of setting up
|
||||||
self.configUpdated()
|
self.configUpdated()
|
||||||
|
|
||||||
@ -525,46 +526,74 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
filexml = None
|
filexml = None
|
||||||
try:
|
try:
|
||||||
zip = zipfile.ZipFile(filename)
|
zip = zipfile.ZipFile(filename)
|
||||||
themename = None
|
xmlfile = filter(lambda name:
|
||||||
for file in zip.namelist():
|
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
|
||||||
ucsfile = file_is_unicode(file)
|
if len(xmlfile) != 1:
|
||||||
if not ucsfile:
|
log.exception(u'Theme contains "%s" XML files' % len(xmlfile))
|
||||||
critical_error_message_box(
|
raise Exception(u'validation')
|
||||||
message=translate('OpenLP.ThemeManager',
|
xml_tree = ElementTree(element=XML(zip.read(xmlfile[0]))).getroot()
|
||||||
'File is not a valid theme.\n'
|
v1_background = xml_tree.find(u'BackgroundType')
|
||||||
'The content encoding is not UTF-8.'))
|
if v1_background is not None:
|
||||||
continue
|
# openlp.org v1.x theme file
|
||||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
themename = xml_tree.find(u'Name').text.strip()
|
||||||
theme_dir = None
|
themename = self.bad_v1_name_chars.sub(u'', themename)
|
||||||
if osfile.endswith(os.path.sep):
|
themedir = os.path.join(dir, themename)
|
||||||
theme_dir = os.path.join(dir, osfile)
|
check_directory_exists(themedir)
|
||||||
check_directory_exists(theme_dir)
|
filexml = unicode(zip.read(xmlfile[0]), u'utf-8')
|
||||||
|
filexml = self._migrateVersion122(filexml)
|
||||||
|
outfile = open(os.path.join(themedir, themename + u'.xml'),
|
||||||
|
u'w')
|
||||||
|
outfile.write(filexml.encode(u'utf-8'))
|
||||||
|
outfile.close()
|
||||||
|
if v1_background.text.strip() == u'2':
|
||||||
|
imagename = xml_tree.find(u'BackgroundParameter1').text\
|
||||||
|
.strip()
|
||||||
|
# image file is in subfolder and has same extension
|
||||||
|
imagefile = filter(lambda name: name.find(r'/') and
|
||||||
|
os.path.splitext(name)[1].lower() == os.path.splitext(
|
||||||
|
imagename)[1].lower(), zip.namelist())
|
||||||
|
if len(imagefile) >= 1:
|
||||||
|
outfile = open(os.path.join(themedir, imagename), u'wb')
|
||||||
|
outfile.write(zip.read(imagefile[0]))
|
||||||
|
outfile.close()
|
||||||
else:
|
else:
|
||||||
fullpath = os.path.join(dir, osfile)
|
log.exception(u'Theme file does not contain image file '
|
||||||
names = osfile.split(os.path.sep)
|
u'"%s"' % imagename.decode(u'utf-8', u'replace'))
|
||||||
if len(names) > 1:
|
raise Exception(u'validation')
|
||||||
# not preview file
|
else:
|
||||||
if themename is None:
|
themename = xml_tree.find(u'name').text.strip()
|
||||||
themename = names[0]
|
for name in zip.namelist():
|
||||||
if theme_dir is None:
|
try:
|
||||||
theme_dir = os.path.join(dir, names[0])
|
uname = unicode(name, u'utf-8')
|
||||||
check_directory_exists(theme_dir)
|
except UnicodeDecodeError:
|
||||||
if os.path.splitext(ucsfile)[1].lower() in [u'.xml']:
|
log.exception(u'Theme file contains non utf-8 filename'
|
||||||
xml_data = zip.read(file)
|
u' "%s"' % name.decode(u'utf-8', u'replace'))
|
||||||
xml_data = file_is_unicode(xml_data)
|
raise Exception(u'validation')
|
||||||
if not xml_data:
|
uname = unicode(QtCore.QDir.toNativeSeparators(uname))
|
||||||
break
|
splitname = uname.split(os.path.sep)
|
||||||
filexml = self._checkVersionAndConvert(xml_data)
|
if splitname[-1] == u'' or len(splitname) == 1:
|
||||||
outfile = open(fullpath, u'w')
|
# is directory or preview file
|
||||||
|
continue
|
||||||
|
fullname = os.path.join(dir, uname)
|
||||||
|
check_directory_exists(os.path.dirname(fullname))
|
||||||
|
if os.path.splitext(uname)[1].lower() == u'.xml':
|
||||||
|
filexml = unicode(zip.read(name), u'utf-8')
|
||||||
|
outfile = open(fullname, u'w')
|
||||||
outfile.write(filexml.encode(u'utf-8'))
|
outfile.write(filexml.encode(u'utf-8'))
|
||||||
else:
|
else:
|
||||||
outfile = open(fullpath, u'wb')
|
outfile = open(fullname, u'wb')
|
||||||
outfile.write(zip.read(file))
|
outfile.write(zip.read(name))
|
||||||
except (IOError, NameError, zipfile.BadZipfile):
|
outfile.close()
|
||||||
critical_error_message_box(
|
except (IOError, zipfile.BadZipfile):
|
||||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
|
||||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
|
||||||
log.exception(u'Importing theme from zip failed %s' % filename)
|
log.exception(u'Importing theme from zip failed %s' % filename)
|
||||||
|
raise Exception(u'validation')
|
||||||
|
except Exception as info:
|
||||||
|
if unicode(info) == u'validation':
|
||||||
|
critical_error_message_box(translate('OpenLP.ThemeManager',
|
||||||
|
'Validation Error'), translate('OpenLP.ThemeManager',
|
||||||
|
'File is not a valid theme.'))
|
||||||
|
else:
|
||||||
|
raise
|
||||||
finally:
|
finally:
|
||||||
# Close the files, to be able to continue creating the theme.
|
# Close the files, to be able to continue creating the theme.
|
||||||
if zip:
|
if zip:
|
||||||
@ -695,22 +724,6 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
image = os.path.join(self.path, theme + u'.png')
|
image = os.path.join(self.path, theme + u'.png')
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def _checkVersionAndConvert(self, xml_data):
|
|
||||||
"""
|
|
||||||
Check if a theme is from OpenLP version 1
|
|
||||||
|
|
||||||
``xml_data``
|
|
||||||
Theme XML to check the version of
|
|
||||||
"""
|
|
||||||
log.debug(u'checkVersion1 ')
|
|
||||||
theme = xml_data.encode(u'ascii', u'xmlcharrefreplace')
|
|
||||||
tree = ElementTree(element=XML(theme)).getroot()
|
|
||||||
# look for old version 1 tags
|
|
||||||
if tree.find(u'BackgroundType') is None:
|
|
||||||
return xml_data
|
|
||||||
else:
|
|
||||||
return self._migrateVersion122(xml_data)
|
|
||||||
|
|
||||||
def _createThemeFromXml(self, themeXml, path):
|
def _createThemeFromXml(self, themeXml, path):
|
||||||
"""
|
"""
|
||||||
Return a theme object using information parsed from XML
|
Return a theme object using information parsed from XML
|
||||||
@ -775,7 +788,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
theme = Theme(xml_data)
|
theme = Theme(xml_data)
|
||||||
newtheme = ThemeXML()
|
newtheme = ThemeXML()
|
||||||
newtheme.theme_name = theme.Name
|
newtheme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
|
||||||
if theme.BackgroundType == 0:
|
if theme.BackgroundType == 0:
|
||||||
newtheme.background_type = \
|
newtheme.background_type = \
|
||||||
BackgroundType.to_string(BackgroundType.Solid)
|
BackgroundType.to_string(BackgroundType.Solid)
|
||||||
|
@ -455,26 +455,6 @@ def get_web_page(url, header=None, update_openlp=False):
|
|||||||
log.debug(page)
|
log.debug(page)
|
||||||
return page
|
return page
|
||||||
|
|
||||||
def file_is_unicode(filename):
|
|
||||||
"""
|
|
||||||
Checks if a file is valid unicode and returns the unicode decoded file or
|
|
||||||
None.
|
|
||||||
|
|
||||||
``filename``
|
|
||||||
File to check is valid unicode.
|
|
||||||
"""
|
|
||||||
if not filename:
|
|
||||||
return None
|
|
||||||
ucsfile = None
|
|
||||||
try:
|
|
||||||
ucsfile = filename.decode(u'utf-8')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
log.exception(u'Filename "%s" is not valid UTF-8' %
|
|
||||||
filename.decode(u'utf-8', u'replace'))
|
|
||||||
if not ucsfile:
|
|
||||||
return None
|
|
||||||
return ucsfile
|
|
||||||
|
|
||||||
def get_uno_command():
|
def get_uno_command():
|
||||||
"""
|
"""
|
||||||
Returns the UNO command to launch an openoffice.org instance.
|
Returns the UNO command to launch an openoffice.org instance.
|
||||||
@ -507,5 +487,5 @@ from actions import ActionList
|
|||||||
|
|
||||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||||
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||||
u'get_uno_instance', u'delete_file', u'clean_filename']
|
u'delete_file', u'clean_filename']
|
||||||
|
Loading…
Reference in New Issue
Block a user