Add a method to update the translation files.

Merge from HEAD.
This commit is contained in:
Raoul Snyman 2010-09-19 19:31:59 +02:00
commit 4949bed443
27 changed files with 388 additions and 177 deletions

View File

@ -162,18 +162,18 @@ def main():
the PyQt4 Application. the PyQt4 Application.
""" """
# Set up command line options. # Set up command line options.
usage = u'Usage: %prog [options] [qt-options]' usage = 'Usage: %prog [options] [qt-options]'
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
parser.add_option(u'-e', u'--no-error-form', dest=u'no_error_form', parser.add_option('-e', '--no-error-form', dest='no_error_form',
action=u'store_true', help=u'Disable the error notification form.') action='store_true', help='Disable the error notification form.')
parser.add_option(u'-l', u'--log-level', dest=u'loglevel', parser.add_option('-l', '--log-level', dest='loglevel',
default=u'warning', metavar=u'LEVEL', help=u'Set logging to LEVEL ' default='warning', metavar='LEVEL', help='Set logging to LEVEL '
u'level. Valid values are "debug", "info", "warning".') 'level. Valid values are "debug", "info", "warning".')
parser.add_option(u'-p', u'--portable', dest=u'portable', parser.add_option('-p', '--portable', dest='portable',
action=u'store_true', help=u'Specify if this should be run as a ' action='store_true', help='Specify if this should be run as a '
u'portable app, off a USB flash drive (not implemented).') 'portable app, off a USB flash drive (not implemented).')
parser.add_option(u'-s', u'--style', dest=u'style', parser.add_option('-s', '--style', dest='style',
help=u'Set the Qt4 style (passed directly to Qt4).') help='Set the Qt4 style (passed directly to Qt4).')
# Set up logging # Set up logging
log_path = AppLocation.get_directory(AppLocation.CacheDir) log_path = AppLocation.get_directory(AppLocation.CacheDir)
if not os.path.exists(log_path): if not os.path.exists(log_path):

View File

@ -73,7 +73,7 @@ class Ui_ExceptionDialog(object):
def retranslateUi(self, exceptionDialog): def retranslateUi(self, exceptionDialog):
exceptionDialog.setWindowTitle( exceptionDialog.setWindowTitle(
translate('OpenLP.ExceptionDialog', 'Error Occured')) translate('OpenLP.ExceptionDialog', 'Error Occurred'))
self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! ' self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! '
'OpenLP hit a problem, and couldn\'t recover. The text in the box ' 'OpenLP hit a problem, and couldn\'t recover. The text in the box '
'below contains information that might be helpful to the OpenLP ' 'below contains information that might be helpful to the OpenLP '

View File

@ -575,7 +575,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage) QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
self.LanguageGroup.triggered.connect(LanguageManager.set_language) self.LanguageGroup.triggered.connect(LanguageManager.set_language)
QtCore.QObject.connect(self.ModeDefaultItem, QtCore.QObject.connect(self.ModeDefaultItem,
QtCore.SIGNAL(u'triggered()'), self.setViewMode) QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked)
QtCore.QObject.connect(self.ModeSetupItem, QtCore.QObject.connect(self.ModeSetupItem,
QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked) QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked)
QtCore.QObject.connect(self.ModeLiveItem, QtCore.QObject.connect(self.ModeLiveItem,
@ -670,6 +670,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.generalSettingsSection + u'/auto open', self.generalSettingsSection + u'/auto open',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.ServiceManagerContents.onLoadService(True) self.ServiceManagerContents.onLoadService(True)
view_mode = QtCore.QSettings().value(u'%s/view mode' % \
self.generalSettingsSection, u'default')
if view_mode == u'default':
self.ModeDefaultItem.setChecked(True)
elif view_mode == u'setup':
self.setViewMode(True, True, False, True, False)
self.ModeSetupItem.setChecked(True)
elif view_mode == u'live':
self.setViewMode(False, True, False, False, True)
self.ModeLiveItem.setChecked(True)
def blankCheck(self): def blankCheck(self):
""" """
@ -677,8 +687,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Triggered by delay thread. Triggered by delay thread.
""" """
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.generalSettingsSection) if settings.value(u'%s/screen blank' % self.generalSettingsSection,
if settings.value(u'screen blank', QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.LiveController.mainDisplaySetBackground() self.LiveController.mainDisplaySetBackground()
if settings.value(u'blank warning', if settings.value(u'blank warning',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
@ -687,7 +697,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
'OpenLP Main Display Blanked'), 'OpenLP Main Display Blanked'),
translate('OpenLP.MainWindow', translate('OpenLP.MainWindow',
'The Main Display has been blanked out')) 'The Main Display has been blanked out'))
settings.endGroup()
def onHelpWebSiteClicked(self): def onHelpWebSiteClicked(self):
""" """
@ -716,16 +725,31 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
self.settingsForm.exec_() self.settingsForm.exec_()
def onModeDefaultItemClicked(self):
"""
Put OpenLP into "Default" view mode.
"""
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'default')
self.setViewMode(True, True, True, True, True)
def onModeSetupItemClicked(self): def onModeSetupItemClicked(self):
""" """
Put OpenLP into "Setup" view mode. Put OpenLP into "Setup" view mode.
""" """
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'setup')
self.setViewMode(True, True, False, True, False) self.setViewMode(True, True, False, True, False)
def onModeLiveItemClicked(self): def onModeLiveItemClicked(self):
""" """
Put OpenLP into "Live" view mode. Put OpenLP into "Live" view mode.
""" """
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'live')
self.setViewMode(False, True, False, False, True) self.setViewMode(False, True, False, False, True)
def setViewMode(self, media=True, service=True, theme=True, preview=True, def setViewMode(self, media=True, service=True, theme=True, preview=True,

View File

@ -884,7 +884,8 @@ class ServiceManager(QtGui.QWidget):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be ' translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it')) 'displayed as the plugin required to display it is missing '
'or inactive'))
def remoteEdit(self): def remoteEdit(self):
""" """

