Development:Song Importer Developers Guide

From OpenLP
Jump to: navigation, search

The Song Import Wizard has been designed to be pluggable for easily adding importers for more song formats. Adding a new importer involves little more than writing a parser for the new song format.

Song Import Wizard

Familiarize yourself with the Song Import Wizard, such as the controls used on the source page and progress page.

The Song Import Wizard is constructed by the SongImportForm class, found in openlp.plugins.songs.forms.songimportform. You generally shouldn't have to modify this class, but it can be helpful to understand how it works.

Base SongImport Class

Each song importer extends the base SongImport class, found in openlp.plugins.songs.lib. It provides several methods you may wish to use which implement common functionality.

isValidSource(import_source)
Override this static method to validate the source prior to import.
setDefaults()
Create defaults for song properties - if importing many songs at once, call this before each song to ensure a clean beginning. You can also refer to this method's implementation to see all the song properties that are available.
logError(filepath_or_title, reason)
Called when a song could not be imported. The error is displayed to the user in a box below the progress bar on the progress page.
tidyText(text)
Get rid of some dodgy unicode and formatting characters we're not interested in.
addCopyright(copyright)
Build the copyright field.
parseAuthor(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 'Mr Smith' and 'Mrs Smith'.
addAuthor(author)
Add an author to the list.
addVerse(verse_text, verse_def=u'v', lang=None)
Add a verse. This is the whole verse, lines split by \\n. It will also attempt to detect duplicates. In this case it will just add to the verse order.
repeatVerse()
Repeat the previous verse in the verse order.
checkComplete()
Check the mandatory fields are entered (i.e. title and a verse). Author not checked here, if no author then "Author unknown" is automatically added.
finish()
All fields have been set to this song. Write the song to disk.

Writing an Import class

Begin by creating a new module containing a single class that extends the base SongImport class.

  • The class name should be the name of the format, and use CamelCase, for example "ZionWorxImport".
  • The module will have the same name, but lowercase, and will be in openlp.plugins.songs.lib.
class MySongFormatImport(SongImport):
  """
  Docstring explaining the song format.
  """
  
  # Optional - validate your source prior to import
  @staticmethod
  def isValidSource(import_source):
    pass
  
  # Main method that parses import source
  def doImport(self):
    pass
    
  # Non-public supporting methods
  def _parseField(self, field):
    pass

isValidSource(import_source)

The isValidSource() method provides an opportunity to validate the import source before attempting to parse it. This method is called when the user clicks "Next" from the source page of the wizard. If their source does not pass validation, they will see an error dialog explaining this (you can define the error message with u'invalidSourceMsg'in the next section).

Example implementation from the PowerSongImport class:

    @staticmethod
    def isValidSource(import_source):
        """
        Checks if source is a PowerSong 1.0 folder:
            * is a directory
            * contains at least one *.song file
        """
        if os.path.isdir(import_source):
            for file in os.listdir(import_source):
                if fnmatch.fnmatch(file, u'*.song'):
                    return True
        return False

If validation fails, the user will be told "You need to specify a valid PowerSong 1.0 database folder."

doImport(self)

The import source is provided in self.importSource. This can be either a list of files, a single file, or a single folder, as determined by the particular song format.

Registering an Import class

You need to "register" your importer, so the Song Import Wizard knows about it. This is done in the SongFormat class in the openlp.plugins.songs.lib.importer module.

import statement

Add an import statement at the top of the module.

from mysongformatimport import MySongFormatImport

Song formats enumeration

Add your song format to the alphabetic enumeration of song formats, being sure to re-number the formats further down the list.

EasyWorship = 7
FoilPresenter = 8
MySongFormat = 9
OpenSong = 10
PowerSong = 11

get_format_list()

Add your song format to the get_format_list() method.

Set attribute values

You can set various attributes for your song format which define its appearance and behaviour in the Song Import Wizard. Locate the __attributes__ dict in the SongFormat class, and add a section for your song format. A few attributes are required for every song format, but most are optional. Default values for the optional attributes are supplied by the __defaults__ dict.

Example implementation for the PowerSong format:

PowerSong: {
    u'class': PowerSongImport,
    u'name': u'PowerSong 1.0',
    u'prefix': u'powerSong',
    u'selectMode': SongFormatSelect.SingleFolder,
    u'invalidSourceMsg': translate('SongsPlugin.ImportWizardForm',
        'You need to specify a valid PowerSong 1.0 database folder.')
},

Required attributes

u'class'
Import class, e.g. MySongFormatImport
u'name'
Name of the format, e.g. u'MySongFormat'
u'prefix'
Prefix for Qt objects. Use mixedCase, e.g. u'mySongFormat'

Optional attributes

u'canDisable'
Whether song format importer is disablable. If True, then u'disabledLabelText' must also be defined.
u'selectMode'
Whether format accepts single file, multiple files, or single folder (as per SongFormatSelect options).
u'filter'
File extension filter for the file selection dialog.

Optional/custom text strings

u'comboBoxText'
Combo box selector (default value is the format's u'name').
u'disabledLabelText'
Required for disablable song formats.
u'getFilesTitle'
Title for the file selection dialog (default includes the format's u'name').
u'invalidSourceMsg'
Message displayed if isValidSource() returns False.
u'descriptionText'
Short description (1-2 lines) about the song format.

Existing Song Importers

You may find some inspiration in the exising song import classes, especially those which parse a similar underlying file format.

Song Format Underlying file format Select Mode Class
openlp.org 1.x SQLite database SingleFile OpenLP1SongImport
Generic Document/Presentation Impress/Powerpoint file (via Open/LibreOffice) MultipleFiles OooImport
CCLI/SongSelect Plain text, line and keyword delimited MultipleFiles CCLIFileImport
DreamBeam XML files MultipleFiles DreamBeamImport
EasySlides XML library SingleFile EasySlidesImport
EasyWorship Borland Database Engine (Paradox) SingleFile EasyWorshipSongImport
Foilpresenter XML files MultipleFiles FoilPresenterImport
MediaShout MS Access database SingleFile MediaShoutImport
OpenSong XML files MultipleFiles OpenSongImport
PowerSong 1.0 Label-field pairs (.NET 7BitEncodedInt) SingleFolder PowerSongImport
SongBeamer Text, with control tags MultipleFiles SongBeamerImport
SongPro Text, with control tags SingleFile SongProImport
SongShow Plus Variable-length binary encoding MultipleFiles SongShowPlusImport
Songs of Fellowship RTF (via Open/LibreOffice) MultipleFiles SofImport
SundayPlus Text, including RTF MultipleFiles SundayPlusImport
Words of Worship Binary: header, blocks, footer MultipleFiles WowImport
ZionWorx CSV library SingleFile ZionWorxImport