Changes PowerSong importer to import a folder, rather than a selection of files. This involved implementing a getFolder method in core.ui.OpenLPWizard.

bzr-revno: 1975
This commit is contained in:
Samuel Findlay 2012-05-23 18:26:47 +02:00 committed by Andreas Preikschat
commit bda1a0c420
6 changed files with 111 additions and 72 deletions

View File

@ -94,6 +94,7 @@ class UiStrings(object):
self.NewService = translate('OpenLP.Ui', 'New Service') self.NewService = translate('OpenLP.Ui', 'New Service')
self.NewTheme = translate('OpenLP.Ui', 'New Theme') self.NewTheme = translate('OpenLP.Ui', 'New Theme')
self.NextTrack = translate('OpenLP.Ui', 'Next Track') self.NextTrack = translate('OpenLP.Ui', 'Next Track')
self.NFdSs = translate('OpenLP.Ui', 'No Folder Selected', 'Singular')
self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')

View File

@ -72,11 +72,14 @@ class WizardStrings(object):
'importer, you will need to install the "python-sqlite" ' 'importer, you will need to install the "python-sqlite" '
'module.') 'module.')
OpenTypeFile = unicode(translate('OpenLP.Ui', 'Open %s File')) OpenTypeFile = unicode(translate('OpenLP.Ui', 'Open %s File'))
OpenTypeFolder = unicode(translate('OpenLP.Ui', 'Open %s Folder'))
PercentSymbolFormat = unicode(translate('OpenLP.Ui', '%p%')) PercentSymbolFormat = unicode(translate('OpenLP.Ui', '%p%'))
Ready = translate('OpenLP.Ui', 'Ready.') Ready = translate('OpenLP.Ui', 'Ready.')
StartingImport = translate('OpenLP.Ui', 'Starting import...') StartingImport = translate('OpenLP.Ui', 'Starting import...')
YouSpecifyFile = unicode(translate('OpenLP.Ui', 'You need to specify at ' YouSpecifyFile = unicode(translate('OpenLP.Ui', 'You need to specify at '
'least one %s file to import from.', 'A file type e.g. OpenSong')) 'least one %s file to import from.', 'A file type e.g. OpenSong'))
YouSpecifyFolder = unicode(translate('OpenLP.Ui', 'You need to specify a '
'%s folder to import from.', 'A file type e.g. OpenSong'))
class OpenLPWizard(QtGui.QWizard): class OpenLPWizard(QtGui.QWizard):
@ -254,7 +257,7 @@ class OpenLPWizard(QtGui.QWizard):
The title of the dialog (unicode). The title of the dialog (unicode).
``editbox`` ``editbox``
A editbox (QLineEdit). An editbox (QLineEdit).
``filters`` ``filters``
The file extension filters. It should contain the file description The file extension filters. It should contain the file description
@ -265,11 +268,28 @@ class OpenLPWizard(QtGui.QWizard):
if filters: if filters:
filters += u';;' filters += u';;'
filters += u'%s (*)' % UiStrings().AllFiles filters += u'%s (*)' % UiStrings().AllFiles
filename = QtGui.QFileDialog.getOpenFileName(self, title, filename = unicode(QtGui.QFileDialog.getOpenFileName(self, title,
os.path.dirname(SettingsManager.get_last_dir( os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)), filters) self.plugin.settingsSection, 1)), filters))
if filename: if filename:
editbox.setText(filename) editbox.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection, SettingsManager.set_last_dir(self.plugin.settingsSection,
filename, 1) filename, 1)
def getFolder(self, title, editbox):
"""
Opens a QFileDialog and saves the selected folder to the given editbox.
``title``
The title of the dialog (unicode).
``editbox``
An editbox (QLineEdit).
"""
folder = unicode(QtGui.QFileDialog.getExistingDirectory(self, title,
os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)), QtGui.QFileDialog.ShowDirsOnly))
if folder:
editbox.setText(folder)
SettingsManager.set_last_dir(self.plugin.settingsSection,
folder, 1)