View File

@ -209,7 +209,8 @@ class SlideController(QtGui.QWidget):
self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton( self.Toolbar.addToolbarButton(
u'Edit Song', u':/general/general_edit.png', u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController', 'Edit and re-preview song'), translate('OpenLP.SlideController',
'Edit and reload song preview'),
self.onEditSong) self.onEditSong)
if isLive: if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Separator') self.Toolbar.addToolbarSeparator(u'Loop Separator')

View File

@ -242,14 +242,14 @@ class ThemeManager(QtGui.QWidget):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'), translate('OpenLP.ThemeManager', 'Error'),
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Theme %s is use in %s plugin.')) % \ 'Theme %s is used in the %s plugin.')) % \
(theme, plugin.name)) (theme, plugin.name))
return return
if unicode(self.serviceComboBox.currentText()) == theme: if unicode(self.serviceComboBox.currentText()) == theme:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'), translate('OpenLP.ThemeManager', 'Error'),
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Theme %s is use by the service manager.')) % theme) 'Theme %s is used by the service manager.')) % theme)
return return
row = self.themeListWidget.row(item) row = self.themeListWidget.row(item)
self.themeListWidget.takeItem(row) self.themeListWidget.takeItem(row)

View File

@ -182,7 +182,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Copyright'), 'Empty Copyright'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to set a copyright for your Bible! ' 'You need to set a copyright for your Bible. '
'Bibles in the Public Domain need to be marked as ' 'Bibles in the Public Domain need to be marked as '
'such.')) 'such.'))
self.CopyrightEdit.setFocus() self.CopyrightEdit.setFocus()
@ -192,7 +192,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Bible Exists'), 'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'This Bible already exists! Please import ' 'This Bible already exists. Please import '
'a different Bible or first delete the existing one.')) 'a different Bible or first delete the existing one.'))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False

View File

@ -246,7 +246,7 @@ class BibleManager(object):
translate('BiblesPlugin.BibleManager', translate('BiblesPlugin.BibleManager',
'Scripture Reference Error'), 'Scripture Reference Error'),
translate('BiblesPlugin.BibleManager', 'Your scripture ' translate('BiblesPlugin.BibleManager', 'Your scripture '
'reference is either not supported by OpenLP or invalid. ' 'reference is either not supported by OpenLP or is invalid. '
'Please make sure your reference conforms to one of the ' 'Please make sure your reference conforms to one of the '
'following patterns:\n\n' 'following patterns:\n\n'
'Book Chapter\n' 'Book Chapter\n'

View File

@ -74,6 +74,7 @@ class ImpressController(PresentationController):
self.process = None self.process = None
self.desktop = None self.desktop = None
self.manager = None self.manager = None
self.uno_connection_type = u'pipe' #u'socket'
def check_available(self): def check_available(self):
""" """
@ -98,7 +99,14 @@ class ImpressController(PresentationController):
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
# -headless # -headless
cmd = u'openoffice.org -nologo -norestore -minimized -invisible -nofirststartwizard -accept="socket,host=localhost,port=2002;urp;"' if self.uno_connection_type == u'pipe':
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
self.process = QtCore.QProcess() self.process = QtCore.QProcess()
self.process.startDetached(cmd) self.process.startDetached(cmd)
self.process.waitForStarted() self.process.waitForStarted()
@ -120,8 +128,14 @@ class ImpressController(PresentationController):
while ctx is None and loop < 3: while ctx is None and loop < 3:
try: try:
log.debug(u'get UNO Desktop Openoffice - resolve') log.debug(u'get UNO Desktop Openoffice - resolve')
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;' if self.uno_connection_type == u'pipe':
u'urp;StarOffice.ComponentContext') ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
log.exception(u'Unable to find running instance ') log.exception(u'Unable to find running instance ')
self.start_process() self.start_process()

View File

@ -97,8 +97,7 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
self, translate('SongsPlugin.AuthorsForm', 'Error'), self, translate('SongsPlugin.AuthorsForm', 'Error'),
translate('SongsPlugin.AuthorsForm', translate('SongsPlugin.AuthorsForm',
'You have not set a display name for the ' 'You have not set a display name for the '
'author, would you like me to combine the first and ' 'author, combine the first and last names?'),
'last names for you?'),
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
) == QtGui.QMessageBox.Yes: ) == QtGui.QMessageBox.Yes:

View File

