openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #15677
[Merge] lp:~sfindlay/openlp/select-folder-powersong into lp:openlp
Samuel Findlay has proposed merging lp:~sfindlay/openlp/select-folder-powersong into lp:openlp.
Requested reviews:
Raoul Snyman (raoul-snyman)
Tim Bentley (trb143)
Samuel Findlay (sfindlay)
For more details, see:
https://code.launchpad.net/~sfindlay/openlp/select-folder-powersong/+merge/106508
Changes PowerSong importer to import a folder, rather than a selection of files. This involved implementing a getFolder method in core.ui.OpenLPWizard.
Rationale:
(1) PowerSong users always deal with their song databases as a whole, as a database folder. To ask them to select individual song files may be a foreign idea.
(2) Although PowerSong songs are stored in individual files, the filenames are unintelligible database IDs, not song titles. So there is no easy way for a user to pick and choose which songs to import anyway.
Test:
Download large PowerSong database of 1057 songs. 1050 should import successfully.
<https://docs.google.com/open?id=0B076ddXXPC2WUnA1VXZoY1FCVzA>
--
https://code.launchpad.net/~sfindlay/openlp/select-folder-powersong/+merge/106508
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/ui.py'
--- openlp/core/lib/ui.py 2012-04-22 19:50:18 +0000
+++ openlp/core/lib/ui.py 2012-05-20 01:51:19 +0000
@@ -94,6 +94,7 @@
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')
=== modified file 'openlp/core/ui/wizard.py'
--- openlp/core/ui/wizard.py 2012-05-03 12:50:10 +0000
+++ openlp/core/ui/wizard.py 2012-05-20 01:51:19 +0000
@@ -72,11 +72,14 @@
'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 @@
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 @@
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)
=== modified file 'openlp/plugins/songs/forms/songexportform.py'
--- openlp/plugins/songs/forms/songexportform.py 2012-04-02 19:34:49 +0000
+++ openlp/plugins/songs/forms/songexportform.py 2012-05-20 01:51:19 +0000
@@ -363,11 +363,5 @@
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)
=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py 2012-05-03 12:50:10 +0000
+++ openlp/plugins/songs/forms/songimportform.py 2012-05-20 01:51:19 +0000
@@ -105,6 +105,9 @@
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 @@
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 @@
# 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
'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 @@
"""
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 @@
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 @@
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 @@
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 @@
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):
"""
=== modified file 'openlp/plugins/songs/lib/powersongimport.py'
--- openlp/plugins/songs/lib/powersongimport.py 2012-05-03 12:50:10 +0000
+++ openlp/plugins/songs/lib/powersongimport.py 2012-05-20 01:51:19 +0000
@@ -29,8 +29,11 @@
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 @@
* .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 @@
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 @@
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):
"""
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2012-05-01 14:00:53 +0000
+++ openlp/plugins/songs/lib/songimport.py 2012-05-20 01:51:19 +0000
@@ -50,6 +50,13 @@
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 @@
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)
Follow ups