Song import cleanups

This commit is contained in:
Tim Bentley 2014-03-05 18:58:22 +00:00
parent 1301b4cfa3
commit 75281b5cf1
28 changed files with 241 additions and 246 deletions

View File

@ -201,7 +201,7 @@ class SongImportForm(OpenLPWizard):
def validateCurrentPage(self):
"""
Re-implement the validateCurrentPage() method. Validate the current page before moving on to the next page.
Provide each song format class with a chance to validate its input by overriding isValidSource().
Provide each song format class with a chance to validate its input by overriding is_valid_source().
"""
if self.currentPage() == self.welcome_page:
return True
@ -217,7 +217,7 @@ class SongImportForm(OpenLPWizard):
import_source = self.format_widgets[this_format]['file_path_edit'].text()
error_title = (UiStrings().IFSs if select_mode == SongFormatSelect.SingleFile else UiStrings().IFdSs)
focus_button = self.format_widgets[this_format]['browseButton']
if not class_.isValidSource(import_source):
if not class_.is_valid_source(import_source):
critical_error_message_box(error_title, error_msg)
focus_button.setFocus()
return False

View File

@ -38,6 +38,7 @@ from .songimport import SongImport
log = logging.getLogger(__name__)
class CCLIFileImport(SongImport):
"""
The :class:`CCLIFileImport` class provides OpenLP with the ability to import
@ -86,13 +87,13 @@ class CCLIFileImport(SongImport):
if ext.lower() == '.usr':
log.info('SongSelect .usr format file found: %s', filename)
if not self.doImportUsrFile(lines):
self.logError(filename)
self.log_error(filename)
elif ext.lower() == '.txt':
log.info('SongSelect .txt format file found: %s', filename)
if not self.doImportTxtFile(lines):
self.logError(filename)
self.log_error(filename)
else:
self.logError(filename,
self.log_error(filename,
translate('SongsPlugin.CCLIFileImport', 'The file does not have a valid extension.'))
log.info('Extension %s is not valid', filename)
if self.stop_import_flag:
@ -163,9 +164,9 @@ class CCLIFileImport(SongImport):
if line.startswith('[S '):
ccli, line = line.split(']', 1)
if ccli.startswith('[S A'):
self.ccliNumber = ccli[4:].strip()
self.ccli_number = ccli[4:].strip()
else:
self.ccliNumber = ccli[3:].strip()
self.ccli_number = ccli[3:].strip()
if line.startswith('Title='):
self.title = line[6:].strip()
elif line.startswith('Author='):
@ -213,7 +214,7 @@ class CCLIFileImport(SongImport):
verse_type = VerseType.tags[VerseType.Other]
verse_text = verse_lines[1]
if verse_text:
self.addVerse(verse_text, verse_type)
self.add_verse(verse_text, verse_type)
check_first_verse_line = False
# Handle multiple authors
author_list = song_author.split('/')
@ -223,7 +224,7 @@ class CCLIFileImport(SongImport):
separated = author.split(',')
if len(separated) > 1:
author = ' '.join(map(str.strip, reversed(separated)))
self.addAuthor(author.strip())
self.add_author(author.strip())
self.topics = [topic.strip() for topic in song_topics.split('/t')]
return self.finish()
@ -272,7 +273,7 @@ class CCLIFileImport(SongImport):
continue
elif verse_start:
if verse_text:
self.addVerse(verse_text, verse_type)
self.add_verse(verse_text, verse_type)
verse_text = ''
verse_start = False
else:
@ -286,7 +287,7 @@ class CCLIFileImport(SongImport):
if clean_line.startswith('CCLI'):
line_number += 1
ccli_parts = clean_line.split(' ')
self.ccliNumber = ccli_parts[len(ccli_parts) - 1]
self.ccli_number = ccli_parts[len(ccli_parts) - 1]
elif not verse_start:
# We have the verse descriptor
verse_desc_parts = clean_line.split(' ')
@ -348,5 +349,5 @@ class CCLIFileImport(SongImport):
author_list = song_author.split('|')
# Clean spaces before and after author names.
for author_name in author_list:
self.addAuthor(author_name.strip())
self.add_author(author_name.strip())
return self.finish()

View File

@ -92,18 +92,18 @@ class DreamBeamImport(SongImport):
for file in self.import_source:
if self.stop_import_flag:
return
self.setDefaults()
self.set_defaults()
parser = etree.XMLParser(remove_blank_text=True)
try:
parsed_file = etree.parse(open(file, 'r'), parser)
except etree.XMLSyntaxError:
log.exception('XML syntax error in file %s' % file)
self.logError(file, SongStrings.XMLSyntaxError)
self.log_error(file, SongStrings.XMLSyntaxError)
continue
xml = etree.tostring(parsed_file).decode()
song_xml = objectify.fromstring(xml)
if song_xml.tag != 'DreamSong':
self.logError(file,
self.log_error(file,
translate('SongsPlugin.DreamBeamImport', 'Invalid DreamBeam song file. Missing DreamSong tag.'))
continue
if hasattr(song_xml, 'Version'):
@ -121,14 +121,14 @@ class DreamBeamImport(SongImport):
verse_type = lyrics_item.get('Type')
verse_number = lyrics_item.get('Number')
verse_text = str(lyrics_item.text)
self.addVerse(verse_text, ('%s%s' % (verse_type[:1], verse_number)))
self.add_verse(verse_text, ('%s%s' % (verse_type[:1], verse_number)))
if hasattr(song_xml, 'Collection'):
self.songBookName = str(song_xml.Collection.text)
self.song_book_name = str(song_xml.Collection.text)
if hasattr(song_xml, 'Number'):
self.songNumber = str(song_xml.Number.text)
self.song_number = str(song_xml.Number.text)
if hasattr(song_xml, 'Sequence'):
for LyricsSequenceItem in (song_xml.Sequence.iterchildren()):
self.verseOrderList.append("%s%s" % (LyricsSequenceItem.get('Type')[:1],
self.verse_order_list.append("%s%s" % (LyricsSequenceItem.get('Type')[:1],
LyricsSequenceItem.get('Number')))
if hasattr(song_xml, 'Notes'):
self.comments = str(song_xml.Notes.text)
@ -138,15 +138,15 @@ class DreamBeamImport(SongImport):
if hasattr(song_xml.Text1, 'Text'):
self.lyrics = str(song_xml.Text1.Text.text)
for verse in self.lyrics.split('\n\n\n'):
self.addVerse(verse)
self.add_verse(verse)
if hasattr(song_xml.Text2, 'Text'):
author_copyright = song_xml.Text2.Text.text
if author_copyright:
author_copyright = str(author_copyright)
if author_copyright.find(
str(SongStrings.CopyrightSymbol)) >= 0:
self.addCopyright(author_copyright)
self.add_copyright(author_copyright)
else:
self.parse_author(author_copyright)
if not self.finish():
self.logError(file)
self.log_error(file)

View File

@ -68,9 +68,9 @@ class EasySlidesImport(SongImport):
if hasattr(song, 'Title2'):
self._add_unicode_attribute('alternateTitle', song.Title2)
if hasattr(song, 'SongNumber'):
self._add_unicode_attribute('songNumber', song.SongNumber)
if self.songNumber == '0':
self.songNumber = ''
self._add_unicode_attribute('song_number', song.SongNumber)
if self.song_number == '0':
self.song_number = ''
self._addAuthors(song)
if hasattr(song, 'Copyright'):
self._add_copyright(song.Copyright)
@ -79,13 +79,13 @@ class EasySlidesImport(SongImport):
if hasattr(song, 'LicenceAdmin2'):
self._add_copyright(song.LicenceAdmin2)
if hasattr(song, 'BookReference'):
self._add_unicode_attribute('songBookName', song.BookReference)
self._add_unicode_attribute('song_book_name', song.BookReference)
self._parseAndAddLyrics(song)
if self._success:
if not self.finish():
self.logError(song.Title1 if song.Title1 else '')
self.log_error(song.Title1 if song.Title1 else '')
else:
self.setDefaults()
self.set_defaults()
def _add_unicode_attribute(self, self_attribute, import_attribute, mandatory=False):
"""
@ -132,7 +132,7 @@ class EasySlidesImport(SongImport):
The imported variable to get the data from.
"""
try:
self.addCopyright(str(element).strip())
self.add_copyright(str(element).strip())
except UnicodeDecodeError:
log.exception('Unicode error on decoding copyright: %s' % element)
self._success = False
@ -235,7 +235,7 @@ class EasySlidesImport(SongImport):
verses[reg].setdefault(vt, {})
verses[reg][vt].setdefault(vn, {})
verses[reg][vt][vn].setdefault(inst, [])
verses[reg][vt][vn][inst].append(self.tidyText(line))
verses[reg][vt][vn][inst].append(self.tidy_text(line))
# done parsing
versetags = []
@ -271,7 +271,7 @@ class EasySlidesImport(SongImport):
else:
continue
if tag in versetags:
self.verseOrderList.append(tag)
self.verse_order_list.append(tag)
else:
log.info('Got order item %s, which is not in versetags, dropping item from presentation order',
tag)

View File

@ -163,7 +163,7 @@ class EasyWorshipSongImport(SongImport):
break
raw_record = db_file.read(record_size)
self.fields = self.recordStruct.unpack(raw_record)
self.setDefaults()
self.set_defaults()
self.title = self.getField(fi_title).decode()
# Get remaining fields.
copy = self.getField(fi_copy)
@ -180,7 +180,7 @@ class EasyWorshipSongImport(SongImport):
self.copyright += translate('SongsPlugin.EasyWorshipSongImport',
'Administered by %s') % admin.decode()
if ccli:
self.ccliNumber = ccli.decode()
self.ccli_number = ccli.decode()
if authors:
# Split up the authors
author_list = authors.split(b'/')
@ -189,7 +189,7 @@ class EasyWorshipSongImport(SongImport):
if len(author_list) < 2:
author_list = authors.split(b',')
for author_name in author_list:
self.addAuthor(author_name.decode().strip())
self.add_author(author_name.decode().strip())
if words:
# Format the lyrics
result = strip_rtf(words.decode(), self.encoding)
@ -227,14 +227,14 @@ class EasyWorshipSongImport(SongImport):
if not number_found:
verse_type += '1'
break
self.addVerse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type)
self.add_verse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type)
if len(self.comments) > 5:
self.comments += str(translate('SongsPlugin.EasyWorshipSongImport',
'\n[above are Song Tags with notes imported from EasyWorship]'))
if self.stop_import_flag:
break
if not self.finish():
self.logError(self.import_source)
self.log_error(self.import_source)
db_file.close()
self.memoFile.close()

View File

@ -133,7 +133,7 @@ class FoilPresenterImport(SongImport):
xml = etree.tostring(parsed_file).decode()
self.FoilPresenter.xml_to_song(xml)
except etree.XMLSyntaxError:
self.logError(file_path, SongStrings.XMLSyntaxError)
self.log_error(file_path, SongStrings.XMLSyntaxError)
log.exception('XML syntax error in file %s' % file_path)
@ -423,7 +423,7 @@ class FoilPresenter(object):
VerseType.tags[VerseType.PreChorus]: 1
}
if not hasattr(foilpresenterfolie.strophen, 'strophe'):
self.importer.logError(self._child(foilpresenterfolie.titel),
self.importer.log_error(self._child(foilpresenterfolie.titel),
str(translate('SongsPlugin.FoilPresenterSongImport',
'Invalid Foilpresenter song file. No verses found.')))
self.save_song = False

View File

@ -137,7 +137,7 @@ class SongFormat(object):
Title for ``QFileDialog`` (default includes the format's ``u'name'``).
``u'invalidSourceMsg'``
Message displayed if ``isValidSource()`` returns ``False``.
Message displayed if ``is_valid_source()`` returns ``False``.
``u'descriptionText'``
Short description (1-2 lines) about the song format.

View File

@ -57,7 +57,7 @@ class MediaShoutImport(SongImport):
'DBQ=%s;PWD=6NOZ4eHK7k' % self.import_source)
except:
# Unfortunately no specific exception type
self.logError(self.import_source,
self.log_error(self.import_source,
translate('SongsPlugin.MediaShoutImport', 'Unable to open the MediaShout database.'))
return
cursor = conn.cursor()
@ -88,21 +88,21 @@ class MediaShoutImport(SongImport):
"""
Create the song, i.e. title, verse etc.
"""
self.setDefaults()
self.set_defaults()
self.title = song.Title
self.parse_author(song.Author)
self.addCopyright(song.Copyright)
self.add_copyright(song.Copyright)
self.comments = song.Notes
for topic in topics:
self.topics.append(topic.Name)
if '-' in song.SongID:
self.songBookName, self.songNumber = song.SongID.split('-', 1)
self.song_book_name, self.song_number = song.SongID.split('-', 1)
else:
self.songBookName = song.SongID
self.song_book_name = song.SongID
for verse in verses:
tag = VERSE_TAGS[verse.Type] + str(verse.Number) if verse.Type < len(VERSE_TAGS) else 'O'
self.addVerse(verse.Text, tag)
self.add_verse(verse.Text, tag)
for order in verse_order:
if order.Type < len(VERSE_TAGS):
self.verseOrderList.append(VERSE_TAGS[order.Type] + str(order.Number))
self.verse_order_list.append(VERSE_TAGS[order.Type] + str(order.Number))
self.finish()

View File

@ -107,7 +107,7 @@ class OpenLPSongImport(SongImport):
# Check the file type
if not self.import_source.endswith('.sqlite'):
self.logError(self.import_source,
self.log_error(self.import_source,
translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2.0 song database.'))
return
self.import_source = 'sqlite:///%s' % self.import_source

View File

@ -71,7 +71,7 @@ class OooImport(SongImport):
try:
self.startOoo()
except NoConnectException as exc:
self.logError(
self.log_error(
self.import_source[0],
translate('SongsPlugin.SongImport', 'Cannot access OpenOffice or LibreOffice'))
log.error(exc)
@ -87,9 +87,9 @@ class OooImport(SongImport):
self.processOooDocument()
self.closeOooFile()
else:
self.logError(self.filepath, translate('SongsPlugin.SongImport', 'Unable to open file'))
self.log_error(self.filepath, translate('SongsPlugin.SongImport', 'Unable to open file'))
else:
self.logError(self.filepath, translate('SongsPlugin.SongImport', 'File not found'))
self.log_error(self.filepath, translate('SongsPlugin.SongImport', 'File not found'))
self.closeOoo()
def processOooDocument(self):
@ -228,13 +228,13 @@ class OooImport(SongImport):
self.processSongsText(text)
def processSongsText(self, text):
songtexts = self.tidyText(text).split('\f')
self.setDefaults()
songtexts = self.tidy_text(text).split('\f')
self.set_defaults()
for songtext in songtexts:
if songtext.strip():
self.processSongText(songtext.strip())
if self.checkComplete():
self.process_song_text(songtext.strip())
if self.check_complete():
self.finish()
self.setDefaults()
if self.checkComplete():
self.set_defaults()
if self.check_complete():
self.finish()

View File

@ -74,8 +74,8 @@ class OpenLyricsImport(SongImport):
self.openLyrics.xml_to_song(xml)
except etree.XMLSyntaxError:
log.exception('XML syntax error in file %s' % file_path)
self.logError(file_path, SongStrings.XMLSyntaxError)
self.log_error(file_path, SongStrings.XMLSyntaxError)
except OpenLyricsError as exception:
log.exception('OpenLyricsException %d in file %s: %s'
% (exception.type, file_path, exception.log_message))
self.logError(file_path, exception.display_message)
self.log_error(file_path, exception.display_message)

View File

@ -122,21 +122,21 @@ class OpenSongImport(SongImport):
"""
Process the OpenSong file - pass in a file-like object, not a file path.
"""
self.setDefaults()
self.set_defaults()
try:
tree = objectify.parse(file)
except (Error, LxmlError):
self.logError(file.name, SongStrings.XMLSyntaxError)
self.log_error(file.name, SongStrings.XMLSyntaxError)
log.exception('Error parsing XML')
return
root = tree.getroot()
if root.tag != 'song':
self.logError(file.name, str(
self.log_error(file.name, str(
translate('SongsPlugin.OpenSongImport', ('Invalid OpenSong song file. Missing song tag.'))))
return
fields = dir(root)
decode = {
'copyright': self.addCopyright,
'copyright': self.add_copyright,
'ccli': 'ccli_number',
'author': self.parse_author,
'title': 'title',
@ -207,7 +207,7 @@ class OpenSongImport(SongImport):
verses[verse_tag][verse_num][inst] = []
our_verse_order.append([verse_tag, verse_num, inst])
# Tidy text and remove the ____s from extended words
this_line = self.tidyText(this_line)
this_line = self.tidy_text(this_line)
this_line = this_line.replace('_', '')
this_line = this_line.replace('|', '\n')
this_line = this_line.strip()
@ -224,9 +224,9 @@ class OpenSongImport(SongImport):
verse_joints[verse_def] = '%s\n[---]\n%s' % (verse_joints[verse_def], lines) \
if verse_def in verse_joints else lines
for verse_def, lines in verse_joints.items():
self.addVerse(lines, verse_def)
self.add_verse(lines, verse_def)
if not self.verses:
self.addVerse('')
self.add_verse('')
# figure out the presentation order, if present
if 'presentation' in fields and root.presentation:
order = str(root.presentation)
@ -246,9 +246,9 @@ class OpenSongImport(SongImport):
verse_num = '1'
verse_def = '%s%s' % (verse_tag, verse_num)
if verse_num in verses.get(verse_tag, {}):
self.verseOrderList.append(verse_def)
self.verse_order_list.append(verse_def)
else:
log.info('Got order %s but not in verse tags, dropping'
'this item from presentation order', verse_def)
if not self.finish():
self.logError(file.name)
self.log_error(file.name)

View File

@ -73,7 +73,7 @@ class PowerSongImport(SongImport):
* .song
"""
@staticmethod
def isValidSource(import_source):
def is_valid_source(import_source):
"""
Checks if source is a PowerSong 1.0 folder:
* is a directory
@ -101,14 +101,14 @@ class PowerSongImport(SongImport):
else:
self.import_source = ''
if not self.import_source or not isinstance(self.import_source, list):
self.logError(translate('SongsPlugin.PowerSongImport', 'No songs to import.'),
self.log_error(translate('SongsPlugin.PowerSongImport', 'No songs to import.'),
translate('SongsPlugin.PowerSongImport', 'No %s files found.') % PS_string)
return
self.import_wizard.progress_bar.setMaximum(len(self.import_source))
for file in self.import_source:
if self.stop_import_flag:
return
self.setDefaults()
self.set_defaults()
parse_error = False
with open(file, 'rb') as song_data:
while True:
@ -119,7 +119,7 @@ class PowerSongImport(SongImport):
field = self._readString(song_data)
except ValueError:
parse_error = True
self.logError(os.path.basename(file), str(
self.log_error(os.path.basename(file), str(
translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Unexpected byte value.')) %
PS_string)
break
@ -132,27 +132,27 @@ class PowerSongImport(SongImport):
found_copyright = True
self._parseCopyrightCCLI(field)
elif label == 'PART':
self.addVerse(field)
self.add_verse(field)
if parse_error:
continue
# Check that file had TITLE field
if not self.title:
self.logError(os.path.basename(file), str(
self.log_error(os.path.basename(file), str(
translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Missing "TITLE" header.')) % PS_string)
continue
# Check that file had COPYRIGHTLINE label
if not found_copyright:
self.logError(self.title, str(
self.log_error(self.title, str(
translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Missing "COPYRIGHTLINE" header.')) %
PS_string)
continue
# Check that file had at least one verse
if not self.verses:
self.logError(self.title, str(
self.log_error(self.title, str(
translate('SongsPlugin.PowerSongImport', 'Verses not found. Missing "PART" header.')))
continue
if not self.finish():
self.logError(self.title)
self.log_error(self.title)
def _readString(self, file_object):
"""
@ -211,8 +211,8 @@ class PowerSongImport(SongImport):
copyright = ccli_no
ccli_no = ''
if copyright:
self.addCopyright(copyright.rstrip('\n').replace('\n', ' '))
self.add_copyright(copyright.rstrip('\n').replace('\n', ' '))
if ccli_no:
ccli_no = ccli_no.strip(' :')
if ccli_no.isdigit():
self.ccliNumber = ccli_no
self.ccli_number = ccli_no