@ -621,6 +621,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.close() self.close()
def saveSong(self): def saveSong(self):
"""
Get all the data from the widgets on the form, and then save it to the
database.
"""
self.song.title = unicode(self.TitleEditItem.text()) self.song.title = unicode(self.TitleEditItem.text())
self.song.alternate_title = unicode(self.AlternativeEdit.text()) self.song.alternate_title = unicode(self.AlternativeEdit.text())
self.song.copyright = unicode(self.CopyrightEditItem.text()) self.song.copyright = unicode(self.CopyrightEditItem.text())
@ -646,6 +650,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.topics.append(self.songmanager.get_object(Topic, self.song.topics.append(self.songmanager.get_object(Topic,
topicId)) topicId))
self.songmanager.save_object(self.song) self.songmanager.save_object(self.song)
self.song = None
return True return True
return False return False

View File

@ -519,7 +519,7 @@ class Ui_SongImportWizard(object):
self.openLyricsDisabledLabel.setText( self.openLyricsDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics ' translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics '
'importer has not yet been developed, but as you can see, we are ' 'importer has not yet been developed, but as you can see, we are '
'still intendeding to do so. Hopefully it will be in the next ' 'still intending to do so. Hopefully it will be in the next '
'release.')) 'release.'))
self.openSongAddButton.setText( self.openSongAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))

View File

@ -324,8 +324,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Error'),
translate('SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified author, because he ' 'Could not save your modified author, because the '
'already exists.')) 'author already exists.'))
def onTopicEditButtonClick(self): def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.TopicsListWidget) topic_id = self._getCurrentItemId(self.TopicsListWidget)

View File

@ -51,7 +51,7 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
self, translate('SongsPlugin.TopicsForm', 'Error'), self, translate('SongsPlugin.TopicsForm', 'Error'),
translate('SongsPlugin.TopicsForm', translate('SongsPlugin.TopicsForm',
'You need to type in a topic name!')) 'You need to type in a topic name.'))
self.NameEdit.setFocus() self.NameEdit.setFocus()
return False return False
else: else:

View File

@ -41,6 +41,8 @@ class OpenLP1SongImport(SongImport):
The :class:`OpenLP1SongImport` class provides OpenLP with the ability to The :class:`OpenLP1SongImport` class provides OpenLP with the ability to
import song databases from installations of openlp.org 1.x. import song databases from installations of openlp.org 1.x.
""" """
last_encoding = u'windows-1252'
def __init__(self, manager, **kwargs): def __init__(self, manager, **kwargs):
""" """
Initialise the import. Initialise the import.
@ -54,20 +56,33 @@ class OpenLP1SongImport(SongImport):
SongImport.__init__(self, manager) SongImport.__init__(self, manager)
self.import_source = kwargs[u'filename'] self.import_source = kwargs[u'filename']
def decode_string(self, raw): def decode_string(self, raw, guess):
""" """
Use chardet to detect the encoding of the raw string, and convert it Use chardet to detect the encoding of the raw string, and convert it
to unicode. to unicode.
``raw`` ``raw``
The raw bytestring to decode. The raw bytestring to decode.
``guess``
What chardet guessed the encoding to be.
""" """
detection = chardet.detect(raw) if guess[u'confidence'] < 0.8:
if detection[u'confidence'] < 0.8:
codec = u'windows-1252' codec = u'windows-1252'
else: else:
codec = detection[u'encoding'] codec = guess[u'encoding']
return unicode(raw, codec) try:
decoded = unicode(raw, codec)
self.last_encoding = codec
except UnicodeDecodeError:
log.exception(u'Error in detecting openlp.org 1.x database encoding.')
try:
decoded = unicode(raw, self.last_encoding)
except UnicodeDecodeError:
# possibly show an error form
#self.import_wizard.showError(u'There was a problem '
# u'detecting the encoding of a string')
decoded = raw
return decoded
def do_import(self): def do_import(self):
""" """
@ -103,9 +118,10 @@ class OpenLP1SongImport(SongImport):
success = False success = False
break break
song_id = song[0] song_id = song[0]
title = self.decode_string(song[1]) guess = chardet.detect(song[2])
lyrics = self.decode_string(song[2]).replace(u'\r', u'') title = self.decode_string(song[1], guess)
copyright = self.decode_string(song[3]) lyrics = self.decode_string(song[2], guess).replace(u'\r', u'')
copyright = self.decode_string(song[3], guess)
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm', unicode(translate('SongsPlugin.ImportWizardForm',
'Importing "%s"...')) % title) 'Importing "%s"...')) % title)
@ -121,7 +137,7 @@ class OpenLP1SongImport(SongImport):
break break
for author in authors: for author in authors:
if author[0] == author_id[0]: if author[0] == author_id[0]:
self.parse_author(self.decode_string(author[1])) self.parse_author(self.decode_string(author[1], guess))
break break
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False
@ -136,7 +152,7 @@ class OpenLP1SongImport(SongImport):
break break
for track in tracks: for track in tracks:
if track[0] == track_id[0]: if track[0] == track_id[0]:
self.add_media_file(self.decode_string(track[1])) self.add_media_file(self.decode_string(track[1], guess))
break break
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False

View File

