forked from openlp/openlp
r1749
This commit is contained in:
commit
d62876b411
@ -236,7 +236,6 @@ def main(args=None):
|
|||||||
logfile.setFormatter(logging.Formatter(
|
logfile.setFormatter(logging.Formatter(
|
||||||
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
||||||
log.addHandler(logfile)
|
log.addHandler(logfile)
|
||||||
logging.addLevelName(15, u'Timer')
|
|
||||||
# Parse command line options and deal with them.
|
# Parse command line options and deal with them.
|
||||||
# Use args supplied programatically if possible.
|
# Use args supplied programatically if possible.
|
||||||
(options, args) = parser.parse_args(args) if args else parser.parse_args()
|
(options, args) = parser.parse_args(args) if args else parser.parse_args()
|
||||||
|
@ -376,18 +376,23 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
The files to be loaded
|
The files to be loaded
|
||||||
"""
|
"""
|
||||||
names = []
|
names = []
|
||||||
|
fullList = []
|
||||||
for count in range(0, self.listView.count()):
|
for count in range(0, self.listView.count()):
|
||||||
names.append(unicode(self.listView.item(count).text()))
|
names.append(unicode(self.listView.item(count).text()))
|
||||||
newFiles = []
|
fullList.append(unicode(self.listView.item(count).
|
||||||
|
data(QtCore.Qt.UserRole).toString()))
|
||||||
duplicatesFound = False
|
duplicatesFound = False
|
||||||
|
filesAdded = False
|
||||||
for file in files:
|
for file in files:
|
||||||
filename = os.path.split(unicode(file))[1]
|
filename = os.path.split(unicode(file))[1]
|
||||||
if filename in names:
|
if filename in names:
|
||||||
duplicatesFound = True
|
duplicatesFound = True
|
||||||
else:
|
else:
|
||||||
newFiles.append(file)
|
filesAdded = True
|
||||||
if newFiles:
|
fullList.append(file)
|
||||||
self.loadList(newFiles)
|
if fullList and filesAdded:
|
||||||
|
self.listView.clear()
|
||||||
|
self.loadList(fullList)
|
||||||
lastDir = os.path.split(unicode(files[0]))[0]
|
lastDir = os.path.split(unicode(files[0]))[0]
|
||||||
SettingsManager.set_last_dir(self.settingsSection, lastDir)
|
SettingsManager.set_last_dir(self.settingsSection, lastDir)
|
||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
@ -485,7 +490,8 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def generateSlideData(self, serviceItem, item=None, xmlVersion=False):
|
def generateSlideData(self, serviceItem, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
|
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
|
||||||
u'to be defined by the plugin')
|
u'to be defined by the plugin')
|
||||||
|
|
||||||
@ -539,12 +545,12 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
else:
|
else:
|
||||||
self.goLive()
|
self.goLive()
|
||||||
|
|
||||||
def goLive(self, item_id=None):
|
def goLive(self, item_id=None, remote=False):
|
||||||
log.debug(u'%s Live requested', self.plugin.name)
|
log.debug(u'%s Live requested', self.plugin.name)
|
||||||
item = None
|
item = None
|
||||||
if item_id:
|
if item_id:
|
||||||
item = self.createItemFromId(item_id)
|
item = self.createItemFromId(item_id)
|
||||||
serviceItem = self.buildServiceItem(item)
|
serviceItem = self.buildServiceItem(item, remote=remote)
|
||||||
if serviceItem:
|
if serviceItem:
|
||||||
if not item_id:
|
if not item_id:
|
||||||
serviceItem.from_plugin = True
|
serviceItem.from_plugin = True
|
||||||
@ -574,8 +580,8 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
for item in items:
|
for item in items:
|
||||||
self.addToService(item)
|
self.addToService(item)
|
||||||
|
|
||||||
def addToService(self, item=None, replace=None):
|
def addToService(self, item=None, replace=None, remote=False):
|
||||||
serviceItem = self.buildServiceItem(item, True)
|
serviceItem = self.buildServiceItem(item, True, remote=remote)
|
||||||
if serviceItem:
|
if serviceItem:
|
||||||
serviceItem.from_plugin = False
|
serviceItem.from_plugin = False
|
||||||
self.plugin.serviceManager.addServiceItem(serviceItem,
|
self.plugin.serviceManager.addServiceItem(serviceItem,
|
||||||
@ -608,13 +614,13 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
unicode(translate('OpenLP.MediaManagerItem',
|
unicode(translate('OpenLP.MediaManagerItem',
|
||||||
'You must select a %s service item.')) % self.title)
|
'You must select a %s service item.')) % self.title)
|
||||||
|
|
||||||
def buildServiceItem(self, item=None, xmlVersion=False):
|
def buildServiceItem(self, item=None, xmlVersion=False, remote=False):
|
||||||
"""
|
"""
|
||||||
Common method for generating a service item
|
Common method for generating a service item
|
||||||
"""
|
"""
|
||||||
serviceItem = ServiceItem(self.plugin)
|
serviceItem = ServiceItem(self.plugin)
|
||||||
serviceItem.add_icon(self.plugin.icon_path)
|
serviceItem.add_icon(self.plugin.icon_path)
|
||||||
if self.generateSlideData(serviceItem, item, xmlVersion):
|
if self.generateSlideData(serviceItem, item, xmlVersion, remote):
|
||||||
return serviceItem
|
return serviceItem
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
@ -28,7 +28,9 @@
|
|||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import urllib
|
import urllib
|
||||||
|
import urllib2
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
from ConfigParser import SafeConfigParser
|
from ConfigParser import SafeConfigParser
|
||||||
|
|
||||||
@ -60,8 +62,13 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
files = self.webAccess.read()
|
files = self.webAccess.read()
|
||||||
self.config.readfp(io.BytesIO(files))
|
self.config.readfp(io.BytesIO(files))
|
||||||
self.updateScreenListCombo()
|
self.updateScreenListCombo()
|
||||||
|
self.downloadCanceled = False
|
||||||
self.downloading = unicode(translate('OpenLP.FirstTimeWizard',
|
self.downloading = unicode(translate('OpenLP.FirstTimeWizard',
|
||||||
'Downloading %s...'))
|
'Downloading %s...'))
|
||||||
|
QtCore.QObject.connect(self.cancelButton,QtCore.SIGNAL('clicked()'),
|
||||||
|
self.onCancelButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.noInternetFinishButton,
|
||||||
|
QtCore.SIGNAL('clicked()'), self.onNoInternetFinishButtonClicked)
|
||||||
QtCore.QObject.connect(self,
|
QtCore.QObject.connect(self,
|
||||||
QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged)
|
QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
@ -80,6 +87,10 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
"""
|
"""
|
||||||
self.restart()
|
self.restart()
|
||||||
check_directory_exists(os.path.join(gettempdir(), u'openlp'))
|
check_directory_exists(os.path.join(gettempdir(), u'openlp'))
|
||||||
|
self.noInternetFinishButton.setVisible(False)
|
||||||
|
# Check if this is a re-run of the wizard.
|
||||||
|
self.hasRunWizard = QtCore.QSettings().value(
|
||||||
|
u'general/has run wizard', QtCore.QVariant(False)).toBool()
|
||||||
# Sort out internet access for downloads
|
# Sort out internet access for downloads
|
||||||
if self.webAccess:
|
if self.webAccess:
|
||||||
songs = self.config.get(u'songs', u'languages')
|
songs = self.config.get(u'songs', u'languages')
|
||||||
@ -120,7 +131,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
title = self.config.get(u'theme_%s' % theme, u'title')
|
title = self.config.get(u'theme_%s' % theme, u'title')
|
||||||
filename = self.config.get(u'theme_%s' % theme, u'filename')
|
filename = self.config.get(u'theme_%s' % theme, u'filename')
|
||||||
screenshot = self.config.get(u'theme_%s' % theme, u'screenshot')
|
screenshot = self.config.get(u'theme_%s' % theme, u'screenshot')
|
||||||
urllib.urlretrieve(u'%s/%s' % (self.web, screenshot),
|
urllib.urlretrieve(u'%s%s' % (self.web, screenshot),
|
||||||
os.path.join(gettempdir(), u'openlp', screenshot))
|
os.path.join(gettempdir(), u'openlp', screenshot))
|
||||||
item = QtGui.QListWidgetItem(title, self.themesListWidget)
|
item = QtGui.QListWidgetItem(title, self.themesListWidget)
|
||||||
item.setData(QtCore.Qt.UserRole,
|
item.setData(QtCore.Qt.UserRole,
|
||||||
@ -152,16 +163,24 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
"""
|
"""
|
||||||
Detects Page changes and updates as approprate.
|
Detects Page changes and updates as approprate.
|
||||||
"""
|
"""
|
||||||
if pageId == FirstTimePage.Defaults:
|
# Keep track of the page we are at. Pressing "Cancel" causes pageId
|
||||||
|
# to be a -1.
|
||||||
|
if pageId != -1:
|
||||||
|
self.lastId = pageId
|
||||||
|
if pageId == FirstTimePage.Plugins:
|
||||||
|
# Set the no internet page text.
|
||||||
|
if self.hasRunWizard:
|
||||||
|
self.noInternetLabel.setText(self.noInternetText)
|
||||||
|
else:
|
||||||
|
self.noInternetLabel.setText(self.noInternetText +
|
||||||
|
self.cancelWizardText)
|
||||||
|
elif pageId == FirstTimePage.Defaults:
|
||||||
self.themeComboBox.clear()
|
self.themeComboBox.clear()
|
||||||
for iter in xrange(self.themesListWidget.count()):
|
for iter in xrange(self.themesListWidget.count()):
|
||||||
item = self.themesListWidget.item(iter)
|
item = self.themesListWidget.item(iter)
|
||||||
if item.checkState() == QtCore.Qt.Checked:
|
if item.checkState() == QtCore.Qt.Checked:
|
||||||
self.themeComboBox.addItem(item.text())
|
self.themeComboBox.addItem(item.text())
|
||||||
# Check if this is a re-run of the wizard.
|
if self.hasRunWizard:
|
||||||
self.has_run_wizard = QtCore.QSettings().value(
|
|
||||||
u'general/has run wizard', QtCore.QVariant(False)).toBool()
|
|
||||||
if self.has_run_wizard:
|
|
||||||
# Add any existing themes to list.
|
# Add any existing themes to list.
|
||||||
for theme in self.parent().themeManagerContents.getThemes():
|
for theme in self.parent().themeManagerContents.getThemes():
|
||||||
index = self.themeComboBox.findText(theme)
|
index = self.themeComboBox.findText(theme)
|
||||||
@ -173,6 +192,12 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
# Pre-select the current default theme.
|
# Pre-select the current default theme.
|
||||||
index = self.themeComboBox.findText(default_theme)
|
index = self.themeComboBox.findText(default_theme)
|
||||||
self.themeComboBox.setCurrentIndex(index)
|
self.themeComboBox.setCurrentIndex(index)
|
||||||
|
elif pageId == FirstTimePage.NoInternet:
|
||||||
|
self.backButton.setVisible(False)
|
||||||
|
self.nextButton.setVisible(False)
|
||||||
|
self.noInternetFinishButton.setVisible(True)
|
||||||
|
if self.hasRunWizard:
|
||||||
|
self.cancelButton.setVisible(False)
|
||||||
elif pageId == FirstTimePage.Progress:
|
elif pageId == FirstTimePage.Progress:
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
self._preWizard()
|
self._preWizard()
|
||||||
@ -192,6 +217,53 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
self.displayComboBox.addItems(self.screens.get_screen_list())
|
self.displayComboBox.addItems(self.screens.get_screen_list())
|
||||||
self.displayComboBox.setCurrentIndex(self.displayComboBox.count() - 1)
|
self.displayComboBox.setCurrentIndex(self.displayComboBox.count() - 1)
|
||||||
|
|
||||||
|
def onCancelButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Process the pressing of the cancel button.
|
||||||
|
"""
|
||||||
|
if self.lastId == FirstTimePage.NoInternet or \
|
||||||
|
(self.lastId <= FirstTimePage.Plugins and \
|
||||||
|
not self.hasRunWizard):
|
||||||
|
QtCore.QCoreApplication.exit()
|
||||||
|
sys.exit()
|
||||||
|
self.downloadCanceled = True
|
||||||
|
Receiver.send_message(u'cursor_normal')
|
||||||
|
|
||||||
|
def onNoInternetFinishButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Process the pressing of the "Finish" button on the No Internet page.
|
||||||
|
"""
|
||||||
|
Receiver.send_message(u'cursor_busy')
|
||||||
|
self._performWizard()
|
||||||
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
Receiver.send_message(u'cursor_normal')
|
||||||
|
QtCore.QSettings().setValue(u'general/has run wizard',
|
||||||
|
QtCore.QVariant(True))
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def urlGetFile(self, url, fpath):
|
||||||
|
""""
|
||||||
|
Download a file given a URL. The file is retrieved in chunks, giving
|
||||||
|
the ability to cancel the download at any point.
|
||||||
|
"""
|
||||||
|
block_count = 0
|
||||||
|
block_size = 4096
|
||||||
|
urlfile = urllib2.urlopen(url)
|
||||||
|
filesize = urlfile.headers["Content-Length"]
|
||||||
|
filename = open(fpath, "wb")
|
||||||
|
# Download until finished or canceled.
|
||||||
|
while not self.downloadCanceled:
|
||||||
|
data = urlfile.read(block_size)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
filename.write(data)
|
||||||
|
block_count += 1
|
||||||
|
self._downloadProgress(block_count, block_size, filesize)
|
||||||
|
filename.close()
|
||||||
|
# Delete file if canceled, it may be a partial file.
|
||||||
|
if self.downloadCanceled:
|
||||||
|
os.remove(fpath)
|
||||||
|
|
||||||
def _getFileSize(self, url):
|
def _getFileSize(self, url):
|
||||||
site = urllib.urlopen(url)
|
site = urllib.urlopen(url)
|
||||||
meta = site.info()
|
meta = site.info()
|
||||||
@ -271,7 +343,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
"""
|
"""
|
||||||
if self.max_progress:
|
if self.max_progress:
|
||||||
self.progressBar.setValue(self.progressBar.maximum())
|
self.progressBar.setValue(self.progressBar.maximum())
|
||||||
if self.has_run_wizard:
|
if self.hasRunWizard:
|
||||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||||
'Download complete.'
|
'Download complete.'
|
||||||
' Click the finish button to return to OpenLP.'))
|
' Click the finish button to return to OpenLP.'))
|
||||||
@ -280,7 +352,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
'Download complete.'
|
'Download complete.'
|
||||||
' Click the finish button to start OpenLP.'))
|
' Click the finish button to start OpenLP.'))
|
||||||
else:
|
else:
|
||||||
if self.has_run_wizard:
|
if self.hasRunWizard:
|
||||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||||
'Click the finish button to return to OpenLP.'))
|
'Click the finish button to return to OpenLP.'))
|
||||||
else:
|
else:
|
||||||
@ -309,42 +381,42 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
self._setPluginStatus(self.customCheckBox, u'custom/status')
|
self._setPluginStatus(self.customCheckBox, u'custom/status')
|
||||||
self._setPluginStatus(self.songUsageCheckBox, u'songusage/status')
|
self._setPluginStatus(self.songUsageCheckBox, u'songusage/status')
|
||||||
self._setPluginStatus(self.alertCheckBox, u'alerts/status')
|
self._setPluginStatus(self.alertCheckBox, u'alerts/status')
|
||||||
# Build directories for downloads
|
if self.webAccess:
|
||||||
songs_destination = os.path.join(unicode(gettempdir()), u'openlp')
|
# Build directories for downloads
|
||||||
bibles_destination = AppLocation.get_section_data_path(u'bibles')
|
songs_destination = os.path.join(unicode(gettempdir()), u'openlp')
|
||||||
themes_destination = AppLocation.get_section_data_path(u'themes')
|
bibles_destination = AppLocation.get_section_data_path(u'bibles')
|
||||||
# Download songs
|
themes_destination = AppLocation.get_section_data_path(u'themes')
|
||||||
for i in xrange(self.songsListWidget.count()):
|
# Download songs
|
||||||
item = self.songsListWidget.item(i)
|
for i in xrange(self.songsListWidget.count()):
|
||||||
if item.checkState() == QtCore.Qt.Checked:
|
item = self.songsListWidget.item(i)
|
||||||
filename = item.data(QtCore.Qt.UserRole).toString()
|
if item.checkState() == QtCore.Qt.Checked:
|
||||||
self._incrementProgressBar(self.downloading % filename, 0)
|
filename = item.data(QtCore.Qt.UserRole).toString()
|
||||||
self.previous_size = 0
|
self._incrementProgressBar(self.downloading % filename, 0)
|
||||||
destination = os.path.join(songs_destination, unicode(filename))
|
self.previous_size = 0
|
||||||
urllib.urlretrieve(u'%s%s' % (self.web, filename), destination,
|
destination = os.path.join(songs_destination,
|
||||||
self._downloadProgress)
|
unicode(filename))
|
||||||
# Download Bibles
|
self.urlGetFile(u'%s%s' % (self.web, filename), destination)
|
||||||
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
|
# Download Bibles
|
||||||
while bibles_iterator.value():
|
bibles_iterator = QtGui.QTreeWidgetItemIterator(
|
||||||
item = bibles_iterator.value()
|
self.biblesTreeWidget)
|
||||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
while bibles_iterator.value():
|
||||||
bible = unicode(item.data(0, QtCore.Qt.UserRole).toString())
|
item = bibles_iterator.value()
|
||||||
self._incrementProgressBar(self.downloading % bible, 0)
|
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||||
self.previous_size = 0
|
bible = unicode(item.data(0, QtCore.Qt.UserRole).toString())
|
||||||
urllib.urlretrieve(u'%s%s' % (self.web, bible),
|
self._incrementProgressBar(self.downloading % bible, 0)
|
||||||
os.path.join(bibles_destination, bible),
|
self.previous_size = 0
|
||||||
self._downloadProgress)
|
self.urlGetFile(u'%s%s' % (self.web, bible),
|
||||||
bibles_iterator += 1
|
os.path.join(bibles_destination, bible))
|
||||||
# Download themes
|
bibles_iterator += 1
|
||||||
for i in xrange(self.themesListWidget.count()):
|
# Download themes
|
||||||
item = self.themesListWidget.item(i)
|
for i in xrange(self.themesListWidget.count()):
|
||||||
if item.checkState() == QtCore.Qt.Checked:
|
item = self.themesListWidget.item(i)
|
||||||
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
if item.checkState() == QtCore.Qt.Checked:
|
||||||
self._incrementProgressBar(self.downloading % theme, 0)
|
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
self.previous_size = 0
|
self._incrementProgressBar(self.downloading % theme, 0)
|
||||||
urllib.urlretrieve(u'%s%s' % (self.web, theme),
|
self.previous_size = 0
|
||||||
os.path.join(themes_destination, theme),
|
self.urlGetFile(u'%s%s' % (self.web, theme),
|
||||||
self._downloadProgress)
|
os.path.join(themes_destination, theme))
|
||||||
# Set Default Display
|
# Set Default Display
|
||||||
if self.displayComboBox.currentIndex() != -1:
|
if self.displayComboBox.currentIndex() != -1:
|
||||||
QtCore.QSettings().setValue(u'General/monitor',
|
QtCore.QSettings().setValue(u'General/monitor',
|
||||||
|
@ -51,8 +51,10 @@ class Ui_FirstTimeWizard(object):
|
|||||||
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||||
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages |
|
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages |
|
||||||
QtGui.QWizard.NoBackButtonOnStartPage |
|
QtGui.QWizard.NoBackButtonOnStartPage |
|
||||||
QtGui.QWizard.NoBackButtonOnLastPage)
|
QtGui.QWizard.NoBackButtonOnLastPage |
|
||||||
|
QtGui.QWizard.HaveCustomButton1)
|
||||||
self.finishButton = self.button(QtGui.QWizard.FinishButton)
|
self.finishButton = self.button(QtGui.QWizard.FinishButton)
|
||||||
|
self.noInternetFinishButton = self.button(QtGui.QWizard.CustomButton1)
|
||||||
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
|
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
|
||||||
self.nextButton = self.button(QtGui.QWizard.NextButton)
|
self.nextButton = self.button(QtGui.QWizard.NextButton)
|
||||||
self.backButton = self.button(QtGui.QWizard.BackButton)
|
self.backButton = self.button(QtGui.QWizard.BackButton)
|
||||||
@ -189,9 +191,7 @@ class Ui_FirstTimeWizard(object):
|
|||||||
self.progressBar.setObjectName(u'progressBar')
|
self.progressBar.setObjectName(u'progressBar')
|
||||||
self.progressLayout.addWidget(self.progressBar)
|
self.progressLayout.addWidget(self.progressBar)
|
||||||
FirstTimeWizard.setPage(FirstTimePage.Progress, self.progressPage)
|
FirstTimeWizard.setPage(FirstTimePage.Progress, self.progressPage)
|
||||||
|
|
||||||
self.retranslateUi(FirstTimeWizard)
|
self.retranslateUi(FirstTimeWizard)
|
||||||
QtCore.QMetaObject.connectSlotsByName(FirstTimeWizard)
|
|
||||||
|
|
||||||
def retranslateUi(self, FirstTimeWizard):
|
def retranslateUi(self, FirstTimeWizard):
|
||||||
FirstTimeWizard.setWindowTitle(translate(
|
FirstTimeWizard.setWindowTitle(translate(
|
||||||
@ -230,14 +230,17 @@ class Ui_FirstTimeWizard(object):
|
|||||||
self.noInternetPage.setSubTitle(translate(
|
self.noInternetPage.setSubTitle(translate(
|
||||||
'OpenLP.FirstTimeWizard',
|
'OpenLP.FirstTimeWizard',
|
||||||
'Unable to detect an Internet connection.'))
|
'Unable to detect an Internet connection.'))
|
||||||
self.noInternetLabel.setText(translate('OpenLP.FirstTimeWizard',
|
self.noInternetText = translate('OpenLP.FirstTimeWizard',
|
||||||
'No Internet connection was found. The First Time Wizard needs an '
|
'No Internet connection was found. The First Time Wizard needs an '
|
||||||
'Internet connection in order to be able to download sample '
|
'Internet connection in order to be able to download sample '
|
||||||
'songs, Bibles and themes.\n\nTo re-run the First Time Wizard and '
|
'songs, Bibles and themes. Press the Finish button now to start '
|
||||||
'import this sample data at a later stage, press the cancel '
|
'OpenLP with initial settings and no sample data.\n\nTo re-run the '
|
||||||
'button now, check your Internet connection, and restart OpenLP.'
|
'First Time Wizard and import this sample data at a later time, '
|
||||||
'\n\nTo cancel the First Time Wizard completely, press the finish '
|
'check your Internet connection and re-run this wizard by '
|
||||||
'button now.'))
|
'selecting "Tools/Re-run First Time Wizard" from OpenLP.')
|
||||||
|
self.cancelWizardText = translate('OpenLP.FirstTimeWizard',
|
||||||
|
'\n\nTo cancel the First Time Wizard completely (and not start '
|
||||||
|
'OpenLP), press the Cancel button now.')
|
||||||
self.songsPage.setTitle(translate('OpenLP.FirstTimeWizard',
|
self.songsPage.setTitle(translate('OpenLP.FirstTimeWizard',
|
||||||
'Sample Songs'))
|
'Sample Songs'))
|
||||||
self.songsPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
|
self.songsPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
|
||||||
@ -260,3 +263,5 @@ class Ui_FirstTimeWizard(object):
|
|||||||
'Select default theme:'))
|
'Select default theme:'))
|
||||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||||
'Starting configuration process...'))
|
'Starting configuration process...'))
|
||||||
|
FirstTimeWizard.setButtonText(QtGui.QWizard.CustomButton1,
|
||||||
|
translate('OpenLP.FirstTimeWizard', 'Finish'))
|
||||||
|
@ -170,6 +170,15 @@ class GeneralTab(SettingsTab):
|
|||||||
self.customHeightValueEdit.setMaximum(9999)
|
self.customHeightValueEdit.setMaximum(9999)
|
||||||
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
|
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
|
||||||
self.rightLayout.addWidget(self.displayGroupBox)
|
self.rightLayout.addWidget(self.displayGroupBox)
|
||||||
|
# Background audio
|
||||||
|
self.audioGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
|
self.audioGroupBox.setObjectName(u'audioGroupBox')
|
||||||
|
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
|
||||||
|
self.audioLayout.setObjectName(u'audioLayout')
|
||||||
|
self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
|
||||||
|
self.startPausedCheckBox.setObjectName(u'startPausedCheckBox')
|
||||||
|
self.audioLayout.addWidget(self.startPausedCheckBox)
|
||||||
|
self.rightLayout.addWidget(self.audioGroupBox)
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
QtCore.QObject.connect(self.overrideCheckBox,
|
QtCore.QObject.connect(self.overrideCheckBox,
|
||||||
@ -243,6 +252,10 @@ class GeneralTab(SettingsTab):
|
|||||||
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
|
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
|
||||||
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
|
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
|
||||||
self.customWidthLabel.setText(translate('OpenLP.GeneralTab', 'Width'))
|
self.customWidthLabel.setText(translate('OpenLP.GeneralTab', 'Width'))
|
||||||
|
self.audioGroupBox.setTitle(
|
||||||
|
translate('OpenLP.GeneralTab', 'Background Audio'))
|
||||||
|
self.startPausedCheckBox.setText(
|
||||||
|
translate('OpenLP.GeneralTab', 'Start background audio paused'))
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
"""
|
"""
|
||||||
@ -290,6 +303,8 @@ class GeneralTab(SettingsTab):
|
|||||||
QtCore.QVariant(self.screens.current[u'size'].height())).toInt()[0])
|
QtCore.QVariant(self.screens.current[u'size'].height())).toInt()[0])
|
||||||
self.customWidthValueEdit.setValue(settings.value(u'width',
|
self.customWidthValueEdit.setValue(settings.value(u'width',
|
||||||
QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
|
QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
|
||||||
|
self.startPausedCheckBox.setChecked(settings.value(
|
||||||
|
u'audio start paused', QtCore.QVariant(True)).toBool())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||||
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
|
||||||
@ -341,6 +356,8 @@ class GeneralTab(SettingsTab):
|
|||||||
QtCore.QVariant(self.customWidthValueEdit.value()))
|
QtCore.QVariant(self.customWidthValueEdit.value()))
|
||||||
settings.setValue(u'override position',
|
settings.setValue(u'override position',
|
||||||
QtCore.QVariant(self.overrideCheckBox.isChecked()))
|
QtCore.QVariant(self.overrideCheckBox.isChecked()))
|
||||||
|
settings.setValue(u'audio start paused',
|
||||||
|
QtCore.QVariant(self.startPausedCheckBox.isChecked()))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
# On save update the screens as well
|
# On save update the screens as well
|
||||||
self.postSetUp(True)
|
self.postSetUp(True)
|
||||||
|
@ -540,6 +540,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.uiSettingsSection = u'user interface'
|
self.uiSettingsSection = u'user interface'
|
||||||
self.generalSettingsSection = u'general'
|
self.generalSettingsSection = u'general'
|
||||||
self.advancedlSettingsSection = u'advanced'
|
self.advancedlSettingsSection = u'advanced'
|
||||||
|
self.shortcutsSettingsSection = u'shortcuts'
|
||||||
self.servicemanagerSettingsSection = u'servicemanager'
|
self.servicemanagerSettingsSection = u'servicemanager'
|
||||||
self.songsSettingsSection = u'songs'
|
self.songsSettingsSection = u'songs'
|
||||||
self.themesSettingsSection = u'themes'
|
self.themesSettingsSection = u'themes'
|
||||||
@ -775,25 +776,25 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
return
|
return
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
screens = ScreenList.get_instance()
|
screens = ScreenList.get_instance()
|
||||||
if FirstTimeForm(screens, self).exec_() == QtGui.QDialog.Accepted:
|
FirstTimeForm(screens, self).exec_()
|
||||||
self.firstTime()
|
self.firstTime()
|
||||||
for plugin in self.pluginManager.plugins:
|
for plugin in self.pluginManager.plugins:
|
||||||
self.activePlugin = plugin
|
self.activePlugin = plugin
|
||||||
oldStatus = self.activePlugin.status
|
oldStatus = self.activePlugin.status
|
||||||
self.activePlugin.setStatus()
|
self.activePlugin.setStatus()
|
||||||
if oldStatus != self.activePlugin.status:
|
if oldStatus != self.activePlugin.status:
|
||||||
if self.activePlugin.status == PluginStatus.Active:
|
if self.activePlugin.status == PluginStatus.Active:
|
||||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||||
self.activePlugin.appStartup()
|
self.activePlugin.appStartup()
|
||||||
else:
|
else:
|
||||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||||
self.themeManagerContents.configUpdated()
|
self.themeManagerContents.configUpdated()
|
||||||
self.themeManagerContents.loadThemes(True)
|
self.themeManagerContents.loadThemes(True)
|
||||||
Receiver.send_message(u'theme_update_global',
|
Receiver.send_message(u'theme_update_global',
|
||||||
self.themeManagerContents.global_theme)
|
self.themeManagerContents.global_theme)
|
||||||
# Check if any Bibles downloaded. If there are, they will be
|
# Check if any Bibles downloaded. If there are, they will be
|
||||||
# processed.
|
# processed.
|
||||||
Receiver.send_message(u'bibles_load_list', True)
|
Receiver.send_message(u'bibles_load_list', True)
|
||||||
|
|
||||||
def blankCheck(self):
|
def blankCheck(self):
|
||||||
"""
|
"""
|
||||||
@ -913,42 +914,43 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtGui.QMessageBox.No)
|
QtGui.QMessageBox.No)
|
||||||
if answer == QtGui.QMessageBox.No:
|
if answer == QtGui.QMessageBox.No:
|
||||||
return
|
return
|
||||||
importFileName = unicode(QtGui.QFileDialog.getOpenFileName(self,
|
import_file_name = unicode(QtGui.QFileDialog.getOpenFileName(self,
|
||||||
translate('OpenLP.MainWindow', 'Open File'),
|
translate('OpenLP.MainWindow', 'Open File'),
|
||||||
'',
|
'',
|
||||||
translate('OpenLP.MainWindow',
|
translate('OpenLP.MainWindow',
|
||||||
'OpenLP Export Settings Files (*.conf)')))
|
'OpenLP Export Settings Files (*.conf)')))
|
||||||
if not importFileName:
|
if not import_file_name:
|
||||||
return
|
return
|
||||||
settingSections = []
|
setting_sections = []
|
||||||
# Add main sections.
|
# Add main sections.
|
||||||
settingSections.extend([self.generalSettingsSection])
|
setting_sections.extend([self.generalSettingsSection])
|
||||||
settingSections.extend([self.advancedlSettingsSection])
|
setting_sections.extend([self.advancedlSettingsSection])
|
||||||
settingSections.extend([self.uiSettingsSection])
|
setting_sections.extend([self.uiSettingsSection])
|
||||||
settingSections.extend([self.servicemanagerSettingsSection])
|
setting_sections.extend([self.shortcutsSettingsSection])
|
||||||
settingSections.extend([self.themesSettingsSection])
|
setting_sections.extend([self.servicemanagerSettingsSection])
|
||||||
settingSections.extend([self.displayTagsSection])
|
setting_sections.extend([self.themesSettingsSection])
|
||||||
settingSections.extend([self.headerSection])
|
setting_sections.extend([self.displayTagsSection])
|
||||||
|
setting_sections.extend([self.headerSection])
|
||||||
# Add plugin sections.
|
# Add plugin sections.
|
||||||
for plugin in self.pluginManager.plugins:
|
for plugin in self.pluginManager.plugins:
|
||||||
settingSections.extend([plugin.name])
|
setting_sections.extend([plugin.name])
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
importSettings = QtCore.QSettings(importFileName,
|
import_settings = QtCore.QSettings(import_file_name,
|
||||||
QtCore.QSettings.IniFormat)
|
QtCore.QSettings.IniFormat)
|
||||||
importKeys = importSettings.allKeys()
|
import_keys = import_settings.allKeys()
|
||||||
for sectionKey in importKeys:
|
for section_key in import_keys:
|
||||||
# We need to handle the really bad files.
|
# We need to handle the really bad files.
|
||||||
try:
|
try:
|
||||||
section, key = sectionKey.split(u'/')
|
section, key = section_key.split(u'/')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
section = u'unknown'
|
section = u'unknown'
|
||||||
key = u''
|
key = u''
|
||||||
# Switch General back to lowercase.
|
# Switch General back to lowercase.
|
||||||
if section == u'General':
|
if section == u'General':
|
||||||
section = u'general'
|
section = u'general'
|
||||||
sectionKey = section + "/" + key
|
section_key = section + "/" + key
|
||||||
# Make sure it's a valid section for us.
|
# Make sure it's a valid section for us.
|
||||||
if not section in settingSections:
|
if not section in setting_sections:
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('OpenLP.MainWindow', 'Import settings'),
|
translate('OpenLP.MainWindow', 'Import settings'),
|
||||||
translate('OpenLP.MainWindow',
|
translate('OpenLP.MainWindow',
|
||||||
@ -961,13 +963,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtGui.QMessageBox.Ok))
|
QtGui.QMessageBox.Ok))
|
||||||
return
|
return
|
||||||
# We have a good file, import it.
|
# We have a good file, import it.
|
||||||
for sectionKey in importKeys:
|
for section_key in import_keys:
|
||||||
value = importSettings.value(sectionKey)
|
value = import_settings.value(section_key)
|
||||||
settings.setValue(u'%s' % (sectionKey) ,
|
settings.setValue(u'%s' % (section_key) ,
|
||||||
QtCore.QVariant(value))
|
QtCore.QVariant(value))
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
settings.beginGroup(self.headerSection)
|
settings.beginGroup(self.headerSection)
|
||||||
settings.setValue( u'file_imported' , QtCore.QVariant(importFileName))
|
settings.setValue( u'file_imported' , QtCore.QVariant(import_file_name))
|
||||||
settings.setValue(u'file_date_imported',
|
settings.setValue(u'file_date_imported',
|
||||||
now.strftime("%Y-%m-%d %H:%M"))
|
now.strftime("%Y-%m-%d %H:%M"))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
@ -986,78 +988,76 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.cleanUp()
|
self.cleanUp()
|
||||||
QtCore.QCoreApplication.exit()
|
QtCore.QCoreApplication.exit()
|
||||||
|
|
||||||
def onSettingsExportItemClicked(self, exportFileName=None):
|
def onSettingsExportItemClicked(self):
|
||||||
"""
|
"""
|
||||||
Export settings to an INI file
|
Export settings to a .conf file in INI format
|
||||||
"""
|
"""
|
||||||
if not exportFileName:
|
export_file_name = unicode(QtGui.QFileDialog.getSaveFileName(self,
|
||||||
exportFileName = unicode(QtGui.QFileDialog.getSaveFileName(self,
|
translate('OpenLP.MainWindow', 'Export Settings File'), '',
|
||||||
translate('OpenLP.MainWindow', 'Export Settings File'), '',
|
translate('OpenLP.MainWindow',
|
||||||
translate('OpenLP.MainWindow',
|
'OpenLP Export Settings File (*.conf)')))
|
||||||
'OpenLP Export Settings File (*.conf)')))
|
if not export_file_name:
|
||||||
if not exportFileName:
|
|
||||||
return
|
return
|
||||||
# Make sure it's an .ini file.
|
# Make sure it's a .conf file.
|
||||||
if not exportFileName.endswith(u'conf'):
|
if not export_file_name.endswith(u'conf'):
|
||||||
exportFileName = exportFileName + u'.conf'
|
export_file_name = export_file_name + u'.conf'
|
||||||
temp_file = os.path.join(unicode(gettempdir()),
|
temp_file = os.path.join(unicode(gettempdir()),
|
||||||
u'openlp', u'exportIni.tmp')
|
u'openlp', u'exportConf.tmp')
|
||||||
self.saveSettings()
|
self.saveSettings()
|
||||||
settingSections = []
|
setting_sections = []
|
||||||
# Add main sections.
|
# Add main sections.
|
||||||
settingSections.extend([self.generalSettingsSection])
|
setting_sections.extend([self.generalSettingsSection])
|
||||||
settingSections.extend([self.advancedlSettingsSection])
|
setting_sections.extend([self.advancedlSettingsSection])
|
||||||
settingSections.extend([self.uiSettingsSection])
|
setting_sections.extend([self.uiSettingsSection])
|
||||||
settingSections.extend([self.servicemanagerSettingsSection])
|
setting_sections.extend([self.shortcutsSettingsSection])
|
||||||
settingSections.extend([self.themesSettingsSection])
|
setting_sections.extend([self.servicemanagerSettingsSection])
|
||||||
settingSections.extend([self.displayTagsSection])
|
setting_sections.extend([self.themesSettingsSection])
|
||||||
|
setting_sections.extend([self.displayTagsSection])
|
||||||
# Add plugin sections.
|
# Add plugin sections.
|
||||||
for plugin in self.pluginManager.plugins:
|
for plugin in self.pluginManager.plugins:
|
||||||
settingSections.extend([plugin.name])
|
setting_sections.extend([plugin.name])
|
||||||
# Delete old files if found.
|
# Delete old files if found.
|
||||||
if os.path.exists(temp_file):
|
if os.path.exists(temp_file):
|
||||||
os.remove(temp_file)
|
os.remove(temp_file)
|
||||||
if os.path.exists(exportFileName):
|
if os.path.exists(export_file_name):
|
||||||
os.remove(exportFileName)
|
os.remove(export_file_name)
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
settings.remove(self.headerSection)
|
settings.remove(self.headerSection)
|
||||||
# Get the settings.
|
# Get the settings.
|
||||||
keys = settings.allKeys()
|
keys = settings.allKeys()
|
||||||
exportSettings = QtCore.QSettings(temp_file,
|
export_settings = QtCore.QSettings(temp_file,
|
||||||
QtCore.QSettings.IniFormat)
|
QtCore.QSettings.IniFormat)
|
||||||
# Add a header section.
|
# Add a header section.
|
||||||
# This is to insure it's our ini file for import.
|
# This is to insure it's our conf file for import.
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
applicationVersion = get_application_version()
|
application_version = get_application_version()
|
||||||
# Write INI format using Qsettings.
|
# Write INI format using Qsettings.
|
||||||
# Write our header.
|
# Write our header.
|
||||||
exportSettings.beginGroup(self.headerSection)
|
export_settings.beginGroup(self.headerSection)
|
||||||
exportSettings.setValue(u'Make_Changes', u'At_Own_RISK')
|
export_settings.setValue(u'Make_Changes', u'At_Own_RISK')
|
||||||
exportSettings.setValue(u'type', u'OpenLP_settings_export')
|
export_settings.setValue(u'type', u'OpenLP_settings_export')
|
||||||
exportSettings.setValue(u'file_date_created',
|
export_settings.setValue(u'file_date_created',
|
||||||
now.strftime("%Y-%m-%d %H:%M"))
|
now.strftime("%Y-%m-%d %H:%M"))
|
||||||
exportSettings.setValue(u'version', applicationVersion[u'full'])
|
export_settings.setValue(u'version', application_version[u'full'])
|
||||||
exportSettings.endGroup()
|
export_settings.endGroup()
|
||||||
# Write all the sections and keys.
|
# Write all the sections and keys.
|
||||||
for sectionKey in keys:
|
for section_key in keys:
|
||||||
section, key = sectionKey.split(u'/')
|
section, key = section_key.split(u'/')
|
||||||
keyValue = settings.value(sectionKey)
|
key_value = settings.value(section_key)
|
||||||
sectionKey = section + u"/" + key
|
export_settings.setValue(section_key, key_value)
|
||||||
# Change the service section to servicemanager.
|
export_settings.sync()
|
||||||
if section == u'service':
|
# Temp CONF file has been written. Blanks in keys are now '%20'.
|
||||||
sectionKey = u'servicemanager/' + key
|
# Read the temp file and output the user's CONF file with blanks to
|
||||||
exportSettings.setValue(sectionKey, keyValue)
|
|
||||||
exportSettings.sync()
|
|
||||||
# Temp INI file has been written. Blanks in keys are now '%20'.
|
|
||||||
# Read the temp file and output the user's INI file with blanks to
|
|
||||||
# make it more readable.
|
# make it more readable.
|
||||||
tempIni = open(temp_file, u'r')
|
temp_conf = open(temp_file, u'r')
|
||||||
exportIni = open(exportFileName, u'w')
|
export_conf = open(export_file_name, u'w')
|
||||||
for fileRecord in tempIni:
|
for file_record in temp_conf:
|
||||||
fileRecord = fileRecord.replace(u'%20', u' ')
|
# Get rid of any invalid entries.
|
||||||
exportIni.write(fileRecord)
|
if file_record.find(u'@Invalid()') == -1:
|
||||||
tempIni.close()
|
file_record = file_record.replace(u'%20', u' ')
|
||||||
exportIni.close()
|
export_conf.write(file_record)
|
||||||
|
temp_conf.close()
|
||||||
|
export_conf.close()
|
||||||
os.remove(temp_file)
|
os.remove(temp_file)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1291,6 +1291,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'Loading QSettings')
|
log.debug(u'Loading QSettings')
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
|
# Remove obsolete entries.
|
||||||
|
settings.remove(u'custom slide')
|
||||||
|
settings.remove(u'service')
|
||||||
settings.beginGroup(self.generalSettingsSection)
|
settings.beginGroup(self.generalSettingsSection)
|
||||||
self.recentFiles = settings.value(u'recent files').toStringList()
|
self.recentFiles = settings.value(u'recent files').toStringList()
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
@ -633,7 +633,14 @@ class SlideController(QtGui.QWidget):
|
|||||||
log.debug(u'Starting to play...')
|
log.debug(u'Starting to play...')
|
||||||
self.display.audioPlayer.addToPlaylist(
|
self.display.audioPlayer.addToPlaylist(
|
||||||
self.serviceItem.background_audio)
|
self.serviceItem.background_audio)
|
||||||
self.display.audioPlayer.play()
|
if QtCore.QSettings().value(
|
||||||
|
self.parent().generalSettingsSection + \
|
||||||
|
u'/audio start paused',
|
||||||
|
QtCore.QVariant(True)).toBool():
|
||||||
|
self.audioPauseItem.setChecked(True)
|
||||||
|
self.display.audioPlayer.pause()
|
||||||
|
else:
|
||||||
|
self.display.audioPlayer.play()
|
||||||
self.setAudioItemsVisibility(True)
|
self.setAudioItemsVisibility(True)
|
||||||
row = 0
|
row = 0
|
||||||
text = []
|
text = []
|
||||||
@ -784,6 +791,8 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.onBlankDisplay(True)
|
self.onBlankDisplay(True)
|
||||||
else:
|
else:
|
||||||
Receiver.send_message(u'maindisplay_show')
|
Receiver.send_message(u'maindisplay_show')
|
||||||
|
else:
|
||||||
|
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
|
||||||
|
|
||||||
def onSlideBlank(self):
|
def onSlideBlank(self):
|
||||||
"""
|
"""
|
||||||
|
@ -788,7 +788,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
items.append(bible_verse)
|
items.append(bible_verse)
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
"""
|
"""
|
||||||
Generates and formats the slides for the service item as well as the
|
Generates and formats the slides for the service item as well as the
|
||||||
service item's title.
|
service item's title.
|
||||||
|
@ -222,7 +222,8 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
def onFocus(self):
|
def onFocus(self):
|
||||||
self.searchTextEdit.setFocus()
|
self.searchTextEdit.setFocus()
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
raw_footer = []
|
raw_footer = []
|
||||||
slide = None
|
slide = None
|
||||||
theme = None
|
theme = None
|
||||||
|
@ -99,6 +99,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
Remove an image item from the list
|
Remove an image item from the list
|
||||||
"""
|
"""
|
||||||
|
# Turn off auto preview triggers.
|
||||||
|
self.listView.blockSignals(True)
|
||||||
if check_item_selected(self.listView, translate('ImagePlugin.MediaItem',
|
if check_item_selected(self.listView, translate('ImagePlugin.MediaItem',
|
||||||
'You must select an image to delete.')):
|
'You must select an image to delete.')):
|
||||||
row_list = [item.row() for item in self.listView.selectedIndexes()]
|
row_list = [item.row() for item in self.listView.selectedIndexes()]
|
||||||
@ -111,6 +113,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
self.listView.takeItem(row)
|
self.listView.takeItem(row)
|
||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
u'images', self.getFileList())
|
u'images', self.getFileList())
|
||||||
|
self.listView.blockSignals(False)
|
||||||
|
|
||||||
def loadList(self, images, initialLoad=False):
|
def loadList(self, images, initialLoad=False):
|
||||||
if not initialLoad:
|
if not initialLoad:
|
||||||
@ -139,7 +142,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
if not initialLoad:
|
if not initialLoad:
|
||||||
self.plugin.formparent.finishedProgressBar()
|
self.plugin.formparent.finishedProgressBar()
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
|
background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
|
||||||
+ u'/background color', QtCore.QVariant(u'#000000')))
|
+ u'/background color', QtCore.QVariant(u'#000000')))
|
||||||
if item:
|
if item:
|
||||||
@ -166,11 +170,12 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
items.remove(item)
|
items.remove(item)
|
||||||
# We cannot continue, as all images do not exist.
|
# We cannot continue, as all images do not exist.
|
||||||
if not items:
|
if not items:
|
||||||
critical_error_message_box(
|
if not remote:
|
||||||
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
critical_error_message_box(
|
||||||
unicode(translate('ImagePlugin.MediaItem',
|
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||||
'The following image(s) no longer exist: %s')) %
|
unicode(translate('ImagePlugin.MediaItem',
|
||||||
u'\n'.join(missing_items_filenames))
|
'The following image(s) no longer exist: %s')) %
|
||||||
|
u'\n'.join(missing_items_filenames))
|
||||||
return False
|
return False
|
||||||
# We have missing as well as existing images. We ask what to do.
|
# We have missing as well as existing images. We ask what to do.
|
||||||
elif missing_items and QtGui.QMessageBox.question(self,
|
elif missing_items and QtGui.QMessageBox.question(self,
|
||||||
|
@ -129,18 +129,20 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
'There was a problem replacing your background, '
|
'There was a problem replacing your background, '
|
||||||
'the media file "%s" no longer exists.')) % filename)
|
'the media file "%s" no longer exists.')) % filename)
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
if item is None:
|
if item is None:
|
||||||
item = self.listView.currentItem()
|
item = self.listView.currentItem()
|
||||||
if item is None:
|
if item is None:
|
||||||
return False
|
return False
|
||||||
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
|
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
# File is no longer present
|
if not remote:
|
||||||
critical_error_message_box(
|
# File is no longer present
|
||||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
critical_error_message_box(
|
||||||
unicode(translate('MediaPlugin.MediaItem',
|
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||||
'The file %s no longer exists.')) % filename)
|
unicode(translate('MediaPlugin.MediaItem',
|
||||||
|
'The file %s no longer exists.')) % filename)
|
||||||
return False
|
return False
|
||||||
self.mediaObject.stop()
|
self.mediaObject.stop()
|
||||||
self.mediaObject.clearQueue()
|
self.mediaObject.clearQueue()
|
||||||
|
@ -233,7 +233,8 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
u'presentations', self.getFileList())
|
u'presentations', self.getFileList())
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
"""
|
"""
|
||||||
Load the relevant information for displaying the presentation
|
Load the relevant information for displaying the presentation
|
||||||
in the slidecontroller. In the case of powerpoints, an image
|
in the slidecontroller. In the case of powerpoints, an image
|
||||||
@ -275,12 +276,13 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
# File is no longer present
|
# File is no longer present
|
||||||
critical_error_message_box(
|
if not remote:
|
||||||
translate('PresentationPlugin.MediaItem',
|
critical_error_message_box(
|
||||||
'Missing Presentation'),
|
translate('PresentationPlugin.MediaItem',
|
||||||
unicode(translate('PresentationPlugin.MediaItem',
|
'Missing Presentation'),
|
||||||
'The Presentation %s is incomplete,'
|
unicode(translate('PresentationPlugin.MediaItem',
|
||||||
' please reload.')) % filename)
|
'The Presentation %s is incomplete,'
|
||||||
|
' please reload.')) % filename)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# File is no longer present
|
# File is no longer present
|
||||||
|
@ -528,7 +528,7 @@ class HttpConnection(object):
|
|||||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||||
plugin.mediaItem.goLive(id)
|
plugin.mediaItem.goLive(id, remote=True)
|
||||||
|
|
||||||
def add_to_service(self, type):
|
def add_to_service(self, type):
|
||||||
"""
|
"""
|
||||||
@ -538,7 +538,7 @@ class HttpConnection(object):
|
|||||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||||
item_id = plugin.mediaItem.createItemFromId(id)
|
item_id = plugin.mediaItem.createItemFromId(id)
|
||||||
plugin.mediaItem.addToService(item_id)
|
plugin.mediaItem.addToService(item_id, remote=True)
|
||||||
|
|
||||||
def send_response(self, response):
|
def send_response(self, response):
|
||||||
http = u'HTTP/1.1 %s\r\n' % response.code
|
http = u'HTTP/1.1 %s\r\n' % response.code
|
||||||
|
@ -686,7 +686,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
def performWizard(self):
|
def performWizard(self):
|
||||||
"""
|
"""
|
||||||
Perform the actual import. This method pulls in the correct importer
|
Perform the actual import. This method pulls in the correct importer
|
||||||
class, and then runs the ``do_import`` method of the importer to do
|
class, and then runs the ``doImport`` method of the importer to do
|
||||||
the actual importing.
|
the actual importing.
|
||||||
"""
|
"""
|
||||||
source_format = self.formatComboBox.currentIndex()
|
source_format = self.formatComboBox.currentIndex()
|
||||||
@ -759,8 +759,8 @@ class SongImportForm(OpenLPWizard):
|
|||||||
importer = self.plugin.importSongs(SongFormat.FoilPresenter,
|
importer = self.plugin.importSongs(SongFormat.FoilPresenter,
|
||||||
filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
|
filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
|
||||||
)
|
)
|
||||||
importer.do_import()
|
importer.doImport()
|
||||||
if importer.error_log:
|
if importer.errorLog:
|
||||||
self.progressLabel.setText(translate(
|
self.progressLabel.setText(translate(
|
||||||
'SongsPlugin.SongImportForm', 'Your song import failed.'))
|
'SongsPlugin.SongImportForm', 'Your song import failed.'))
|
||||||
else:
|
else:
|
||||||
|
@ -55,13 +55,13 @@ class CCLIFileImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Import either a ``.usr`` or a ``.txt`` SongSelect file.
|
Import either a ``.usr`` or a ``.txt`` SongSelect file.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Starting CCLI File Import')
|
log.debug(u'Starting CCLI File Import')
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for filename in self.import_source:
|
for filename in self.importSource:
|
||||||
filename = unicode(filename)
|
filename = unicode(filename)
|
||||||
log.debug(u'Importing CCLI File: %s', filename)
|
log.debug(u'Importing CCLI File: %s', filename)
|
||||||
lines = []
|
lines = []
|
||||||
@ -80,23 +80,23 @@ class CCLIFileImport(SongImport):
|
|||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
if ext.lower() == u'.usr':
|
if ext.lower() == u'.usr':
|
||||||
log.info(u'SongSelect .usr format file found: %s', filename)
|
log.info(u'SongSelect .usr format file found: %s', filename)
|
||||||
if not self.do_import_usr_file(lines):
|
if not self.doImportUsrFile(lines):
|
||||||
self.log_error(filename)
|
self.logError(filename)
|
||||||
elif ext.lower() == u'.txt':
|
elif ext.lower() == u'.txt':
|
||||||
log.info(u'SongSelect .txt format file found: %s', filename)
|
log.info(u'SongSelect .txt format file found: %s', filename)
|
||||||
if not self.do_import_txt_file(lines):
|
if not self.doImportTxtFile(lines):
|
||||||
self.log_error(filename)
|
self.logError(filename)
|
||||||
else:
|
else:
|
||||||
self.log_error(filename,
|
self.logError(filename,
|
||||||
translate('SongsPlugin.CCLIFileImport',
|
translate('SongsPlugin.CCLIFileImport',
|
||||||
'The file does not have a valid extension.'))
|
'The file does not have a valid extension.'))
|
||||||
log.info(u'Extension %s is not valid', filename)
|
log.info(u'Extension %s is not valid', filename)
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
|
|
||||||
def do_import_usr_file(self, textList):
|
def doImportUsrFile(self, textList):
|
||||||
"""
|
"""
|
||||||
The :func:`do_import_usr_file` method provides OpenLP with the ability
|
The :func:`doImport_usr_file` method provides OpenLP with the ability
|
||||||
to import CCLI SongSelect songs in *USR* file format.
|
to import CCLI SongSelect songs in *USR* file format.
|
||||||
|
|
||||||
``textList``
|
``textList``
|
||||||
@ -165,7 +165,7 @@ class CCLIFileImport(SongImport):
|
|||||||
elif line.startswith(u'Themes='):
|
elif line.startswith(u'Themes='):
|
||||||
song_topics = line[7:].strip()
|
song_topics = line[7:].strip()
|
||||||
elif line.startswith(u'[S A'):
|
elif line.startswith(u'[S A'):
|
||||||
self.ccli_number = line[4:-3].strip()
|
self.ccliNumber = line[4:-3].strip()
|
||||||
elif line.startswith(u'Fields='):
|
elif line.startswith(u'Fields='):
|
||||||
# Fields contain single line indicating verse, chorus, etc,
|
# Fields contain single line indicating verse, chorus, etc,
|
||||||
# /t delimited, same as with words field. store seperately
|
# /t delimited, same as with words field. store seperately
|
||||||
@ -204,7 +204,7 @@ class CCLIFileImport(SongImport):
|
|||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.Tags[VerseType.Other]
|
||||||
verse_text = verse_lines[1]
|
verse_text = verse_lines[1]
|
||||||
if len(verse_text) > 0:
|
if len(verse_text) > 0:
|
||||||
self.add_verse(verse_text, verse_type)
|
self.addVerse(verse_text, verse_type)
|
||||||
check_first_verse_line = False
|
check_first_verse_line = False
|
||||||
# Handle multiple authors
|
# Handle multiple authors
|
||||||
author_list = song_author.split(u'/')
|
author_list = song_author.split(u'/')
|
||||||
@ -213,15 +213,15 @@ class CCLIFileImport(SongImport):
|
|||||||
for author in author_list:
|
for author in author_list:
|
||||||
separated = author.split(u',')
|
separated = author.split(u',')
|
||||||
if len(separated) > 1:
|
if len(separated) > 1:
|
||||||
self.add_author(u' '.join(reversed(separated)))
|
self.addAuthor(u' '.join(reversed(separated)))
|
||||||
else:
|
else:
|
||||||
self.add_author(author)
|
self.addAuthor(author)
|
||||||
self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
|
self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
|
||||||
return self.finish()
|
return self.finish()
|
||||||
|
|
||||||
def do_import_txt_file(self, textList):
|
def doImportTxtFile(self, textList):
|
||||||
"""
|
"""
|
||||||
The :func:`do_import_txt_file` method provides OpenLP with the ability
|
The :func:`doImport_txt_file` method provides OpenLP with the ability
|
||||||
to import CCLI SongSelect songs in *TXT* file format.
|
to import CCLI SongSelect songs in *TXT* file format.
|
||||||
|
|
||||||
``textList``
|
``textList``
|
||||||
@ -264,7 +264,7 @@ class CCLIFileImport(SongImport):
|
|||||||
continue
|
continue
|
||||||
elif verse_start:
|
elif verse_start:
|
||||||
if verse_text:
|
if verse_text:
|
||||||
self.add_verse(verse_text, verse_type)
|
self.addVerse(verse_text, verse_type)
|
||||||
verse_text = u''
|
verse_text = u''
|
||||||
verse_start = False
|
verse_start = False
|
||||||
else:
|
else:
|
||||||
@ -278,7 +278,7 @@ class CCLIFileImport(SongImport):
|
|||||||
if clean_line.startswith(u'CCLI'):
|
if clean_line.startswith(u'CCLI'):
|
||||||
line_number += 1
|
line_number += 1
|
||||||
ccli_parts = clean_line.split(' ')
|
ccli_parts = clean_line.split(' ')
|
||||||
self.ccli_number = ccli_parts[len(ccli_parts) - 1]
|
self.ccliNumber = ccli_parts[len(ccli_parts) - 1]
|
||||||
elif not verse_start:
|
elif not verse_start:
|
||||||
# We have the verse descriptor
|
# We have the verse descriptor
|
||||||
verse_desc_parts = clean_line.split(u' ')
|
verse_desc_parts = clean_line.split(u' ')
|
||||||
@ -333,5 +333,5 @@ class CCLIFileImport(SongImport):
|
|||||||
if len(author_list) < 2:
|
if len(author_list) < 2:
|
||||||
author_list = song_author.split(u'|')
|
author_list = song_author.split(u'|')
|
||||||
# Clean spaces before and after author names.
|
# Clean spaces before and after author names.
|
||||||
[self.add_author(author_name.strip()) for author_name in author_list]
|
[self.addAuthor(author_name.strip()) for author_name in author_list]
|
||||||
return self.finish()
|
return self.finish()
|
||||||
|
@ -49,50 +49,50 @@ class EasiSlidesImport(SongImport):
|
|||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.commit = True
|
self.commit = True
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Import either each of the files in self.import_sources - each element of
|
Import either each of the files in self.importSources - each element of
|
||||||
which can be either a single opensong file, or a zipfile containing
|
which can be either a single opensong file, or a zipfile containing
|
||||||
multiple opensong files. If `self.commit` is set False, the
|
multiple opensong files. If `self.commit` is set False, the
|
||||||
import will not be committed to the database (useful for test scripts).
|
import will not be committed to the database (useful for test scripts).
|
||||||
"""
|
"""
|
||||||
log.info(u'Importing EasiSlides XML file %s', self.import_source)
|
log.info(u'Importing EasiSlides XML file %s', self.importSource)
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
parsed_file = etree.parse(self.import_source, parser)
|
parsed_file = etree.parse(self.importSource, parser)
|
||||||
xml = unicode(etree.tostring(parsed_file))
|
xml = unicode(etree.tostring(parsed_file))
|
||||||
song_xml = objectify.fromstring(xml)
|
song_xml = objectify.fromstring(xml)
|
||||||
self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
|
self.importWizard.progressBar.setMaximum(len(song_xml.Item))
|
||||||
for song in song_xml.Item:
|
for song in song_xml.Item:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
self._parse_song(song)
|
self._parseSong(song)
|
||||||
|
|
||||||
def _parse_song(self, song):
|
def _parseSong(self, song):
|
||||||
self._success = True
|
self._success = True
|
||||||
self._add_unicode_attribute(u'title', song.Title1, True)
|
self._addUnicodeAttribute(u'title', song.Title1, True)
|
||||||
if hasattr(song, u'Title2'):
|
if hasattr(song, u'Title2'):
|
||||||
self._add_unicode_attribute(u'alternate_title', song.Title2)
|
self._addUnicodeAttribute(u'alternateTitle', song.Title2)
|
||||||
if hasattr(song, u'SongNumber'):
|
if hasattr(song, u'SongNumber'):
|
||||||
self._add_unicode_attribute(u'song_number', song.SongNumber)
|
self._addUnicodeAttribute(u'songNumber', song.SongNumber)
|
||||||
if self.song_number == u'0':
|
if self.songNumber == u'0':
|
||||||
self.song_number = u''
|
self.songNumber = u''
|
||||||
self._add_authors(song)
|
self._addAuthors(song)
|
||||||
if hasattr(song, u'Copyright'):
|
if hasattr(song, u'Copyright'):
|
||||||
self._add_copyright(song.Copyright)
|
self._addCopyright(song.Copyright)
|
||||||
if hasattr(song, u'LicenceAdmin1'):
|
if hasattr(song, u'LicenceAdmin1'):
|
||||||
self._add_copyright(song.LicenceAdmin1)
|
self._addCopyright(song.LicenceAdmin1)
|
||||||
if hasattr(song, u'LicenceAdmin2'):
|
if hasattr(song, u'LicenceAdmin2'):
|
||||||
self._add_copyright(song.LicenceAdmin2)
|
self._addCopyright(song.LicenceAdmin2)
|
||||||
if hasattr(song, u'BookReference'):
|
if hasattr(song, u'BookReference'):
|
||||||
self._add_unicode_attribute(u'song_book_name', song.BookReference)
|
self._addUnicodeAttribute(u'songBookName', song.BookReference)
|
||||||
self._parse_and_add_lyrics(song)
|
self._parseAndAddLyrics(song)
|
||||||
if self._success:
|
if self._success:
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(song.Title1 if song.Title1 else u'')
|
self.logError(song.Title1 if song.Title1 else u'')
|
||||||
else:
|
else:
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
|
|
||||||
def _add_unicode_attribute(self, self_attribute, import_attribute,
|
def _addUnicodeAttribute(self, self_attribute, import_attribute,
|
||||||
mandatory=False):
|
mandatory=False):
|
||||||
"""
|
"""
|
||||||
Add imported values to the song model converting them to unicode at the
|
Add imported values to the song model converting them to unicode at the
|
||||||
@ -119,7 +119,7 @@ class EasiSlidesImport(SongImport):
|
|||||||
if mandatory:
|
if mandatory:
|
||||||
self._success = False
|
self._success = False
|
||||||
|
|
||||||
def _add_authors(self, song):
|
def _addAuthors(self, song):
|
||||||
try:
|
try:
|
||||||
authors = unicode(song.Writer).split(u',')
|
authors = unicode(song.Writer).split(u',')
|
||||||
self.authors = \
|
self.authors = \
|
||||||
@ -130,7 +130,7 @@ class EasiSlidesImport(SongImport):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _add_copyright(self, element):
|
def _addCopyright(self, element):
|
||||||
"""
|
"""
|
||||||
Add a piece of copyright to the total copyright information for the
|
Add a piece of copyright to the total copyright information for the
|
||||||
song.
|
song.
|
||||||
@ -139,14 +139,14 @@ class EasiSlidesImport(SongImport):
|
|||||||
The imported variable to get the data from.
|
The imported variable to get the data from.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.add_copyright(unicode(element).strip())
|
self.addCopyright(unicode(element).strip())
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.exception(u'Unicode error on decoding copyright: %s' % element)
|
log.exception(u'Unicode error on decoding copyright: %s' % element)
|
||||||
self._success = False
|
self._success = False
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _parse_and_add_lyrics(self, song):
|
def _parseAndAddLyrics(self, song):
|
||||||
try:
|
try:
|
||||||
lyrics = unicode(song.Contents).strip()
|
lyrics = unicode(song.Contents).strip()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
@ -295,7 +295,7 @@ class EasiSlidesImport(SongImport):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
if tag in versetags:
|
if tag in versetags:
|
||||||
self.verse_order_list.append(tag)
|
self.verseOrderList.append(tag)
|
||||||
else:
|
else:
|
||||||
log.info(u'Got order item %s, which is not in versetags,'
|
log.info(u'Got order item %s, which is not in versetags,'
|
||||||
u'dropping item from presentation order', tag)
|
u'dropping item from presentation order', tag)
|
||||||
|
@ -155,24 +155,24 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
def __init__(self, manager, **kwargs):
|
def __init__(self, manager, **kwargs):
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
# Open the DB and MB files if they exist
|
# Open the DB and MB files if they exist
|
||||||
import_source_mb = self.import_source.replace('.DB', '.MB')
|
import_source_mb = self.importSource.replace('.DB', '.MB')
|
||||||
if not os.path.isfile(self.import_source):
|
if not os.path.isfile(self.importSource):
|
||||||
return
|
return
|
||||||
if not os.path.isfile(import_source_mb):
|
if not os.path.isfile(import_source_mb):
|
||||||
return
|
return
|
||||||
db_size = os.path.getsize(self.import_source)
|
db_size = os.path.getsize(self.importSource)
|
||||||
if db_size < 0x800:
|
if db_size < 0x800:
|
||||||
return
|
return
|
||||||
db_file = open(self.import_source, 'rb')
|
db_file = open(self.importSource, 'rb')
|
||||||
self.memo_file = open(import_source_mb, 'rb')
|
self.memoFile = open(import_source_mb, 'rb')
|
||||||
# Don't accept files that are clearly not paradox files
|
# Don't accept files that are clearly not paradox files
|
||||||
record_size, header_size, block_size, first_block, num_fields \
|
record_size, header_size, block_size, first_block, num_fields \
|
||||||
= struct.unpack('<hhxb8xh17xh', db_file.read(35))
|
= struct.unpack('<hhxb8xh17xh', db_file.read(35))
|
||||||
if header_size != 0x800 or block_size < 1 or block_size > 4:
|
if header_size != 0x800 or block_size < 1 or block_size > 4:
|
||||||
db_file.close()
|
db_file.close()
|
||||||
self.memo_file.close()
|
self.memoFile.close()
|
||||||
return
|
return
|
||||||
# Take a stab at how text is encoded
|
# Take a stab at how text is encoded
|
||||||
self.encoding = u'cp1252'
|
self.encoding = u'cp1252'
|
||||||
@ -204,7 +204,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
# There does not appear to be a _reliable_ way of getting the number
|
# There does not appear to be a _reliable_ way of getting the number
|
||||||
# of songs/records, so let's use file blocks for measuring progress.
|
# of songs/records, so let's use file blocks for measuring progress.
|
||||||
total_blocks = (db_size - header_size) / (block_size * 1024)
|
total_blocks = (db_size - header_size) / (block_size * 1024)
|
||||||
self.import_wizard.progressBar.setMaximum(total_blocks)
|
self.importWizard.progressBar.setMaximum(total_blocks)
|
||||||
# Read the field description information
|
# Read the field description information
|
||||||
db_file.seek(120)
|
db_file.seek(120)
|
||||||
field_info = db_file.read(num_fields * 2)
|
field_info = db_file.read(num_fields * 2)
|
||||||
@ -218,16 +218,16 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
field_info, i * 2)
|
field_info, i * 2)
|
||||||
field_descs.append(FieldDescEntry(field_name, field_type,
|
field_descs.append(FieldDescEntry(field_name, field_type,
|
||||||
field_size))
|
field_size))
|
||||||
self.set_record_struct(field_descs)
|
self.setRecordStruct(field_descs)
|
||||||
# Pick out the field description indexes we will need
|
# Pick out the field description indexes we will need
|
||||||
try:
|
try:
|
||||||
success = True
|
success = True
|
||||||
fi_title = self.find_field(u'Title')
|
fi_title = self.findField(u'Title')
|
||||||
fi_author = self.find_field(u'Author')
|
fi_author = self.findField(u'Author')
|
||||||
fi_copy = self.find_field(u'Copyright')
|
fi_copy = self.findField(u'Copyright')
|
||||||
fi_admin = self.find_field(u'Administrator')
|
fi_admin = self.findField(u'Administrator')
|
||||||
fi_words = self.find_field(u'Words')
|
fi_words = self.findField(u'Words')
|
||||||
fi_ccli = self.find_field(u'Song Number')
|
fi_ccli = self.findField(u'Song Number')
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# This is the wrong table
|
# This is the wrong table
|
||||||
success = False
|
success = False
|
||||||
@ -239,18 +239,18 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
rec_count = (rec_count + record_size) / record_size
|
rec_count = (rec_count + record_size) / record_size
|
||||||
# Loop through each record within the current block
|
# Loop through each record within the current block
|
||||||
for i in range(rec_count):
|
for i in range(rec_count):
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
raw_record = db_file.read(record_size)
|
raw_record = db_file.read(record_size)
|
||||||
self.fields = self.record_struct.unpack(raw_record)
|
self.fields = self.record_struct.unpack(raw_record)
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
self.title = self.get_field(fi_title)
|
self.title = self.getField(fi_title)
|
||||||
# Get remaining fields.
|
# Get remaining fields.
|
||||||
copy = self.get_field(fi_copy)
|
copy = self.getField(fi_copy)
|
||||||
admin = self.get_field(fi_admin)
|
admin = self.getField(fi_admin)
|
||||||
ccli = self.get_field(fi_ccli)
|
ccli = self.getField(fi_ccli)
|
||||||
authors = self.get_field(fi_author)
|
authors = self.getField(fi_author)
|
||||||
words = self.get_field(fi_words)
|
words = self.getField(fi_words)
|
||||||
# Set the SongImport object members.
|
# Set the SongImport object members.
|
||||||
if copy:
|
if copy:
|
||||||
self.copyright = copy
|
self.copyright = copy
|
||||||
@ -261,7 +261,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
unicode(translate('SongsPlugin.EasyWorshipSongImport',
|
unicode(translate('SongsPlugin.EasyWorshipSongImport',
|
||||||
'Administered by %s')) % admin
|
'Administered by %s')) % admin
|
||||||
if ccli:
|
if ccli:
|
||||||
self.ccli_number = ccli
|
self.ccliNumber = ccli
|
||||||
if authors:
|
if authors:
|
||||||
# Split up the authors
|
# Split up the authors
|
||||||
author_list = authors.split(u'/')
|
author_list = authors.split(u'/')
|
||||||
@ -270,7 +270,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
if len(author_list) < 2:
|
if len(author_list) < 2:
|
||||||
author_list = authors.split(u',')
|
author_list = authors.split(u',')
|
||||||
for author_name in author_list:
|
for author_name in author_list:
|
||||||
self.add_author(author_name.strip())
|
self.addAuthor(author_name.strip())
|
||||||
if words:
|
if words:
|
||||||
# Format the lyrics
|
# Format the lyrics
|
||||||
words = strip_rtf(words, self.encoding)
|
words = strip_rtf(words, self.encoding)
|
||||||
@ -305,23 +305,24 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
if not number_found:
|
if not number_found:
|
||||||
verse_type += u'1'
|
verse_type += u'1'
|
||||||
break
|
break
|
||||||
self.add_verse(
|
self.addVerse(
|
||||||
verse_split[-1].strip() if first_line_is_tag else verse,
|
verse_split[-1].strip() \
|
||||||
|
if first_line_is_tag else verse,
|
||||||
verse_type)
|
verse_type)
|
||||||
if len(self.comments) > 5:
|
if len(self.comments) > 5:
|
||||||
self.comments += unicode(
|
self.comments += unicode(
|
||||||
translate('SongsPlugin.EasyWorshipSongImport',
|
translate('SongsPlugin.EasyWorshipSongImport',
|
||||||
'\n[above are Song Tags with notes imported from \
|
'\n[above are Song Tags with notes imported from \
|
||||||
EasyWorship]'))
|
EasyWorship]'))
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(self.import_source)
|
self.logError(self.importSource)
|
||||||
db_file.close()
|
db_file.close()
|
||||||
self.memo_file.close()
|
self.memoFile.close()
|
||||||
|
|
||||||
def find_field(self, field_name):
|
def find_field(self, field_name):
|
||||||
return [i for i, x in enumerate(self.field_descs)
|
return [i for i, x in enumerate(self.fieldDescs)
|
||||||
if x.name == field_name][0]
|
if x.name == field_name][0]
|
||||||
|
|
||||||
def set_record_struct(self, field_descs):
|
def set_record_struct(self, field_descs):
|
||||||
@ -351,12 +352,12 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
fsl.append('Q')
|
fsl.append('Q')
|
||||||
else:
|
else:
|
||||||
fsl.append('%ds' % field_desc.size)
|
fsl.append('%ds' % field_desc.size)
|
||||||
self.record_struct = struct.Struct(''.join(fsl))
|
self.recordStruct = struct.Struct(''.join(fsl))
|
||||||
self.field_descs = field_descs
|
self.fieldDescs = field_descs
|
||||||
|
|
||||||
def get_field(self, field_desc_index):
|
def get_field(self, field_desc_index):
|
||||||
field = self.fields[field_desc_index]
|
field = self.fields[field_desc_index]
|
||||||
field_desc = self.field_descs[field_desc_index]
|
field_desc = self.fieldDescs[field_desc_index]
|
||||||
# Return None in case of 'blank' entries
|
# Return None in case of 'blank' entries
|
||||||
if isinstance(field, str):
|
if isinstance(field, str):
|
||||||
if len(field.rstrip('\0')) == 0:
|
if len(field.rstrip('\0')) == 0:
|
||||||
@ -382,18 +383,18 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
struct.unpack_from('<II', field, len(field)-10)
|
struct.unpack_from('<II', field, len(field)-10)
|
||||||
sub_block = block_start & 0xff
|
sub_block = block_start & 0xff
|
||||||
block_start &= ~0xff
|
block_start &= ~0xff
|
||||||
self.memo_file.seek(block_start)
|
self.memoFile.seek(block_start)
|
||||||
memo_block_type, = struct.unpack('b', self.memo_file.read(1))
|
memo_block_type, = struct.unpack('b', self.memoFile.read(1))
|
||||||
if memo_block_type == 2:
|
if memo_block_type == 2:
|
||||||
self.memo_file.seek(8, os.SEEK_CUR)
|
self.memoFile.seek(8, os.SEEK_CUR)
|
||||||
elif memo_block_type == 3:
|
elif memo_block_type == 3:
|
||||||
if sub_block > 63:
|
if sub_block > 63:
|
||||||
return u''
|
return u''
|
||||||
self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR)
|
self.memoFile.seek(11 + (5 * sub_block), os.SEEK_CUR)
|
||||||
sub_block_start, = struct.unpack('B', self.memo_file.read(1))
|
sub_block_start, = struct.unpack('B', self.memoFile.read(1))
|
||||||
self.memo_file.seek(block_start + (sub_block_start * 16))
|
self.memoFile.seek(block_start + (sub_block_start * 16))
|
||||||
else:
|
else:
|
||||||
return u''
|
return u''
|
||||||
return self.memo_file.read(blob_size)
|
return self.memoFile.read(blob_size)
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
@ -115,23 +115,23 @@ class FoilPresenterImport(SongImport):
|
|||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.FoilPresenter = FoilPresenter(self.manager)
|
self.FoilPresenter = FoilPresenter(self.manager)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Imports the songs.
|
Imports the songs.
|
||||||
"""
|
"""
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
for file_path in self.import_source:
|
for file_path in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % os.path.basename(file_path))
|
WizardStrings.ImportingType % os.path.basename(file_path))
|
||||||
try:
|
try:
|
||||||
parsed_file = etree.parse(file_path, parser)
|
parsed_file = etree.parse(file_path, parser)
|
||||||
xml = unicode(etree.tostring(parsed_file))
|
xml = unicode(etree.tostring(parsed_file))
|
||||||
self.FoilPresenter.xml_to_song(xml)
|
self.FoilPresenter.xml_to_song(xml)
|
||||||
except etree.XMLSyntaxError:
|
except etree.XMLSyntaxError:
|
||||||
self.log_error(file_path, SongStrings.XMLSyntaxError)
|
self.logError(file_path, SongStrings.XMLSyntaxError)
|
||||||
log.exception(u'XML syntax error in file %s' % file_path)
|
log.exception(u'XML syntax error in file %s' % file_path)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
def __init__(self, parent, plugin, icon):
|
def __init__(self, parent, plugin, icon):
|
||||||
self.IconPath = u'songs/song'
|
self.IconPath = u'songs/song'
|
||||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||||
self.edit_song_form = EditSongForm(self, self.plugin.formparent,
|
self.editSongForm = EditSongForm(self, self.plugin.formparent,
|
||||||
self.plugin.manager)
|
self.plugin.manager)
|
||||||
self.openLyrics = OpenLyrics(self.plugin.manager)
|
self.openLyrics = OpenLyrics(self.plugin.manager)
|
||||||
self.singleServiceItem = False
|
self.singleServiceItem = False
|
||||||
self.song_maintenance_form = SongMaintenanceForm(
|
self.songMaintenanceForm = SongMaintenanceForm(
|
||||||
self.plugin.manager, self)
|
self.plugin.manager, self)
|
||||||
# Holds information about whether the edit is remotly triggered and
|
# Holds information about whether the edit is remotly triggered and
|
||||||
# which Song is required.
|
# which Song is required.
|
||||||
@ -316,25 +316,26 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.onClearTextButtonClick()
|
self.onClearTextButtonClick()
|
||||||
|
|
||||||
def onImportClick(self):
|
def onImportClick(self):
|
||||||
if not hasattr(self, u'import_wizard'):
|
if not hasattr(self, u'importWizard'):
|
||||||
self.import_wizard = SongImportForm(self, self.plugin)
|
self.importWizard = SongImportForm(self, self.plugin)
|
||||||
if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
|
if self.importWizard.exec_() == QtGui.QDialog.Accepted:
|
||||||
Receiver.send_message(u'songs_load_list')
|
Receiver.send_message(u'songs_load_list')
|
||||||
|
|
||||||
def onExportClick(self):
|
def onExportClick(self):
|
||||||
export_wizard = SongExportForm(self, self.plugin)
|
if not hasattr(self, u'exportWizard'):
|
||||||
export_wizard.exec_()
|
self.exportWizard = SongExportForm(self, self.plugin)
|
||||||
|
self.exportWizard.exec_()
|
||||||
|
|
||||||
def onNewClick(self):
|
def onNewClick(self):
|
||||||
log.debug(u'onNewClick')
|
log.debug(u'onNewClick')
|
||||||
self.edit_song_form.newSong()
|
self.editSongForm.newSong()
|
||||||
self.edit_song_form.exec_()
|
self.editSongForm.exec_()
|
||||||
self.onClearTextButtonClick()
|
self.onClearTextButtonClick()
|
||||||
self.onSelectionChange()
|
self.onSelectionChange()
|
||||||
self.autoSelectId = -1
|
self.autoSelectId = -1
|
||||||
|
|
||||||
def onSongMaintenanceClick(self):
|
def onSongMaintenanceClick(self):
|
||||||
self.song_maintenance_form.exec_()
|
self.songMaintenanceForm.exec_()
|
||||||
|
|
||||||
def onRemoteEditClear(self):
|
def onRemoteEditClear(self):
|
||||||
log.debug(u'onRemoteEditClear')
|
log.debug(u'onRemoteEditClear')
|
||||||
@ -354,8 +355,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
if valid:
|
if valid:
|
||||||
self.remoteSong = song_id
|
self.remoteSong = song_id
|
||||||
self.remoteTriggered = remote_type
|
self.remoteTriggered = remote_type
|
||||||
self.edit_song_form.loadSong(song_id, remote_type == u'P')
|
self.editSongForm.loadSong(song_id, remote_type == u'P')
|
||||||
self.edit_song_form.exec_()
|
self.editSongForm.exec_()
|
||||||
self.autoSelectId = -1
|
self.autoSelectId = -1
|
||||||
self.onSongListLoad()
|
self.onSongListLoad()
|
||||||
|
|
||||||
@ -367,8 +368,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
||||||
self.editItem = self.listView.currentItem()
|
self.editItem = self.listView.currentItem()
|
||||||
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
self.edit_song_form.loadSong(item_id, False)
|
self.editSongForm.loadSong(item_id, False)
|
||||||
self.edit_song_form.exec_()
|
self.editSongForm.exec_()
|
||||||
self.autoSelectId = -1
|
self.autoSelectId = -1
|
||||||
self.onSongListLoad()
|
self.onSongListLoad()
|
||||||
self.editItem = None
|
self.editItem = None
|
||||||
@ -390,6 +391,20 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
return
|
return
|
||||||
for item in items:
|
for item in items:
|
||||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
|
media_files = self.plugin.manager.get_all_objects(MediaFile,
|
||||||
|
MediaFile.song_id == item_id)
|
||||||
|
for media_file in media_files:
|
||||||
|
try:
|
||||||
|
os.remove(media_file.file_name)
|
||||||
|
except:
|
||||||
|
log.exception('Could not remove file: %s', audio)
|
||||||
|
try:
|
||||||
|
save_path = os.path.join(AppLocation.get_section_data_path(
|
||||||
|
self.plugin.name), 'audio', str(item_id))
|
||||||
|
if os.path.exists(save_path):
|
||||||
|
os.rmdir(save_path)
|
||||||
|
except OSError:
|
||||||
|
log.exception(u'Could not remove directory: %s', save_path)
|
||||||
self.plugin.manager.delete_object(Song, item_id)
|
self.plugin.manager.delete_object(Song, item_id)
|
||||||
self.onSearchTextButtonClick()
|
self.onSearchTextButtonClick()
|
||||||
|
|
||||||
@ -411,7 +426,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.plugin.manager.save_object(new_song)
|
self.plugin.manager.save_object(new_song)
|
||||||
self.onSongListLoad()
|
self.onSongListLoad()
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||||
|
remote=False):
|
||||||
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
|
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
|
||||||
item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
|
item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
|
||||||
service_item.add_capability(ItemCapabilities.CanEdit)
|
service_item.add_capability(ItemCapabilities.CanEdit)
|
||||||
|
@ -32,6 +32,8 @@ openlp.org 1.x song databases into the current installation database.
|
|||||||
import logging
|
import logging
|
||||||
from chardet.universaldetector import UniversalDetector
|
from chardet.universaldetector import UniversalDetector
|
||||||
import sqlite
|
import sqlite
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
||||||
@ -44,7 +46,7 @@ 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'
|
lastEncoding = u'windows-1252'
|
||||||
|
|
||||||
def __init__(self, manager, **kwargs):
|
def __init__(self, manager, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -57,23 +59,23 @@ class OpenLP1SongImport(SongImport):
|
|||||||
The database providing the data to import.
|
The database providing the data to import.
|
||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.available_themes = \
|
self.availableThemes = \
|
||||||
kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
|
kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Run the import for an openlp.org 1.x song database.
|
Run the import for an openlp.org 1.x song database.
|
||||||
"""
|
"""
|
||||||
if not self.import_source.endswith(u'.olp'):
|
if not self.importSource.endswith(u'.olp'):
|
||||||
self.log_error(self.import_source,
|
self.logError(self.importSource,
|
||||||
translate('SongsPlugin.OpenLP1SongImport',
|
translate('SongsPlugin.OpenLP1SongImport',
|
||||||
'Not a valid openlp.org 1.x song database.'))
|
'Not a valid openlp.org 1.x song database.'))
|
||||||
return
|
return
|
||||||
encoding = self.get_encoding()
|
encoding = self.getEncoding()
|
||||||
if not encoding:
|
if not encoding:
|
||||||
return
|
return
|
||||||
# Connect to the database.
|
# Connect to the database.
|
||||||
connection = sqlite.connect(self.import_source, mode=0444,
|
connection = sqlite.connect(self.importSource, mode=0444,
|
||||||
encoding=(encoding, 'replace'))
|
encoding=(encoding, 'replace'))
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
# Determine if we're using a new or an old DB.
|
# Determine if we're using a new or an old DB.
|
||||||
@ -94,64 +96,66 @@ class OpenLP1SongImport(SongImport):
|
|||||||
cursor.execute(u'SELECT settingsid, settingsname FROM settings')
|
cursor.execute(u'SELECT settingsid, settingsname FROM settings')
|
||||||
themes = {}
|
themes = {}
|
||||||
for theme_id, theme_name in cursor.fetchall():
|
for theme_id, theme_name in cursor.fetchall():
|
||||||
if theme_name in self.available_themes:
|
if theme_name in self.availableThemes:
|
||||||
themes[theme_id] = theme_name
|
themes[theme_id] = theme_name
|
||||||
# Import the songs.
|
# Import the songs.
|
||||||
cursor.execute(u'-- types int, unicode, unicode, unicode, int')
|
cursor.execute(u'-- types int, unicode, unicode, unicode, int')
|
||||||
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
||||||
u'copyrightinfo, settingsid FROM songs')
|
u'copyrightinfo, settingsid FROM songs')
|
||||||
songs = cursor.fetchall()
|
songs = cursor.fetchall()
|
||||||
self.import_wizard.progressBar.setMaximum(len(songs))
|
self.importWizard.progressBar.setMaximum(len(songs))
|
||||||
for song in songs:
|
for song in songs:
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
song_id = song[0]
|
song_id = song[0]
|
||||||
self.title = song[1]
|
self.title = song[1]
|
||||||
lyrics = song[2].replace(u'\r\n', u'\n')
|
lyrics = song[2].replace(u'\r\n', u'\n')
|
||||||
self.add_copyright(song[3])
|
self.addCopyright(song[3])
|
||||||
if themes.has_key(song[4]):
|
if themes.has_key(song[4]):
|
||||||
self.theme_name = themes[song[4]]
|
self.themeName = themes[song[4]]
|
||||||
verses = lyrics.split(u'\n\n')
|
verses = lyrics.split(u'\n\n')
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
if verse.strip():
|
if verse.strip():
|
||||||
self.add_verse(verse.strip())
|
self.addVerse(verse.strip())
|
||||||
cursor.execute(u'-- types int')
|
cursor.execute(u'-- types int')
|
||||||
cursor.execute(u'SELECT authorid FROM songauthors '
|
cursor.execute(u'SELECT authorid FROM songauthors '
|
||||||
u'WHERE songid = %s' % song_id)
|
u'WHERE songid = %s' % song_id)
|
||||||
author_ids = cursor.fetchall()
|
author_ids = cursor.fetchall()
|
||||||
for author_id in author_ids:
|
for author_id in author_ids:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
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(author[1])
|
self.parseAuthor(author[1])
|
||||||
break
|
break
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
if new_db:
|
if new_db:
|
||||||
cursor.execute(u'-- types int')
|
cursor.execute(u'-- types int, int')
|
||||||
cursor.execute(u'SELECT trackid FROM songtracks '
|
cursor.execute(u'SELECT trackid, listindex '
|
||||||
|
u'FROM songtracks '
|
||||||
u'WHERE songid = %s ORDER BY listindex' % song_id)
|
u'WHERE songid = %s ORDER BY listindex' % song_id)
|
||||||
track_ids = cursor.fetchall()
|
track_ids = cursor.fetchall()
|
||||||
for track_id in track_ids:
|
for track_id, listindex in track_ids:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
if track[0] == track_id[0]:
|
if track[0] == track_id:
|
||||||
self.add_media_file(track[1])
|
media_file = self.expandMediaFile(track[1])
|
||||||
|
self.addMediaFile(media_file, listindex)
|
||||||
break
|
break
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(self.import_source)
|
self.logError(self.importSource)
|
||||||
|
|
||||||
def get_encoding(self):
|
def getEncoding(self):
|
||||||
"""
|
"""
|
||||||
Detect character encoding of an openlp.org 1.x song database.
|
Detect character encoding of an openlp.org 1.x song database.
|
||||||
"""
|
"""
|
||||||
# Connect to the database.
|
# Connect to the database.
|
||||||
connection = sqlite.connect(self.import_source, mode=0444)
|
connection = sqlite.connect(self.importSource, mode=0444)
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
detector = UniversalDetector()
|
detector = UniversalDetector()
|
||||||
@ -186,3 +190,22 @@ class OpenLP1SongImport(SongImport):
|
|||||||
return detector.result[u'encoding']
|
return detector.result[u'encoding']
|
||||||
detector.close()
|
detector.close()
|
||||||
return retrieve_windows_encoding(detector.result[u'encoding'])
|
return retrieve_windows_encoding(detector.result[u'encoding'])
|
||||||
|
|
||||||
|
def expandMediaFile(self, filename):
|
||||||
|
"""
|
||||||
|
When you're on Windows, this function expands the file name to include
|
||||||
|
the path to OpenLP's application data directory. If you are not on
|
||||||
|
Windows, it returns the original file name.
|
||||||
|
|
||||||
|
``filename``
|
||||||
|
The filename to expand.
|
||||||
|
"""
|
||||||
|
if sys.platform != u'win32' and \
|
||||||
|
not os.environ.get(u'ALLUSERSPROFILE') and \
|
||||||
|
not os.environ.get(u'APPDATA'):
|
||||||
|
return filename
|
||||||
|
common_app_data = os.path.join(os.environ[u'ALLUSERSPROFILE'],
|
||||||
|
os.path.split(os.environ[u'APPDATA'])[1])
|
||||||
|
if not common_app_data:
|
||||||
|
return filename
|
||||||
|
return os.path.join(common_app_data, u'openlp.org', 'Audio', filename)
|
||||||
|
@ -95,22 +95,22 @@ class OpenLPSongImport(SongImport):
|
|||||||
The database providing the data to import.
|
The database providing the data to import.
|
||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.source_session = None
|
self.sourceSession = None
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Run the import for an OpenLP version 2 song database.
|
Run the import for an OpenLP version 2 song database.
|
||||||
"""
|
"""
|
||||||
if not self.import_source.endswith(u'.sqlite'):
|
if not self.importSource.endswith(u'.sqlite'):
|
||||||
self.log_error(self.import_source,
|
self.logError(self.importSource,
|
||||||
translate('SongsPlugin.OpenLPSongImport',
|
translate('SongsPlugin.OpenLPSongImport',
|
||||||
'Not a valid OpenLP 2.0 song database.'))
|
'Not a valid OpenLP 2.0 song database.'))
|
||||||
return
|
return
|
||||||
self.import_source = u'sqlite:///%s' % self.import_source
|
self.importSource = u'sqlite:///%s' % self.importSource
|
||||||
engine = create_engine(self.import_source)
|
engine = create_engine(self.importSource)
|
||||||
source_meta = MetaData()
|
source_meta = MetaData()
|
||||||
source_meta.reflect(engine)
|
source_meta.reflect(engine)
|
||||||
self.source_session = scoped_session(sessionmaker(bind=engine))
|
self.sourceSession = scoped_session(sessionmaker(bind=engine))
|
||||||
if u'media_files' in source_meta.tables.keys():
|
if u'media_files' in source_meta.tables.keys():
|
||||||
has_media_files = True
|
has_media_files = True
|
||||||
else:
|
else:
|
||||||
@ -156,9 +156,9 @@ class OpenLPSongImport(SongImport):
|
|||||||
except UnmappedClassError:
|
except UnmappedClassError:
|
||||||
mapper(OldTopic, source_topics_table)
|
mapper(OldTopic, source_topics_table)
|
||||||
|
|
||||||
source_songs = self.source_session.query(OldSong).all()
|
source_songs = self.sourceSession.query(OldSong).all()
|
||||||
if self.import_wizard:
|
if self.importWizard:
|
||||||
self.import_wizard.progressBar.setMaximum(len(source_songs))
|
self.importWizard.progressBar.setMaximum(len(source_songs))
|
||||||
for song in source_songs:
|
for song in source_songs:
|
||||||
new_song = Song()
|
new_song = Song()
|
||||||
new_song.title = song.title
|
new_song.title = song.title
|
||||||
@ -201,22 +201,22 @@ class OpenLPSongImport(SongImport):
|
|||||||
if existing_topic is None:
|
if existing_topic is None:
|
||||||
existing_topic = Topic.populate(name=topic.name)
|
existing_topic = Topic.populate(name=topic.name)
|
||||||
new_song.topics.append(existing_topic)
|
new_song.topics.append(existing_topic)
|
||||||
# if has_media_files:
|
if has_media_files:
|
||||||
# if song.media_files:
|
if song.media_files:
|
||||||
# for media_file in song.media_files:
|
for media_file in song.media_files:
|
||||||
# existing_media_file = \
|
existing_media_file = \
|
||||||
# self.manager.get_object_filtered(MediaFile,
|
self.manager.get_object_filtered(MediaFile,
|
||||||
# MediaFile.file_name == media_file.file_name)
|
MediaFile.file_name == media_file.file_name)
|
||||||
# if existing_media_file:
|
if existing_media_file:
|
||||||
# new_song.media_files.append(existing_media_file)
|
new_song.media_files.append(existing_media_file)
|
||||||
# else:
|
else:
|
||||||
# new_song.media_files.append(MediaFile.populate(
|
new_song.media_files.append(MediaFile.populate(
|
||||||
# file_name=media_file.file_name))
|
file_name=media_file.file_name))
|
||||||
clean_song(self.manager, new_song)
|
clean_song(self.manager, new_song)
|
||||||
self.manager.save_object(new_song)
|
self.manager.save_object(new_song)
|
||||||
if self.import_wizard:
|
if self.importWizard:
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % new_song.title)
|
WizardStrings.ImportingType % new_song.title)
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
@ -59,58 +59,58 @@ class OooImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.document = None
|
self.document = None
|
||||||
self.process_started = False
|
self.processStarted = False
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
if not isinstance(self.import_source, list):
|
if not isinstance(self.importSource, list):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.start_ooo()
|
self.start_ooo()
|
||||||
except NoConnectException as exc:
|
except NoConnectException as exc:
|
||||||
self.log_error(
|
self.logError(
|
||||||
self.import_source[0],
|
self.importSource[0],
|
||||||
translate('SongsPlugin.SongImport',
|
translate('SongsPlugin.SongImport',
|
||||||
'Cannot access OpenOffice or LibreOffice'))
|
'Cannot access OpenOffice or LibreOffice'))
|
||||||
log.error(exc)
|
log.error(exc)
|
||||||
return
|
return
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for filename in self.import_source:
|
for filename in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
break
|
break
|
||||||
filename = unicode(filename)
|
filename = unicode(filename)
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
self.open_ooo_file(filename)
|
self.openOooFile(filename)
|
||||||
if self.document:
|
if self.document:
|
||||||
self.process_ooo_document()
|
self.processOooDocument()
|
||||||
self.close_ooo_file()
|
self.closeOooFile()
|
||||||
else:
|
else:
|
||||||
self.log_error(self.filepath,
|
self.logError(self.filepath,
|
||||||
translate('SongsPlugin.SongImport',
|
translate('SongsPlugin.SongImport',
|
||||||
'Unable to open file'))
|
'Unable to open file'))
|
||||||
else:
|
else:
|
||||||
self.log_error(self.filepath,
|
self.logError(self.filepath,
|
||||||
translate('SongsPlugin.SongImport', 'File not found'))
|
translate('SongsPlugin.SongImport', 'File not found'))
|
||||||
self.close_ooo()
|
self.closeOoo()
|
||||||
|
|
||||||
def process_ooo_document(self):
|
def processOooDocument(self):
|
||||||
"""
|
"""
|
||||||
Handle the import process for OpenOffice files. This method facilitates
|
Handle the import process for OpenOffice files. This method facilitates
|
||||||
allowing subclasses to handle specific types of OpenOffice files.
|
allowing subclasses to handle specific types of OpenOffice files.
|
||||||
"""
|
"""
|
||||||
if self.document.supportsService(
|
if self.document.supportsService(
|
||||||
"com.sun.star.presentation.PresentationDocument"):
|
"com.sun.star.presentation.PresentationDocument"):
|
||||||
self.process_pres()
|
self.processPres()
|
||||||
if self.document.supportsService("com.sun.star.text.TextDocument"):
|
if self.document.supportsService("com.sun.star.text.TextDocument"):
|
||||||
self.process_doc()
|
self.processDoc()
|
||||||
|
|
||||||
def start_ooo(self):
|
def startOoo(self):
|
||||||
"""
|
"""
|
||||||
Start OpenOffice.org process
|
Start OpenOffice.org process
|
||||||
TODO: The presentation/Impress plugin may already have it running
|
TODO: The presentation/Impress plugin may already have it running
|
||||||
"""
|
"""
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
self.start_ooo_process()
|
self.startOooProcess()
|
||||||
self.desktop = self.ooo_manager.createInstance(
|
self.desktop = self.oooManager.createInstance(
|
||||||
u'com.sun.star.frame.Desktop')
|
u'com.sun.star.frame.Desktop')
|
||||||
else:
|
else:
|
||||||
context = uno.getComponentContext()
|
context = uno.getComponentContext()
|
||||||
@ -123,7 +123,7 @@ class OooImport(SongImport):
|
|||||||
uno_instance = get_uno_instance(resolver)
|
uno_instance = get_uno_instance(resolver)
|
||||||
except NoConnectException:
|
except NoConnectException:
|
||||||
log.exception("Failed to resolve uno connection")
|
log.exception("Failed to resolve uno connection")
|
||||||
self.start_ooo_process()
|
self.startOooProcess()
|
||||||
loop += 1
|
loop += 1
|
||||||
else:
|
else:
|
||||||
manager = uno_instance.ServiceManager
|
manager = uno_instance.ServiceManager
|
||||||
@ -132,22 +132,22 @@ class OooImport(SongImport):
|
|||||||
return
|
return
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def start_ooo_process(self):
|
def startOooProcess(self):
|
||||||
try:
|
try:
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
self.ooo_manager = Dispatch(u'com.sun.star.ServiceManager')
|
self.oooManager = Dispatch(u'com.sun.star.ServiceManager')
|
||||||
self.ooo_manager._FlagAsMethod(u'Bridge_GetStruct')
|
self.oooManager._FlagAsMethod(u'Bridge_GetStruct')
|
||||||
self.ooo_manager._FlagAsMethod(u'Bridge_GetValueObject')
|
self.oooManager._FlagAsMethod(u'Bridge_GetValueObject')
|
||||||
else:
|
else:
|
||||||
cmd = get_uno_command()
|
cmd = get_uno_command()
|
||||||
process = QtCore.QProcess()
|
process = QtCore.QProcess()
|
||||||
process.startDetached(cmd)
|
process.startDetached(cmd)
|
||||||
process.waitForStarted()
|
process.waitForStarted()
|
||||||
self.process_started = True
|
self.processStarted = True
|
||||||
except:
|
except:
|
||||||
log.exception("start_ooo_process failed")
|
log.exception("start_ooo_process failed")
|
||||||
|
|
||||||
def open_ooo_file(self, filepath):
|
def openOooFile(self, filepath):
|
||||||
"""
|
"""
|
||||||
Open the passed file in OpenOffice.org Impress
|
Open the passed file in OpenOffice.org Impress
|
||||||
"""
|
"""
|
||||||
@ -166,29 +166,29 @@ class OooImport(SongImport):
|
|||||||
if not self.document.supportsService(
|
if not self.document.supportsService(
|
||||||
"com.sun.star.presentation.PresentationDocument") and not \
|
"com.sun.star.presentation.PresentationDocument") and not \
|
||||||
self.document.supportsService("com.sun.star.text.TextDocument"):
|
self.document.supportsService("com.sun.star.text.TextDocument"):
|
||||||
self.close_ooo_file()
|
self.closeOooFile()
|
||||||
else:
|
else:
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
u'Processing file ' + filepath, 0)
|
u'Processing file ' + filepath, 0)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
log.exception("open_ooo_file failed: %s", url)
|
log.exception("open_ooo_file failed: %s", url)
|
||||||
return
|
return
|
||||||
|
|
||||||
def close_ooo_file(self):
|
def closeOooFile(self):
|
||||||
"""
|
"""
|
||||||
Close file.
|
Close file.
|
||||||
"""
|
"""
|
||||||
self.document.close(True)
|
self.document.close(True)
|
||||||
self.document = None
|
self.document = None
|
||||||
|
|
||||||
def close_ooo(self):
|
def closeOoo(self):
|
||||||
"""
|
"""
|
||||||
Close OOo. But only if we started it and not on windows
|
Close OOo. But only if we started it and not on windows
|
||||||
"""
|
"""
|
||||||
if self.process_started:
|
if self.processStarted:
|
||||||
self.desktop.terminate()
|
self.desktop.terminate()
|
||||||
|
|
||||||
def process_pres(self):
|
def processPres(self):
|
||||||
"""
|
"""
|
||||||
Process the file
|
Process the file
|
||||||
"""
|
"""
|
||||||
@ -196,8 +196,8 @@ class OooImport(SongImport):
|
|||||||
slides = doc.getDrawPages()
|
slides = doc.getDrawPages()
|
||||||
text = u''
|
text = u''
|
||||||
for slide_no in range(slides.getCount()):
|
for slide_no in range(slides.getCount()):
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
|
self.importWizard.incrementProgressBar(u'Import cancelled', 0)
|
||||||
return
|
return
|
||||||
slide = slides.getByIndex(slide_no)
|
slide = slides.getByIndex(slide_no)
|
||||||
slidetext = u''
|
slidetext = u''
|
||||||
@ -209,10 +209,10 @@ class OooImport(SongImport):
|
|||||||
if slidetext.strip() == u'':
|
if slidetext.strip() == u'':
|
||||||
slidetext = u'\f'
|
slidetext = u'\f'
|
||||||
text += slidetext
|
text += slidetext
|
||||||
self.process_songs_text(text)
|
self.processSongsText(text)
|
||||||
return
|
return
|
||||||
|
|
||||||
def process_doc(self):
|
def processDoc(self):
|
||||||
"""
|
"""
|
||||||
Process the doc file, a paragraph at a time
|
Process the doc file, a paragraph at a time
|
||||||
"""
|
"""
|
||||||
@ -231,16 +231,16 @@ class OooImport(SongImport):
|
|||||||
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
|
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
|
||||||
paratext += u'\f'
|
paratext += u'\f'
|
||||||
text += paratext + u'\n'
|
text += paratext + u'\n'
|
||||||
self.process_songs_text(text)
|
self.processSongsText(text)
|
||||||
|
|
||||||
def process_songs_text(self, text):
|
def processSongsText(self, text):
|
||||||
songtexts = self.tidy_text(text).split(u'\f')
|
songtexts = self.tidyText(text).split(u'\f')
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
for songtext in songtexts:
|
for songtext in songtexts:
|
||||||
if songtext.strip():
|
if songtext.strip():
|
||||||
self.process_song_text(songtext.strip())
|
self.processSongText(songtext.strip())
|
||||||
if self.check_complete():
|
if self.checkComplete():
|
||||||
self.finish()
|
self.finish()
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
if self.check_complete():
|
if self.checkComplete():
|
||||||
self.finish()
|
self.finish()
|
||||||
|
@ -53,16 +53,16 @@ class OpenLyricsImport(SongImport):
|
|||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.openLyrics = OpenLyrics(self.manager)
|
self.openLyrics = OpenLyrics(self.manager)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Imports the songs.
|
Imports the songs.
|
||||||
"""
|
"""
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
for file_path in self.import_source:
|
for file_path in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % os.path.basename(file_path))
|
WizardStrings.ImportingType % os.path.basename(file_path))
|
||||||
try:
|
try:
|
||||||
# Pass a file object, because lxml does not cope with some
|
# Pass a file object, because lxml does not cope with some
|
||||||
@ -72,4 +72,4 @@ class OpenLyricsImport(SongImport):
|
|||||||
self.openLyrics.xml_to_song(xml)
|
self.openLyrics.xml_to_song(xml)
|
||||||
except etree.XMLSyntaxError:
|
except etree.XMLSyntaxError:
|
||||||
log.exception(u'XML syntax error in file %s' % file_path)
|
log.exception(u'XML syntax error in file %s' % file_path)
|
||||||
self.log_error(file_path, SongStrings.XMLSyntaxError)
|
self.logError(file_path, SongStrings.XMLSyntaxError)
|
||||||
|
@ -107,32 +107,32 @@ class OpenSongImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for filename in self.import_source:
|
for filename in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
song_file = open(filename)
|
song_file = open(filename)
|
||||||
self.do_import_file(song_file)
|
self.doImportFile(song_file)
|
||||||
song_file.close()
|
song_file.close()
|
||||||
|
|
||||||
def do_import_file(self, file):
|
def doImportFile(self, file):
|
||||||
"""
|
"""
|
||||||
Process the OpenSong file - pass in a file-like object, not a file path.
|
Process the OpenSong file - pass in a file-like object, not a file path.
|
||||||
"""
|
"""
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
try:
|
try:
|
||||||
tree = objectify.parse(file)
|
tree = objectify.parse(file)
|
||||||
except (Error, LxmlError):
|
except (Error, LxmlError):
|
||||||
self.log_error(file.name, SongStrings.XMLSyntaxError)
|
self.logError(file.name, SongStrings.XMLSyntaxError)
|
||||||
log.exception(u'Error parsing XML')
|
log.exception(u'Error parsing XML')
|
||||||
return
|
return
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
fields = dir(root)
|
fields = dir(root)
|
||||||
decode = {
|
decode = {
|
||||||
u'copyright': self.add_copyright,
|
u'copyright': self.addCopyright,
|
||||||
u'ccli': u'ccli_number',
|
u'ccli': u'ccli_number',
|
||||||
u'author': self.parse_author,
|
u'author': self.parseAuthor,
|
||||||
u'title': u'title',
|
u'title': u'title',
|
||||||
u'aka': u'alternate_title',
|
u'aka': u'alternate_title',
|
||||||
u'hymn_number': u'song_number'
|
u'hymn_number': u'song_number'
|
||||||
@ -214,7 +214,7 @@ class OpenSongImport(SongImport):
|
|||||||
verses[verse_tag][verse_num][inst] = []
|
verses[verse_tag][verse_num][inst] = []
|
||||||
our_verse_order.append([verse_tag, verse_num, inst])
|
our_verse_order.append([verse_tag, verse_num, inst])
|
||||||
# Tidy text and remove the ____s from extended words
|
# Tidy text and remove the ____s from extended words
|
||||||
this_line = self.tidy_text(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')
|
||||||
verses[verse_tag][verse_num][inst].append(this_line)
|
verses[verse_tag][verse_num][inst].append(this_line)
|
||||||
@ -223,9 +223,9 @@ class OpenSongImport(SongImport):
|
|||||||
for (verse_tag, verse_num, inst) in our_verse_order:
|
for (verse_tag, verse_num, inst) in our_verse_order:
|
||||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||||
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
|
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
|
||||||
self.add_verse(lines, verse_def)
|
self.addVerse(lines, verse_def)
|
||||||
if not self.verses:
|
if not self.verses:
|
||||||
self.add_verse('')
|
self.addVerse('')
|
||||||
# figure out the presentation order, if present
|
# figure out the presentation order, if present
|
||||||
if u'presentation' in fields and root.presentation:
|
if u'presentation' in fields and root.presentation:
|
||||||
order = unicode(root.presentation)
|
order = unicode(root.presentation)
|
||||||
@ -246,9 +246,9 @@ class OpenSongImport(SongImport):
|
|||||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||||
if verses.has_key(verse_tag) and \
|
if verses.has_key(verse_tag) and \
|
||||||
verses[verse_tag].has_key(verse_num):
|
verses[verse_tag].has_key(verse_num):
|
||||||
self.verse_order_list.append(verse_def)
|
self.verseOrderList.append(verse_def)
|
||||||
else:
|
else:
|
||||||
log.info(u'Got order %s but not in verse tags, dropping'
|
log.info(u'Got order %s but not in verse tags, dropping'
|
||||||
u'this item from presentation order', verse_def)
|
u'this item from presentation order', verse_def)
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(file.name)
|
self.logError(file.name)
|
||||||
|
@ -83,32 +83,32 @@ class SofImport(OooImport):
|
|||||||
OooImport.__init__(self, manager, **kwargs)
|
OooImport.__init__(self, manager, **kwargs)
|
||||||
self.song = False
|
self.song = False
|
||||||
|
|
||||||
def process_ooo_document(self):
|
def processOooDocument(self):
|
||||||
"""
|
"""
|
||||||
Handle the import process for SoF files.
|
Handle the import process for SoF files.
|
||||||
"""
|
"""
|
||||||
self.process_sof_file()
|
self.processSofFile()
|
||||||
|
|
||||||
def process_sof_file(self):
|
def processSofFile(self):
|
||||||
"""
|
"""
|
||||||
Process the RTF file, a paragraph at a time
|
Process the RTF file, a paragraph at a time
|
||||||
"""
|
"""
|
||||||
self.blanklines = 0
|
self.blankLines = 0
|
||||||
self.new_song()
|
self.newSong()
|
||||||
try:
|
try:
|
||||||
paragraphs = self.document.getText().createEnumeration()
|
paragraphs = self.document.getText().createEnumeration()
|
||||||
while paragraphs.hasMoreElements():
|
while paragraphs.hasMoreElements():
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
paragraph = paragraphs.nextElement()
|
paragraph = paragraphs.nextElement()
|
||||||
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
||||||
self.process_paragraph(paragraph)
|
self.processParagraph(paragraph)
|
||||||
except RuntimeException as exc:
|
except RuntimeException as exc:
|
||||||
log.exception(u'Error processing file: %s', exc)
|
log.exception(u'Error processing file: %s', exc)
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(self.filepath)
|
self.logError(self.filepath)
|
||||||
|
|
||||||
def process_paragraph(self, paragraph):
|
def processParagraph(self, paragraph):
|
||||||
"""
|
"""
|
||||||
Process a paragraph.
|
Process a paragraph.
|
||||||
In the first book, a paragraph is a single line. In the latter ones
|
In the first book, a paragraph is a single line. In the latter ones
|
||||||
@ -124,26 +124,26 @@ class SofImport(OooImport):
|
|||||||
while textportions.hasMoreElements():
|
while textportions.hasMoreElements():
|
||||||
textportion = textportions.nextElement()
|
textportion = textportions.nextElement()
|
||||||
if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
|
if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
|
||||||
self.process_paragraph_text(text)
|
self.processParagraphText(text)
|
||||||
self.new_song()
|
self.newSong()
|
||||||
text = u''
|
text = u''
|
||||||
text += self.process_textportion(textportion)
|
text += self.process_textportion(textportion)
|
||||||
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
|
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
|
||||||
self.process_paragraph_text(text)
|
self.processParagraphText(text)
|
||||||
self.new_song()
|
self.newSong()
|
||||||
text = u''
|
text = u''
|
||||||
self.process_paragraph_text(text)
|
self.processParagraphText(text)
|
||||||
|
|
||||||
def process_paragraph_text(self, text):
|
def processParagraphText(self, text):
|
||||||
"""
|
"""
|
||||||
Split the paragraph text into multiple lines and process
|
Split the paragraph text into multiple lines and process
|
||||||
"""
|
"""
|
||||||
for line in text.split(u'\n'):
|
for line in text.split(u'\n'):
|
||||||
self.process_paragraph_line(line)
|
self.processParagraphLine(line)
|
||||||
if self.blanklines > 2:
|
if self.blankLines > 2:
|
||||||
self.new_song()
|
self.newSong()
|
||||||
|
|
||||||
def process_paragraph_line(self, text):
|
def processParagraphLine(self, text):
|
||||||
"""
|
"""
|
||||||
Process a single line. Throw away that text which isn't relevant, i.e.
|
Process a single line. Throw away that text which isn't relevant, i.e.
|
||||||
stuff that appears at the end of the song.
|
stuff that appears at the end of the song.
|
||||||
@ -151,16 +151,16 @@ class SofImport(OooImport):
|
|||||||
"""
|
"""
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
if text == u'':
|
if text == u'':
|
||||||
self.blanklines += 1
|
self.blankLines += 1
|
||||||
if self.blanklines > 1:
|
if self.blankLines > 1:
|
||||||
return
|
return
|
||||||
if self.title != u'':
|
if self.title != u'':
|
||||||
self.finish_verse()
|
self.finishVerse()
|
||||||
return
|
return
|
||||||
self.blanklines = 0
|
self.blankLines = 0
|
||||||
if self.skip_to_close_bracket:
|
if self.skipToCloseBracket:
|
||||||
if text.endswith(u')'):
|
if text.endswith(u')'):
|
||||||
self.skip_to_close_bracket = False
|
self.skipToCloseBracket = False
|
||||||
return
|
return
|
||||||
if text.startswith(u'CCL Licence'):
|
if text.startswith(u'CCL Licence'):
|
||||||
self.italics = False
|
self.italics = False
|
||||||
@ -169,24 +169,24 @@ class SofImport(OooImport):
|
|||||||
return
|
return
|
||||||
if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \
|
if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \
|
||||||
or text.startswith(u'(From'):
|
or text.startswith(u'(From'):
|
||||||
self.skip_to_close_bracket = True
|
self.skipToCloseBracket = True
|
||||||
return
|
return
|
||||||
if text.startswith(u'Copyright'):
|
if text.startswith(u'Copyright'):
|
||||||
self.add_copyright(text)
|
self.addCopyright(text)
|
||||||
return
|
return
|
||||||
if text == u'(Repeat)':
|
if text == u'(Repeat)':
|
||||||
self.finish_verse()
|
self.finishVerse()
|
||||||
self.repeat_verse()
|
self.repeatVerse()
|
||||||
return
|
return
|
||||||
if self.title == u'':
|
if self.title == u'':
|
||||||
if self.copyright == u'':
|
if self.copyright == u'':
|
||||||
self.add_sof_author(text)
|
self.addSofAuthor(text)
|
||||||
else:
|
else:
|
||||||
self.add_copyright(text)
|
self.addCopyright(text)
|
||||||
return
|
return
|
||||||
self.add_verse_line(text)
|
self.addVerseLine(text)
|
||||||
|
|
||||||
def process_textportion(self, textportion):
|
def processTextPortion(self, textportion):
|
||||||
"""
|
"""
|
||||||
Process a text portion. Here we just get the text and detect if
|
Process a text portion. Here we just get the text and detect if
|
||||||
it's bold or italics. If it's bold then its a song number or song title.
|
it's bold or italics. If it's bold then its a song number or song title.
|
||||||
@ -199,53 +199,53 @@ class SofImport(OooImport):
|
|||||||
return text
|
return text
|
||||||
if textportion.CharWeight == BOLD:
|
if textportion.CharWeight == BOLD:
|
||||||
boldtext = text.strip()
|
boldtext = text.strip()
|
||||||
if boldtext.isdigit() and self.song_number == '':
|
if boldtext.isdigit() and self.songNumber == '':
|
||||||
self.add_songnumber(boldtext)
|
self.addSongNumber(boldtext)
|
||||||
return u''
|
return u''
|
||||||
if self.title == u'':
|
if self.title == u'':
|
||||||
text = self.uncap_text(text)
|
text = self.uncap_text(text)
|
||||||
self.add_title(text)
|
self.addTitle(text)
|
||||||
return text
|
return text
|
||||||
if text.strip().startswith(u'('):
|
if text.strip().startswith(u'('):
|
||||||
return text
|
return text
|
||||||
self.italics = (textportion.CharPosture == ITALIC)
|
self.italics = (textportion.CharPosture == ITALIC)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def new_song(self):
|
def newSong(self):
|
||||||
"""
|
"""
|
||||||
A change of song. Store the old, create a new
|
A change of song. Store the old, create a new
|
||||||
... but only if the last song was complete. If not, stick with it
|
... but only if the last song was complete. If not, stick with it
|
||||||
"""
|
"""
|
||||||
if self.song:
|
if self.song:
|
||||||
self.finish_verse()
|
self.finishVerse()
|
||||||
if not self.check_complete():
|
if not self.checkComplete():
|
||||||
return
|
return
|
||||||
self.finish()
|
self.finish()
|
||||||
self.song = True
|
self.song = True
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
self.skip_to_close_bracket = False
|
self.skipToCloseBracket = False
|
||||||
self.is_chorus = False
|
self.isChorus = False
|
||||||
self.italics = False
|
self.italics = False
|
||||||
self.currentverse = u''
|
self.currentVerse = u''
|
||||||
|
|
||||||
def add_songnumber(self, song_no):
|
def addSongNumber(self, song_no):
|
||||||
"""
|
"""
|
||||||
Add a song number, store as alternate title. Also use the song
|
Add a song number, store as alternate title. Also use the song
|
||||||
number to work out which songbook we're in
|
number to work out which songbook we're in
|
||||||
"""
|
"""
|
||||||
self.song_number = song_no
|
self.songNumber = song_no
|
||||||
self.alternate_title = song_no + u'.'
|
self.alternateTitle = song_no + u'.'
|
||||||
self.song_book_pub = u'Kingsway Publications'
|
self.songBook_pub = u'Kingsway Publications'
|
||||||
if int(song_no) <= 640:
|
if int(song_no) <= 640:
|
||||||
self.song_book = u'Songs of Fellowship 1'
|
self.songBook = u'Songs of Fellowship 1'
|
||||||
elif int(song_no) <= 1150:
|
elif int(song_no) <= 1150:
|
||||||
self.song_book = u'Songs of Fellowship 2'
|
self.songBook = u'Songs of Fellowship 2'
|
||||||
elif int(song_no) <= 1690:
|
elif int(song_no) <= 1690:
|
||||||
self.song_book = u'Songs of Fellowship 3'
|
self.songBook = u'Songs of Fellowship 3'
|
||||||
else:
|
else:
|
||||||
self.song_book = u'Songs of Fellowship 4'
|
self.songBook = u'Songs of Fellowship 4'
|
||||||
|
|
||||||
def add_title(self, text):
|
def addTitle(self, text):
|
||||||
"""
|
"""
|
||||||
Add the title to the song. Strip some leading/trailing punctuation that
|
Add the title to the song. Strip some leading/trailing punctuation that
|
||||||
we don't want in a title
|
we don't want in a title
|
||||||
@ -256,9 +256,9 @@ class SofImport(OooImport):
|
|||||||
if title.endswith(u','):
|
if title.endswith(u','):
|
||||||
title = title[:-1]
|
title = title[:-1]
|
||||||
self.title = title
|
self.title = title
|
||||||
self.import_wizard.incrementProgressBar(u'Processing song ' + title, 0)
|
self.importWizard.incrementProgressBar(u'Processing song ' + title, 0)
|
||||||
|
|
||||||
def add_sof_author(self, text):
|
def addSofAuthor(self, text):
|
||||||
"""
|
"""
|
||||||
Add the author. OpenLP stores them individually so split by 'and', '&'
|
Add the author. OpenLP stores them individually so split by 'and', '&'
|
||||||
and comma.
|
and comma.
|
||||||
@ -266,42 +266,42 @@ class SofImport(OooImport):
|
|||||||
"Mr Smith" and "Mrs Smith".
|
"Mr Smith" and "Mrs Smith".
|
||||||
"""
|
"""
|
||||||
text = text.replace(u' and ', u' & ')
|
text = text.replace(u' and ', u' & ')
|
||||||
self.parse_author(text)
|
self.parseAuthor(text)
|
||||||
|
|
||||||
def add_verse_line(self, text):
|
def addVerseLine(self, text):
|
||||||
"""
|
"""
|
||||||
Add a line to the current verse. If the formatting has changed and
|
Add a line to the current verse. If the formatting has changed and
|
||||||
we're beyond the second line of first verse, then this indicates
|
we're beyond the second line of first verse, then this indicates
|
||||||
a change of verse. Italics are a chorus
|
a change of verse. Italics are a chorus
|
||||||
"""
|
"""
|
||||||
if self.italics != self.is_chorus and ((len(self.verses) > 0) or
|
if self.italics != self.isChorus and ((len(self.verses) > 0) or
|
||||||
(self.currentverse.count(u'\n') > 1)):
|
(self.currentVerse.count(u'\n') > 1)):
|
||||||
self.finish_verse()
|
self.finishVerse()
|
||||||
if self.italics:
|
if self.italics:
|
||||||
self.is_chorus = True
|
self.isChorus = True
|
||||||
self.currentverse += text + u'\n'
|
self.currentVerse += text + u'\n'
|
||||||
|
|
||||||
def finish_verse(self):
|
def finishVerse(self):
|
||||||
"""
|
"""
|
||||||
Verse is finished, store it. Note in book 1+2, some songs are formatted
|
Verse is finished, store it. Note in book 1+2, some songs are formatted
|
||||||
incorrectly. Here we try and split songs with missing line breaks into
|
incorrectly. Here we try and split songs with missing line breaks into
|
||||||
the correct number of verses.
|
the correct number of verses.
|
||||||
"""
|
"""
|
||||||
if self.currentverse.strip() == u'':
|
if self.currentVerse.strip() == u'':
|
||||||
return
|
return
|
||||||
if self.is_chorus:
|
if self.isChorus:
|
||||||
versetag = u'C'
|
versetag = u'C'
|
||||||
splitat = None
|
splitat = None
|
||||||
else:
|
else:
|
||||||
versetag = u'V'
|
versetag = u'V'
|
||||||
splitat = self.verse_splits(self.song_number)
|
splitat = self.verseSplits(self.songNumber)
|
||||||
if splitat:
|
if splitat:
|
||||||
ln = 0
|
ln = 0
|
||||||
verse = u''
|
verse = u''
|
||||||
for line in self.currentverse.split(u'\n'):
|
for line in self.currentVerse.split(u'\n'):
|
||||||
ln += 1
|
ln += 1
|
||||||
if line == u'' or ln > splitat:
|
if line == u'' or ln > splitat:
|
||||||
self.add_sof_verse(verse, versetag)
|
self.addSofVerse(verse, versetag)
|
||||||
ln = 0
|
ln = 0
|
||||||
if line:
|
if line:
|
||||||
verse = line + u'\n'
|
verse = line + u'\n'
|
||||||
@ -310,19 +310,19 @@ class SofImport(OooImport):
|
|||||||
else:
|
else:
|
||||||
verse += line + u'\n'
|
verse += line + u'\n'
|
||||||
if verse:
|
if verse:
|
||||||
self.add_sof_verse(verse, versetag)
|
self.addSofVerse(verse, versetag)
|
||||||
else:
|
else:
|
||||||
self.add_sof_verse(self.currentverse, versetag)
|
self.addSofVerse(self.currentVerse, versetag)
|
||||||
self.currentverse = u''
|
self.currentVerse = u''
|
||||||
self.is_chorus = False
|
self.isChorus = False
|
||||||
|
|
||||||
def add_sof_verse(self, lyrics, tag):
|
def addSofVerse(self, lyrics, tag):
|
||||||
self.add_verse(lyrics, tag)
|
self.addVerse(lyrics, tag)
|
||||||
if not self.is_chorus and u'C1' in self.verse_order_list_generated:
|
if not self.isChorus and u'C1' in self.verseOrderListGenerated:
|
||||||
self.verse_order_list_generated.append(u'C1')
|
self.verseOrderListGenerated.append(u'C1')
|
||||||
self.verse_order_list_generated_useful = True
|
self.verseOrderListGenerated_useful = True
|
||||||
|
|
||||||
def uncap_text(self, text):
|
def uncapText(self, text):
|
||||||
"""
|
"""
|
||||||
Words in the title are in all capitals, so we lowercase them.
|
Words in the title are in all capitals, so we lowercase them.
|
||||||
However some of these words, e.g. referring to God need a leading
|
However some of these words, e.g. referring to God need a leading
|
||||||
@ -348,7 +348,7 @@ class SofImport(OooImport):
|
|||||||
text = u''.join(textarr)
|
text = u''.join(textarr)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def verse_splits(self, song_number):
|
def verseSplits(self, song_number):
|
||||||
"""
|
"""
|
||||||
Because someone at Kingsway forgot to check the 1+2 RTF file,
|
Because someone at Kingsway forgot to check the 1+2 RTF file,
|
||||||
some verses were not formatted correctly.
|
some verses were not formatted correctly.
|
||||||
|
@ -98,20 +98,20 @@ class SongBeamerImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Receive a single file or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
if not isinstance(self.import_source, list):
|
if not isinstance(self.importSource, list):
|
||||||
return
|
return
|
||||||
for file in self.import_source:
|
for file in self.importSource:
|
||||||
# TODO: check that it is a valid SongBeamer file
|
# TODO: check that it is a valid SongBeamer file
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
self.current_verse = u''
|
self.currentVerse = u''
|
||||||
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
self.currentVerseType = VerseType.Tags[VerseType.Verse]
|
||||||
read_verses = False
|
read_verses = False
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
if os.path.isfile(file):
|
if os.path.isfile(file):
|
||||||
@ -119,48 +119,48 @@ class SongBeamerImport(SongImport):
|
|||||||
details = chardet.detect(detect_file.read())
|
details = chardet.detect(detect_file.read())
|
||||||
detect_file.close()
|
detect_file.close()
|
||||||
infile = codecs.open(file, u'r', details['encoding'])
|
infile = codecs.open(file, u'r', details['encoding'])
|
||||||
songData = infile.readlines()
|
song_data = infile.readlines()
|
||||||
infile.close()
|
infile.close()
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
self.title = file_name.split('.sng')[0]
|
self.title = file_name.split('.sng')[0]
|
||||||
read_verses = False
|
read_verses = False
|
||||||
for line in songData:
|
for line in song_data:
|
||||||
# Just make sure that the line is of the type 'Unicode'.
|
# Just make sure that the line is of the type 'Unicode'.
|
||||||
line = unicode(line).strip()
|
line = unicode(line).strip()
|
||||||
if line.startswith(u'#') and not read_verses:
|
if line.startswith(u'#') and not read_verses:
|
||||||
self.parse_tags(line)
|
self.parseTags(line)
|
||||||
elif line.startswith(u'---'):
|
elif line.startswith(u'---'):
|
||||||
if self.current_verse:
|
if self.currentVerse:
|
||||||
self.replace_html_tags()
|
self.replaceHtmlTags()
|
||||||
self.add_verse(self.current_verse,
|
self.addVerse(self.currentVerse,
|
||||||
self.current_verse_type)
|
self.currentVerseType)
|
||||||
self.current_verse = u''
|
self.currentVerse = u''
|
||||||
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
self.currentVerseType = VerseType.Tags[VerseType.Verse]
|
||||||
read_verses = True
|
read_verses = True
|
||||||
verse_start = True
|
verse_start = True
|
||||||
elif read_verses:
|
elif read_verses:
|
||||||
if verse_start:
|
if verse_start:
|
||||||
verse_start = False
|
verse_start = False
|
||||||
if not self.check_verse_marks(line):
|
if not self.checkVerseMarks(line):
|
||||||
self.current_verse = line + u'\n'
|
self.currentVerse = line + u'\n'
|
||||||
else:
|
else:
|
||||||
self.current_verse += line + u'\n'
|
self.currentVerse += line + u'\n'
|
||||||
if self.current_verse:
|
if self.currentVerse:
|
||||||
self.replace_html_tags()
|
self.replaceHtmlTags()
|
||||||
self.add_verse(self.current_verse, self.current_verse_type)
|
self.addVerse(self.currentVerse, self.currentVerseType)
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(file)
|
self.logError(file)
|
||||||
|
|
||||||
def replace_html_tags(self):
|
def replaceHtmlTags(self):
|
||||||
"""
|
"""
|
||||||
This can be called to replace SongBeamer's specific (html) tags with
|
This can be called to replace SongBeamer's specific (html) tags with
|
||||||
OpenLP's specific (html) tags.
|
OpenLP's specific (html) tags.
|
||||||
"""
|
"""
|
||||||
for pair in SongBeamerImport.HTML_TAG_PAIRS:
|
for pair in SongBeamerImport.HTML_TAG_PAIRS:
|
||||||
self.current_verse = pair[0].sub(pair[1], self.current_verse)
|
self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
|
||||||
|
|
||||||
def parse_tags(self, line):
|
def parseTags(self, line):
|
||||||
"""
|
"""
|
||||||
Parses a meta data line.
|
Parses a meta data line.
|
||||||
|
|
||||||
@ -176,11 +176,11 @@ class SongBeamerImport(SongImport):
|
|||||||
if not tag_val[0] or not tag_val[1]:
|
if not tag_val[0] or not tag_val[1]:
|
||||||
return
|
return
|
||||||
if tag_val[0] == u'#(c)':
|
if tag_val[0] == u'#(c)':
|
||||||
self.add_copyright(tag_val[1])
|
self.addCopyright(tag_val[1])
|
||||||
elif tag_val[0] == u'#AddCopyrightInfo':
|
elif tag_val[0] == u'#AddCopyrightInfo':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#Author':
|
elif tag_val[0] == u'#Author':
|
||||||
self.parse_author(tag_val[1])
|
self.parseAuthor(tag_val[1])
|
||||||
elif tag_val[0] == u'#BackgroundImage':
|
elif tag_val[0] == u'#BackgroundImage':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#Bible':
|
elif tag_val[0] == u'#Bible':
|
||||||
@ -188,7 +188,7 @@ class SongBeamerImport(SongImport):
|
|||||||
elif tag_val[0] == u'#Categories':
|
elif tag_val[0] == u'#Categories':
|
||||||
self.topics = tag_val[1].split(',')
|
self.topics = tag_val[1].split(',')
|
||||||
elif tag_val[0] == u'#CCLI':
|
elif tag_val[0] == u'#CCLI':
|
||||||
self.ccli_number = tag_val[1]
|
self.ccliNumber = tag_val[1]
|
||||||
elif tag_val[0] == u'#Chords':
|
elif tag_val[0] == u'#Chords':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#ChurchSongID':
|
elif tag_val[0] == u'#ChurchSongID':
|
||||||
@ -220,7 +220,7 @@ class SongBeamerImport(SongImport):
|
|||||||
elif tag_val[0] == u'#LangCount':
|
elif tag_val[0] == u'#LangCount':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#Melody':
|
elif tag_val[0] == u'#Melody':
|
||||||
self.parse_author(tag_val[1])
|
self.parseAuthor(tag_val[1])
|
||||||
elif tag_val[0] == u'#NatCopyright':
|
elif tag_val[0] == u'#NatCopyright':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#OTitle':
|
elif tag_val[0] == u'#OTitle':
|
||||||
@ -235,10 +235,10 @@ class SongBeamerImport(SongImport):
|
|||||||
song_book_pub = tag_val[1]
|
song_book_pub = tag_val[1]
|
||||||
elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
|
elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
|
||||||
book_data = tag_val[1].split(u'/')
|
book_data = tag_val[1].split(u'/')
|
||||||
self.song_book_name = book_data[0].strip()
|
self.songBookName = book_data[0].strip()
|
||||||
if len(book_data) == 2:
|
if len(book_data) == 2:
|
||||||
number = book_data[1].strip()
|
number = book_data[1].strip()
|
||||||
self.song_number = number if number.isdigit() else u''
|
self.songNumber = number if number.isdigit() else u''
|
||||||
elif tag_val[0] == u'#Speed':
|
elif tag_val[0] == u'#Speed':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'Tempo':
|
elif tag_val[0] == u'Tempo':
|
||||||
@ -269,7 +269,7 @@ class SongBeamerImport(SongImport):
|
|||||||
# TODO: add the verse order.
|
# TODO: add the verse order.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def check_verse_marks(self, line):
|
def checkVerseMarks(self, line):
|
||||||
"""
|
"""
|
||||||
Check and add the verse's MarkType. Returns ``True`` if the given line
|
Check and add the verse's MarkType. Returns ``True`` if the given line
|
||||||
contains a correct verse mark otherwise ``False``.
|
contains a correct verse mark otherwise ``False``.
|
||||||
@ -279,10 +279,10 @@ class SongBeamerImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
marks = line.split(u' ')
|
marks = line.split(u' ')
|
||||||
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
|
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
|
||||||
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
|
self.currentVerseType = SongBeamerTypes.MarkTypes[marks[0]]
|
||||||
if len(marks) == 2:
|
if len(marks) == 2:
|
||||||
# If we have a digit, we append it to current_verse_type.
|
# If we have a digit, we append it to current_verse_type.
|
||||||
if marks[1].isdigit():
|
if marks[1].isdigit():
|
||||||
self.current_verse_type += marks[1]
|
self.currentVerseType += marks[1]
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||||
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
||||||
from openlp.plugins.songs.lib.ui import SongStrings
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
@ -58,51 +61,51 @@ class SongImport(QtCore.QObject):
|
|||||||
self.manager = manager
|
self.manager = manager
|
||||||
QtCore.QObject.__init__(self)
|
QtCore.QObject.__init__(self)
|
||||||
if kwargs.has_key(u'filename'):
|
if kwargs.has_key(u'filename'):
|
||||||
self.import_source = kwargs[u'filename']
|
self.importSource = kwargs[u'filename']
|
||||||
elif kwargs.has_key(u'filenames'):
|
elif kwargs.has_key(u'filenames'):
|
||||||
self.import_source = kwargs[u'filenames']
|
self.importSource = kwargs[u'filenames']
|
||||||
else:
|
else:
|
||||||
raise KeyError(u'Keyword arguments "filename[s]" not supplied.')
|
raise KeyError(u'Keyword arguments "filename[s]" not supplied.')
|
||||||
log.debug(self.import_source)
|
log.debug(self.importSource)
|
||||||
self.import_wizard = None
|
self.importWizard = None
|
||||||
self.song = None
|
self.song = None
|
||||||
self.stop_import_flag = False
|
self.stopImportFlag = False
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
self.error_log = []
|
self.errorLog = []
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)
|
||||||
|
|
||||||
def set_defaults(self):
|
def setDefaults(self):
|
||||||
"""
|
"""
|
||||||
Create defaults for properties - call this before each song
|
Create defaults for properties - call this before each song
|
||||||
if importing many songs at once to ensure a clean beginning
|
if importing many songs at once to ensure a clean beginning
|
||||||
"""
|
"""
|
||||||
self.title = u''
|
self.title = u''
|
||||||
self.song_number = u''
|
self.songNumber = u''
|
||||||
self.alternate_title = u''
|
self.alternateTitle = u''
|
||||||
self.copyright = u''
|
self.copyright = u''
|
||||||
self.comments = u''
|
self.comments = u''
|
||||||
self.theme_name = u''
|
self.themeName = u''
|
||||||
self.ccli_number = u''
|
self.ccliNumber = u''
|
||||||
self.authors = []
|
self.authors = []
|
||||||
self.topics = []
|
self.topics = []
|
||||||
self.media_files = []
|
self.mediaFiles = []
|
||||||
self.song_book_name = u''
|
self.songBookName = u''
|
||||||
self.song_book_pub = u''
|
self.songBookPub = u''
|
||||||
self.verse_order_list_generated_useful = False
|
self.verseOrderListGeneratedUseful = False
|
||||||
self.verse_order_list_generated = []
|
self.verseOrderListGenerated = []
|
||||||
self.verse_order_list = []
|
self.verseOrderList = []
|
||||||
self.verses = []
|
self.verses = []
|
||||||
self.verse_counts = {}
|
self.verseCounts = {}
|
||||||
self.copyright_string = unicode(translate(
|
self.copyrightString = unicode(translate(
|
||||||
'SongsPlugin.SongImport', 'copyright'))
|
'SongsPlugin.SongImport', 'copyright'))
|
||||||
|
|
||||||
def log_error(self, filepath, reason=SongStrings.SongIncomplete):
|
def logError(self, filepath, reason=SongStrings.SongIncomplete):
|
||||||
"""
|
"""
|
||||||
This should be called, when a song could not be imported.
|
This should be called, when a song could not be imported.
|
||||||
|
|
||||||
``filepath``
|
``filepath``
|
||||||
This should be the file path if ``self.import_source`` is a list
|
This should be the file path if ``self.importSource`` is a list
|
||||||
with different files. If it is not a list, but a single file (for
|
with different files. If it is not a list, but a single file (for
|
||||||
instance a database), then this should be the song's title.
|
instance a database), then this should be the song's title.
|
||||||
|
|
||||||
@ -110,30 +113,30 @@ class SongImport(QtCore.QObject):
|
|||||||
The reason, why the import failed. The string should be as
|
The reason, why the import failed. The string should be as
|
||||||
informative as possible.
|
informative as possible.
|
||||||
"""
|
"""
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
if self.import_wizard is None:
|
if self.importWizard is None:
|
||||||
return
|
return
|
||||||
if self.import_wizard.errorReportTextEdit.isHidden():
|
if self.importWizard.errorReportTextEdit.isHidden():
|
||||||
self.import_wizard.errorReportTextEdit.setText(
|
self.importWizard.errorReportTextEdit.setText(
|
||||||
translate('SongsPlugin.SongImport',
|
translate('SongsPlugin.SongImport',
|
||||||
'The following songs could not be imported:'))
|
'The following songs could not be imported:'))
|
||||||
self.import_wizard.errorReportTextEdit.setVisible(True)
|
self.importWizard.errorReportTextEdit.setVisible(True)
|
||||||
self.import_wizard.errorCopyToButton.setVisible(True)
|
self.importWizard.errorCopyToButton.setVisible(True)
|
||||||
self.import_wizard.errorSaveToButton.setVisible(True)
|
self.importWizard.errorSaveToButton.setVisible(True)
|
||||||
self.import_wizard.errorReportTextEdit.append(
|
self.importWizard.errorReportTextEdit.append(
|
||||||
u'- %s (%s)' % (filepath, reason))
|
u'- %s (%s)' % (filepath, reason))
|
||||||
|
|
||||||
def stop_import(self):
|
def stopImport(self):
|
||||||
"""
|
"""
|
||||||
Sets the flag for importers to stop their import
|
Sets the flag for importers to stop their import
|
||||||
"""
|
"""
|
||||||
log.debug(u'Stopping songs import')
|
log.debug(u'Stopping songs import')
|
||||||
self.stop_import_flag = True
|
self.stopImportFlag = True
|
||||||
|
|
||||||
def register(self, import_wizard):
|
def register(self, import_wizard):
|
||||||
self.import_wizard = import_wizard
|
self.importWizard = import_wizard
|
||||||
|
|
||||||
def tidy_text(self, text):
|
def tidyText(self, text):
|
||||||
"""
|
"""
|
||||||
Get rid of some dodgy unicode and formatting characters we're not
|
Get rid of some dodgy unicode and formatting characters we're not
|
||||||
interested in. Some can be converted to ascii.
|
interested in. Some can be converted to ascii.
|
||||||
@ -151,34 +154,34 @@ class SongImport(QtCore.QObject):
|
|||||||
text = re.sub(r' ?(\n{5}|\f)+ ?', u'\f', text)
|
text = re.sub(r' ?(\n{5}|\f)+ ?', u'\f', text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def process_song_text(self, text):
|
def processSongText(self, text):
|
||||||
verse_texts = text.split(u'\n\n')
|
verse_texts = text.split(u'\n\n')
|
||||||
for verse_text in verse_texts:
|
for verse_text in verse_texts:
|
||||||
if verse_text.strip() != u'':
|
if verse_text.strip() != u'':
|
||||||
self.process_verse_text(verse_text.strip())
|
self.processVerseText(verse_text.strip())
|
||||||
|
|
||||||
def process_verse_text(self, text):
|
def processVerseText(self, text):
|
||||||
lines = text.split(u'\n')
|
lines = text.split(u'\n')
|
||||||
if text.lower().find(self.copyright_string) >= 0 \
|
if text.lower().find(self.copyrightString) >= 0 \
|
||||||
or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
|
or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
|
||||||
copyright_found = False
|
copyright_found = False
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if (copyright_found or
|
if (copyright_found or
|
||||||
line.lower().find(self.copyright_string) >= 0 or
|
line.lower().find(self.copyrightString) >= 0 or
|
||||||
line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
|
line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
|
||||||
copyright_found = True
|
copyright_found = True
|
||||||
self.add_copyright(line)
|
self.addCopyright(line)
|
||||||
else:
|
else:
|
||||||
self.parse_author(line)
|
self.parseAuthor(line)
|
||||||
return
|
return
|
||||||
if len(lines) == 1:
|
if len(lines) == 1:
|
||||||
self.parse_author(lines[0])
|
self.parseAuthor(lines[0])
|
||||||
return
|
return
|
||||||
if not self.title:
|
if not self.title:
|
||||||
self.title = lines[0]
|
self.title = lines[0]
|
||||||
self.add_verse(text)
|
self.addVerse(text)
|
||||||
|
|
||||||
def add_copyright(self, copyright):
|
def addCopyright(self, copyright):
|
||||||
"""
|
"""
|
||||||
Build the copyright field
|
Build the copyright field
|
||||||
"""
|
"""
|
||||||
@ -188,7 +191,7 @@ class SongImport(QtCore.QObject):
|
|||||||
self.copyright += ' '
|
self.copyright += ' '
|
||||||
self.copyright += copyright
|
self.copyright += copyright
|
||||||
|
|
||||||
def parse_author(self, text):
|
def parseAuthor(self, text):
|
||||||
"""
|
"""
|
||||||
Add the author. OpenLP stores them individually so split by 'and', '&'
|
Add the author. OpenLP stores them individually so split by 'and', '&'
|
||||||
and comma. However need to check for 'Mr and Mrs Smith' and turn it to
|
and comma. However need to check for 'Mr and Mrs Smith' and turn it to
|
||||||
@ -204,9 +207,9 @@ class SongImport(QtCore.QObject):
|
|||||||
if author2.endswith(u'.'):
|
if author2.endswith(u'.'):
|
||||||
author2 = author2[:-1]
|
author2 = author2[:-1]
|
||||||
if author2:
|
if author2:
|
||||||
self.add_author(author2)
|
self.addAuthor(author2)
|
||||||
|
|
||||||
def add_author(self, author):
|
def addAuthor(self, author):
|
||||||
"""
|
"""
|
||||||
Add an author to the list
|
Add an author to the list
|
||||||
"""
|
"""
|
||||||
@ -214,15 +217,15 @@ class SongImport(QtCore.QObject):
|
|||||||
return
|
return
|
||||||
self.authors.append(author)
|
self.authors.append(author)
|
||||||
|
|
||||||
def add_media_file(self, filename):
|
def addMediaFile(self, filename, weight=0):
|
||||||
"""
|
"""
|
||||||
Add a media file to the list
|
Add a media file to the list
|
||||||
"""
|
"""
|
||||||
if filename in self.media_files:
|
if filename in map(lambda x: x[0], self.mediaFiles):
|
||||||
return
|
return
|
||||||
self.media_files.append(filename)
|
self.mediaFiles.append((filename, weight))
|
||||||
|
|
||||||
def add_verse(self, verse_text, verse_def=u'v', lang=None):
|
def addVerse(self, verse_text, verse_def=u'v', lang=None):
|
||||||
"""
|
"""
|
||||||
Add a verse. This is the whole verse, lines split by \\n. It will also
|
Add a verse. This is the whole verse, lines split by \\n. It will also
|
||||||
attempt to detect duplicates. In this case it will just add to the verse
|
attempt to detect duplicates. In this case it will just add to the verse
|
||||||
@ -241,29 +244,29 @@ class SongImport(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
for (old_verse_def, old_verse, old_lang) in self.verses:
|
for (old_verse_def, old_verse, old_lang) in self.verses:
|
||||||
if old_verse.strip() == verse_text.strip():
|
if old_verse.strip() == verse_text.strip():
|
||||||
self.verse_order_list_generated.append(old_verse_def)
|
self.verseOrderListGenerated.append(old_verse_def)
|
||||||
self.verse_order_list_generated_useful = True
|
self.verseOrderListGeneratedUseful = True
|
||||||
return
|
return
|
||||||
if verse_def[0] in self.verse_counts:
|
if verse_def[0] in self.verseCounts:
|
||||||
self.verse_counts[verse_def[0]] += 1
|
self.verseCounts[verse_def[0]] += 1
|
||||||
else:
|
else:
|
||||||
self.verse_counts[verse_def[0]] = 1
|
self.verseCounts[verse_def[0]] = 1
|
||||||
if len(verse_def) == 1:
|
if len(verse_def) == 1:
|
||||||
verse_def += unicode(self.verse_counts[verse_def[0]])
|
verse_def += unicode(self.verseCounts[verse_def[0]])
|
||||||
elif int(verse_def[1:]) > self.verse_counts[verse_def[0]]:
|
elif int(verse_def[1:]) > self.verseCounts[verse_def[0]]:
|
||||||
self.verse_counts[verse_def[0]] = int(verse_def[1:])
|
self.verseCounts[verse_def[0]] = int(verse_def[1:])
|
||||||
self.verses.append([verse_def, verse_text.rstrip(), lang])
|
self.verses.append([verse_def, verse_text.rstrip(), lang])
|
||||||
self.verse_order_list_generated.append(verse_def)
|
self.verseOrderListGenerated.append(verse_def)
|
||||||
|
|
||||||
def repeat_verse(self):
|
def repeatVerse(self):
|
||||||
"""
|
"""
|
||||||
Repeat the previous verse in the verse order
|
Repeat the previous verse in the verse order
|
||||||
"""
|
"""
|
||||||
self.verse_order_list_generated.append(
|
self.verseOrderListGenerated.append(
|
||||||
self.verse_order_list_generated[-1])
|
self.verseOrderListGenerated[-1])
|
||||||
self.verse_order_list_generated_useful = True
|
self.verseOrderListGeneratedUseful = True
|
||||||
|
|
||||||
def check_complete(self):
|
def checkComplete(self):
|
||||||
"""
|
"""
|
||||||
Check the mandatory fields are entered (i.e. title and a verse)
|
Check the mandatory fields are entered (i.e. title and a verse)
|
||||||
Author not checked here, if no author then "Author unknown" is
|
Author not checked here, if no author then "Author unknown" is
|
||||||
@ -278,21 +281,21 @@ class SongImport(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
All fields have been set to this song. Write the song to disk.
|
All fields have been set to this song. Write the song to disk.
|
||||||
"""
|
"""
|
||||||
if not self.check_complete():
|
if not self.checkComplete():
|
||||||
self.set_defaults()
|
self.setDefaults()
|
||||||
return False
|
return False
|
||||||
log.info(u'committing song %s to database', self.title)
|
log.info(u'committing song %s to database', self.title)
|
||||||
song = Song()
|
song = Song()
|
||||||
song.title = self.title
|
song.title = self.title
|
||||||
if self.import_wizard is not None:
|
if self.importWizard is not None:
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % song.title)
|
WizardStrings.ImportingType % song.title)
|
||||||
song.alternate_title = self.alternate_title
|
song.alternate_title = self.alternateTitle
|
||||||
# Values will be set when cleaning the song.
|
# Values will be set when cleaning the song.
|
||||||
song.search_title = u''
|
song.search_title = u''
|
||||||
song.search_lyrics = u''
|
song.search_lyrics = u''
|
||||||
song.verse_order = u''
|
song.verse_order = u''
|
||||||
song.song_number = self.song_number
|
song.song_number = self.songNumber
|
||||||
verses_changed_to_other = {}
|
verses_changed_to_other = {}
|
||||||
sxml = SongXML()
|
sxml = SongXML()
|
||||||
other_count = 1
|
other_count = 1
|
||||||
@ -310,18 +313,18 @@ class SongImport(QtCore.QObject):
|
|||||||
verse_def = new_verse_def
|
verse_def = new_verse_def
|
||||||
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
|
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
|
||||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||||
if not len(self.verse_order_list) and \
|
if not len(self.verseOrderList) and \
|
||||||
self.verse_order_list_generated_useful:
|
self.verseOrderListGeneratedUseful:
|
||||||
self.verse_order_list = self.verse_order_list_generated
|
self.verseOrderList = self.verseOrderListGenerated
|
||||||
for i, current_verse_def in enumerate(self.verse_order_list):
|
for i, current_verse_def in enumerate(self.verseOrderList):
|
||||||
if verses_changed_to_other.has_key(current_verse_def):
|
if verses_changed_to_other.has_key(current_verse_def):
|
||||||
self.verse_order_list[i] = \
|
self.verseOrderList[i] = \
|
||||||
verses_changed_to_other[current_verse_def]
|
verses_changed_to_other[current_verse_def]
|
||||||
song.verse_order = u' '.join(self.verse_order_list)
|
song.verse_order = u' '.join(self.verseOrderList)
|
||||||
song.copyright = self.copyright
|
song.copyright = self.copyright
|
||||||
song.comments = self.comments
|
song.comments = self.comments
|
||||||
song.theme_name = self.theme_name
|
song.theme_name = self.themeName
|
||||||
song.ccli_number = self.ccli_number
|
song.ccli_number = self.ccliNumber
|
||||||
for authortext in self.authors:
|
for authortext in self.authors:
|
||||||
author = self.manager.get_object_filtered(Author,
|
author = self.manager.get_object_filtered(Author,
|
||||||
Author.display_name == authortext)
|
Author.display_name == authortext)
|
||||||
@ -330,17 +333,12 @@ class SongImport(QtCore.QObject):
|
|||||||
last_name=authortext.split(u' ')[-1],
|
last_name=authortext.split(u' ')[-1],
|
||||||
first_name=u' '.join(authortext.split(u' ')[:-1]))
|
first_name=u' '.join(authortext.split(u' ')[:-1]))
|
||||||
song.authors.append(author)
|
song.authors.append(author)
|
||||||
for filename in self.media_files:
|
if self.songBookName:
|
||||||
media_file = self.manager.get_object_filtered(MediaFile,
|
|
||||||
MediaFile.file_name == filename)
|
|
||||||
if not media_file:
|
|
||||||
song.media_files.append(MediaFile.populate(file_name=filename))
|
|
||||||
if self.song_book_name:
|
|
||||||
song_book = self.manager.get_object_filtered(Book,
|
song_book = self.manager.get_object_filtered(Book,
|
||||||
Book.name == self.song_book_name)
|
Book.name == self.songBookName)
|
||||||
if song_book is None:
|
if song_book is None:
|
||||||
song_book = Book.populate(name=self.song_book_name,
|
song_book = Book.populate(name=self.songBookName,
|
||||||
publisher=self.song_book_pub)
|
publisher=self.songBookPub)
|
||||||
song.book = song_book
|
song.book = song_book
|
||||||
for topictext in self.topics:
|
for topictext in self.topics:
|
||||||
if not topictext:
|
if not topictext:
|
||||||
@ -350,38 +348,42 @@ class SongImport(QtCore.QObject):
|
|||||||
if topic is None:
|
if topic is None:
|
||||||
topic = Topic.populate(name=topictext)
|
topic = Topic.populate(name=topictext)
|
||||||
song.topics.append(topic)
|
song.topics.append(topic)
|
||||||
|
# We need to save the song now, before adding the media files, so that
|
||||||
|
# we know where to save the media files to.
|
||||||
clean_song(self.manager, song)
|
clean_song(self.manager, song)
|
||||||
self.manager.save_object(song)
|
self.manager.save_object(song)
|
||||||
self.set_defaults()
|
# Now loop through the media files, copy them to the correct location,
|
||||||
|
# and save the song again.
|
||||||
|
for filename, weight in self.mediaFiles:
|
||||||
|
media_file = self.manager.get_object_filtered(MediaFile,
|
||||||
|
MediaFile.file_name == filename)
|
||||||
|
if not media_file:
|
||||||
|
if os.path.dirname(filename):
|
||||||
|
filename = self.copyMediaFile(song.id, filename)
|
||||||
|
song.media_files.append(
|
||||||
|
MediaFile.populate(file_name=filename, weight=weight)
|
||||||
|
)
|
||||||
|
self.manager.save_object(song)
|
||||||
|
self.setDefaults()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def print_song(self):
|
def copyMediaFile(self, song_id, filename):
|
||||||
"""
|
"""
|
||||||
For debugging
|
This method copies the media file to the correct location and returns
|
||||||
|
the new file location.
|
||||||
|
|
||||||
|
``filename``
|
||||||
|
The file to copy.
|
||||||
"""
|
"""
|
||||||
print u'========================================' \
|
if not hasattr(self, u'save_path'):
|
||||||
+ u'========================================'
|
self.save_path = os.path.join(
|
||||||
print u'TITLE: ' + self.title
|
AppLocation.get_section_data_path(
|
||||||
print u'ALT TITLE: ' + self.alternate_title
|
self.importWizard.plugin.name),
|
||||||
for (verse_def, verse_text, lang) in self.verses:
|
'audio', str(song_id))
|
||||||
print u'VERSE ' + verse_def + u': ' + verse_text
|
if not os.path.exists(self.save_path):
|
||||||
print u'ORDER: ' + u' '.join(self.verse_order_list)
|
os.makedirs(self.save_path)
|
||||||
print u'GENERATED ORDER: ' + u' '.join(self.verse_order_list_generated)
|
if not filename.startswith(self.save_path):
|
||||||
for author in self.authors:
|
oldfile, filename = filename, os.path.join(self.save_path,
|
||||||
print u'AUTHOR: ' + author
|
os.path.split(filename)[1])
|
||||||
if self.copyright:
|
shutil.copyfile(oldfile, filename)
|
||||||
print u'COPYRIGHT: ' + self.copyright
|
return filename
|
||||||
if self.song_book_name:
|
|
||||||
print u'BOOK: ' + self.song_book_name
|
|
||||||
if self.song_book_pub:
|
|
||||||
print u'BOOK PUBLISHER: ' + self.song_book_pub
|
|
||||||
if self.song_number:
|
|
||||||
print u'NUMBER: ' + self.song_number
|
|
||||||
for topictext in self.topics:
|
|
||||||
print u'TOPIC: ' + topictext
|
|
||||||
if self.comments:
|
|
||||||
print u'COMMENTS: ' + self.comments
|
|
||||||
if self.theme_name:
|
|
||||||
print u'THEME: ' + self.theme_name
|
|
||||||
if self.ccli_number:
|
|
||||||
print u'CCLI: ' + self.ccli_number
|
|
||||||
|
@ -95,120 +95,120 @@ class SongShowPlusImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Receive a single file or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.import_source, list):
|
if not isinstance(self.importSource, list):
|
||||||
return
|
return
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for file in self.import_source:
|
for file in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
self.sspVerseOrderList = []
|
self.sspVerseOrderList = []
|
||||||
otherCount = 0
|
other_count = 0
|
||||||
otherList = {}
|
other_list = {}
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
self.importWizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
WizardStrings.ImportingType % file_name, 0)
|
||||||
songData = open(file, 'rb')
|
song_data = open(file, 'rb')
|
||||||
while True:
|
while True:
|
||||||
blockKey, = struct.unpack("I", songData.read(4))
|
block_key, = struct.unpack("I", song_data.read(4))
|
||||||
# The file ends with 4 NUL's
|
# The file ends with 4 NUL's
|
||||||
if blockKey == 0:
|
if block_key == 0:
|
||||||
break
|
break
|
||||||
nextBlockStarts, = struct.unpack("I", songData.read(4))
|
next_block_starts, = struct.unpack("I", song_data.read(4))
|
||||||
nextBlockStarts += songData.tell()
|
next_block_starts += song_data.tell()
|
||||||
if blockKey in (VERSE, CHORUS, BRIDGE):
|
if block_key in (VERSE, CHORUS, BRIDGE):
|
||||||
null, verseNo, = struct.unpack("BB", songData.read(2))
|
null, verse_no, = struct.unpack("BB", song_data.read(2))
|
||||||
elif blockKey == CUSTOM_VERSE:
|
elif block_key == CUSTOM_VERSE:
|
||||||
null, verseNameLength, = struct.unpack("BB",
|
null, verse_name_length, = struct.unpack("BB",
|
||||||
songData.read(2))
|
song_data.read(2))
|
||||||
verseName = songData.read(verseNameLength)
|
verse_name = song_data.read(verse_name_length)
|
||||||
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
length_descriptor_size, = struct.unpack("B", song_data.read(1))
|
||||||
log.debug(lengthDescriptorSize)
|
log.debug(length_descriptor_size)
|
||||||
# Detect if/how long the length descriptor is
|
# Detect if/how long the length descriptor is
|
||||||
if lengthDescriptorSize == 12 or lengthDescriptorSize == 20:
|
if length_descriptor_size == 12 or length_descriptor_size == 20:
|
||||||
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
length_descriptor, = struct.unpack("I", song_data.read(4))
|
||||||
elif lengthDescriptorSize == 2:
|
elif length_descriptor_size == 2:
|
||||||
lengthDescriptor = 1
|
length_descriptor = 1
|
||||||
elif lengthDescriptorSize == 9:
|
elif length_descriptor_size == 9:
|
||||||
lengthDescriptor = 0
|
length_descriptor = 0
|
||||||
else:
|
else:
|
||||||
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
length_descriptor, = struct.unpack("B", song_data.read(1))
|
||||||
log.debug(lengthDescriptorSize)
|
log.debug(length_descriptor_size)
|
||||||
data = songData.read(lengthDescriptor)
|
data = song_data.read(length_descriptor)
|
||||||
if blockKey == TITLE:
|
if block_key == TITLE:
|
||||||
self.title = unicode(data, u'cp1252')
|
self.title = unicode(data, u'cp1252')
|
||||||
elif blockKey == 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.parse_author(unicode(author, u'cp1252'))
|
self.parseAuthor(unicode(author, u'cp1252'))
|
||||||
elif blockKey == COPYRIGHT:
|
elif block_key == COPYRIGHT:
|
||||||
self.add_copyright(unicode(data, u'cp1252'))
|
self.addCopyright(unicode(data, u'cp1252'))
|
||||||
elif blockKey == CCLI_NO:
|
elif block_key == CCLI_NO:
|
||||||
self.ccli_number = int(data)
|
self.ccliNumber = int(data)
|
||||||
elif blockKey == VERSE:
|
elif block_key == VERSE:
|
||||||
self.add_verse(unicode(data, u'cp1252'),
|
self.addVerse(unicode(data, u'cp1252'),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Verse], verseNo))
|
"%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
|
||||||
elif blockKey == CHORUS:
|
elif block_key == CHORUS:
|
||||||
self.add_verse(unicode(data, u'cp1252'),
|
self.addVerse(unicode(data, u'cp1252'),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Chorus], verseNo))
|
"%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
|
||||||
elif blockKey == BRIDGE:
|
elif block_key == BRIDGE:
|
||||||
self.add_verse(unicode(data, u'cp1252'),
|
self.addVerse(unicode(data, u'cp1252'),
|
||||||
"%s%s" % (VerseType.Tags[VerseType.Bridge], verseNo))
|
"%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
|
||||||
elif blockKey == TOPIC:
|
elif block_key == TOPIC:
|
||||||
self.topics.append(unicode(data, u'cp1252'))
|
self.topics.append(unicode(data, u'cp1252'))
|
||||||
elif blockKey == COMMENTS:
|
elif block_key == COMMENTS:
|
||||||
self.comments = unicode(data, u'cp1252')
|
self.comments = unicode(data, u'cp1252')
|
||||||
elif blockKey == VERSE_ORDER:
|
elif block_key == VERSE_ORDER:
|
||||||
verseTag = self.toOpenLPVerseTag(data, True)
|
verse_tag = self.toOpenLPVerseTag(data, True)
|
||||||
if verseTag:
|
if verse_tag:
|
||||||
if not isinstance(verseTag, unicode):
|
if not isinstance(verse_tag, unicode):
|
||||||
verseTag = unicode(verseTag, u'cp1252')
|
verse_tag = unicode(verse_tag, u'cp1252')
|
||||||
self.sspVerseOrderList.append(verseTag)
|
self.sspVerseOrderList.append(verse_tag)
|
||||||
elif blockKey == SONG_BOOK:
|
elif block_key == SONG_BOOK:
|
||||||
self.song_book_name = unicode(data, u'cp1252')
|
self.songBookName = unicode(data, u'cp1252')
|
||||||
elif blockKey == SONG_NUMBER:
|
elif block_key == SONG_NUMBER:
|
||||||
self.song_number = ord(data)
|
self.songNumber = ord(data)
|
||||||
elif blockKey == CUSTOM_VERSE:
|
elif block_key == CUSTOM_VERSE:
|
||||||
verseTag = self.toOpenLPVerseTag(verseName)
|
verse_tag = self.toOpenLPVerseTag(verse_name)
|
||||||
self.add_verse(unicode(data, u'cp1252'), verseTag)
|
self.addVerse(unicode(data, u'cp1252'), verse_tag)
|
||||||
else:
|
else:
|
||||||
log.debug("Unrecognised blockKey: %s, data: %s"
|
log.debug("Unrecognised blockKey: %s, data: %s"
|
||||||
% (blockKey, data))
|
% (block_key, data))
|
||||||
songData.seek(nextBlockStarts)
|
song_data.seek(next_block_starts)
|
||||||
self.verse_order_list = self.sspVerseOrderList
|
self.verseOrderList = self.sspVerseOrderList
|
||||||
songData.close()
|
song_data.close()
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(file)
|
self.logError(file)
|
||||||
|
|
||||||
def toOpenLPVerseTag(self, verseName, ignoreUnique=False):
|
def toOpenLPVerseTag(self, verse_name, ignore_unique=False):
|
||||||
if verseName.find(" ") != -1:
|
if verse_name.find(" ") != -1:
|
||||||
verseParts = verseName.split(" ")
|
verse_parts = verse_name.split(" ")
|
||||||
verseType = verseParts[0]
|
verse_type = verse_parts[0]
|
||||||
verseNumber = verseParts[1]
|
verse_number = verse_parts[1]
|
||||||
else:
|
else:
|
||||||
verseType = verseName
|
verse_type = verse_name
|
||||||
verseNumber = "1"
|
verse_number = "1"
|
||||||
verseType = verseType.lower()
|
verse_type = verse_type.lower()
|
||||||
if verseType == "verse":
|
if verse_type == "verse":
|
||||||
verseTag = VerseType.Tags[VerseType.Verse]
|
verse_tag = VerseType.Tags[VerseType.Verse]
|
||||||
elif verseType == "chorus":
|
elif verse_type == "chorus":
|
||||||
verseTag = VerseType.Tags[VerseType.Chorus]
|
verse_tag = VerseType.Tags[VerseType.Chorus]
|
||||||
elif verseType == "bridge":
|
elif verse_type == "bridge":
|
||||||
verseTag = VerseType.Tags[VerseType.Bridge]
|
verse_tag = VerseType.Tags[VerseType.Bridge]
|
||||||
elif verseType == "pre-chorus":
|
elif verse_type == "pre-chorus":
|
||||||
verseTag = VerseType.Tags[VerseType.PreChorus]
|
verse_tag = VerseType.Tags[VerseType.PreChorus]
|
||||||
else:
|
else:
|
||||||
if not self.otherList.has_key(verseName):
|
if not self.otherList.has_key(verse_name):
|
||||||
if ignoreUnique:
|
if ignore_unique:
|
||||||
return None
|
return None
|
||||||
self.otherCount = self.otherCount + 1
|
self.otherCount = self.otherCount + 1
|
||||||
self.otherList[verseName] = str(self.otherCount)
|
self.otherList[verse_name] = str(self.otherCount)
|
||||||
verseTag = VerseType.Tags[VerseType.Other]
|
verse_tag = VerseType.Tags[VerseType.Other]
|
||||||
verseNumber = self.otherList[verseName]
|
verse_number = self.otherList[verse_name]
|
||||||
return verseTag + verseNumber
|
return verse_tag + verse_number
|
||||||
|
@ -98,58 +98,58 @@ class WowImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def doImport(self):
|
||||||
"""
|
"""
|
||||||
Receive a single file or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.import_source, list):
|
if isinstance(self.importSource, list):
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for file in self.import_source:
|
for file in self.importSource:
|
||||||
if self.stop_import_flag:
|
if self.stopImportFlag:
|
||||||
return
|
return
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
# Get the song title
|
# Get the song title
|
||||||
self.title = file_name.rpartition(u'.')[0]
|
self.title = file_name.rpartition(u'.')[0]
|
||||||
songData = open(file, 'rb')
|
song_data = open(file, 'rb')
|
||||||
if songData.read(19) != u'WoW File\nSong Words':
|
if song_data.read(19) != u'WoW File\nSong Words':
|
||||||
self.log_error(file)
|
self.logError(file)
|
||||||
continue
|
continue
|
||||||
# Seek to byte which stores number of blocks in the song
|
# Seek to byte which stores number of blocks in the song
|
||||||
songData.seek(56)
|
song_data.seek(56)
|
||||||
no_of_blocks = ord(songData.read(1))
|
no_of_blocks = ord(song_data.read(1))
|
||||||
# Seek to the beging of the first block
|
# Seek to the beging of the first block
|
||||||
songData.seek(82)
|
song_data.seek(82)
|
||||||
for block in range(no_of_blocks):
|
for block in range(no_of_blocks):
|
||||||
self.lines_to_read = ord(songData.read(1))
|
self.linesToRead = ord(song_data.read(1))
|
||||||
# Skip 3 nulls to the beginnig of the 1st line
|
# Skip 3 nulls to the beginnig of the 1st line
|
||||||
songData.seek(3, os.SEEK_CUR)
|
song_data.seek(3, os.SEEK_CUR)
|
||||||
block_text = u''
|
block_text = u''
|
||||||
while self.lines_to_read:
|
while self.linesToRead:
|
||||||
self.line_text = unicode(
|
self.lineText = unicode(
|
||||||
songData.read(ord(songData.read(1))), u'cp1252')
|
song_data.read(ord(song_data.read(1))), u'cp1252')
|
||||||
songData.seek(1, os.SEEK_CUR)
|
song_data.seek(1, os.SEEK_CUR)
|
||||||
if block_text:
|
if block_text:
|
||||||
block_text += u'\n'
|
block_text += u'\n'
|
||||||
block_text += self.line_text
|
block_text += self.lineText
|
||||||
self.lines_to_read -= 1
|
self.linesToRead -= 1
|
||||||
block_type = BLOCK_TYPES[ord(songData.read(1))]
|
block_type = BLOCK_TYPES[ord(song_data.read(1))]
|
||||||
# Skip 3 nulls at the end of the block
|
# Skip 3 nulls at the end of the block
|
||||||
songData.seek(3, os.SEEK_CUR)
|
song_data.seek(3, os.SEEK_CUR)
|
||||||
# Blocks are seperated by 2 bytes, skip them, but not if
|
# Blocks are seperated by 2 bytes, skip them, but not if
|
||||||
# this is the last block!
|
# this is the last block!
|
||||||
if block + 1 < no_of_blocks:
|
if block + 1 < no_of_blocks:
|
||||||
songData.seek(2, os.SEEK_CUR)
|
song_data.seek(2, os.SEEK_CUR)
|
||||||
self.add_verse(block_text, block_type)
|
self.addVerse(block_text, block_type)
|
||||||
# Now to extract the author
|
# Now to extract the author
|
||||||
author_length = ord(songData.read(1))
|
author_length = ord(song_data.read(1))
|
||||||
if author_length:
|
if author_length:
|
||||||
self.parse_author(
|
self.parseAuthor(
|
||||||
unicode(songData.read(author_length), u'cp1252'))
|
unicode(song_data.read(author_length), u'cp1252'))
|
||||||
# Finally the copyright
|
# Finally the copyright
|
||||||
copyright_length = ord(songData.read(1))
|
copyright_length = ord(song_data.read(1))
|
||||||
if copyright_length:
|
if copyright_length:
|
||||||
self.add_copyright(unicode(
|
self.addCopyright(unicode(
|
||||||
songData.read(copyright_length), u'cp1252'))
|
song_data.read(copyright_length), u'cp1252'))
|
||||||
songData.close()
|
song_data.close()
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.log_error(file)
|
self.logError(file)
|
||||||
|
@ -196,7 +196,7 @@ class SongsPlugin(Plugin):
|
|||||||
def importSongs(self, format, **kwargs):
|
def importSongs(self, format, **kwargs):
|
||||||
class_ = SongFormat.get_class(format)
|
class_ = SongFormat.get_class(format)
|
||||||
importer = class_(self.manager, **kwargs)
|
importer = class_(self.manager, **kwargs)
|
||||||
importer.register(self.mediaItem.import_wizard)
|
importer.register(self.mediaItem.importWizard)
|
||||||
return importer
|
return importer
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def setPluginTextStrings(self):
|
||||||
@ -252,7 +252,7 @@ class SongsPlugin(Plugin):
|
|||||||
progress.setValue(idx)
|
progress.setValue(idx)
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
importer = OpenLPSongImport(self.manager, filename=db)
|
importer = OpenLPSongImport(self.manager, filename=db)
|
||||||
importer.do_import()
|
importer.doImport()
|
||||||
progress.setValue(len(song_dbs))
|
progress.setValue(len(song_dbs))
|
||||||
self.mediaItem.onSearchTextButtonClick()
|
self.mediaItem.onSearchTextButtonClick()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user