View File

@ -363,11 +363,5 @@ class SongExportForm(OpenLPWizard):
Called when the *directoryButton* was clicked. Opens a dialog and writes Called when the *directoryButton* was clicked. Opens a dialog and writes
the path to *directoryLineEdit*. the path to *directoryLineEdit*.
""" """
path = unicode(QtGui.QFileDialog.getExistingDirectory(self, self.getFolder(translate('SongsPlugin.ExportWizardForm',
translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'), self.directoryLineEdit)
'Select Destination Folder'),
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
options=QtGui.QFileDialog.ShowDirsOnly))
SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1)
self.directoryLineEdit.setText(path)

View File

@ -105,6 +105,9 @@ class SongImportForm(OpenLPWizard):
QtCore.QObject.connect(self.openLP1BrowseButton, QtCore.QObject.connect(self.openLP1BrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOpenLP1BrowseButtonClicked) self.onOpenLP1BrowseButtonClicked)
QtCore.QObject.connect(self.powerSongBrowseButton,
QtCore.SIGNAL(u'clicked()'),
self.onPowerSongBrowseButtonClicked)
QtCore.QObject.connect(self.openLyricsAddButton, QtCore.QObject.connect(self.openLyricsAddButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOpenLyricsAddButtonClicked) self.onOpenLyricsAddButtonClicked)
@ -171,12 +174,6 @@ class SongImportForm(OpenLPWizard):
QtCore.QObject.connect(self.foilPresenterRemoveButton, QtCore.QObject.connect(self.foilPresenterRemoveButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onFoilPresenterRemoveButtonClicked) self.onFoilPresenterRemoveButtonClicked)
QtCore.QObject.connect(self.powerSongAddButton,
QtCore.SIGNAL(u'clicked()'),
self.onPowerSongAddButtonClicked)
QtCore.QObject.connect(self.powerSongRemoveButton,
QtCore.SIGNAL(u'clicked()'),
self.onPowerSongRemoveButtonClicked)
def addCustomPages(self): def addCustomPages(self):
""" """
@ -224,7 +221,7 @@ class SongImportForm(OpenLPWizard):
# Open Song # Open Song
self.addFileSelectItem(u'openSong', u'OpenSong') self.addFileSelectItem(u'openSong', u'OpenSong')
# PowerSong # PowerSong
self.addFileSelectItem(u'powerSong') self.addFileSelectItem(u'powerSong', single_select=True)
# SongBeamer # SongBeamer
self.addFileSelectItem(u'songBeamer') self.addFileSelectItem(u'songBeamer')
# Song Show Plus # Song Show Plus
@ -290,6 +287,9 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'Filename:')) translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.openLP1BrowseButton.setText(UiStrings().Browse) self.openLP1BrowseButton.setText(UiStrings().Browse)
self.openLP1DisabledLabel.setText(WizardStrings.NoSqlite) self.openLP1DisabledLabel.setText(WizardStrings.NoSqlite)
self.powerSongFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Folder:'))
self.powerSongBrowseButton.setText(UiStrings().Browse)
self.openLyricsAddButton.setText( self.openLyricsAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.openLyricsRemoveButton.setText( self.openLyricsRemoveButton.setText(
@ -315,10 +315,6 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.dreamBeamRemoveButton.setText( self.dreamBeamRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.powerSongAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.powerSongRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songsOfFellowshipAddButton.setText( self.songsOfFellowshipAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songsOfFellowshipRemoveButton.setText( self.songsOfFellowshipRemoveButton.setText(
@ -389,6 +385,7 @@ class SongImportForm(OpenLPWizard):
source_format = self.formatComboBox.currentIndex() source_format = self.formatComboBox.currentIndex()
QtCore.QSettings().setValue(u'songs/last import type', QtCore.QSettings().setValue(u'songs/last import type',
source_format) source_format)
import_class = SongFormat.get_class(source_format)
if source_format == SongFormat.OpenLP2: if source_format == SongFormat.OpenLP2:
if self.openLP2FilenameEdit.text().isEmpty(): if self.openLP2FilenameEdit.text().isEmpty():
critical_error_message_box(UiStrings().NFSs, critical_error_message_box(UiStrings().NFSs,
@ -401,6 +398,14 @@ class SongImportForm(OpenLPWizard):
WizardStrings.YouSpecifyFile % UiStrings().OLPV1) WizardStrings.YouSpecifyFile % UiStrings().OLPV1)
self.openLP1BrowseButton.setFocus() self.openLP1BrowseButton.setFocus()
return False return False
elif source_format == SongFormat.PowerSong:
if self.powerSongFilenameEdit.text().isEmpty() or \
not import_class.isValidSource(
folder=self.powerSongFilenameEdit.text()):
critical_error_message_box(UiStrings().NFdSs,
WizardStrings.YouSpecifyFolder % WizardStrings.PS)
self.powerSongBrowseButton.setFocus()
return False
elif source_format == SongFormat.OpenLyrics: elif source_format == SongFormat.OpenLyrics:
if self.openLyricsFileListWidget.count() == 0: if self.openLyricsFileListWidget.count() == 0:
critical_error_message_box(UiStrings().NFSp, critical_error_message_box(UiStrings().NFSp,
@ -431,12 +436,6 @@ class SongImportForm(OpenLPWizard):
WizardStrings.YouSpecifyFile % WizardStrings.DB) WizardStrings.YouSpecifyFile % WizardStrings.DB)
self.dreamBeamAddButton.setFocus() self.dreamBeamAddButton.setFocus()
return False return False
elif source_format == SongFormat.PowerSong:
if self.powerSongFileListWidget.count() == 0:
critical_error_message_box(UiStrings().NFSp,
WizardStrings.YouSpecifyFile % WizardStrings.PS)
self.powerSongAddButton.setFocus()
return False
elif source_format == SongFormat.SongsOfFellowship: elif source_format == SongFormat.SongsOfFellowship:
if self.songsOfFellowshipFileListWidget.count() == 0: if self.songsOfFellowshipFileListWidget.count() == 0:
critical_error_message_box(UiStrings().NFSp, critical_error_message_box(UiStrings().NFSp,
@ -546,6 +545,13 @@ class SongImportForm(OpenLPWizard):
'openlp.org v1.x Databases') 'openlp.org v1.x Databases')
) )
def onPowerSongBrowseButtonClicked(self):
"""
Get PowerSong song database folder
"""
self.getFolder(WizardStrings.OpenTypeFolder % WizardStrings.PS,
self.powerSongFilenameEdit)
def onOpenLyricsAddButtonClicked(self): def onOpenLyricsAddButtonClicked(self):
""" """
Get OpenLyrics song database files Get OpenLyrics song database files
@ -620,22 +626,6 @@ class SongImportForm(OpenLPWizard):
""" """
self.removeSelectedItems(self.dreamBeamFileListWidget) self.removeSelectedItems(self.dreamBeamFileListWidget)
def onPowerSongAddButtonClicked(self):
"""
Get PowerSong song database files
"""
self.getFiles(WizardStrings.OpenTypeFile % WizardStrings.PS,
self.powerSongFileListWidget, u'%s (*.song)'
% translate('SongsPlugin.ImportWizardForm',
'PowerSong 1.0 Song Files')
)
def onPowerSongRemoveButtonClicked(self):
"""
Remove selected PowerSong files from the import list
"""
self.removeSelectedItems(self.powerSongFileListWidget)
def onSongsOfFellowshipAddButtonClicked(self): def onSongsOfFellowshipAddButtonClicked(self):
""" """
Get Songs of Fellowship song database files Get Songs of Fellowship song database files
@ -748,12 +738,12 @@ class SongImportForm(OpenLPWizard):
self.formatComboBox.setCurrentIndex(last_import_type) self.formatComboBox.setCurrentIndex(last_import_type)
self.openLP2FilenameEdit.setText(u'') self.openLP2FilenameEdit.setText(u'')
self.openLP1FilenameEdit.setText(u'') self.openLP1FilenameEdit.setText(u'')
self.powerSongFilenameEdit.setText(u'')
self.openLyricsFileListWidget.clear() self.openLyricsFileListWidget.clear()
self.openSongFileListWidget.clear() self.openSongFileListWidget.clear()
self.wordsOfWorshipFileListWidget.clear() self.wordsOfWorshipFileListWidget.clear()
self.ccliFileListWidget.clear() self.ccliFileListWidget.clear()
self.dreamBeamFileListWidget.clear() self.dreamBeamFileListWidget.clear()
self.powerSongFileListWidget.clear()
self.songsOfFellowshipFileListWidget.clear() self.songsOfFellowshipFileListWidget.clear()
self.genericFileListWidget.clear() self.genericFileListWidget.clear()
self.easySlidesFilenameEdit.setText(u'') self.easySlidesFilenameEdit.setText(u'')
@ -794,6 +784,11 @@ class SongImportForm(OpenLPWizard):
filename=unicode(self.openLP1FilenameEdit.text()), filename=unicode(self.openLP1FilenameEdit.text()),
plugin=self.plugin plugin=self.plugin
) )
elif source_format == SongFormat.PowerSong:
# Import PowerSong folder
importer = self.plugin.importSongs(SongFormat.PowerSong,
folder=unicode(self.powerSongFilenameEdit.text())
)
elif source_format == SongFormat.OpenLyrics: elif source_format == SongFormat.OpenLyrics:
# Import OpenLyrics songs # Import OpenLyrics songs
importer = self.plugin.importSongs(SongFormat.OpenLyrics, importer = self.plugin.importSongs(SongFormat.OpenLyrics,
@ -821,12 +816,6 @@ class SongImportForm(OpenLPWizard):
filenames=self.getListOfFiles( filenames=self.getListOfFiles(
self.dreamBeamFileListWidget) self.dreamBeamFileListWidget)
) )
elif source_format == SongFormat.PowerSong:
# Import PowerSong songs
importer = self.plugin.importSongs(SongFormat.PowerSong,
filenames=self.getListOfFiles(
self.powerSongFileListWidget)
)
elif source_format == SongFormat.SongsOfFellowship: elif source_format == SongFormat.SongsOfFellowship:
# Import a Songs of Fellowship RTF file # Import a Songs of Fellowship RTF file
importer = self.plugin.importSongs(SongFormat.SongsOfFellowship, importer = self.plugin.importSongs(SongFormat.SongsOfFellowship,
@ -864,11 +853,7 @@ class SongImportForm(OpenLPWizard):
filenames=self.getListOfFiles(self.foilPresenterFileListWidget) filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
) )
importer.doImport() importer.doImport()
if importer.errorLog: self.progressLabel.setText(WizardStrings.FinishedImport)
self.progressLabel.setText(translate(
'SongsPlugin.SongImportForm', 'Your song import failed.'))
else:
self.progressLabel.setText(WizardStrings.FinishedImport)
def onErrorCopyToButtonClicked(self): def onErrorCopyToButtonClicked(self):
""" """

View File

@ -29,8 +29,11 @@ The :mod:`powersongimport` module provides the functionality for importing
PowerSong songs into the OpenLP database. PowerSong songs into the OpenLP database.
""" """
import logging import logging
import fnmatch
import os
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -69,13 +72,39 @@ class PowerSongImport(SongImport):
* .song * .song
""" """
@staticmethod
def isValidSource(**kwargs):
"""
Checks if source is a PowerSong 1.0 folder:
* is a directory
* contains at least one *.song file
"""
if u'folder' in kwargs:
dir = kwargs[u'folder']
if os.path.isdir(dir):
for file in os.listdir(dir):
if fnmatch.fnmatch(file, u'*.song'):
return True
return False
def doImport(self): def doImport(self):
""" """
Receive a list of files to import. Receive either a list of files or a folder (unicode) to import.
""" """
if not isinstance(self.importSource, list): if isinstance(self.importSource, unicode):
if os.path.isdir(self.importSource):
dir = self.importSource
self.importSource = []
for file in os.listdir(dir):
if fnmatch.fnmatch(file, u'*.song'):
self.importSource.append(os.path.join(dir, file))
else:
self.importSource = u''
if not self.importSource or not isinstance(self.importSource, list):
self.logError(unicode(translate('SongsPlugin.PowerSongImport', self.logError(unicode(translate('SongsPlugin.PowerSongImport',
'No files to import.'))) 'No songs to import.')),
unicode(translate('SongsPlugin.PowerSongImport',
'No %s files found.' % WizardStrings.PS)))
return return
self.importWizard.progressBar.setMaximum(len(self.importSource)) self.importWizard.progressBar.setMaximum(len(self.importSource))
for file in self.importSource: for file in self.importSource:
@ -92,9 +121,10 @@ class PowerSongImport(SongImport):
field = self._readString(song_data) field = self._readString(song_data)
except ValueError: except ValueError:
parse_error = True parse_error = True
self.logError(file, unicode( self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport',
'Invalid PowerSong file. Unexpected byte value.'))) 'Invalid %s file. Unexpected byte value.'
% WizardStrings.PS)))
break break
else: else:
if label == u'TITLE': if label == u'TITLE':
@ -110,26 +140,26 @@ class PowerSongImport(SongImport):
continue continue
# Check that file had TITLE field # Check that file had TITLE field
if not self.title: if not self.title:
self.logError(file, unicode( self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport',
'Invalid PowerSong file. Missing "TITLE" header.'))) 'Invalid %s file. Missing "TITLE" header.'
% WizardStrings.PS)))
continue continue
# Check that file had COPYRIGHTLINE label # Check that file had COPYRIGHTLINE label
if not found_copyright: if not found_copyright:
self.logError(file, unicode( self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport',
'"%s" Invalid PowerSong file. Missing "COPYRIGHTLINE" ' 'Invalid %s file. Missing "COPYRIGHTLINE" '
'header.' % self.title))) 'header.' % WizardStrings.PS)))
continue continue
# Check that file had at least one verse # Check that file had at least one verse
if not self.verses: if not self.verses:
self.logError(file, unicode( self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport',
'"%s" Verses not found. Missing "PART" header.' 'Verses not found. Missing "PART" header.')))
% self.title)))
continue continue
if not self.finish(): if not self.finish():
self.logError(file) self.logError(self.title)
def _readString(self, file_object): def _readString(self, file_object):
""" """