@ -59,6 +59,7 @@ class OooImport(SongImport):
self.document = None self.document = None
self.process_started = False self.process_started = False
self.filenames = kwargs[u'filenames'] self.filenames = kwargs[u'filenames']
self.uno_connection_type = u'pipe' #u'socket'
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'song_stop_import'), self.stop_import) QtCore.SIGNAL(u'song_stop_import'), self.stop_import)
@ -106,8 +107,14 @@ class OooImport(SongImport):
loop = 0 loop = 0
while ctx is None and loop < 5: while ctx is None and loop < 5:
try: try:
ctx = resolver.resolve(u'uno:socket,host=localhost,' \ if self.uno_connection_type == u'pipe':
+ 'port=2002;urp;StarOffice.ComponentContext') ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
pass pass
self.start_ooo_process() self.start_ooo_process()
@ -123,9 +130,14 @@ class OooImport(SongImport):
self.manager._FlagAsMethod(u'Bridge_GetStruct') self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \ if self.uno_connection_type == u'pipe':
+ u'-invisible -nofirststartwizard ' \ cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ '-accept="socket,host=localhost,port=2002;urp;"' + u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
process = QtCore.QProcess() process = QtCore.QProcess()
process.startDetached(cmd) process.startDetached(cmd)
process.waitForStarted() process.waitForStarted()

View File

@ -29,6 +29,7 @@ import os
from zipfile import ZipFile from zipfile import ZipFile
from lxml import objectify from lxml import objectify
from lxml.etree import Error, LxmlError from lxml.etree import Error, LxmlError
import re
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib.songimport import SongImport
@ -113,12 +114,22 @@ class OpenSongImport(SongImport):
def do_import(self): def do_import(self):
""" """
Import either a single opensong file, or a zipfile containing multiple Import either each of the files in self.filenames - each element of
opensong files. If `self.commit` is set False, the import will not be which can be either a single opensong file, or a zipfile containing
committed to the database (useful for test scripts). multiple opensong files. If `self.commit` is set False, the
import will not be committed to the database (useful for test scripts).
""" """
success = True success = True
self.import_wizard.importProgressBar.setMaximum(len(self.filenames)) numfiles = 0
for filename in self.filenames:
ext = os.path.splitext(filename)[1]
if ext.lower() == u'.zip':
z = ZipFile(filename, u'r')
numfiles += len(z.infolist())
else:
numfiles += 1
log.debug("Total number of files: %d", numfiles)
self.import_wizard.importProgressBar.setMaximum(numfiles)
for filename in self.filenames: for filename in self.filenames:
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False
@ -127,9 +138,6 @@ class OpenSongImport(SongImport):
if ext.lower() == u'.zip': if ext.lower() == u'.zip':
log.debug(u'Zipfile found %s', filename) log.debug(u'Zipfile found %s', filename)
z = ZipFile(filename, u'r') z = ZipFile(filename, u'r')
self.import_wizard.importProgressBar.setMaximum(
self.import_wizard.importProgressBar.maximum() +
len(z.infolist()))
for song in z.infolist(): for song in z.infolist():
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False
@ -138,6 +146,7 @@ class OpenSongImport(SongImport):
if parts[-1] == u'': if parts[-1] == u'':
#No final part => directory #No final part => directory
continue continue
log.info(u'Zip importing %s', parts[-1])
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm', unicode(translate('SongsPlugin.ImportWizardForm',
'Importing %s...')) % parts[-1]) 'Importing %s...')) % parts[-1])
@ -145,11 +154,11 @@ class OpenSongImport(SongImport):
self.do_import_file(songfile) self.do_import_file(songfile)
if self.commit: if self.commit:
self.finish() self.finish()
self.set_defaults()
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False
break break
else: else:
# not a zipfile
log.info('Direct import %s', filename) log.info('Direct import %s', filename)
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm', unicode(translate('SongsPlugin.ImportWizardForm',
@ -158,9 +167,7 @@ class OpenSongImport(SongImport):
self.do_import_file(file) self.do_import_file(file)
if self.commit: if self.commit:
self.finish() self.finish()
self.set_defaults()
if not self.commit:
self.finish()
return success return success
def do_import_file(self, file): def do_import_file(self, file):
@ -168,7 +175,7 @@ class OpenSongImport(SongImport):
Process the OpenSong file - pass in a file-like object, Process the OpenSong file - pass in a file-like object,
not a filename not a filename
""" """
self.authors = [] self.set_defaults()
try: try:
tree = objectify.parse(file) tree = objectify.parse(file)
except (Error, LxmlError): except (Error, LxmlError):
@ -197,7 +204,6 @@ class OpenSongImport(SongImport):
self.topics.append(unicode(root.alttheme)) self.topics.append(unicode(root.alttheme))
# data storage while importing # data storage while importing
verses = {} verses = {}
lyrics = unicode(root.lyrics)
# keep track of a "default" verse order, in case none is specified # keep track of a "default" verse order, in case none is specified
our_verse_order = [] our_verse_order = []
verses_seen = {} verses_seen = {}
@ -205,6 +211,7 @@ class OpenSongImport(SongImport):
# erm, versetype! # erm, versetype!
versetype = u'V' versetype = u'V'
versenum = None versenum = None
lyrics = unicode(root.lyrics)
for thisline in lyrics.split(u'\n'): for thisline in lyrics.split(u'\n'):
# remove comments # remove comments
semicolon = thisline.find(u';') semicolon = thisline.find(u';')
@ -219,16 +226,18 @@ class OpenSongImport(SongImport):
continue continue
# verse/chorus/etc. marker # verse/chorus/etc. marker
if thisline[0] == u'[': if thisline[0] == u'[':
versetype = thisline[1].upper() # drop the square brackets
if versetype.isdigit(): right_bracket = thisline.find(u']')
versenum = versetype content = thisline[1:right_bracket].upper()
versetype = u'V' # have we got any digits? If so, versenumber is everything from the digits
elif thisline[2] != u']': # to the end (even if there are some alpha chars on the end)
# there's a number to go with it - extract that as well match = re.match(u'(.*)(\d+.*)', content)
right_bracket = thisline.find(u']') if match is not None:
versenum = thisline[2:right_bracket] versetype = match.group(1)
versenum = match.group(2)
else: else:
# if there's no number, assume it's no.1 # otherwise we assume number 1 and take the whole prefix as versetype
versetype = content
versenum = u'1' versenum = u'1'
continue continue
words = None words = None
@ -236,10 +245,10 @@ class OpenSongImport(SongImport):
if thisline[0].isdigit(): if thisline[0].isdigit():
versenum = thisline[0] versenum = thisline[0]
words = thisline[1:].strip() words = thisline[1:].strip()
if words is None and \ if words is None:
versenum is not None and \
versetype is not None:
words = thisline words = thisline
if not versenum:
versenum = u'1'
if versenum is not None: if versenum is not None:
versetag = u'%s%s' % (versetype, versenum) versetag = u'%s%s' % (versetype, versenum)
if not verses.has_key(versetype): if not verses.has_key(versetype):
@ -260,10 +269,13 @@ class OpenSongImport(SongImport):
versetypes.sort() versetypes.sort()
versetags = {} versetags = {}
for versetype in versetypes: for versetype in versetypes:
our_verse_type = versetype
if our_verse_type == u'':
our_verse_type = u'V'
versenums = verses[versetype].keys() versenums = verses[versetype].keys()
versenums.sort() versenums.sort()
for num in versenums: for num in versenums:
versetag = u'%s%s' % (versetype, num) versetag = u'%s%s' % (our_verse_type, num)
lines = u'\n'.join(verses[versetype][num]) lines = u'\n'.join(verses[versetype][num])
self.verses.append([versetag, lines]) self.verses.append([versetag, lines])
# Keep track of what we have for error checking later # Keep track of what we have for error checking later
@ -272,7 +284,9 @@ class OpenSongImport(SongImport):
order = [] order = []
if u'presentation' in fields and root.presentation != u'': if u'presentation' in fields and root.presentation != u'':
order = unicode(root.presentation) order = unicode(root.presentation)
order = order.split() # We make all the tags in the lyrics upper case, so match that here
# and then split into a list on the whitespace
order = order.upper().split()
else: else:
if len(our_verse_order) > 0: if len(our_verse_order) > 0:
order = our_verse_order order = our_verse_order
@ -280,9 +294,13 @@ class OpenSongImport(SongImport):
log.warn(u'No verse order available for %s, skipping.', log.warn(u'No verse order available for %s, skipping.',
self.title) self.title)
for tag in order: for tag in order:
if len(tag) == 1: if tag[0].isdigit():
tag = tag + u'1' # Assume it's no.1 if it's not there # Assume it's a verse if it has no prefix
tag = u'V' + tag
elif not re.search('\d+', tag):
# Assume it's no.1 if there's no digits
tag = tag + u'1'
if not versetags.has_key(tag): if not versetags.has_key(tag):
log.warn(u'Got order %s but not in versetags, skipping', tag) log.info(u'Got order %s but not in versetags, dropping this item from presentation order', tag)
else: else:
self.verse_order_list.append(tag) self.verse_order_list.append(tag)