View File

@ -108,7 +108,7 @@ class SofImport(OooImport):
except RuntimeException as exc:
log.exception('Error processing file: %s', exc)
if not self.finish():
self.logError(self.filepath)
self.log_error(self.filepath)
def processParagraph(self, paragraph):
"""
@ -173,17 +173,17 @@ class SofImport(OooImport):
self.skipToCloseBracket = True
return
if text.startswith('Copyright'):
self.addCopyright(text)
self.add_copyright(text)
return
if text == '(Repeat)':
self.finishVerse()
self.repeatVerse()
self.repeat_verse()
return
if self.title == '':
if self.copyright == '':
self.addSofAuthor(text)
else:
self.addCopyright(text)
self.add_copyright(text)
return
self.addVerseLine(text)
@ -195,12 +195,12 @@ class SofImport(OooImport):
into line
"""
text = textportion.getString()
text = self.tidyText(text)
text = self.tidy_text(text)
if text.strip() == '':
return text
if textportion.CharWeight == BOLD:
boldtext = text.strip()
if boldtext.isdigit() and self.songNumber == '':
if boldtext.isdigit() and self.song_number == '':
self.addSongNumber(boldtext)
return ''
text = self.uncapText(text)
@ -219,11 +219,11 @@ class SofImport(OooImport):
"""
if self.song:
self.finishVerse()
if not self.checkComplete():
if not self.check_complete():
return
self.finish()
self.song = True
self.setDefaults()
self.set_defaults()
self.skipToCloseBracket = False
self.isChorus = False
self.italics = False
@ -234,7 +234,7 @@ class SofImport(OooImport):
Add a song number, store as alternate title. Also use the song
number to work out which songbook we're in
"""
self.songNumber = song_no
self.song_number = song_no
self.alternateTitle = song_no + '.'
self.songBook_pub = 'Kingsway Publications'
if int(song_no) <= 640:
@ -299,7 +299,7 @@ class SofImport(OooImport):
splitat = None
else:
versetag = 'V'
splitat = self.verseSplits(self.songNumber)
splitat = self.verseSplits(self.song_number)
if splitat:
ln = 0
verse = ''
@ -322,9 +322,9 @@ class SofImport(OooImport):
self.isChorus = False
def addSofVerse(self, lyrics, tag):
self.addVerse(lyrics, tag)
if not self.isChorus and 'C1' in self.verseOrderListGenerated:
self.verseOrderListGenerated.append('C1')
self.add_verse(lyrics, tag)
if not self.isChorus and 'C1' in self.verse_order_list_generated:
self.verse_order_list_generated.append('C1')
self.verseOrderListGenerated_useful = True
def uncapText(self, text):

