← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~derek-scotney/openlp/songselectfileimport into lp:openlp

 

DerekScotney has proposed merging lp:~derek-scotney/openlp/songselectfileimport into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)


Required changes to code and docstrings implemented 
-- 
https://code.launchpad.net/~derek-scotney/openlp/songselectfileimport/+merge/34025
Your team OpenLP Core is requested to review the proposed merge of lp:~derek-scotney/openlp/songselectfileimport into lp:openlp.
=== added file 'openlp/plugins/songs/.directory'
--- openlp/plugins/songs/.directory	1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/.directory	2010-08-29 18:29:38 +0000
@@ -0,0 +1,3 @@
+[Dolphin]
+Timestamp=2010,8,20,16,22,57
+ViewMode=1

=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py	2010-08-27 15:25:29 +0000
+++ openlp/plugins/songs/forms/songimportform.py	2010-08-29 18:29:38 +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/.directory'
--- openlp/plugins/songs/lib/.directory	1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/lib/.directory	2010-08-29 18:29:38 +0000
@@ -0,0 +1,3 @@
+[Dolphin]
+Timestamp=2010,8,21,15,53,23
+ViewMode=1

=== 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-08-29 18:29:38 +0000
@@ -0,0 +1,313 @@
+# -*- 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, master_manager, **kwargs):
+        """
+        Initialise the import.
+
+        ``manager``
+            The song manager for the running OpenLP installation.
+        ``filenames``
+            The files to be imported.
+        
+        """
+        SongImport.__init__(self, master_manager)
+        self.master_manager = master_manager
+        if u'filenames' in kwargs:
+            self.filenames = kwargs[u'filenames']
+            log.debug(self.filenames)
+
+    def do_import(self):
+        """
+        Import either a .usr or a .txt SongSelect file
+        """
+        
+        log.debug('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('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('SongSelect .usr format file found %s: ' ,  filename)
+                    self.do_import_usr_file(lines)
+                elif ext.lower() == ".txt":
+                    log.info('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) | (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('USR file text: %s', textList)
+        
+        n = 0 # line number
+        lyrics = []
+
+        new_song = SongImport(self.master_manager)
+
+        for line in textList:
+            n += 1
+            if line.startswith(u'Title='):
+                sname = line[6:].strip()
+            elif line.startswith(u'Author='):
+                sauthor = line[7:].strip()
+            elif line.startswith(u'Copyright='):
+                scopyright = line[10:].strip()
+            elif line.startswith(u'[S A'):
+                sccli = 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.
+                sfields = line[7:].strip()
+            elif line.startswith(u'Words='):
+                swords = line[6:].strip()
+            #Unhandled usr keywords:Type, Version, Admin, Themes, Keys
+
+        #Process Fields and words sections
+        fieldlst = sfields.split(u'/t')
+        wordslst = swords.split(u'/t')
+        for i in range(0, len(fieldlst)):
+            if fieldlst[i].startswith(u'Ver'): #Verse
+                vtype = u'V'
+            elif fieldlst[i].startswith(u'Ch'): #Chorus
+                vtype = u'C'
+            elif fieldlst[i].startswith(u'Br'): #Bridge
+                vtype = u'B'
+            else: #Other
+                vtype = u'O'
+            vcontent = unicode(wordslst[i])
+            vcontent = vcontent.replace("/n",  "\n")
+            if (len(vcontent) > 0):                
+                new_song.add_verse(vcontent, vtype);
+
+        #Handle multiple authors
+        lst = sauthor.split(u'/')
+        if len(lst) < 2:
+            lst = sauthor.split(u'|')
+        for author in lst:
+            seperated = author.split(u',')
+            new_song.add_author(seperated[1].strip() + " " + seperated[0].strip())
+
+        new_song.title = sname
+        new_song.copyright = scopyright
+        new_song.ccli_number = sccli
+        new_song.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('TXT file text: %s', textList)
+        
+        new_song = SongImport(self.master_manager)
+        n = 0
+        vcontent = u''
+        scomments = u''
+        scopyright = u'';
+        verse_start = False
+
+        for line in textList:
+            ln = line.strip()
+            if (len(ln)== 0):
+                if (n==0):
+                    continue
+                elif (verse_start == True):
+                      if (len(vcontent) > 0):
+                        new_song.add_verse(vcontent, vtype)
+                        vcontent = ''
+                        verse_start = False
+            else:
+                if (n==0): #n=0, song title
+                    sname = ln
+                    n += 1
+                elif (n==1): #n=1, verses
+                    if ln.startswith(u'CCLI'): #n=1, ccli number, first line after verses
+                        n += 1
+                        cparts = ln.split(' ')
+                        sccli = cparts[len(cparts)-1]
+                    elif (verse_start == False):
+                        # We have the verse descriptor
+                        parts = ln.split(' ')
+                        if (len(parts) == 2):
+                            if parts[0].startswith(u'Ver'): #Verse
+                                vtype = u'V'
+                            elif parts[0].startswith(u'Ch'): #Chorus
+                                vtype = u'C'
+                            elif parts[0].startswith(u'Br'): #Bridge
+                                vtype = u'B'
+                            else:
+                                vtype = u'O'
+                            vnumber = parts[1]
+                        else:
+                            vtype = u'O'
+                            vnumber = 1
+                        verse_start = True
+                    else:
+                        # We have verse content or the start of the last part
+                        # Add l so as to keep the CRLF
+                        vcontent = vcontent + line
+                else:
+                    if (n==2): #n=2, copyright
+                        n += 1
+                        scopyright = ln
+                    elif (n==3): #n=3, authors
+                        n += 1
+                        sauthor = ln
+                    elif (n==4) and (not ln.startswith(u'CCL')): #n=4, comments lines before last line
+                        scomments = scomments + ln
+        # split on known separators
+        alist = sauthor.split(u'/')
+        if len(alist) < 2:
+            alist = sauthor.split(u'|')
+        new_song.authors = alist
+        new_song.title = sname
+        new_song.copyright = scopyright
+        new_song.ccli_number = sccli
+        new_song.comments = scomments
+        new_song.finish()

=== modified file 'openlp/plugins/songs/lib/importer.py'
--- openlp/plugins/songs/lib/importer.py	2010-08-23 17:36:42 +0000
+++ openlp/plugins/songs/lib/importer.py	2010-08-29 18:29:38 +0000
@@ -29,6 +29,7 @@
 try:
     from sofimport import SofImport
     from oooimport import OooImport
+    from cclifileimport import CCLIFileImport
 except ImportError:
     pass
 
@@ -65,6 +66,8 @@
             return SofImport
         elif format == SongFormat.Generic:
             return OooImport
+        elif format == SongFormat.CCLI:
+            return CCLIFileImport            
 #        else:
         return None
 

=== added file 'resources/songs/.directory'
--- resources/songs/.directory	1970-01-01 00:00:00 +0000
+++ resources/songs/.directory	2010-08-29 18:29:38 +0000
@@ -0,0 +1,3 @@
+[Dolphin]
+Timestamp=2010,8,21,16,21,36
+ViewMode=1


Follow ups