Source code for openlp.plugins.songs.lib.importers.chordpro

# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4

###############################################################################
# OpenLP - Open Source Lyrics Projection                                      #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2016 OpenLP Developers                                   #
# --------------------------------------------------------------------------- #
# 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:`chordpro` module provides the functionality for importing
ChordPro files into the current database.
"""

import logging
import re

from openlp.core.common import Settings

from .songimport import SongImport


log = logging.getLogger(__name__)


[docs]class ChordProImport(SongImport): """ The :class:`ChordProImport` class provides OpenLP with the ability to import ChordPro files. This importer is based on the information available on these webpages: http://webchord.sourceforge.net/tech.html http://www.vromans.org/johan/projects/Chordii/chordpro/ http://www.tenbyten.com/software/songsgen/help/HtmlHelp/files_reference.htm http://linkesoft.com/songbook/chordproformat.html """
[docs] def do_import(self): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) for filename in self.import_source: if self.stop_import_flag: return song_file = open(filename, 'rt') self.do_import_file(song_file) song_file.close()
[docs] def do_import_file(self, song_file): """ Imports the songs in the given file :param song_file: The file object to be imported from. """ self.set_defaults() # Loop over the lines of the file file_content = song_file.read() current_verse = '' current_verse_type = 'v' skip_block = False for line in file_content.splitlines(): line = line.rstrip() # Detect tags if line.startswith('{'): tag_name, tag_value = self.parse_tag(line) # Detect which tag if tag_name in ['title', 't']: self.title = tag_value elif tag_name in ['subtitle', 'su', 'st']: self.alternate_title = tag_value elif tag_name in ['comment', 'c', 'comment_italic', 'ci', 'comment_box', 'cb']: # Detect if the comment is used as a chorus repeat marker if tag_value.lower().startswith('chorus'): if current_verse.strip(): # Add collected verse to the lyrics # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value( 'songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' self.repeat_verse('c1') else: self.add_comment(tag_value) elif tag_name in ['start_of_chorus', 'soc']: current_verse_type = 'c' elif tag_name in ['end_of_chorus', 'eoc']: # Add collected chorus to the lyrics # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value('songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' elif tag_name in ['start_of_tab', 'sot']: if current_verse.strip(): # Add collected verse to the lyrics # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value( 'songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' skip_block = True elif tag_name in ['end_of_tab', 'eot']: skip_block = False elif tag_name in ['new_song', 'ns']: # A new song starts below this tag if self.verses and self.title: if current_verse.strip(): # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value( 'songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) if not self.finish(): self.log_error(song_file.name) self.set_defaults() current_verse_type = 'v' current_verse = '' else: # Unsupported tag log.debug('unsupported tag: %s' % line) elif line.startswith('#'): # Found a comment line, which is ignored... continue elif line == "['|]": # Found a vertical bar continue else: if skip_block: continue elif line == '' and current_verse.strip() and current_verse_type != 'c': # Add collected verse to the lyrics # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value('songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' else: if current_verse.strip() == '': current_verse = line + '\n' else: current_verse += line + '\n' if current_verse.strip(): # Strip out chords if set up to if not Settings().value('songs/enable chords') or Settings().value( 'songs/disable chords import'): current_verse = re.sub(r'\[.*?\]', '', current_verse) self.add_verse(current_verse.rstrip(), current_verse_type) if not self.finish(): self.log_error(song_file.name)
[docs] def parse_tag(self, line): """ :param line: Line with the tag to be parsed :return: A tuple with tag name and tag value (if any) """ # Strip the first '}' line = line[1:].strip() colon_idx = line.find(':') # check if this is a tag without value if colon_idx < 0: # strip the final '}' and return the tag name return line[:-1], None tag_name = line[:colon_idx] tag_value = line[colon_idx + 1:-1].strip() return tag_name, tag_value