View File

@ -109,7 +109,7 @@ class SongBeamerImport(SongImport):
# TODO: check that it is a valid SongBeamer file
if self.stop_import_flag:
return
self.setDefaults()
self.set_defaults()
self.currentVerse = ''
self.currentVerseType = VerseType.tags[VerseType.Verse]
read_verses = False
@ -134,7 +134,7 @@ class SongBeamerImport(SongImport):
elif line.startswith('---'):
if self.currentVerse:
self.replaceHtmlTags()
self.addVerse(self.currentVerse, self.currentVerseType)
self.add_verse(self.currentVerse, self.currentVerseType)
self.currentVerse = ''
self.currentVerseType = VerseType.tags[VerseType.Verse]
read_verses = True
@ -148,9 +148,9 @@ class SongBeamerImport(SongImport):
self.currentVerse += line + '\n'
if self.currentVerse:
self.replaceHtmlTags()
self.addVerse(self.currentVerse, self.currentVerseType)
self.add_verse(self.currentVerse, self.currentVerseType)
if not self.finish():
self.logError(import_file)
self.log_error(import_file)
def replaceHtmlTags(self):
"""
@ -174,7 +174,7 @@ class SongBeamerImport(SongImport):
if not tag_val[0] or not tag_val[1]:
return
if tag_val[0] == '#(c)':
self.addCopyright(tag_val[1])
self.add_copyright(tag_val[1])
elif tag_val[0] == '#AddCopyrightInfo':
pass
elif tag_val[0] == '#Author':
@ -186,7 +186,7 @@ class SongBeamerImport(SongImport):
elif tag_val[0] == '#Categories':
self.topics = tag_val[1].split(',')
elif tag_val[0] == '#CCLI':
self.ccliNumber = tag_val[1]
self.ccli_number = tag_val[1]
elif tag_val[0] == '#Chords':
pass
elif tag_val[0] == '#ChurchSongID':
@ -233,10 +233,10 @@ class SongBeamerImport(SongImport):
song_book_pub = tag_val[1]
elif tag_val[0] == '#Songbook' or tag_val[0] == '#SongBook':
book_data = tag_val[1].split('/')
self.songBookName = book_data[0].strip()
self.song_book_name = book_data[0].strip()
if len(book_data) == 2:
number = book_data[1].strip()
self.songNumber = number if number.isdigit() else ''
self.song_number = number if number.isdigit() else ''
elif tag_val[0] == '#Speed':
pass
elif tag_val[0] == 'Tempo':

View File

@ -53,7 +53,7 @@ class SongImport(QtCore.QObject):
as necessary
"""
@staticmethod
def isValidSource(import_source):
def is_valid_source(import_source):
"""
Override this method to validate the source prior to import.
"""
@ -63,10 +63,8 @@ class SongImport(QtCore.QObject):
"""
Initialise and create defaults for properties
``manager``
An instance of a SongManager, through which all database access is
performed.
:param manager: An instance of a SongManager, through which all database access is performed.
:param kwargs:
"""
self.manager = manager
QtCore.QObject.__init__(self)
@ -82,56 +80,51 @@ class SongImport(QtCore.QObject):
self.import_wizard = None
self.song = None
self.stop_import_flag = False
self.setDefaults()
self.set_defaults()
Registry().register_function('openlp_stop_wizard', self.stop_import)
def setDefaults(self):
def set_defaults(self):
"""
Create defaults for properties - call this before each song
if importing many songs at once to ensure a clean beginning
"""
self.title = ''
self.songNumber = ''
self.song_number = ''
self.alternate_title = ''
self.copyright = ''
self.comments = ''
self.themeName = ''
self.ccliNumber = ''
self.theme_name = ''
self.ccli_number = ''
self.authors = []
self.topics = []
self.mediaFiles = []
self.songBookName = ''
self.songBookPub = ''
self.verseOrderListGeneratedUseful = False
self.verseOrderListGenerated = []
self.verseOrderList = []
self.media_files = []
self.song_book_name = ''
self.song_book_pub = ''
self.verse_order_list_generated_useful = False
self.verse_order_list_generated = []
self.verse_order_list = []
self.verses = []
self.verseCounts = {}
self.copyrightString = translate('SongsPlugin.SongImport', 'copyright')
self.verse_counts = {}
self.copyright_string = translate('SongsPlugin.SongImport', 'copyright')
def logError(self, filepath, reason=SongStrings.SongIncomplete):
def log_error(self, file_path, reason=SongStrings.SongIncomplete):
"""
This should be called, when a song could not be imported.
``filepath``
This should be the file path if ``self.import_source`` is a list
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.
``reason``
The reason why the import failed. The string should be as
informative as possible.
:param file_path: This should be the file path if ``self.import_source`` is a list 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.
:param reason: The reason why the import failed. The string should be as informative as possible.
"""
self.setDefaults()
self.set_defaults()
if self.import_wizard is None:
return
if self.import_wizard.error_report_text_edit.isHidden():
self.import_wizard.error_report_text_edit.setText(translate('SongsPlugin.SongImport',
'The following songs could not be imported:'))
self.import_wizard.error_report_text_edit.setText(
translate('SongsPlugin.SongImport', 'The following songs could not be imported:'))
self.import_wizard.error_report_text_edit.setVisible(True)
self.import_wizard.error_copy_to_button.setVisible(True)
self.import_wizard.error_save_to_button.setVisible(True)
self.import_wizard.error_report_text_edit.append('- %s (%s)' % (filepath, reason))
self.import_wizard.error_report_text_edit.append('- %s (%s)' % (file_path, reason))
def stop_import(self):
"""
@ -143,10 +136,9 @@ class SongImport(QtCore.QObject):
def register(self, import_wizard):
self.import_wizard = import_wizard
def tidyText(self, text):
def tidy_text(self, text):
"""
Get rid of some dodgy unicode and formatting characters we're not
interested in. Some can be converted to ascii.
Get rid of some dodgy unicode and formatting characters we're not interested in. Some can be converted to ascii.
"""
text = text.replace('\u2018', '\'')
text = text.replace('\u2019', '\'')
@ -161,21 +153,21 @@ class SongImport(QtCore.QObject):
text = re.sub(r' ?(\n{5}|\f)+ ?', '\f', text)
return text
def processSongText(self, text):
def process_song_text(self, text):
verse_texts = text.split('\n\n')
for verse_text in verse_texts:
if verse_text.strip() != '':
self.processVerseText(verse_text.strip())
self.process_verse_text(verse_text.strip())
def processVerseText(self, text):
def process_verse_text(self, text):
lines = text.split('\n')
if text.lower().find(self.copyrightString) >= 0 or text.find(str(SongStrings.CopyrightSymbol)) >= 0:
if text.lower().find(self.copyright_string) >= 0 or text.find(str(SongStrings.CopyrightSymbol)) >= 0:
copyright_found = False
for line in lines:
if (copyright_found or line.lower().find(self.copyrightString) >= 0 or
if (copyright_found or line.lower().find(self.copyright_string) >= 0 or
line.find(str(SongStrings.CopyrightSymbol)) >= 0):
copyright_found = True
self.addCopyright(line)
self.add_copyright(line)
else:
self.parse_author(line)
return
@ -184,9 +176,9 @@ class SongImport(QtCore.QObject):
return
if not self.title:
self.title = lines[0]
self.addVerse(text)
self.add_verse(text)
def addCopyright(self, copyright):
def add_copyright(self, copyright):
"""
Build the copyright field
"""
@ -211,9 +203,9 @@ class SongImport(QtCore.QObject):
if author2.endswith('.'):
author2 = author2[:-1]
if author2:
self.addAuthor(author2)
self.add_author(author2)
def addAuthor(self, author):
def add_author(self, author):
"""
Add an author to the list
"""
@ -221,15 +213,15 @@ class SongImport(QtCore.QObject):
return
self.authors.append(author)
def addMediaFile(self, filename, weight=0):
def add_media_file(self, filename, weight=0):
"""
Add a media file to the list
"""
if filename in [x[0] for x in self.mediaFiles]:
if filename in [x[0] for x in self.media_files]:
return
self.mediaFiles.append((filename, weight))
self.media_files.append((filename, weight))
def addVerse(self, verse_text, verse_def='v', lang=None):
def add_verse(self, verse_text, verse_def='v', lang=None):
"""
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
@ -248,32 +240,32 @@ class SongImport(QtCore.QObject):
"""
for (old_verse_def, old_verse, old_lang) in self.verses:
if old_verse.strip() == verse_text.strip():
self.verseOrderListGenerated.append(old_verse_def)
self.verseOrderListGeneratedUseful = True
self.verse_order_list_generated.append(old_verse_def)
self.verse_order_list_generated_useful = True
return
if verse_def[0] in self.verseCounts:
self.verseCounts[verse_def[0]] += 1
if verse_def[0] in self.verse_counts:
self.verse_counts[verse_def[0]] += 1
else:
self.verseCounts[verse_def[0]] = 1
self.verse_counts[verse_def[0]] = 1
if len(verse_def) == 1:
verse_def += str(self.verseCounts[verse_def[0]])
elif int(verse_def[1:]) > self.verseCounts[verse_def[0]]:
self.verseCounts[verse_def[0]] = int(verse_def[1:])
verse_def += str(self.verse_counts[verse_def[0]])
elif int(verse_def[1:]) > self.verse_counts[verse_def[0]]:
self.verse_counts[verse_def[0]] = int(verse_def[1:])
self.verses.append([verse_def, verse_text.rstrip(), lang])
# A verse_def refers to all verses with that name, adding it once adds every instance, so do not add if already
# used.
if verse_def not in self.verseOrderListGenerated:
self.verseOrderListGenerated.append(verse_def)
if verse_def not in self.verse_order_list_generated:
self.verse_order_list_generated.append(verse_def)
def repeatVerse(self):
def repeat_verse(self):
"""
Repeat the previous verse in the verse order
"""
if self.verseOrderListGenerated:
self.verseOrderListGenerated.append(self.verseOrderListGenerated[-1])
self.verseOrderListGeneratedUseful = True
if self.verse_order_list_generated:
self.verse_order_list_generated.append(self.verse_order_list_generated[-1])
self.verse_order_list_generated_useful = True
def checkComplete(self):
def check_complete(self):
"""
Check the mandatory fields are entered (i.e. title and a verse)
Author not checked here, if no author then "Author unknown" is
@ -288,8 +280,8 @@ class SongImport(QtCore.QObject):
"""
All fields have been set to this song. Write the song to disk.
"""
if not self.checkComplete():
self.setDefaults()
if not self.check_complete():
self.set_defaults()
return False
log.info('committing song %s to database', self.title)
song = Song()
@ -301,7 +293,7 @@ class SongImport(QtCore.QObject):
song.search_title = ''
song.search_lyrics = ''
song.verse_order = ''
song.song_number = self.songNumber
song.song_number = self.song_number
verses_changed_to_other = {}
sxml = SongXML()
other_count = 1
@ -317,14 +309,14 @@ class SongImport(QtCore.QObject):
verse_def = new_verse_def
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
song.lyrics = str(sxml.extract_xml(), 'utf-8')
if not self.verseOrderList and self.verseOrderListGeneratedUseful:
self.verseOrderList = self.verseOrderListGenerated
self.verseOrderList = [verses_changed_to_other.get(v, v) for v in self.verseOrderList]
song.verse_order = ' '.join(self.verseOrderList)
if not self.verse_order_list and self.verse_order_list_generated_useful:
self.verse_order_list = self.verse_order_list_generated
self.verse_order_list = [verses_changed_to_other.get(v, v) for v in self.verse_order_list]
song.verse_order = ' '.join(self.verse_order_list)
song.copyright = self.copyright
song.comments = self.comments
song.theme_name = self.themeName
song.ccli_number = self.ccliNumber
song.theme_name = self.theme_name
song.ccli_number = self.ccli_number
for authortext in self.authors:
author = self.manager.get_object_filtered(Author, Author.display_name == authortext)
if not author:
@ -332,10 +324,10 @@ class SongImport(QtCore.QObject):
last_name=authortext.split(' ')[-1],
first_name=' '.join(authortext.split(' ')[:-1]))
song.authors.append(author)
if self.songBookName:
song_book = self.manager.get_object_filtered(Book, Book.name == self.songBookName)
if self.song_book_name:
song_book = self.manager.get_object_filtered(Book, Book.name == self.song_book_name)
if song_book is None:
song_book = Book.populate(name=self.songBookName, publisher=self.songBookPub)
song_book = Book.populate(name=self.song_book_name, publisher=self.song_book_pub)
song.book = song_book
for topictext in self.topics:
if not topictext:
@ -350,17 +342,17 @@ class SongImport(QtCore.QObject):
self.manager.save_object(song)
# Now loop through the media files, copy them to the correct location,
# and save the song again.
for filename, weight in self.mediaFiles:
for filename, weight in self.media_files:
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)
filename = self.copy_media_file(song.id, filename)
song.media_files.append(MediaFile.populate(file_name=filename, weight=weight))
self.manager.save_object(song)
self.setDefaults()
self.set_defaults()
return True
def copyMediaFile(self, song_id, filename):
def copy_media_file(self, song_id, filename):
"""
This method copies the media file to the correct location and returns
the new file location.

View File

@ -100,7 +100,7 @@ class SongProImport(SongImport):
Process a section of the song, i.e. title, verse etc.
"""
if tag == 'T':
self.setDefaults()
self.set_defaults()
if text:
self.title = text
return
@ -118,29 +118,29 @@ class SongProImport(SongImport):
if tag == 'A':
self.parse_author(text)
elif tag in ['B', 'C']:
self.addVerse(text, tag)
self.add_verse(text, tag)
elif tag == 'D':
self.addVerse(text, 'E')
self.add_verse(text, 'E')
elif tag == 'G':
self.topics.append(text)
elif tag == 'M':
matches = re.findall(r'\d+', text)
if matches:
self.songNumber = matches[-1]
self.songBookName = text[:text.rfind(self.songNumber)]
self.song_number = matches[-1]
self.song_book_name = text[:text.rfind(self.song_number)]
elif tag == 'N':
self.comments = text
elif tag == 'O':
for char in text:
if char == 'C':
self.verseOrderList.append('C1')
self.verse_order_list.append('C1')
elif char == 'B':
self.verseOrderList.append('B1')
self.verse_order_list.append('B1')
elif char == 'D':
self.verseOrderList.append('E1')
self.verse_order_list.append('E1')
elif '1' <= char <= '7':
self.verseOrderList.append('V' + char)
self.verse_order_list.append('V' + char)
elif tag == 'R':
self.addCopyright(text)
self.add_copyright(text)
elif '1' <= tag <= '7':
self.addVerse(text, 'V' + tag[1:])
self.add_verse(text, 'V' + tag[1:])

