forked from openlp/openlp
Fix code so values saved
This commit is contained in:
commit
9648e0c81b
|
@ -384,6 +384,7 @@ def create_separated_list(stringlist):
|
||||||
|
|
||||||
|
|
||||||
from eventreceiver import Receiver
|
from eventreceiver import Receiver
|
||||||
|
from filedialog import FileDialog
|
||||||
from listwidgetwithdnd import ListWidgetWithDnD
|
from listwidgetwithdnd import ListWidgetWithDnD
|
||||||
from formattingtags import FormattingTags
|
from formattingtags import FormattingTags
|
||||||
from spelltextedit import SpellTextEdit
|
from spelltextedit import SpellTextEdit
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2013 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||||
|
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||||
|
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||||
|
# Frode Woldsund, Martin Zibricky #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
"""
|
||||||
|
Provide a work around for a bug in QFileDialog
|
||||||
|
<https://bugs.launchpad.net/openlp/+bug/1209515>
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib.ui import UiStrings
|
||||||
|
|
||||||
|
class FileDialog(QtGui.QFileDialog):
|
||||||
|
"""
|
||||||
|
Subclass QFileDialog to work round a bug
|
||||||
|
"""
|
||||||
|
@staticmethod
|
||||||
|
def getOpenFileNames(parent, title, path, filters):
|
||||||
|
"""
|
||||||
|
Reimplement getOpenFileNames to fix the way it returns some file
|
||||||
|
names that url encoded when selecting multiple files/
|
||||||
|
"""
|
||||||
|
files = QtGui.QFileDialog.getOpenFileNames(parent, title, path, filters)
|
||||||
|
file_list = QtCore.QStringList()
|
||||||
|
for file in files:
|
||||||
|
file = unicode(file)
|
||||||
|
if not os.path.exists(file):
|
||||||
|
file = urllib.unquote(file)
|
||||||
|
if not os.path.exists(file):
|
||||||
|
QtGui.QMessageBox.information(parent,
|
||||||
|
UiStrings().FileNotFound,
|
||||||
|
UiStrings().FileNotFoundMessage % file)
|
||||||
|
continue
|
||||||
|
file_list.append(QtCore.QString(file))
|
||||||
|
return file_list
|
|
@ -35,7 +35,7 @@ import re
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
|
from openlp.core.lib import FileDialog, SettingsManager, OpenLPToolbar, ServiceItem, \
|
||||||
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
|
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
|
||||||
from openlp.core.lib.searchedit import SearchEdit
|
from openlp.core.lib.searchedit import SearchEdit
|
||||||
from openlp.core.lib.ui import UiStrings, create_widget_action, \
|
from openlp.core.lib.ui import UiStrings, create_widget_action, \
|
||||||
|
@ -337,7 +337,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
"""
|
"""
|
||||||
Add a file to the list widget to make it available for showing
|
Add a file to the list widget to make it available for showing
|
||||||
"""
|
"""
|
||||||
files = QtGui.QFileDialog.getOpenFileNames(
|
files = FileDialog.getOpenFileNames(
|
||||||
self, self.onNewPrompt,
|
self, self.onNewPrompt,
|
||||||
SettingsManager.get_last_dir(self.settingsSection),
|
SettingsManager.get_last_dir(self.settingsSection),
|
||||||
self.onNewFileMasks)
|
self.onNewFileMasks)
|
||||||
|
|
|
@ -77,6 +77,10 @@ class UiStrings(object):
|
||||||
self.Error = translate('OpenLP.Ui', 'Error')
|
self.Error = translate('OpenLP.Ui', 'Error')
|
||||||
self.Export = translate('OpenLP.Ui', 'Export')
|
self.Export = translate('OpenLP.Ui', 'Export')
|
||||||
self.File = translate('OpenLP.Ui', 'File')
|
self.File = translate('OpenLP.Ui', 'File')
|
||||||
|
self.FileNotFound = unicode(translate('OpenLP.Ui',
|
||||||
|
'File Not Found'))
|
||||||
|
self.FileNotFoundMessage = unicode(translate('OpenLP.Ui',
|
||||||
|
'File %s not found.\nPlease try selecting it individually.'))
|
||||||
self.FontSizePtUnit = translate('OpenLP.Ui', 'pt',
|
self.FontSizePtUnit = translate('OpenLP.Ui', 'pt',
|
||||||
'Abbreviated font pointsize unit')
|
'Abbreviated font pointsize unit')
|
||||||
self.Help = translate('OpenLP.Ui', 'Help')
|
self.Help = translate('OpenLP.Ui', 'Help')
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The First Time Wizard
|
||||||
|
"""
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -48,6 +50,7 @@ from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ThemeScreenshotThread(QtCore.QThread):
|
class ThemeScreenshotThread(QtCore.QThread):
|
||||||
"""
|
"""
|
||||||
This thread downloads the theme screenshots.
|
This thread downloads the theme screenshots.
|
||||||
|
@ -56,6 +59,9 @@ class ThemeScreenshotThread(QtCore.QThread):
|
||||||
QtCore.QThread.__init__(self, parent)
|
QtCore.QThread.__init__(self, parent)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""
|
||||||
|
Run the thread.
|
||||||
|
"""
|
||||||
themes = self.parent().config.get(u'themes', u'files')
|
themes = self.parent().config.get(u'themes', u'files')
|
||||||
themes = themes.split(u',')
|
themes = themes.split(u',')
|
||||||
themes_dir = self.parent().config.get(u'themes', u'directory')
|
themes_dir = self.parent().config.get(u'themes', u'directory')
|
||||||
|
@ -180,15 +186,28 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||||
Determine the next page in the Wizard to go to.
|
Determine the next page in the Wizard to go to.
|
||||||
"""
|
"""
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
# If we are currently on the plugins page
|
||||||
if self.currentId() == FirstTimePage.Plugins:
|
if self.currentId() == FirstTimePage.Plugins:
|
||||||
|
# But we don't have Internet access
|
||||||
if not self.webAccess:
|
if not self.webAccess:
|
||||||
return FirstTimePage.NoInternet
|
return FirstTimePage.NoInternet
|
||||||
else:
|
# The songs plugin is enabled
|
||||||
|
elif self.songsCheckBox.isChecked():
|
||||||
return FirstTimePage.Songs
|
return FirstTimePage.Songs
|
||||||
|
# The Bibles plugin is enabled
|
||||||
|
elif self.bibleCheckBox.isChecked():
|
||||||
|
return FirstTimePage.Bibles
|
||||||
|
else:
|
||||||
|
return FirstTimePage.Themes
|
||||||
elif self.currentId() == FirstTimePage.Progress:
|
elif self.currentId() == FirstTimePage.Progress:
|
||||||
return -1
|
return -1
|
||||||
elif self.currentId() == FirstTimePage.NoInternet:
|
elif self.currentId() == FirstTimePage.NoInternet:
|
||||||
return FirstTimePage.Progress
|
return FirstTimePage.Progress
|
||||||
|
elif self.currentId() == FirstTimePage.Songs:
|
||||||
|
if self.bibleCheckBox.isChecked():
|
||||||
|
return FirstTimePage.Bibles
|
||||||
|
else:
|
||||||
|
return FirstTimePage.Themes
|
||||||
elif self.currentId() == FirstTimePage.Themes:
|
elif self.currentId() == FirstTimePage.Themes:
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
@ -395,7 +414,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||||
self.max_progress += size
|
self.max_progress += size
|
||||||
if self.max_progress:
|
if self.max_progress:
|
||||||
# Add on 2 for plugins status setting plus a "finished" point.
|
# Add on 2 for plugins status setting plus a "finished" point.
|
||||||
self.max_progress = self.max_progress + 2
|
self.max_progress += 2
|
||||||
self.progressBar.setValue(0)
|
self.progressBar.setValue(0)
|
||||||
self.progressBar.setMinimum(0)
|
self.progressBar.setMinimum(0)
|
||||||
self.progressBar.setMaximum(self.max_progress)
|
self.progressBar.setMaximum(self.max_progress)
|
||||||
|
|
|
@ -34,7 +34,11 @@ import sys
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib.ui import add_welcome_page
|
from openlp.core.lib.ui import add_welcome_page
|
||||||
|
|
||||||
|
|
||||||
class FirstTimePage(object):
|
class FirstTimePage(object):
|
||||||
|
"""
|
||||||
|
An enumeration object to make it easy for a developer to determine which page is which by index
|
||||||
|
"""
|
||||||
Welcome = 0
|
Welcome = 0
|
||||||
Plugins = 1
|
Plugins = 1
|
||||||
NoInternet = 2
|
NoInternet = 2
|
||||||
|
|
|
@ -109,6 +109,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||||
has been changed.
|
has been changed.
|
||||||
"""
|
"""
|
||||||
self.savePushButton.setEnabled(True)
|
self.savePushButton.setEnabled(True)
|
||||||
|
self.savePushButton.setDefault(True)
|
||||||
|
|
||||||
def onNewClicked(self):
|
def onNewClicked(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -89,7 +89,8 @@ VIDEO_EXT = [
|
||||||
u'*.xa',
|
u'*.xa',
|
||||||
u'*.iso',
|
u'*.iso',
|
||||||
u'*.vob',
|
u'*.vob',
|
||||||
u'*.webm'
|
u'*.webm',
|
||||||
|
u'*.divx'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -229,32 +229,32 @@ FLASH_HTML = u"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VIDEO_EXT = [
|
VIDEO_EXT = [
|
||||||
u'*.3gp'
|
u'*.3gp',
|
||||||
, u'*.3gpp'
|
u'*.3gpp',
|
||||||
, u'*.3g2'
|
u'*.3g2',
|
||||||
, u'*.3gpp2'
|
u'*.3gpp2',
|
||||||
, u'*.aac'
|
u'*.aac',
|
||||||
, u'*.flv'
|
u'*.flv',
|
||||||
, u'*.f4a'
|
u'*.f4a',
|
||||||
, u'*.f4b'
|
u'*.f4b',
|
||||||
, u'*.f4p'
|
u'*.f4p',
|
||||||
, u'*.f4v'
|
u'*.f4v',
|
||||||
, u'*.mov'
|
u'*.mov',
|
||||||
, u'*.m4a'
|
u'*.m4a',
|
||||||
, u'*.m4b'
|
u'*.m4b',
|
||||||
, u'*.m4p'
|
u'*.m4p',
|
||||||
, u'*.m4v'
|
u'*.m4v',
|
||||||
, u'*.mkv'
|
u'*.mkv',
|
||||||
, u'*.mp4'
|
u'*.mp4',
|
||||||
, u'*.ogv'
|
u'*.ogv',
|
||||||
, u'*.webm'
|
u'*.webm',
|
||||||
, u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi'
|
u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi',
|
||||||
, u'*.swf'
|
u'*.swf'
|
||||||
]
|
]
|
||||||
|
|
||||||
AUDIO_EXT = [
|
AUDIO_EXT = [
|
||||||
u'*.mp3'
|
u'*.mp3',
|
||||||
, u'*.ogg'
|
u'*.ogg'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onGradientEndButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onGradientEndButtonClicked)
|
||||||
QtCore.QObject.connect(self.imageBrowseButton,
|
QtCore.QObject.connect(self.imageBrowseButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onImageBrowseButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onImageBrowseButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.imageFileEdit,
|
||||||
|
QtCore.SIGNAL(u'editingFinished()'), self.onImageFileEditEditingFinished)
|
||||||
QtCore.QObject.connect(self.mainColorButton,
|
QtCore.QObject.connect(self.mainColorButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked)
|
||||||
QtCore.QObject.connect(self.outlineColorButton,
|
QtCore.QObject.connect(self.outlineColorButton,
|
||||||
|
@ -233,7 +235,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
background_image = BackgroundType.to_string(BackgroundType.Image)
|
background_image = BackgroundType.to_string(BackgroundType.Image)
|
||||||
if self.page(self.currentId()) == self.backgroundPage and \
|
if self.page(self.currentId()) == self.backgroundPage and \
|
||||||
self.theme.background_type == background_image and \
|
self.theme.background_type == background_image and \
|
||||||
is_not_image_file(self.imageFileEdit.text()):
|
is_not_image_file(self.theme.background_filename):
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('OpenLP.ThemeWizard', 'Background Image Empty'),
|
translate('OpenLP.ThemeWizard', 'Background Image Empty'),
|
||||||
translate('OpenLP.ThemeWizard', 'You have not selected a '
|
translate('OpenLP.ThemeWizard', 'You have not selected a '
|
||||||
|
@ -545,6 +547,12 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
self.theme.background_filename = unicode(filename)
|
self.theme.background_filename = unicode(filename)
|
||||||
self.setBackgroundPageValues()
|
self.setBackgroundPageValues()
|
||||||
|
|
||||||
|
def onImageFileEditEditingFinished(self):
|
||||||
|
"""
|
||||||
|
Background image path edited
|
||||||
|
"""
|
||||||
|
self.theme.background_filename = unicode(self.imageFileEdit.text())
|
||||||
|
|
||||||
def onMainColorButtonClicked(self):
|
def onMainColorButtonClicked(self):
|
||||||
self.theme.font_main_color = \
|
self.theme.font_main_color = \
|
||||||
self._colorButton(self.theme.font_main_color)
|
self._colorButton(self.theme.font_main_color)
|
||||||
|
|
|
@ -36,7 +36,7 @@ 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
|
||||||
|
|
||||||
from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \
|
from openlp.core.lib import FileDialog, OpenLPToolbar, get_text_file_string, build_icon, \
|
||||||
Receiver, SettingsManager, translate, check_item_selected, \
|
Receiver, SettingsManager, translate, check_item_selected, \
|
||||||
check_directory_exists, create_thumb, validate_thumb, ImageSource
|
check_directory_exists, create_thumb, validate_thumb, ImageSource
|
||||||
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
|
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
|
||||||
|
@ -420,7 +420,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
attempting to extract OpenLP themes from those files. This process
|
attempting to extract OpenLP themes from those files. This process
|
||||||
will load both OpenLP version 1 and version 2 themes.
|
will load both OpenLP version 1 and version 2 themes.
|
||||||
"""
|
"""
|
||||||
files = QtGui.QFileDialog.getOpenFileNames(self,
|
files = FileDialog.getOpenFileNames(self,
|
||||||
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
||||||
SettingsManager.get_last_dir(self.settingsSection),
|
SettingsManager.get_last_dir(self.settingsSection),
|
||||||
unicode(translate('OpenLP.ThemeManager',
|
unicode(translate('OpenLP.ThemeManager',
|
||||||
|
|
|
@ -371,15 +371,14 @@ def is_not_image_file(file_name):
|
||||||
``file_name``
|
``file_name``
|
||||||
File name to be checked.
|
File name to be checked.
|
||||||
"""
|
"""
|
||||||
if file_name.isEmpty():
|
if not file_name:
|
||||||
return True
|
|
||||||
else:
|
|
||||||
formats = [unicode(fmt).lower()
|
|
||||||
for fmt in QtGui.QImageReader.supportedImageFormats()]
|
|
||||||
file_part, file_extension = os.path.splitext(unicode(file_name))
|
|
||||||
if file_extension[1:].lower() in formats and os.path.exists(file_name):
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
|
formats = [unicode(fmt).lower()
|
||||||
|
for fmt in QtGui.QImageReader.supportedImageFormats()]
|
||||||
|
file_part, file_extension = os.path.splitext(unicode(file_name))
|
||||||
|
if file_extension[1:].lower() in formats and os.path.exists(file_name):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def join_url(base, *args):
|
def join_url(base, *args):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -862,6 +862,26 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||||
return book[0]
|
return book[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_language_by_id(language_id):
|
||||||
|
"""
|
||||||
|
Return a dict containing the language id, name and code by id.
|
||||||
|
|
||||||
|
``id``
|
||||||
|
The id of the language in the database.
|
||||||
|
"""
|
||||||
|
log.debug(u'BiblesResourcesDB.get_language_by_id(%d)', language_id)
|
||||||
|
language = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
|
||||||
|
u'language WHERE id = ?', (language_id,))
|
||||||
|
if language:
|
||||||
|
return {
|
||||||
|
u'id': language[0][0],
|
||||||
|
u'name': unicode(language[0][1]),
|
||||||
|
u'code': unicode(language[0][2])
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_language(name):
|
def get_language(name):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -245,6 +245,8 @@ class BGExtract(object):
|
||||||
return None
|
return None
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
div = soup.find('div', 'result-text-style-normal')
|
div = soup.find('div', 'result-text-style-normal')
|
||||||
|
if not div:
|
||||||
|
return None
|
||||||
self._clean_soup(div)
|
self._clean_soup(div)
|
||||||
span_list = div.findAll('span', 'text')
|
span_list = div.findAll('span', 'text')
|
||||||
log.debug('Span list: %s', span_list)
|
log.debug('Span list: %s', span_list)
|
||||||
|
@ -375,6 +377,7 @@ class BSExtract(object):
|
||||||
content = content.findAll(u'li')
|
content = content.findAll(u'li')
|
||||||
return [
|
return [
|
||||||
book.contents[0].contents[0] for book in content
|
book.contents[0].contents[0] for book in content
|
||||||
|
if len(book.contents[0].contents)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import codecs
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation, LanguageManager
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -148,10 +148,22 @@ class OSISBible(BibleDB):
|
||||||
self.filename)
|
self.filename)
|
||||||
return False
|
return False
|
||||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||||
if not db_book or db_book.name != book_details[u'name']:
|
bible_language = BiblesResourcesDB.get_language_by_id(language_id)
|
||||||
log.debug(u'New book: "%s"' % book_details[u'name'])
|
if bible_language is not None:
|
||||||
|
# The language of this bible was found, so we can
|
||||||
|
# translate the name of this book
|
||||||
|
custom_translator = LanguageManager.get_translator(
|
||||||
|
bible_language['code'])[0]
|
||||||
|
book_name_localized = unicode(custom_translator.translate(
|
||||||
|
'BiblesPlugin', book_details[u'name']))
|
||||||
|
else:
|
||||||
|
# The language of this bible was not found, so we just
|
||||||
|
# use the English name for this book
|
||||||
|
book_name_localized = book_details[u'name']
|
||||||
|
if not db_book or db_book.name != book_name_localized:
|
||||||
|
log.debug(u'New book: "%s"' % book_name_localized)
|
||||||
db_book = self.create_book(
|
db_book = self.create_book(
|
||||||
book_details[u'name'],
|
book_name_localized,
|
||||||
book_ref_id,
|
book_ref_id,
|
||||||
book_details[u'testament_id'])
|
book_details[u'testament_id'])
|
||||||
if last_chapter == 0:
|
if last_chapter == 0:
|
||||||
|
@ -162,7 +174,7 @@ class OSISBible(BibleDB):
|
||||||
self.wizard.incrementProgressBar(unicode(translate(
|
self.wizard.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.OsisImport', 'Importing %s %s...',
|
'BiblesPlugin.OsisImport', 'Importing %s %s...',
|
||||||
'Importing <book name> <chapter>...')) %
|
'Importing <book name> <chapter>...')) %
|
||||||
(book_details[u'name'], chapter))
|
(book_name_localized, chapter))
|
||||||
last_chapter = chapter
|
last_chapter = chapter
|
||||||
# All of this rigmarol below is because the mod2osis
|
# All of this rigmarol below is because the mod2osis
|
||||||
# tool from the Sword library embeds XML in the OSIS
|
# tool from the Sword library embeds XML in the OSIS
|
||||||
|
|
|
@ -44,6 +44,7 @@ import time
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
from win32com.client import Dispatch
|
from win32com.client import Dispatch
|
||||||
import pywintypes
|
import pywintypes
|
||||||
|
|
||||||
# Declare an empty exception to match the exception imported from UNO
|
# Declare an empty exception to match the exception imported from UNO
|
||||||
class ErrorCodeIOException(Exception):
|
class ErrorCodeIOException(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -63,6 +64,7 @@ from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ImpressController(PresentationController):
|
class ImpressController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with Impress presentations.
|
Class to control interactions with Impress presentations.
|
||||||
|
@ -79,7 +81,7 @@ class ImpressController(PresentationController):
|
||||||
PresentationController.__init__(self, plugin, u'Impress',
|
PresentationController.__init__(self, plugin, u'Impress',
|
||||||
ImpressDocument)
|
ImpressDocument)
|
||||||
self.supports = [u'odp']
|
self.supports = [u'odp']
|
||||||
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx', u'pptm']
|
||||||
self.process = None
|
self.process = None
|
||||||
self.desktop = None
|
self.desktop = None
|
||||||
self.manager = None
|
self.manager = None
|
||||||
|
|
|
@ -45,6 +45,7 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
ERROR = QtGui.QImage(u':/general/general_delete.png')
|
ERROR = QtGui.QImage(u':/general/general_delete.png')
|
||||||
|
|
||||||
|
|
||||||
class PresentationMediaItem(MediaManagerItem):
|
class PresentationMediaItem(MediaManagerItem):
|
||||||
"""
|
"""
|
||||||
This is the Presentation media manager item for Presentation Items.
|
This is the Presentation media manager item for Presentation Items.
|
||||||
|
@ -88,10 +89,10 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
if self.controllers[controller].enabled():
|
if self.controllers[controller].enabled():
|
||||||
types = self.controllers[controller].supports + \
|
types = self.controllers[controller].supports + \
|
||||||
self.controllers[controller].alsosupports
|
self.controllers[controller].alsosupports
|
||||||
for type in types:
|
for type_ in types:
|
||||||
if fileType.find(type) == -1:
|
if fileType.find(type_) == -1:
|
||||||
fileType += u'*.%s ' % type
|
fileType += u'*.%s ' % type_
|
||||||
self.plugin.serviceManager.supportedSuffixes(type)
|
self.plugin.serviceManager.supportedSuffixes(type_)
|
||||||
self.onNewFileMasks = unicode(translate('PresentationPlugin.MediaItem',
|
self.onNewFileMasks = unicode(translate('PresentationPlugin.MediaItem',
|
||||||
'Presentations (%s)')) % fileType
|
'Presentations (%s)')) % fileType
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ log = logging.getLogger(__name__)
|
||||||
# PPT API documentation:
|
# PPT API documentation:
|
||||||
# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
|
# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
|
||||||
|
|
||||||
|
|
||||||
class PowerpointController(PresentationController):
|
class PowerpointController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with PowerPoint Presentations
|
Class to control interactions with PowerPoint Presentations
|
||||||
|
@ -58,7 +59,7 @@ class PowerpointController(PresentationController):
|
||||||
log.debug(u'Initialising')
|
log.debug(u'Initialising')
|
||||||
PresentationController.__init__(self, plugin, u'Powerpoint',
|
PresentationController.__init__(self, plugin, u'Powerpoint',
|
||||||
PowerpointDocument)
|
PowerpointDocument)
|
||||||
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx', u'pptm']
|
||||||
self.process = None
|
self.process = None
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
|
|
|
@ -38,6 +38,7 @@ from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PptviewController(PresentationController):
|
class PptviewController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with PowerPOint Viewer Presentations
|
Class to control interactions with PowerPOint Viewer Presentations
|
||||||
|
@ -54,7 +55,7 @@ class PptviewController(PresentationController):
|
||||||
self.process = None
|
self.process = None
|
||||||
PresentationController.__init__(self, plugin, u'Powerpoint Viewer',
|
PresentationController.__init__(self, plugin, u'Powerpoint Viewer',
|
||||||
PptviewDocument)
|
PptviewDocument)
|
||||||
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx', u'pptm']
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -34,7 +34,7 @@ import shutil
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, \
|
from openlp.core.lib import FileDialog, PluginStatus, Receiver, MediaType, translate, \
|
||||||
create_separated_list, check_directory_exists
|
create_separated_list, check_directory_exists
|
||||||
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \
|
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \
|
||||||
critical_error_message_box, find_and_set_in_combo_box
|
critical_error_message_box, find_and_set_in_combo_box
|
||||||
|
@ -47,6 +47,7 @@ from editsongdialog import Ui_EditSongDialog
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
"""
|
"""
|
||||||
Class to manage the editing of a song
|
Class to manage the editing of a song
|
||||||
|
@ -229,6 +230,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
self.loadTopics()
|
self.loadTopics()
|
||||||
self.loadBooks()
|
self.loadBooks()
|
||||||
self.loadMediaFiles()
|
self.loadMediaFiles()
|
||||||
|
self.themeComboBox.setEditText(u'')
|
||||||
self.themeComboBox.setCurrentIndex(0)
|
self.themeComboBox.setCurrentIndex(0)
|
||||||
# it's a new song to preview is not possible
|
# it's a new song to preview is not possible
|
||||||
self.previewButton.setVisible(False)
|
self.previewButton.setVisible(False)
|
||||||
|
@ -261,6 +263,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
if self.song.theme_name:
|
if self.song.theme_name:
|
||||||
find_and_set_in_combo_box(
|
find_and_set_in_combo_box(
|
||||||
self.themeComboBox, unicode(self.song.theme_name))
|
self.themeComboBox, unicode(self.song.theme_name))
|
||||||
|
else:
|
||||||
|
self.themeComboBox.setEditText(u'')
|
||||||
|
self.themeComboBox.setCurrentIndex(0)
|
||||||
self.copyrightEdit.setText(
|
self.copyrightEdit.setText(
|
||||||
self.song.copyright if self.song.copyright else u'')
|
self.song.copyright if self.song.copyright else u'')
|
||||||
self.commentsEdit.setPlainText(
|
self.commentsEdit.setPlainText(
|
||||||
|
@ -757,7 +762,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
Loads file(s) from the filesystem.
|
Loads file(s) from the filesystem.
|
||||||
"""
|
"""
|
||||||
filters = u'%s (*)' % UiStrings().AllFiles
|
filters = u'%s (*)' % UiStrings().AllFiles
|
||||||
filenames = QtGui.QFileDialog.getOpenFileNames(self,
|
filenames = FileDialog.getOpenFileNames(self,
|
||||||
translate('SongsPlugin.EditSongForm', 'Open File(s)'),
|
translate('SongsPlugin.EditSongForm', 'Open File(s)'),
|
||||||
QtCore.QString(), filters)
|
QtCore.QString(), filters)
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
|
|
|
@ -35,7 +35,7 @@ import os
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
from openlp.core.lib import FileDialog, Receiver, SettingsManager, translate
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
from openlp.core.lib.settings import Settings
|
from openlp.core.lib.settings import Settings
|
||||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||||
|
@ -281,7 +281,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
if filters:
|
if filters:
|
||||||
filters += u';;'
|
filters += u';;'
|
||||||
filters += u'%s (*)' % UiStrings().AllFiles
|
filters += u'%s (*)' % UiStrings().AllFiles
|
||||||
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
|
filenames = FileDialog.getOpenFileNames(self, title,
|
||||||
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
||||||
filters)
|
filters)
|
||||||
if filenames:
|
if filenames:
|
||||||
|
|
|
@ -96,6 +96,7 @@ import os
|
||||||
|
|
||||||
from lxml import etree, objectify
|
from lxml import etree, objectify
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
@ -115,7 +116,7 @@ class FoilPresenterImport(SongImport):
|
||||||
"""
|
"""
|
||||||
log.debug(u'initialise FoilPresenterImport')
|
log.debug(u'initialise FoilPresenterImport')
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.FoilPresenter = FoilPresenter(self.manager)
|
self.FoilPresenter = FoilPresenter(self.manager, self)
|
||||||
|
|
||||||
def doImport(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
|
@ -202,8 +203,9 @@ class FoilPresenter(object):
|
||||||
<copyright> tag.
|
<copyright> tag.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, manager):
|
def __init__(self, manager, importer):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
|
self.importer = importer
|
||||||
|
|
||||||
def xml_to_song(self, xml):
|
def xml_to_song(self, xml):
|
||||||
"""
|
"""
|
||||||
|
@ -222,6 +224,7 @@ class FoilPresenter(object):
|
||||||
song.search_lyrics = u''
|
song.search_lyrics = u''
|
||||||
song.verse_order = u''
|
song.verse_order = u''
|
||||||
song.search_title = u''
|
song.search_title = u''
|
||||||
|
self.save_song = True
|
||||||
# Because "text" seems to be an reserverd word, we have to recompile it.
|
# Because "text" seems to be an reserverd word, we have to recompile it.
|
||||||
xml = re.compile(u'<text>').sub(u'<text_>', xml)
|
xml = re.compile(u'<text>').sub(u'<text_>', xml)
|
||||||
xml = re.compile(u'</text>').sub(u'</text_>', xml)
|
xml = re.compile(u'</text>').sub(u'</text_>', xml)
|
||||||
|
@ -236,8 +239,9 @@ class FoilPresenter(object):
|
||||||
self._process_authors(foilpresenterfolie, song)
|
self._process_authors(foilpresenterfolie, song)
|
||||||
self._process_songbooks(foilpresenterfolie, song)
|
self._process_songbooks(foilpresenterfolie, song)
|
||||||
self._process_topics(foilpresenterfolie, song)
|
self._process_topics(foilpresenterfolie, song)
|
||||||
clean_song(self.manager, song)
|
if self.save_song:
|
||||||
self.manager.save_object(song)
|
clean_song(self.manager, song)
|
||||||
|
self.manager.save_object(song)
|
||||||
|
|
||||||
def _child(self, element):
|
def _child(self, element):
|
||||||
"""
|
"""
|
||||||
|
@ -424,6 +428,12 @@ class FoilPresenter(object):
|
||||||
VerseType.Tags[VerseType.Intro]: 1,
|
VerseType.Tags[VerseType.Intro]: 1,
|
||||||
VerseType.Tags[VerseType.PreChorus]: 1
|
VerseType.Tags[VerseType.PreChorus]: 1
|
||||||
}
|
}
|
||||||
|
if not hasattr(foilpresenterfolie.strophen, u'strophe'):
|
||||||
|
self.importer.logError(self._child(foilpresenterfolie.titel),
|
||||||
|
unicode(translate('SongsPlugin.FoilPresenterSongImport',
|
||||||
|
'Invalid Foilpresenter song file. No verses found.')))
|
||||||
|
self.save_song = False
|
||||||
|
return
|
||||||
for strophe in foilpresenterfolie.strophen.strophe:
|
for strophe in foilpresenterfolie.strophen.strophe:
|
||||||
text = self._child(strophe.text_) if hasattr(strophe, u'text_') \
|
text = self._child(strophe.text_) if hasattr(strophe, u'text_') \
|
||||||
else u''
|
else u''
|
||||||
|
|
|
@ -49,6 +49,9 @@ class OpenSongImport(SongImport):
|
||||||
the OpenSong web site. However, it doesn't describe the <lyrics> section,
|
the OpenSong web site. However, it doesn't describe the <lyrics> section,
|
||||||
so here's an attempt:
|
so here's an attempt:
|
||||||
|
|
||||||
|
If the first charachter of a line is a space, then the rest of that line
|
||||||
|
is lyrics. If it is not a space the following applies.
|
||||||
|
|
||||||
Verses can be expressed in one of 2 ways, either in complete verses, or by
|
Verses can be expressed in one of 2 ways, either in complete verses, or by
|
||||||
line grouping, i.e. grouping all line 1's of a verse together, all line 2's
|
line grouping, i.e. grouping all line 1's of a verse together, all line 2's
|
||||||
of a verse together, and so on.
|
of a verse together, and so on.
|
||||||
|
@ -171,13 +174,11 @@ class OpenSongImport(SongImport):
|
||||||
else:
|
else:
|
||||||
lyrics = u''
|
lyrics = u''
|
||||||
for this_line in lyrics.split(u'\n'):
|
for this_line in lyrics.split(u'\n'):
|
||||||
# remove comments
|
|
||||||
semicolon = this_line.find(u';')
|
|
||||||
if semicolon >= 0:
|
|
||||||
this_line = this_line[:semicolon]
|
|
||||||
this_line = this_line.strip()
|
|
||||||
if not this_line:
|
if not this_line:
|
||||||
continue
|
continue
|
||||||
|
# skip this line if it is a comment
|
||||||
|
if this_line.startswith(u';'):
|
||||||
|
continue
|
||||||
# skip guitar chords and page and column breaks
|
# skip guitar chords and page and column breaks
|
||||||
if this_line.startswith(u'.') or this_line.startswith(u'---') \
|
if this_line.startswith(u'.') or this_line.startswith(u'---') \
|
||||||
or this_line.startswith(u'-!!'):
|
or this_line.startswith(u'-!!'):
|
||||||
|
@ -212,7 +213,6 @@ class OpenSongImport(SongImport):
|
||||||
if this_line[0].isdigit():
|
if this_line[0].isdigit():
|
||||||
verse_num = this_line[0]
|
verse_num = this_line[0]
|
||||||
this_line = this_line[1:].strip()
|
this_line = this_line[1:].strip()
|
||||||
our_verse_order.append([verse_tag, verse_num, inst])
|
|
||||||
verses.setdefault(verse_tag, {})
|
verses.setdefault(verse_tag, {})
|
||||||
verses[verse_tag].setdefault(verse_num, {})
|
verses[verse_tag].setdefault(verse_num, {})
|
||||||
if inst not in verses[verse_tag][verse_num]:
|
if inst not in verses[verse_tag][verse_num]:
|
||||||
|
@ -222,6 +222,7 @@ class OpenSongImport(SongImport):
|
||||||
this_line = self.tidyText(this_line)
|
this_line = self.tidyText(this_line)
|
||||||
this_line = this_line.replace(u'_', u'')
|
this_line = this_line.replace(u'_', u'')
|
||||||
this_line = this_line.replace(u'|', u'\n')
|
this_line = this_line.replace(u'|', u'\n')
|
||||||
|
this_line = this_line.strip()
|
||||||
verses[verse_tag][verse_num][inst].append(this_line)
|
verses[verse_tag][verse_num][inst].append(this_line)
|
||||||
# done parsing
|
# done parsing
|
||||||
# add verses in original order
|
# add verses in original order
|
||||||
|
|
|
@ -30,13 +30,14 @@
|
||||||
The :mod:`songshowplusimport` module provides the functionality for importing
|
The :mod:`songshowplusimport` module provides the functionality for importing
|
||||||
SongShow Plus songs into the OpenLP database.
|
SongShow Plus songs into the OpenLP database.
|
||||||
"""
|
"""
|
||||||
|
import chardet
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
TITLE = 1
|
TITLE = 1
|
||||||
|
@ -142,44 +143,44 @@ class SongShowPlusImport(SongImport):
|
||||||
log.debug(length_descriptor_size)
|
log.debug(length_descriptor_size)
|
||||||
data = song_data.read(length_descriptor)
|
data = song_data.read(length_descriptor)
|
||||||
if block_key == TITLE:
|
if block_key == TITLE:
|
||||||
self.title = unicode(data, u'cp1252')
|
self.title = self.decode(data)
|
||||||
elif block_key == AUTHOR:
|
elif block_key == AUTHOR:
|
||||||
authors = data.split(" / ")
|
authors = data.split(" / ")
|
||||||
for author in authors:
|
for author in authors:
|
||||||
if author.find(",") !=-1:
|
if author.find(",") !=-1:
|
||||||
authorParts = author.split(", ")
|
authorParts = author.split(", ")
|
||||||
author = authorParts[1] + " " + authorParts[0]
|
author = authorParts[1] + " " + authorParts[0]
|
||||||
self.parseAuthor(unicode(author, u'cp1252'))
|
self.parseAuthor(self.decode(author))
|
||||||
elif block_key == COPYRIGHT:
|
elif block_key == COPYRIGHT:
|
||||||
self.addCopyright(unicode(data, u'cp1252'))
|
self.addCopyright(self.decode(data))
|
||||||
elif block_key == CCLI_NO:
|
elif block_key == CCLI_NO:
|
||||||
self.ccliNumber = int(data)
|
self.ccliNumber = int(data)
|
||||||
elif block_key == VERSE:
|
elif block_key == VERSE:
|
||||||
self.addVerse(unicode(data, u'cp1252'),
|
self.addVerse(self.decode(data),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
|
"%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
|
||||||
elif block_key == CHORUS:
|
elif block_key == CHORUS:
|
||||||
self.addVerse(unicode(data, u'cp1252'),
|
self.addVerse(self.decode(data),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
|
"%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
|
||||||
elif block_key == BRIDGE:
|
elif block_key == BRIDGE:
|
||||||
self.addVerse(unicode(data, u'cp1252'),
|
self.addVerse(self.decode(data),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
|
"%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
|
||||||
elif block_key == TOPIC:
|
elif block_key == TOPIC:
|
||||||
self.topics.append(unicode(data, u'cp1252'))
|
self.topics.append(self.decode(data))
|
||||||
elif block_key == COMMENTS:
|
elif block_key == COMMENTS:
|
||||||
self.comments = unicode(data, u'cp1252')
|
self.comments = self.decode(data)
|
||||||
elif block_key == VERSE_ORDER:
|
elif block_key == VERSE_ORDER:
|
||||||
verse_tag = self.toOpenLPVerseTag(data, True)
|
verse_tag = self.toOpenLPVerseTag(data, True)
|
||||||
if verse_tag:
|
if verse_tag:
|
||||||
if not isinstance(verse_tag, unicode):
|
if not isinstance(verse_tag, unicode):
|
||||||
verse_tag = unicode(verse_tag, u'cp1252')
|
verse_tag = self.decode(verse_tag)
|
||||||
self.sspVerseOrderList.append(verse_tag)
|
self.sspVerseOrderList.append(verse_tag)
|
||||||
elif block_key == SONG_BOOK:
|
elif block_key == SONG_BOOK:
|
||||||
self.songBookName = unicode(data, u'cp1252')
|
self.songBookName = self.decode(data)
|
||||||
elif block_key == SONG_NUMBER:
|
elif block_key == SONG_NUMBER:
|
||||||
self.songNumber = ord(data)
|
self.songNumber = ord(data)
|
||||||
elif block_key == CUSTOM_VERSE:
|
elif block_key == CUSTOM_VERSE:
|
||||||
verse_tag = self.toOpenLPVerseTag(verse_name)
|
verse_tag = self.toOpenLPVerseTag(verse_name)
|
||||||
self.addVerse(unicode(data, u'cp1252'), verse_tag)
|
self.addVerse(self.decode(data), verse_tag)
|
||||||
else:
|
else:
|
||||||
log.debug("Unrecognised blockKey: %s, data: %s"
|
log.debug("Unrecognised blockKey: %s, data: %s"
|
||||||
% (block_key, data))
|
% (block_key, data))
|
||||||
|
@ -221,3 +222,9 @@ class SongShowPlusImport(SongImport):
|
||||||
verse_tag = VerseType.Tags[VerseType.Other]
|
verse_tag = VerseType.Tags[VerseType.Other]
|
||||||
verse_number = self.otherList[verse_name]
|
verse_number = self.otherList[verse_name]
|
||||||
return verse_tag + verse_number
|
return verse_tag + verse_number
|
||||||
|
|
||||||
|
def decode(self, data):
|
||||||
|
try:
|
||||||
|
return unicode(data, chardet.detect(data)['encoding'])
|
||||||
|
except:
|
||||||
|
return unicode(data, retrieve_windows_encoding())
|
||||||
|
|
|
@ -68,7 +68,7 @@ class SundayPlusImport(SongImport):
|
||||||
for filename in self.importSource:
|
for filename in self.importSource:
|
||||||
if self.stopImportFlag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
song_file = open(filename)
|
song_file = open(filename, 'rb')
|
||||||
self.doImportFile(song_file)
|
self.doImportFile(song_file)
|
||||||
song_file.close()
|
song_file.close()
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class SundayPlusImport(SongImport):
|
||||||
# Now we are looking for the name.
|
# Now we are looking for the name.
|
||||||
if data[i:i + 1] == '#':
|
if data[i:i + 1] == '#':
|
||||||
name_end = data.find(':', i + 1)
|
name_end = data.find(':', i + 1)
|
||||||
name = data[i + 1:name_end]
|
name = data[i + 1:name_end].upper()
|
||||||
i = name_end + 1
|
i = name_end + 1
|
||||||
while data[i:i + 1] == ' ':
|
while data[i:i + 1] == ' ':
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -122,13 +122,13 @@ class SundayPlusImport(SongImport):
|
||||||
value = data[i:end]
|
value = data[i:end]
|
||||||
# If we are in the main group.
|
# If we are in the main group.
|
||||||
if cell == False:
|
if cell == False:
|
||||||
if name == 'title':
|
if name == 'TITLE':
|
||||||
self.title = self.decode(self.unescape(value))
|
self.title = self.decode(self.unescape(value))
|
||||||
elif name == 'Author':
|
elif name == 'AUTHOR':
|
||||||
author = self.decode(self.unescape(value))
|
author = self.decode(self.unescape(value))
|
||||||
if len(author):
|
if len(author):
|
||||||
self.addAuthor(author)
|
self.addAuthor(author)
|
||||||
elif name == 'Copyright':
|
elif name == 'COPYRIGHT':
|
||||||
self.copyright = self.decode(self.unescape(value))
|
self.copyright = self.decode(self.unescape(value))
|
||||||
elif name[0:4] == 'CELL':
|
elif name[0:4] == 'CELL':
|
||||||
self.parse(value, cell = name[4:])
|
self.parse(value, cell = name[4:])
|
||||||
|
@ -142,13 +142,13 @@ class SundayPlusImport(SongImport):
|
||||||
if len(value) >= 2 and value[-1] in ['0', '1', '2',
|
if len(value) >= 2 and value[-1] in ['0', '1', '2',
|
||||||
'3', '4', '5', '6', '7', '8', '9']:
|
'3', '4', '5', '6', '7', '8', '9']:
|
||||||
verse_type = "%s%s" % (verse_type, value[-1])
|
verse_type = "%s%s" % (verse_type, value[-1])
|
||||||
elif name == 'Hotkey':
|
elif name == 'HOTKEY':
|
||||||
# Hotkey always appears after MARKER_NAME, so it
|
# Hotkey always appears after MARKER_NAME, so it
|
||||||
# effectively overrides MARKER_NAME, if present.
|
# effectively overrides MARKER_NAME, if present.
|
||||||
if len(value) and \
|
if len(value) and \
|
||||||
value in HOTKEY_TO_VERSE_TYPE.keys():
|
value in HOTKEY_TO_VERSE_TYPE.keys():
|
||||||
verse_type = HOTKEY_TO_VERSE_TYPE[value]
|
verse_type = HOTKEY_TO_VERSE_TYPE[value]
|
||||||
if name == 'rtf':
|
if name == 'RTF':
|
||||||
value = self.unescape(value)
|
value = self.unescape(value)
|
||||||
result = strip_rtf(value, self.encoding)
|
result = strip_rtf(value, self.encoding)
|
||||||
if result is None:
|
if result is None:
|
||||||
|
|
|
@ -79,6 +79,33 @@ NAMESPACE = u'http://openlyrics.info/namespace/2009/song'
|
||||||
NSMAP = '{' + NAMESPACE + '}' + '%s'
|
NSMAP = '{' + NAMESPACE + '}' + '%s'
|
||||||
|
|
||||||
|
|
||||||
|
def clean_xml_string(xml):
|
||||||
|
"""
|
||||||
|
Filter out invalid characters in xml
|
||||||
|
Source <http://stackoverflow.com/questions/8733233/filtering-out-certain-bytes-in-python>
|
||||||
|
|
||||||
|
``xml``
|
||||||
|
The actual text to be checked.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return ''.join(char for char in xml if valid_XML_char_ordinal(ord(char)))
|
||||||
|
|
||||||
|
|
||||||
|
def valid_XML_char_ordinal(char):
|
||||||
|
"""
|
||||||
|
Undertake the filter test.
|
||||||
|
|
||||||
|
``char``
|
||||||
|
The individual character to be checked.
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
0x20 <= char <= 0xD7FF
|
||||||
|
or char in (0x9, 0xA, 0xD)
|
||||||
|
or 0xE000 <= char <= 0xFFFD
|
||||||
|
or 0x10000 <= char <= 0x10FFFF
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SongXML(object):
|
class SongXML(object):
|
||||||
"""
|
"""
|
||||||
This class builds and parses the XML used to describe songs.
|
This class builds and parses the XML used to describe songs.
|
||||||
|
@ -112,6 +139,7 @@ class SongXML(object):
|
||||||
The verse's language code (ISO-639). This is not required, but
|
The verse's language code (ISO-639). This is not required, but
|
||||||
should be added if available.
|
should be added if available.
|
||||||
"""
|
"""
|
||||||
|
content = clean_xml_string(content)
|
||||||
verse = etree.Element(u'verse', type=unicode(type),
|
verse = etree.Element(u'verse', type=unicode(type),
|
||||||
label=unicode(number))
|
label=unicode(number))
|
||||||
if lang:
|
if lang:
|
||||||
|
|
Loading…
Reference in New Issue