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.NewTheme = translate('OpenLP.Ui', 'New Theme')
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.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
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" '
'module.')
OpenTypeFile = unicode(translate('OpenLP.Ui', 'Open %s File'))
OpenTypeFolder = unicode(translate('OpenLP.Ui', 'Open %s Folder'))
PercentSymbolFormat = unicode(translate('OpenLP.Ui', '%p%'))
Ready = translate('OpenLP.Ui', 'Ready.')
StartingImport = translate('OpenLP.Ui', 'Starting import...')
YouSpecifyFile = unicode(translate('OpenLP.Ui', 'You need to specify at '
'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):
@ -254,7 +257,7 @@ class OpenLPWizard(QtGui.QWizard):
The title of the dialog (unicode).
``editbox``
A editbox (QLineEdit).
An editbox (QLineEdit).
``filters``
The file extension filters. It should contain the file description
@ -265,11 +268,28 @@ class OpenLPWizard(QtGui.QWizard):
if filters:
filters += u';;'
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(
self.plugin.settingsSection, 1)), filters)
self.plugin.settingsSection, 1)), filters))
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection,
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
the path to *directoryLineEdit*.
"""
path = unicode(QtGui.QFileDialog.getExistingDirectory(self,
translate('SongsPlugin.ExportWizardForm',
'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)
self.getFolder(translate('SongsPlugin.ExportWizardForm',
'Select Destination Folder'), self.directoryLineEdit)

View File

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

View File

@ -29,8 +29,11 @@ The :mod:`powersongimport` module provides the functionality for importing
PowerSong songs into the OpenLP database.
"""
import logging
import fnmatch
import os
from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__)
@ -69,13 +72,39 @@ class PowerSongImport(SongImport):
* .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):
"""
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',
'No files to import.')))
'No songs to import.')),
unicode(translate('SongsPlugin.PowerSongImport',
'No %s files found.' % WizardStrings.PS)))
return
self.importWizard.progressBar.setMaximum(len(self.importSource))
for file in self.importSource:
@ -92,9 +121,10 @@ class PowerSongImport(SongImport):
field = self._readString(song_data)
except ValueError:
parse_error = True
self.logError(file, unicode(
self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport',
'Invalid PowerSong file. Unexpected byte value.')))
'Invalid %s file. Unexpected byte value.'
% WizardStrings.PS)))
break
else:
if label == u'TITLE':
@ -110,26 +140,26 @@ class PowerSongImport(SongImport):
continue
# Check that file had TITLE field
if not self.title:
self.logError(file, unicode(
self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport',
'Invalid PowerSong file. Missing "TITLE" header.')))
'Invalid %s file. Missing "TITLE" header.'
% WizardStrings.PS)))
continue
# Check that file had COPYRIGHTLINE label
if not found_copyright:
self.logError(file, unicode(
self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport',
'"%s" Invalid PowerSong file. Missing "COPYRIGHTLINE" '
'header.' % self.title)))
'Invalid %s file. Missing "COPYRIGHTLINE" '
'header.' % WizardStrings.PS)))
continue
# Check that file had at least one verse
if not self.verses:
self.logError(file, unicode(
self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport',
'"%s" Verses not found. Missing "PART" header.'
% self.title)))
'Verses not found. Missing "PART" header.')))
continue
if not self.finish():
self.logError(file)
self.logError(self.title)
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
as necessary
"""
@staticmethod
def isValidSource(**kwargs):
"""
Override this method to validate the source prior to import.
"""
pass
def __init__(self, manager, **kwargs):
"""
Initialise and create defaults for properties
@ -65,14 +72,16 @@ class SongImport(QtCore.QObject):
self.importSource = kwargs[u'filename']
elif u'filenames' in kwargs:
self.importSource = kwargs[u'filenames']
elif u'folder' in kwargs:
self.importSource = kwargs[u'folder']
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)
self.importWizard = None
self.song = None
self.stopImportFlag = False
self.setDefaults()
self.errorLog = []
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)