View File

@ -55,8 +55,12 @@ class SongImport(QtCore.QObject):
self.set_defaults() self.set_defaults()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songs_stop_import'), self.stop_import) QtCore.SIGNAL(u'songs_stop_import'), self.stop_import)
def set_defaults(self): def set_defaults(self):
"""
Create defaults for properties - call this before each song
if importing many songs at once to ensure a clean beginning
"""
self.authors = []
self.title = u'' self.title = u''
self.song_number = u'' self.song_number = u''
self.alternate_title = u'' self.alternate_title = u''
@ -255,13 +259,16 @@ class SongImport(QtCore.QObject):
""" """
Write the song and its fields to disk Write the song and its fields to disk
""" """
log.info(u'commiting song %s to database', self.title)
song = Song() song = Song()
song.title = self.title song.title = self.title
song.search_title = self.remove_punctuation(self.title) \ song.search_title = self.remove_punctuation(self.title) \
+ '@' + self.alternate_title + '@' + self.alternate_title
song.song_number = self.song_number song.song_number = self.song_number
song.search_lyrics = u'' song.search_lyrics = u''
verses_changed_to_other = {}
sxml = SongXMLBuilder() sxml = SongXMLBuilder()
other_count = 1
for (versetag, versetext) in self.verses: for (versetag, versetext) in self.verses:
if versetag[0] == u'C': if versetag[0] == u'C':
versetype = VerseType.to_string(VerseType.Chorus) versetype = VerseType.to_string(VerseType.Chorus)
@ -276,10 +283,18 @@ class SongImport(QtCore.QObject):
elif versetag[0] == u'E': elif versetag[0] == u'E':
versetype = VerseType.to_string(VerseType.Ending) versetype = VerseType.to_string(VerseType.Ending)
else: else:
newversetag = u'O%d' % other_count
verses_changed_to_other[versetag] = newversetag
other_count += 1
versetype = VerseType.to_string(VerseType.Other) versetype = VerseType.to_string(VerseType.Other)
log.info(u'Versetype %s changing to %s' , versetag, newversetag)
versetag = newversetag
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext) sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext)
song.search_lyrics += u' ' + self.remove_punctuation(versetext) song.search_lyrics += u' ' + self.remove_punctuation(versetext)
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for i, current_verse_tag in enumerate(self.verse_order_list):
if verses_changed_to_other.has_key(current_verse_tag):
self.verse_order_list[i] = verses_changed_to_other[current_verse_tag]
song.verse_order = u' '.join(self.verse_order_list) song.verse_order = u' '.join(self.verse_order_list)
song.copyright = self.copyright song.copyright = self.copyright
song.comments = self.comments song.comments = self.comments

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<song> <song>
<title>Martins Test</title> <title>Martins Test</title>
<author>MartiÑ Thómpson</author> <author>MartiÑ &amp; Martin2 Thómpson</author>
<copyright>2010 Martin Thompson</copyright> <copyright>2010 Martin Thompson</copyright>
<hymn_number>1</hymn_number> <hymn_number>1</hymn_number>
<presentation>V1 C V2 C2 V3 B1 V1</presentation> <presentation>V1 C V2 C2 3a B1 V1 T U Rap1 Rap2 Rap3</presentation>
<ccli>Blah</ccli> <ccli>Blah</ccli>
<capo print="false"></capo> <capo print="false"></capo>
<key></key> <key></key>
@ -17,7 +17,12 @@
<alttheme>TestAltTheme</alttheme> <alttheme>TestAltTheme</alttheme>
<tempo></tempo> <tempo></tempo>
<time_sig></time_sig> <time_sig></time_sig>
<lyrics>;Comment <lyrics>[3a]
. G A B
V3 Line 1
. G A B
V3 Line 2
. A B C . A B C
1 v1 Line 1___ 1 v1 Line 1___
2 v2 Line 1___ 2 v2 Line 1___
@ -25,10 +30,6 @@
1 V1 Line 2 1 V1 Line 2
2 V2 Line 2 2 V2 Line 2
[3]
V3 Line 1
V3 Line 2
[b1] [b1]
Bridge 1 Bridge 1
--- ---
@ -36,12 +37,29 @@
Bridge 1 line 2 Bridge 1 line 2
[C] [C]
. A B . A B
Chorus 1 Chorus 1
[C2] [C2]
. A B . A B
Chorus 2 Chorus 2
[T]
T Line 1
[Rap]
1 Rap 1 Line 1
2 Rap 2 Line 1
1 Rap 1 Line 2
2 Rap 2 Line 2
[rap3]
Rap 3 Line 1
Rap 3 Line 2
[X]
Unreferenced verse line 1
</lyrics> </lyrics>
<style index="default_style"> <style index="default_style">
<title enabled="true" valign="bottom" align="center" include_verse="false" margin-left="0" margin-right="0" margin-top="0" margin-bottom="0" font="Helvetica" size="26" bold="true" italic="true" underline="false" color="#FFFFFF" border="true" border_color="#000000" shadow="true" shadow_color="#000000" fill="false" fill_color="#000000"/> <title enabled="true" valign="bottom" align="center" include_verse="false" margin-left="0" margin-right="0" margin-top="0" margin-bottom="0" font="Helvetica" size="26" bold="true" italic="true" underline="false" color="#FFFFFF" border="true" border_color="#000000" shadow="true" shadow_color="#000000" fill="false" fill_color="#000000"/>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<song>
<title>Test single verse</title>
<author>Martin Thompson</author>
<copyright>2010</copyright>
<ccli>123456</ccli>
<theme>Worship: Declaration</theme>
<lyrics> Line 1
Line 2
</lyrics></song>

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import sys
from openlp.plugins.songs.lib.opensongimport import OpenSongImport
from openlp.core.lib.db import Manager
from openlp.plugins.songs.lib.db import init_schema
import logging
LOG_FILENAME = 'test_import_file.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO)
from test_opensongimport import wizard_stub, progbar_stub
def test(filenames):
manager = Manager(u'songs', init_schema)
o = OpenSongImport(manager, filenames=filenames)
o.import_wizard = wizard_stub()
o.commit = False
o.do_import()
o.print_song()
if __name__ == "__main__":
test(sys.argv[1:])

