diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index c62fa058e..ef655a12a 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -112,6 +112,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): QtCore.QObject.connect(self.ewBrowseButton, QtCore.SIGNAL(u'clicked()'), self.onEWBrowseButtonClicked) + QtCore.QObject.connect(self.songBeamerAddButton, + QtCore.SIGNAL(u'clicked()'), + self.onSongBeamerAddButtonClicked) + QtCore.QObject.connect(self.songBeamerRemoveButton, + QtCore.SIGNAL(u'clicked()'), + self.onSongBeamerRemoveButtonClicked) QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(u'clicked(bool)'), self.onCancelButtonClicked) @@ -227,6 +233,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): 'file to import from.')) self.ewBrowseButton.setFocus() return False + elif source_format == SongFormat.SongBeamer: + if self.songBeamerFileListWidget.count() == 0: + QtGui.QMessageBox.critical(self, + translate('SongsPlugin.ImportWizardForm', + 'No SongBeamer File Selected'), + translate('SongsPlugin.ImportWizardForm', + 'You need to add at least one SongBeamer ' + 'file to import from.')) + self.songBeamerAddButton.setFocus() + return False return True elif self.currentId() == 2: # Progress page @@ -342,6 +358,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): self.ewFilenameEdit ) + def onSongBeamerAddButtonClicked(self): + self.getFiles( + translate('SongsPlugin.ImportWizardForm', + 'Select SongBeamer Files'), + self.songBeamerFileListWidget + ) + + def onSongBeamerRemoveButtonClicked(self): + self.removeSelectedItems(self.songBeamerFileListWidget) + def onCancelButtonClicked(self, checked): """ Stop the import on pressing the cancel button. @@ -373,6 +399,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): self.songsOfFellowshipFileListWidget.clear() self.genericFileListWidget.clear() self.ewFilenameEdit.setText(u'') + self.songBeamerFileListWidget.clear() #self.csvFilenameEdit.setText(u'') def incrementProgressBar(self, status_text, increment=1): @@ -448,6 +475,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): importer = self.plugin.importSongs(SongFormat.EasyWorship, filename=unicode(self.ewFilenameEdit.text()) ) + elif source_format == SongFormat.SongBeamer: + # Import SongBeamer songs + importer = self.plugin.importSongs(SongFormat.SongBeamer, + filenames=self.getListOfFiles( + self.songBeamerFileListWidget) + ) success = importer.do_import() if success: # reload songs diff --git a/openlp/plugins/songs/forms/songimportwizard.py b/openlp/plugins/songs/forms/songimportwizard.py index bad85676f..5be8ccfba 100644 --- a/openlp/plugins/songs/forms/songimportwizard.py +++ b/openlp/plugins/songs/forms/songimportwizard.py @@ -116,6 +116,8 @@ class Ui_SongImportWizard(object): self.addMultiFileSelectItem(u'generic', None, True) # EasyWorship self.addSingleFileSelectItem(u'ew') + # Words of Worship + self.addMultiFileSelectItem(u'songBeamer') # Commented out for future use. # self.addSingleFileSelectItem(u'csv', u'CSV') self.sourceLayout.addWidget(self.formatStackedWidget) @@ -180,6 +182,8 @@ class Ui_SongImportWizard(object): 'Generic Document/Presentation')) self.formatComboBox.setItemText(8, translate('SongsPlugin.ImportWizardForm', 'EasyWorship')) + self.formatComboBox.setItemText(9, + translate('SongsPlugin.ImportWizardForm', 'SongBeamer')) # self.formatComboBox.setItemText(9, # translate('SongsPlugin.ImportWizardForm', 'CSV')) self.openLP2FilenameLabel.setText( @@ -236,6 +240,10 @@ class Ui_SongImportWizard(object): translate('SongsPlugin.ImportWizardForm', 'Filename:')) self.ewBrowseButton.setText( translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.songBeamerAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.songBeamerRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) # self.csvFilenameLabel.setText( # translate('SongsPlugin.ImportWizardForm', 'Filename:')) # self.csvBrowseButton.setText( diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index d8028db24..63d19b95c 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -29,6 +29,7 @@ from olpimport import OpenLPSongImport from wowimport import WowImport from cclifileimport import CCLIFileImport from ewimport import EasyWorshipSongImport +from songbeamerimport import SongBeamerImport # Imports that might fail try: from olp1import import OpenLP1SongImport @@ -64,6 +65,7 @@ class SongFormat(object): Generic = 7 #CSV = 8 EasyWorship = 8 + SongBeamer = 9 @staticmethod def get_class(format): @@ -89,6 +91,8 @@ class SongFormat(object): return CCLIFileImport elif format == SongFormat.EasyWorship: return EasyWorshipSongImport + elif format == SongFormat.SongBeamer: + return SongBeamerImport # else: return None @@ -106,7 +110,8 @@ class SongFormat(object): SongFormat.CCLI, SongFormat.SongsOfFellowship, SongFormat.Generic, - SongFormat.EasyWorship + SongFormat.EasyWorship, + SongFormat.SongBeamer ] @staticmethod diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py new file mode 100644 index 000000000..a839e2418 --- /dev/null +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`songbeamerimport` module provides the functionality for importing + SongBeamer songs into the OpenLP database. +""" +import logging +import os +import re +import chardet +import codecs + +from openlp.plugins.songs.lib.songimport import SongImport + +log = logging.getLogger(__name__) + +class SongBeamerTypes(object): + MarkTypes = { + u'Refrain': u'C', + u'Chorus': u'C', + u'Vers': u'V', + u'Verse': u'V', + u'Strophe': u'V', + u'Intro': u'I', + u'Coda': u'E', + u'Ending': u'E', + u'Bridge': u'B', + u'Interlude': u'B', + u'Zwischenspiel': u'B', + u'Pre-Chorus': u'P', + u'Pre-Refrain': u'P', + u'Pre-Bridge': u'O', + u'Pre-Coda': u'O', + u'Unbekannt': u'O', + u'Unknown': u'O' + } + +class SongBeamerImport(SongImport): + """ + Import Song Beamer files(s) + Song Beamer file format is text based + in the beginning are one or more control tags written + """ + def __init__(self, master_manager, **kwargs): + """ + Initialise the import. + ``master_manager`` + The song manager for the running OpenLP installation. + """ + SongImport.__init__(self, master_manager) + self.master_manager = master_manager + if kwargs.has_key(u'filename'): + self.import_source = kwargs[u'filename'] + if kwargs.has_key(u'filenames'): + self.import_source = kwargs[u'filenames'] + log.debug(self.import_source) + + def do_import(self): + """ + Recieve a single file, or a list of files to import. + """ + if isinstance(self.import_source, list): + self.import_wizard.importProgressBar.setMaximum( + len(self.import_source)) + for file in self.import_source: + # TODO: check that it is a valid SongBeamer file + self.current_verse = u'' + self.current_verse_type = u'V' + self.file_name = os.path.split(file)[1] + self.import_wizard.incrementProgressBar( + "Importing %s" % (self.file_name), 0) + if os.path.isfile(file): + detect_file = open(file, u'r') + details = chardet.detect(detect_file.read(2048)) + detect_file.close() + infile = codecs.open(file, u'r', details['encoding']) + self.songData = infile.readlines() + else: + return False + for line in self.songData: + line = line.strip() + if line.startswith('#'): + log.debug(u'find tag: %s' % line) + if not self.parse_tags(line): + return False + elif line.startswith('---'): + log.debug(u'find ---') + if len(self.current_verse) > 0: + self.add_verse(self.current_verse, + self.current_verse_type) + self.current_verse = u'' + self.current_verse_type = u'V' + self.read_verse = True + self.verse_start = True + elif self.read_verse: + if self.verse_start: + self.check_verse_marks(line) + self.verse_start = False + else: + self.current_verse += u'%s\n' % line + if len(self.current_verse) > 0: + self.add_verse(self.current_verse, self.current_verse_type) + self.finish() + self.import_wizard.incrementProgressBar( + "Importing %s" % (self.file_name)) + return True + + def parse_tags(self, line): + tag_val = line.split('=') + if len(tag_val[0]) == 0 or \ + len(tag_val[1]) == 0: + return True + if tag_val[0] == '#(c)': + self.add_copyright(tag_val[1]) + elif tag_val[0] == '#AddCopyrightInfo': + pass + elif tag_val[0] == '#Author': + #TODO split Authors + self.add_author(tag_val[1]) + elif tag_val[0] == '#BackgroundImage': + pass + elif tag_val[0] == '#Bible': + pass + elif tag_val[0] == '#Categories': + self.topics = line.split(',') + elif tag_val[0] == '#CCLI': + self.ccli_number = tag_val[1] + elif tag_val[0] == '#Chords': + pass + elif tag_val[0] == '#ChurchSongID': + pass + elif tag_val[0] == '#ColorChords': + pass + elif tag_val[0] == '#Comments': + self.comments = tag_val[1] + elif tag_val[0] == '#Editor': + pass + elif tag_val[0] == '#Font': + pass + elif tag_val[0] == '#FontLang2': + pass + elif tag_val[0] == '#FontSize': + pass + elif tag_val[0] == '#Format': + pass + elif tag_val[0] == '#Format_PreLine': + pass + elif tag_val[0] == '#Format_PrePage': + pass + elif tag_val[0] == '#ID': + pass + elif tag_val[0] == '#Key': + pass + elif tag_val[0] == '#Keywords': + pass + elif tag_val[0] == '#LangCount': + pass + elif tag_val[0] == '#Melody': + #TODO split Authors + self.add_author(tag_val[1]) + elif tag_val[0] == '#NatCopyright': + pass + elif tag_val[0] == '#OTitle': + pass + elif tag_val[0] == '#OutlineColor': + pass + elif tag_val[0] == '#OutlinedFont': + pass + elif tag_val[0] == '#QuickFind': + pass + elif tag_val[0] == '#Rights': + song_book_pub = tag_val[1] + elif tag_val[0] == '#Songbook': + book_num = tag_val[1].split(' / ') + self.song_book_name = book_num[0] + if len(book_num) == book_num[1]: + self.song_number = u'' + elif tag_val[0] == '#Speed': + pass + elif tag_val[0] == '#TextAlign': + pass + elif tag_val[0] == '#Title': + self.title = u'%s' % tag_val[1] + elif tag_val[0] == '#TitleAlign': + pass + elif tag_val[0] == '#TitleFontSize': + pass + elif tag_val[0] == '#TitleLang2': + pass + elif tag_val[0] == '#TitleLang3': + pass + elif tag_val[0] == '#TitleLang4': + pass + elif tag_val[0] == '#Translation': + pass + elif tag_val[0] == '#Transpose': + pass + elif tag_val[0] == '#TransposeAccidental': + pass + elif tag_val[0] == '#Version': + pass + else: + pass + return True + + def check_verse_marks(self, line): + marks = line.split(' ') + if len(marks) <= 2 and \ + marks[0] in SongBeamerTypes.MarkTypes: + self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]] + if len(marks) == 2: + #TODO: may check, because of only digits are allowed + self.current_verse_type += marks[1]