View File

@ -145,15 +145,15 @@ class SongShowPlusImport(SongImport):
author = authorParts[1] + " " + authorParts[0]
self.parse_author(author)
elif block_key == COPYRIGHT:
self.addCopyright(self.decode(data))
self.add_copyright(self.decode(data))
elif block_key == CCLI_NO:
self.ccliNumber = int(data)
self.ccli_number = int(data)
elif block_key == VERSE:
self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no))
self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no))
elif block_key == CHORUS:
self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no))
self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no))
elif block_key == BRIDGE:
self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no))
self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no))
elif block_key == TOPIC:
self.topics.append(self.decode(data))
elif block_key == COMMENTS:
@ -165,19 +165,19 @@ class SongShowPlusImport(SongImport):
verse_tag = self.decode(verse_tag)
self.ssp_verse_order_list.append(verse_tag)
elif block_key == SONG_BOOK:
self.songBookName = self.decode(data)
self.song_book_name = self.decode(data)
elif block_key == SONG_NUMBER:
self.songNumber = ord(data)
self.song_number = ord(data)
elif block_key == CUSTOM_VERSE:
verse_tag = self.to_openlp_verse_tag(verse_name)
self.addVerse(self.decode(data), verse_tag)
self.add_verse(self.decode(data), verse_tag)
else:
log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data))
song_data.seek(next_block_starts)
self.verseOrderList = self.ssp_verse_order_list
self.verse_order_list = self.ssp_verse_order_list
song_data.close()
if not self.finish():
self.logError(file)
self.log_error(file)
def to_openlp_verse_tag(self, verse_name, ignore_unique=False):
# Have we got any digits? If so, verse number is everything from the digits to the end (OpenLP does not have