View File

@ -8,50 +8,29 @@ from traceback import print_exc
import sys import sys
import codecs import codecs
import logging
LOG_FILENAME = 'import.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO)
from test_opensongimport import wizard_stub, progbar_stub
# Useful test function for importing a variety of different files
# Uncomment below depending on what problem trying to make occur!
def opensong_import_lots(): def opensong_import_lots():
ziploc = u'/home/mjt/openlp/OpenSong_Data/' ziploc = u'/home/mjt/openlp/OpenSong_Data/'
files = [] files = []
#files = [u'test.opensong.zip', ziploc+u'ADond.zip'] files = [os.path.join(ziploc, u'RaoulSongs', u'Songs', u'Jesus Freak')]
files.extend(glob(ziploc+u'Songs.zip')) # files.extend(glob(ziploc+u'Songs.zip'))
#files.extend(glob(ziploc+u'SOF.zip')) # files.extend(glob(ziploc+u'RaoulSongs.zip'))
#files.extend(glob(ziploc+u'spanish_songs_for_opensong.zip')) # files.extend(glob(ziploc+u'SOF.zip'))
# files.extend(glob(ziploc+u'opensong_*.zip')) # files.extend(glob(ziploc+u'spanish_songs_for_opensong.zip'))
# files.extend(glob(ziploc+u'opensong_*.zip'))
errfile = codecs.open(u'import_lots_errors.txt', u'w', u'utf8') errfile = codecs.open(u'import_lots_errors.txt', u'w', u'utf8')
manager = Manager(u'songs', init_schema) manager = Manager(u'songs', init_schema)
for file in files: o = OpenSongImport(manager, filenames=files)
print u'Importing', file o.import_wizard=wizard_stub()
z = ZipFile(file, u'r') o.do_import()
for song in z.infolist():
# need to handle unicode filenames (CP437 - Winzip does this)
filename = song.filename#.decode('cp852')
parts = os.path.split(filename)
if parts[-1] == u'':
#No final part => directory
continue
print " ", file, ":",filename,
songfile = z.open(song)
#z.extract(song)
#songfile=open(filename, u'r')
o = OpenSongImport(manager)
try:
o.do_import_file(songfile)
# o.song_import.print_song()
except:
print "Failure",
errfile.write(u'Failure: %s:%s\n' %(file, filename.decode('cp437')))
songfile = z.open(song)
for l in songfile.readlines():
l = l.decode('utf8')
print(u' |%s\n' % l.strip())
errfile.write(u' |%s\n'%l.strip())
print_exc(3, file = errfile)
print_exc(3)
sys.exit(1)
# continue
#o.finish()
print "OK"
#os.unlink(filename)
# o.song_import.print_song()
if __name__ == "__main__": if __name__ == "__main__":
opensong_import_lots() opensong_import_lots()

