← Back to team overview

openlp-core team mailing list archive

[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