View File

@ -75,18 +75,18 @@ class SundayPlusImport(SongImport):
"""
Process the Sunday Plus file object.
"""
self.setDefaults()
self.set_defaults()
if not self.parse(file.read()):
self.logError(file.name)
self.log_error(file.name)
return
if not self.title:
self.title = self.titleFromFilename(file.name)
if not self.finish():
self.logError(file.name)
self.log_error(file.name)
def parse(self, data, cell=False):
if len(data) == 0 or data[0:1] != '[' or data[-1] != ']':
self.logError('File is malformed')
self.log_error('File is malformed')
return False
i = 1
verse_type = VerseType.tags[VerseType.Verse]
@ -126,7 +126,7 @@ class SundayPlusImport(SongImport):
elif name == 'Author':
author = self.decode(self.unescape(value))
if len(author):
self.addAuthor(author)
self.add_author(author)
elif name == 'Copyright':
self.copyright = self.decode(self.unescape(value))
elif name[0:4] == 'CELL':
@ -160,13 +160,13 @@ class SundayPlusImport(SongImport):
if line[:3].lower() == 'ccl':
m = re.search(r'[0-9]+', line)
if m:
self.ccliNumber = int(m.group(0))
self.ccli_number = int(m.group(0))
continue
elif line.lower() == 'public domain':
self.copyright = 'Public Domain'
continue
processed_lines.append(line)
self.addVerse('\n'.join(processed_lines).strip(), verse_type)
self.add_verse('\n'.join(processed_lines).strip(), verse_type)
if end == -1:
break
i = end + 1