View File

@ -28,62 +28,101 @@ from openlp.plugins.songs.lib.opensongimport import OpenSongImport
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
from openlp.plugins.songs.lib.db import init_schema from openlp.plugins.songs.lib.db import init_schema
import logging
LOG_FILENAME = 'test.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO)
# Stubs to replace the UI functions for raw testing
class wizard_stub:
def __init__(self):
self.importProgressBar=progbar_stub()
def incrementProgressBar(self, str):
pass
class progbar_stub:
def __init__(self):
pass
def setMaximum(self, arg):
pass
def test(): def test():
manager = Manager(u'songs', init_schema) manager = Manager(u'songs', init_schema)
o = OpenSongImport(manager) o = OpenSongImport(manager, filenames=[u'test.opensong'])
o.do_import(u'test.opensong', commit=False) o.import_wizard = wizard_stub()
o.song_import.print_song() o.commit = False
assert o.song_import.copyright == u'2010 Martin Thompson' o.do_import()
assert o.song_import.authors == [u'MartiÑ Thómpson'] o.print_song()
assert o.song_import.title == u'Martins Test' assert o.copyright == u'2010 Martin Thompson'
assert o.song_import.alternate_title == u'' assert o.authors == [u'MartiÑ Thómpson', u'Martin2 Thómpson']
assert o.song_import.song_number == u'1' assert o.title == u'Martins Test'
assert [u'C1', u'Chorus 1'] in o.song_import.verses assert o.alternate_title == u''
assert [u'C2', u'Chorus 2'] in o.song_import.verses assert o.song_number == u'1'
assert not [u'C3', u'Chorus 3'] in o.song_import.verses assert [u'C1', u'Chorus 1'] in o.verses
assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.song_import.verses assert [u'C2', u'Chorus 2'] in o.verses
assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.song_import.verses assert not [u'C3', u'Chorus 3'] in o.verses
assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.song_import.verses assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.verses
assert o.song_import.verse_order_list == [u'V1', u'C1', u'V2', u'C2', u'V3', u'B1', u'V1'] assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.verses
assert o.song_import.ccli_number == u'Blah' assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.verses
assert o.song_import.topics == [u'TestTheme', u'TestAltTheme'] assert [u'V3A', u'V3 Line 1\nV3 Line 2'] in o.verses
o.do_import(u'test.opensong.zip', commit=False) assert [u'RAP1', u'Rap 1 Line 1\nRap 1 Line 2'] in o.verses
o.song_import.print_song() assert [u'RAP2', u'Rap 2 Line 1\nRap 2 Line 2'] in o.verses
o.finish() assert [u'RAP3', u'Rap 3 Line 1\nRap 3 Line 2'] in o.verses
assert o.song_import.copyright == u'2010 Martin Thompson' assert [u'X1', u'Unreferenced verse line 1'] in o.verses
assert o.song_import.authors == [u'MartiÑ Thómpson'] assert o.verse_order_list == [u'V1', u'C1', u'V2', u'C2', u'V3A', u'B1', u'V1', u'T1', u'RAP1', u'RAP2', u'RAP3']
assert o.song_import.title == u'Martins Test' assert o.ccli_number == u'Blah'
assert o.song_import.alternate_title == u'' assert o.topics == [u'TestTheme', u'TestAltTheme']
assert o.song_import.song_number == u'1'
assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.song_import.verses
assert [u'C1', u'Chorus 1'] in o.song_import.verses
assert [u'C2', u'Chorus 2'] in o.song_import.verses
assert not [u'C3', u'Chorus 3'] in o.song_import.verses
assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.song_import.verses
assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.song_import.verses
assert o.song_import.verse_order_list == [u'V1', u'C1', u'V2', u'C2', u'V3', u'B1', u'V1']
o = OpenSongImport(manager) o.filenames = [u'test.opensong.zip']
o.do_import(u'test2.opensong', commit=False) o.set_defaults()
# o.finish() o.do_import()
o.song_import.print_song() o.print_song()
assert o.song_import.copyright == u'2010 Martin Thompson' assert o.copyright == u'2010 Martin Thompson'
assert o.song_import.authors == [u'Martin Thompson'] assert o.authors == [u'MartiÑ Thómpson']
assert o.song_import.title == u'Martins 2nd Test' assert o.title == u'Martins Test'
assert o.song_import.alternate_title == u'' assert o.alternate_title == u''
assert o.song_import.song_number == u'2' assert o.song_number == u'1'
print o.song_import.verses assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.verses
assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.song_import.verses assert [u'C1', u'Chorus 1'] in o.verses
assert [u'C1', u'Chorus 1'] in o.song_import.verses assert [u'C2', u'Chorus 2'] in o.verses
assert [u'C2', u'Chorus 2'] in o.song_import.verses assert not [u'C3', u'Chorus 3'] in o.verses
assert not [u'C3', u'Chorus 3'] in o.song_import.verses assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.verses
assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.song_import.verses assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.verses
assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.song_import.verses print o.verse_order_list
print o.song_import.verse_order_list assert o.verse_order_list == [u'V1', u'C1', u'V2', u'C2', u'V3', u'B1', u'V1']
assert o.song_import.verse_order_list == [u'V1', u'V2', u'B1', u'C1', u'C2']
o.filenames = [u'test2.opensong']
o.set_defaults()
o.do_import()
o.print_song()
assert o.copyright == u'2010 Martin Thompson'
assert o.authors == [u'Martin Thompson']
assert o.title == u'Martins 2nd Test'
assert o.alternate_title == u''
assert o.song_number == u'2'
print o.verses
assert [u'B1', u'Bridge 1\nBridge 1 line 2'] in o.verses
assert [u'C1', u'Chorus 1'] in o.verses
assert [u'C2', u'Chorus 2'] in o.verses
assert not [u'C3', u'Chorus 3'] in o.verses
assert [u'V1', u'v1 Line 1\nV1 Line 2'] in o.verses
assert [u'V2', u'v2 Line 1\nV2 Line 2'] in o.verses
print o.verse_order_list
assert o.verse_order_list == [u'V1', u'V2', u'B1', u'C1', u'C2']
o.filenames = [u'test3.opensong']
o.set_defaults()
o.do_import()
o.print_song()
assert o.copyright == u'2010'
assert o.authors == [u'Martin Thompson']
assert o.title == u'Test single verse'
assert o.alternate_title == u''
assert o.ccli_number == u'123456'
assert o.verse_order_list == [u'V1']
assert o.topics == [u'Worship: Declaration']
print o.verses[0]
assert [u'V1', u'Line 1\nLine 2'] in o.verses
print "Tests passed" print "Tests passed"
pass
if __name__ == "__main__": if __name__ == "__main__":
test() test()