View File

@ -50,6 +50,13 @@ class SongImport(QtCore.QObject):
whether the authors etc already exist and add them or refer to them whether the authors etc already exist and add them or refer to them
as necessary as necessary
""" """
@staticmethod
def isValidSource(**kwargs):
"""
Override this method to validate the source prior to import.
"""
pass
def __init__(self, manager, **kwargs): def __init__(self, manager, **kwargs):
""" """
Initialise and create defaults for properties Initialise and create defaults for properties
@ -65,14 +72,16 @@ class SongImport(QtCore.QObject):
self.importSource = kwargs[u'filename'] self.importSource = kwargs[u'filename']
elif u'filenames' in kwargs: elif u'filenames' in kwargs:
self.importSource = kwargs[u'filenames'] self.importSource = kwargs[u'filenames']
elif u'folder' in kwargs:
self.importSource = kwargs[u'folder']
else: else:
raise KeyError(u'Keyword arguments "filename[s]" not supplied.') raise KeyError(
u'Keyword arguments "filename[s]" or "folder" not supplied.')
log.debug(self.importSource) log.debug(self.importSource)
self.importWizard = None self.importWizard = None
self.song = None self.song = None
self.stopImportFlag = False self.stopImportFlag = False
self.setDefaults() self.setDefaults()
self.errorLog = []
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)