openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #03154
[Merge] lp:~derek-scotney/openlp/songselectfileimport into lp:openlp
Derek Scotney has proposed merging lp:~derek-scotney/openlp/songselectfileimport into lp:openlp.
Requested reviews:
Tim Bentley (trb143)
Raoul Snyman (raoul-snyman): syntactic sugar
Required changes to code and docstrings implemented
--
https://code.launchpad.net/~derek-scotney/openlp/songselectfileimport/+merge/34334
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py 2010-08-27 19:53:22 +0000
+++ openlp/plugins/songs/forms/songimportform.py 2010-09-01 19:49:41 +0000
@@ -83,6 +83,12 @@
QtCore.QObject.connect(self.wordsOfWorshipRemoveButton,
QtCore.SIGNAL(u'clicked()'),
self.onWordsOfWorshipRemoveButtonClicked)
+ QtCore.QObject.connect(self.ccliAddButton,
+ QtCore.SIGNAL(u'clicked()'),
+ self.onCCLIAddButtonClicked)
+ QtCore.QObject.connect(self.ccliRemoveButton,
+ QtCore.SIGNAL(u'clicked()'),
+ self.onCCLIRemoveButtonClicked)
QtCore.QObject.connect(self.songsOfFellowshipAddButton,
QtCore.SIGNAL(u'clicked()'),
self.onSongsOfFellowshipAddButtonClicked)
@@ -277,6 +283,16 @@
def onWordsOfWorshipRemoveButtonClicked(self):
self.removeSelectedItems(self.wordsOfWorshipFileListWidget)
+ def onCCLIAddButtonClicked(self):
+ self.getFiles(
+ translate('SongsPlugin.ImportWizardForm',
+ 'Select CCLI Files'),
+ self.ccliFileListWidget
+ )
+
+ def onCCLIRemoveButtonClicked(self):
+ self.removeSelectedItems(self.ccliFileListWidget)
+
def onSongsOfFellowshipAddButtonClicked(self):
self.getFiles(
translate('SongsPlugin.ImportWizardForm',
=== added file 'openlp/plugins/songs/lib/cclifileimport.py'
--- openlp/plugins/songs/lib/cclifileimport.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/lib/cclifileimport.py 2010-09-01 19:49:41 +0000
@@ -0,0 +1,310 @@
+# -*- 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, Derek Scotney #
+# --------------------------------------------------------------------------- #
+# 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 #
+###############################################################################
+
+import logging
+import os
+import chardet
+import codecs
+
+from songimport import SongImport
+
+log = logging.getLogger(__name__)
+
+class CCLIFileImportError(Exception):
+ pass
+
+class CCLIFileImport(SongImport):
+ """
+ The :class:`CCLIFileImport` class provides OpenLP with the
+ ability to import CCLI SongSelect song files in both .txt and
+ .usr formats. See http://www.ccli.com
+ """
+
+ def __init__(self, manager, **kwargs):
+ """
+ Initialise the import.
+
+ ``manager``
+ The song manager for the running OpenLP installation.
+ ``filenames``
+ The files to be imported.
+ """
+ SongImport.__init__(self, manager)
+ if u'filenames' in kwargs:
+ self.filenames = kwargs[u'filenames']
+ log.debug(self.filenames)
+ else:
+ raise KeyError(u'Keyword argument "filenames" not supplied.')
+
+ def do_import(self):
+ """
+ Import either a .usr or a .txt SongSelect file
+ """
+ log.debug(u'Starting CCLI File Import')
+ song_total = len(self.filenames)
+ self.import_wizard.importProgressBar.setMaximum(song_total)
+ song_count = 1
+ for filename in self.filenames:
+ self.import_wizard.incrementProgressBar(
+ u'Importing song %s of %s' % (song_count, song_total))
+ filename = unicode(filename)
+ log.debug(u'Importing CCLI File: %s', filename)
+ lines = []
+ if os.path.isfile(filename):
+ detect_file = open(filename, u'r')
+ details = chardet.detect(detect_file.read(2048))
+ detect_file.close()
+ infile = codecs.open(filename, u'r', details['encoding'])
+ lines = infile.readlines()
+ ext = os.path.splitext(filename)[1]
+ if ext.lower() == ".usr":
+ log.info(u'SongSelect .usr format file found %s: ' , filename)
+ self.do_import_usr_file(lines)
+ elif ext.lower() == ".txt":
+ log.info(u'SongSelect .txt format file found %s: ', filename)
+ self.do_import_txt_file(lines)
+ else:
+ log.info(u'Extension %s is not valid', filename)
+ pass
+ song_count += 1
+ if self.stop_import_flag:
+ return False
+ return True
+
+ def do_import_usr_file(self, textList):
+ """
+ The :method:`do_import_usr_file` method provides OpenLP
+ with the ability to import CCLI SongSelect songs in
+ *USR* file format
+
+ ``textList``
+ An array of strings containing the usr file content.
+
+ **SongSelect .usr file format**
+ ``[File]``
+ USR file format first line
+ ``Type=``
+ Indicates the file type
+ e.g. *Type=SongSelect Import File*
+ ``Version=3.0``
+ File format version
+ ``[S A2672885]``
+ Contains the CCLI Song number e.g. *2672885*
+ ``Title=``
+ Contains the song title (e.g. *Title=Above All*)
+ ``Author=``
+ Contains a | delimited list of the song authors
+ e.g. *Author=LeBlanc, Lenny | Baloche, Paul*
+ ``Copyright=``
+ Contains a | delimited list of the song copyrights
+ e.g. Copyright=1999 Integrity's Hosanna! Music |
+ LenSongs Publishing (Verwaltet von Gerth Medien
+ Musikverlag)
+ ``Admin=``
+ Contains the song administrator
+ e.g. *Admin=Gerth Medien Musikverlag*
+ ``Themes=``
+ Contains a /t delimited list of the song themes
+ e.g. *Themes=Cross/tKingship/tMajesty/tRedeemer*
+ ``Keys=``
+ Contains the keys in which the music is played??
+ e.g. *Keys=A*
+ ``Fields=``
+ Contains a list of the songs fields in order /t delimited
+ e.g. *Fields=Vers 1/tVers 2/tChorus 1/tAndere 1*
+ ``Words=``
+ Contains the songs various lyrics in order as shown by the
+ *Fields* description
+ e.g. *Words=Above all powers....* [/n = CR, /n/t = CRLF]
+ """
+ log.debug(u'USR file text: %s', textList)
+ lyrics = []
+ self.set_defaults()
+ for line in textList:
+ if line.startswith(u'Title='):
+ song_name = line[6:].strip()
+ elif line.startswith(u'Author='):
+ song_author = line[7:].strip()
+ elif line.startswith(u'Copyright='):
+ song_copyright = line[10:].strip()
+ elif line.startswith(u'[S A'):
+ song_ccli = line[4:-3].strip()
+ elif line.startswith(u'Fields='):
+ #Fields contain single line indicating verse, chorus, etc,
+ #/t delimited, same as with words field. store seperately
+ #and process at end.
+ song_fields = line[7:].strip()
+ elif line.startswith(u'Words='):
+ song_words = line[6:].strip()
+ #Unhandled usr keywords:Type,Version,Admin,Themes,Keys
+ #Process Fields and words sections
+ field_list = song_fields.split(u'/t')
+ words_list = song_words.split(u'/t')
+ for counter in range(0, len(field_list)):
+ if field_list[counter].startswith(u'Ver'):
+ verse_type = u'V'
+ elif field_list[counter].startswith(u'Ch'):
+ verse_type = u'C'
+ elif field_list[counter].startswith(u'Br'):
+ verse_type = u'B'
+ else: #Other
+ verse_type = u'O'
+ verse_text = unicode(words_list[counter])
+ verse_text = verse_text.replace("/n", "\n")
+ if len(verse_text) > 0:
+ self.add_verse(verse_text, verse_type);
+ #Handle multiple authors
+ author_list = song_author.split(u'/')
+ if len(author_list) < 2:
+ author_list = song_author.split(u'|')
+ for author in author_list:
+ seperated = author.split(u',')
+ self.add_author(seperated[1].strip() + " " + seperated[0].strip())
+ self.title = song_name
+ self.copyright = song_copyright
+ self.ccli_number = song_ccli
+ self.finish()
+
+ def do_import_txt_file(self, textList):
+ """
+ The :method:`do_import_txt_file` method provides OpenLP
+ with the ability to import CCLI SongSelect songs in
+ *TXT* file format
+
+ ``textList``
+ An array of strings containing the txt file content.
+
+ **SongSelect .txt file format**
+
+ ``Song Title``
+ Contains the song title
+
+ <Empty line>
+
+ ``Title of following verse/chorus and number``
+ e.g. Verse 1, Chorus 1
+
+ ``Verse/Chorus lyrics``
+
+ <Empty line>
+
+ <Empty line>
+
+ ``Title of next verse/chorus (repeats)``
+
+ ``Verse/Chorus lyrics``
+
+ <Empty line>
+
+ <Empty line>
+
+ ``Song CCLI Number``
+ e.g. CCLI Number (e.g.CCLI-Liednummer: 2672885)
+ ``Song Copyright``
+ e.g. © 1999 Integrity's Hosanna! Music | LenSongs Publishing
+ ``Song Authors``
+ e.g. Lenny LeBlanc | Paul Baloche
+ ``Licencing info``
+ e.g. For use solely with the SongSelect Terms of Use.
+ All rights Reserved. www.ccli.com
+ ``CCLI Licence number of user``
+ e.g. CCL-Liedlizenznummer: 14 / CCLI License No. 14
+ """
+ log.debug(u'TXT file text: %s', textList)
+ self.set_defaults()
+ line_number = 0
+ verse_text = u''
+ song_comments = u''
+ song_copyright = u'';
+ verse_start = False
+ for line in textList:
+ clean_line = line.strip()
+ if not clean_line:
+ if line_number==0:
+ continue
+ elif verse_start:
+ if verse_text:
+ self.add_verse(verse_text, verse_type)
+ verse_text = ''
+ verse_start = False
+ else:
+ #line_number=0, song title
+ if line_number==0:
+ song_name = clean_line
+ line_number += 1
+ #line_number=1, verses
+ elif line_number==1:
+ #line_number=1, ccli number, first line after verses
+ if clean_line.startswith(u'CCLI'):
+ line_number += 1
+ ccli_parts = clean_line.split(' ')
+ song_ccli = ccli_parts[len(ccli_parts)-1]
+ elif not verse_start:
+ # We have the verse descriptor
+ verse_desc_parts = clean_line.split(' ')
+ if len(verse_desc_parts) == 2:
+ if verse_desc_parts[0].startswith(u'Ver'):
+ verse_type = u'V'
+ elif verse_desc_parts[0].startswith(u'Ch'):
+ verse_type = u'C'
+ elif verse_desc_parts[0].startswith(u'Br'):
+ verse_type = u'B'
+ else:
+ verse_type = u'O'
+ verse_number = verse_desc_parts[1]
+ else:
+ verse_type = u'O'
+ verse_number = 1
+ verse_start = True
+ else:
+ # We have verse content or the start of the
+ # last part. Add l so as to keep the CRLF
+ verse_text = verse_text + line
+ else:
+ #line_number=2, copyright
+ if line_number==2:
+ line_number += 1
+ song_copyright = clean_line
+ #n=3, authors
+ elif line_number==3:
+ line_number += 1
+ song_author = clean_line
+ #line_number=4, comments lines before last line
+ elif (line_number==4) and (not clean_line.startswith(u'CCL')):
+ song_comments = song_comments + clean_line
+ # split on known separators
+ author_list = song_author.split(u'/')
+ if len(author_list) < 2:
+ author_list = song_author.split(u'|')
+ #Clean spaces before and after author names
+ for author_name in author_list:
+ self.add_author(author_name.strip())
+ self.title = song_name
+ self.copyright = song_copyright
+ self.ccli_number = song_ccli
+ self.comments = song_comments
+ self.finish()
+
=== modified file 'openlp/plugins/songs/lib/importer.py'
--- openlp/plugins/songs/lib/importer.py 2010-08-27 19:53:22 +0000
+++ openlp/plugins/songs/lib/importer.py 2010-09-01 19:49:41 +0000
@@ -29,7 +29,11 @@
try:
from sofimport import SofImport
from oooimport import OooImport
+<<<<<<< TREE
from wowimport import WowImport
+=======
+ from cclifileimport import CCLIFileImport
+>>>>>>> MERGE-SOURCE
except ImportError:
pass
@@ -68,6 +72,8 @@
return WowImport
elif format == SongFormat.Generic:
return OooImport
+ elif format == SongFormat.CCLI:
+ return CCLIFileImport
# else:
return None
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2010-08-28 20:46:03 +0000
+++ openlp/plugins/songs/lib/songimport.py 2010-09-01 19:49:41 +0000
@@ -58,11 +58,19 @@
"""
self.manager = manager
self.stop_import_flag = False
+<<<<<<< TREE
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songs_stop_import'), self.stop_import)
self.setDefaults()
def setDefaults(self):
+=======
+ self.set_defaults()
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'songs_stop_import'), self.stop_import)
+
+ def set_defaults(self):
+>>>>>>> MERGE-SOURCE
self.title = u''
self.song_number = u''
self.alternate_title = u''
@@ -78,7 +86,15 @@
self.verses = []
self.versecount = 0
self.choruscount = 0
+<<<<<<< TREE
+=======
+ self.copyright_string = unicode(translate(
+ 'SongsPlugin.SongImport', 'copyright'))
+ self.copyright_symbol = unicode(translate(
+ 'SongsPlugin.SongImport', '\xa9'))
+
+>>>>>>> MERGE-SOURCE
def stop_import(self):
"""
Sets the flag for importers to stop their import
@@ -163,8 +179,7 @@
def parse_author(self, text):
"""
Add the author. OpenLP stores them individually so split by 'and', '&'
- and comma.
- However need to check for 'Mr and Mrs Smith' and turn it to
+ and comma. However need to check for 'Mr and Mrs Smith' and turn it to
'Mr Smith' and 'Mrs Smith'.
"""
for author in text.split(u','):
@@ -241,7 +256,7 @@
"""
All fields have been set to this song. Write it away
"""
- if len(self.authors) == 0:
+ if not self.authors:
self.authors.append(u'Author unknown')
self.commit_song()
Follow ups