View File

@ -60,7 +60,7 @@ class WorshipCenterProImport(SongImport):
except (pyodbc.DatabaseError, pyodbc.IntegrityError, pyodbc.InternalError, pyodbc.OperationalError) as e:
log.warn('Unable to connect the WorshipCenter Pro database %s. %s', self.import_source, str(e))
# Unfortunately no specific exception type
self.logError(self.import_source,
self.log_error(self.import_source,
translate('SongsPlugin.WorshipCenterProImport', 'Unable to connect the WorshipCenter Pro database.'))
return
cursor = conn.cursor()
@ -76,10 +76,10 @@ class WorshipCenterProImport(SongImport):
for song in songs:
if self.stop_import_flag:
break
self.setDefaults()
self.set_defaults()
self.title = songs[song]['TITLE']
lyrics = songs[song]['LYRICS'].strip('&crlf;&crlf;')
for verse in lyrics.split('&crlf;&crlf;'):
verse = verse.replace('&crlf;', '\n')
self.addVerse(verse)
self.add_verse(verse)
self.finish()

View File

@ -110,10 +110,10 @@ class WowImport(SongImport):
for source in self.import_source:
if self.stop_import_flag:
return
self.setDefaults()
self.set_defaults()
song_data = open(source, 'rb')
if song_data.read(19) != 'WoW File\nSong Words':
self.logError(source, str(translate('SongsPlugin.WordsofWorshipSongImport',
self.log_error(source, str(translate('SongsPlugin.WordsofWorshipSongImport',
('Invalid Words of Worship song file. Missing "Wow File\\nSong Words" header.'))))
continue
# Seek to byte which stores number of blocks in the song
@ -121,7 +121,7 @@ class WowImport(SongImport):
no_of_blocks = ord(song_data.read(1))
song_data.seek(66)
if song_data.read(16) != 'CSongDoc::CBlock':
self.logError(source, str(translate('SongsPlugin.WordsofWorshipSongImport',
self.log_error(source, str(translate('SongsPlugin.WordsofWorshipSongImport',
('Invalid Words of Worship song file. Missing "CSongDoc::CBlock" string.'))))
continue
# Seek to the beginning of the first block
@ -141,7 +141,7 @@ class WowImport(SongImport):
# this is the last block!
if block + 1 < no_of_blocks:
song_data.seek(2, os.SEEK_CUR)
self.addVerse(block_text, block_type)
self.add_verse(block_text, block_type)
# Now to extract the author
author_length = ord(song_data.read(1))
if author_length:
@ -149,10 +149,10 @@ class WowImport(SongImport):
# Finally the copyright
copyright_length = ord(song_data.read(1))
if copyright_length:
self.addCopyright(str(song_data.read(copyright_length), 'cp1252'))
self.add_copyright(str(song_data.read(copyright_length), 'cp1252'))
file_name = os.path.split(source)[1]
# Get the song title
self.title = file_name.rpartition('.')[0]
song_data.close()
if not self.finish():
self.logError(source)
self.log_error(source)

View File

@ -89,7 +89,7 @@ class ZionWorxImport(SongImport):
try:
records = list(songs_reader)
except csv.Error as e:
self.logError(translate('SongsPlugin.ZionWorxImport', 'Error reading CSV file.'),
self.log_error(translate('SongsPlugin.ZionWorxImport', 'Error reading CSV file.'),
translate('SongsPlugin.ZionWorxImport', 'Line %d: %s') % (songs_reader.line_num, e))
return
num_records = len(records)
@ -98,20 +98,20 @@ class ZionWorxImport(SongImport):
for index, record in enumerate(records, 1):
if self.stop_import_flag:
return
self.setDefaults()
self.set_defaults()
try:
self.title = self._decode(record['Title1'])
if record['Title2']:
self.alternate_title = self._decode(record['Title2'])
self.parse_author(self._decode(record['Writer']))
self.addCopyright(self._decode(record['Copyright']))
self.add_copyright(self._decode(record['Copyright']))
lyrics = self._decode(record['Lyrics'])
except UnicodeDecodeError as e:
self.logError(translate('SongsPlugin.ZionWorxImport', 'Record %d' % index),
self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d' % index),
translate('SongsPlugin.ZionWorxImport', 'Decoding error: %s') % e)
continue
except TypeError as e:
self.logError(translate(
self.log_error(translate(
'SongsPlugin.ZionWorxImport', 'File not valid ZionWorx CSV format.'), 'TypeError: %s' % e)
return
verse = ''
@ -119,13 +119,13 @@ class ZionWorxImport(SongImport):
if line and not line.isspace():
verse += line + '\n'
elif verse:
self.addVerse(verse)
self.add_verse(verse)
verse = ''
if verse:
self.addVerse(verse)
self.add_verse(verse)
title = self.title
if not self.finish():
self.logError(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index
self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index
+ (': "' + title + '"' if title else ''))
def _decode(self, str):

View File

@ -369,8 +369,8 @@ class TestEasyWorshipSongImport(TestCase):
importer = EasyWorshipSongImportLogger(mocked_manager)
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = False
importer.addAuthor = mocked_add_author
importer.addVerse = mocked_add_verse
importer.add_author = mocked_add_author
importer.add_verse = mocked_add_verse
importer.title = mocked_title
importer.finish = mocked_finish
importer.topics = []
@ -394,11 +394,11 @@ class TestEasyWorshipSongImport(TestCase):
if song_copyright:
self.assertEqual(importer.copyright, song_copyright)
if ccli_number:
self.assertEquals(importer.ccliNumber, ccli_number, 'ccliNumber for %s should be %s'
self.assertEquals(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s'
% (title, ccli_number))
for verse_text, verse_tag in add_verse_calls:
mocked_add_verse.assert_any_call(verse_text, verse_tag)
if verse_order_list:
self.assertEquals(importer.verseOrderList, verse_order_list, 'verseOrderList for %s should be %s'
self.assertEquals(importer.verse_order_list, verse_order_list, 'verse_order_list for %s should be %s'
% (title, verse_order_list))
mocked_finish.assert_called_with()

View File

@ -169,7 +169,7 @@ class TestFoilPresenter(TestCase):
# WHEN: xml_to_song is called with a string without an xml encoding declaration
foil_presenter_instance.xml_to_song('<foilpresenterfolie>')
# THEN: the string shiuld have been left intact
# THEN: the string should have been left intact
self.mocked_re.compile.sub.called_with('<foilpresenterfolie>')
def process_lyrics_no_verses_test(self):
@ -188,7 +188,7 @@ class TestFoilPresenter(TestCase):
# WHEN: _process_lyrics is called
result = foil_presenter_instance._process_lyrics(mock_foilpresenterfolie, mocked_song)
# THEN: _process_lyrics should return None and the song_import logError method should have been called once
# THEN: _process_lyrics should return None and the song_import log_error method should have been called once
self.assertIsNone(result)
self.mocked_song_import.logError.assert_called_once_with('Element Text', 'Translated String')
self.mocked_song_import.log_error.assert_called_once_with('Element Text', 'Translated String')
self.process_lyrics_patcher.start()

View File

@ -130,7 +130,7 @@ class TestSongBeamerImport(TestCase):
importer = SongBeamerImport(mocked_manager)
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = False
importer.addVerse = mocked_add_verse
importer.add_verse = mocked_add_verse
importer.finish = mocked_finish
# WHEN: Importing each file
@ -147,9 +147,9 @@ class TestSongBeamerImport(TestCase):
for verse_text, verse_tag in add_verse_calls:
mocked_add_verse.assert_any_call(verse_text, verse_tag)
if song_book_name:
self.assertEquals(importer.songBookName, song_book_name, 'songBookName for %s should be "%s"'
self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"'
% (song_file, song_book_name))
if song_number:
self.assertEquals(importer.songNumber, song_number, 'songNumber for %s should be %s'
self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s'
% (song_file, song_number))
mocked_finish.assert_called_with()

View File

@ -41,6 +41,7 @@ from tests.functional import patch, MagicMock
TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'songshowplussongs'))
class TestSongShowPlusFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'SongShowPlusImport'

View File

@ -152,7 +152,7 @@ class TestWorshipCenterProSongImport(TestCase):
Test that exceptions raised by pyodbc are handled
"""
# GIVEN: A mocked out SongImport class, a mocked out pyodbc module, a mocked out translate method,
# a mocked "manager" and a mocked out logError method.
# a mocked "manager" and a mocked out log_error method.
with patch('openlp.plugins.songs.lib.worshipcenterproimport.SongImport'), \
patch('openlp.plugins.songs.lib.worshipcenterproimport.pyodbc.connect') as mocked_pyodbc_connect, \
patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate:
@ -160,7 +160,7 @@ class TestWorshipCenterProSongImport(TestCase):
mocked_log_error = MagicMock()
mocked_translate.return_value = 'Translated Text'
importer = WorshipCenterProImport(mocked_manager)
importer.logError = mocked_log_error
importer.log_error = mocked_log_error
importer.import_source = 'import_source'
pyodbc_errors = [pyodbc.DatabaseError, pyodbc.IntegrityError, pyodbc.InternalError, pyodbc.OperationalError]
mocked_pyodbc_connect.side_effect = pyodbc_errors
@ -169,7 +169,7 @@ class TestWorshipCenterProSongImport(TestCase):
for effect in pyodbc_errors:
return_value = importer.doImport()
# THEN: doImport should return None, and pyodbc, translate & logError are called with known calls
# THEN: doImport should return None, and pyodbc, translate & log_error are called with known calls
self.assertIsNone(return_value, 'doImport should return None when pyodbc raises an exception.')
mocked_pyodbc_connect.assert_called_with( 'DRIVER={Microsoft Access Driver (*.mdb)};DBQ=import_source')
mocked_translate.assert_called_with('SongsPlugin.WorshipCenterProImport',
@ -181,7 +181,7 @@ class TestWorshipCenterProSongImport(TestCase):
Test that a simulated WorshipCenter Pro recordset is imported correctly
"""
# GIVEN: A mocked out SongImport class, a mocked out pyodbc module with a simulated recordset, a mocked out
# translate method, a mocked "manager", addVerse method & mocked_finish method.
# translate method, a mocked "manager", add_verse method & mocked_finish method.
with patch('openlp.plugins.songs.lib.worshipcenterproimport.SongImport'), \
patch('openlp.plugins.songs.lib.worshipcenterproimport.pyodbc') as mocked_pyodbc, \
patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate:
@ -194,7 +194,7 @@ class TestWorshipCenterProSongImport(TestCase):
importer = WorshipCenterProImportLogger(mocked_manager)
importer.import_source = 'import_source'
importer.import_wizard = mocked_import_wizard
importer.addVerse = mocked_add_verse
importer.add_verse = mocked_add_verse
importer.stop_import_flag = False
importer.finish = mocked_finish
@ -202,7 +202,7 @@ class TestWorshipCenterProSongImport(TestCase):
return_value = importer.doImport()
# THEN: doImport should return None, and pyodbc, import_wizard, importer.title and addVerse are called with
# THEN: doImport should return None, and pyodbc, import_wizard, importer.title and add_verse are called with
# known calls
self.assertIsNone(return_value, 'doImport should return None when pyodbc raises an exception.')
mocked_pyodbc.connect.assert_called_with('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=import_source')
@ -220,4 +220,4 @@ class TestWorshipCenterProSongImport(TestCase):
for call in verse_calls:
mocked_add_verse.assert_any_call(call)
self.assertEqual(mocked_add_verse.call_count, add_verse_call_count,
'Incorrect number of calls made to addVerse')
'Incorrect number of calls made to add_verse')

View File

@ -35,6 +35,7 @@ from unittest import TestCase
from tests.functional import patch, MagicMock
class SongImportTestHelper(TestCase):
"""
This class is designed to be a helper class to reduce repition when testing the import of song files.
@ -50,9 +51,9 @@ class SongImportTestHelper(TestCase):
Patch and set up the mocks required.
"""
self.add_copyright_patcher = patch(
'openlp.plugins.songs.lib.%s.%s.addCopyright' % (self.importer_module_name, self.importer_class_name))
'openlp.plugins.songs.lib.%s.%s.add_copyright' % (self.importer_module_name, self.importer_class_name))
self.add_verse_patcher = patch(
'openlp.plugins.songs.lib.%s.%s.addVerse' % (self.importer_module_name, self.importer_class_name))
'openlp.plugins.songs.lib.%s.%s.add_verse' % (self.importer_module_name, self.importer_class_name))
self.finish_patcher = patch(
'openlp.plugins.songs.lib.%s.%s.finish' % (self.importer_module_name, self.importer_class_name))
self.parse_author_patcher = patch(
@ -115,7 +116,7 @@ class SongImportTestHelper(TestCase):
if song_copyright:
self.mocked_add_copyright.assert_called_with(song_copyright)
if ccli_number:
self.assertEquals(importer.ccliNumber, ccli_number, 'ccliNumber for %s should be %s'
self.assertEquals(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s'
% (source_file_name, ccli_number))
for verse_text, verse_tag in add_verse_calls:
self.mocked_add_verse.assert_any_call(verse_text, verse_tag)
@ -125,13 +126,13 @@ class SongImportTestHelper(TestCase):
self.assertEquals(importer.comments, comments, 'comments for %s should be "%s"'
% (source_file_name, comments))
if song_book_name:
self.assertEquals(importer.songBookName, song_book_name, 'songBookName for %s should be "%s"'
self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"'
% (source_file_name, song_book_name))
if song_number:
self.assertEquals(importer.songNumber, song_number, 'songNumber for %s should be %s'
self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s'
% (source_file_name, song_number))
if verse_order_list:
self.assertEquals(importer.verseOrderList, [], 'verseOrderList for %s should be %s'
self.assertEquals(importer.verse_order_list, [], 'verse_order_list for %s should be %s'
% (source_file_name, verse_order_list))
self.mocked_finish.assert_called_with()