0
resources/images/about-new.bmp Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

1
resources/openlp.desktop Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!/usr/bin/env xdg-open
[Desktop Entry] [Desktop Entry]
Encoding=UTF-8 Encoding=UTF-8
Name=OpenLP Name=OpenLP

View File

@ -127,6 +127,8 @@ def import_bible():
for row in rows: for row in rows:
key = unicode(row[0], u'cp1252') key = unicode(row[0], u'cp1252')
value = unicode(row[1], u'cp1252') value = unicode(row[1], u'cp1252')
if key == u'Permission':
key = u'Permissions'
sql_insert = u'INSERT INTO metadata '\ sql_insert = u'INSERT INTO metadata '\
'("key", "value") '\ '("key", "value") '\
'VALUES (?, ?)' 'VALUES (?, ?)'

View File

@ -179,7 +179,16 @@ def copy_windows_files():
copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico')) copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico'))
copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt')) copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt'))
def update_translations():
print u'Updating translations...'
os.chdir(script_path)
translation_utils = Popen(u'python translation_utils.py -dpu')
code = translation_utils.wait()
if code != 0:
print u'Error running translation_utils.py'
def compile_translations(): def compile_translations():
print u'Compiling translations...'
files = os.listdir(i18n_path) files = os.listdir(i18n_path)
if not os.path.exists(os.path.join(dist_path, u'i18n')): if not os.path.exists(os.path.join(dist_path, u'i18n')):
os.makedirs(os.path.join(dist_path, u'i18n')) os.makedirs(os.path.join(dist_path, u'i18n'))
@ -221,6 +230,7 @@ def main():
copy_enchant() copy_enchant()
copy_plugins() copy_plugins()
copy_windows_files() copy_windows_files()
update_translations()
compile_translations() compile_translations()
run_innosetup() run_innosetup()
print "Done." print "Done."