~ubuntu-branches/debian/sid/openlp/sid

« back to all changes in this revision

Viewing changes to openlp/plugins/songs/lib/songbeamerimport.py

  • Committer: Package Import Robot
  • Author(s): Raoul Snyman
  • Date: 2012-05-09 18:40:30 UTC
  • Revision ID: package-import@ubuntu.com-20120509184030-pqz3jwr61635nld9
Tags: upstream-1.9.9
ImportĀ upstreamĀ versionĀ 1.9.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
 
3
 
 
4
###############################################################################
 
5
# OpenLP - Open Source Lyrics Projection                                      #
 
6
# --------------------------------------------------------------------------- #
 
7
# Copyright (c) 2008-2012 Raoul Snyman                                        #
 
8
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan      #
 
9
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan,      #
 
10
# Armin Kƶhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias     #
 
11
# PƵldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,    #
 
12
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             #
 
13
# --------------------------------------------------------------------------- #
 
14
# This program is free software; you can redistribute it and/or modify it     #
 
15
# under the terms of the GNU General Public License as published by the Free  #
 
16
# Software Foundation; version 2 of the License.                              #
 
17
#                                                                             #
 
18
# This program is distributed in the hope that it will be useful, but WITHOUT #
 
19
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
 
20
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
 
21
# more details.                                                               #
 
22
#                                                                             #
 
23
# You should have received a copy of the GNU General Public License along     #
 
24
# with this program; if not, write to the Free Software Foundation, Inc., 59  #
 
25
# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
 
26
###############################################################################
 
27
"""
 
28
The :mod:`songbeamerimport` module provides the functionality for importing
 
29
 SongBeamer songs into the OpenLP database.
 
30
"""
 
31
import chardet
 
32
import codecs
 
33
import logging
 
34
import os
 
35
import re
 
36
 
 
37
from openlp.plugins.songs.lib import VerseType
 
38
from openlp.plugins.songs.lib.songimport import SongImport
 
39
 
 
40
log = logging.getLogger(__name__)
 
41
 
 
42
class SongBeamerTypes(object):
 
43
    MarkTypes = {
 
44
        u'Refrain': VerseType.Tags[VerseType.Chorus],
 
45
        u'Chorus': VerseType.Tags[VerseType.Chorus],
 
46
        u'Vers': VerseType.Tags[VerseType.Verse],
 
47
        u'Verse': VerseType.Tags[VerseType.Verse],
 
48
        u'Strophe': VerseType.Tags[VerseType.Verse],
 
49
        u'Intro': VerseType.Tags[VerseType.Intro],
 
50
        u'Coda': VerseType.Tags[VerseType.Ending],
 
51
        u'Ending': VerseType.Tags[VerseType.Ending],
 
52
        u'Bridge': VerseType.Tags[VerseType.Bridge],
 
53
        u'Interlude': VerseType.Tags[VerseType.Bridge],
 
54
        u'Zwischenspiel': VerseType.Tags[VerseType.Bridge],
 
55
        u'Pre-Chorus': VerseType.Tags[VerseType.PreChorus],
 
56
        u'Pre-Refrain': VerseType.Tags[VerseType.PreChorus],
 
57
        u'Pre-Bridge': VerseType.Tags[VerseType.Other],
 
58
        u'Pre-Coda': VerseType.Tags[VerseType.Other],
 
59
        u'Unbekannt': VerseType.Tags[VerseType.Other],
 
60
        u'Unknown': VerseType.Tags[VerseType.Other],
 
61
        u'Unbenannt': VerseType.Tags[VerseType.Other]
 
62
    }
 
63
 
 
64
 
 
65
class SongBeamerImport(SongImport):
 
66
    """
 
67
    Import Song Beamer files(s)
 
68
    Song Beamer file format is text based
 
69
    in the beginning are one or more control tags written
 
70
    """
 
71
    HTML_TAG_PAIRS = [
 
72
        (re.compile(u'<b>'), u'{st}'),
 
73
        (re.compile(u'</b>'), u'{/st}'),
 
74
        (re.compile(u'<i>'), u'{it}'),
 
75
        (re.compile(u'</i>'), u'{/it}'),
 
76
        (re.compile(u'<u>'), u'{u}'),
 
77
        (re.compile(u'</u>'), u'{/u}'),
 
78
        (re.compile(u'<p>'), u'{p}'),
 
79
        (re.compile(u'</p>'), u'{/p}'),
 
80
        (re.compile(u'<super>'), u'{su}'),
 
81
        (re.compile(u'</super>'), u'{/su}'),
 
82
        (re.compile(u'<sub>'), u'{sb}'),
 
83
        (re.compile(u'</sub>'), u'{/sb}'),
 
84
        (re.compile(u'<br.*?>'), u'{br}'),
 
85
        (re.compile(u'<[/]?wordwrap>'), u''),
 
86
        (re.compile(u'<[/]?strike>'), u''),
 
87
        (re.compile(u'<[/]?h.*?>'), u''),
 
88
        (re.compile(u'<[/]?s.*?>'), u''),
 
89
        (re.compile(u'<[/]?linespacing.*?>'), u''),
 
90
        (re.compile(u'<[/]?c.*?>'), u''),
 
91
        (re.compile(u'<align.*?>'), u''),
 
92
        (re.compile(u'<valign.*?>'), u'')
 
93
    ]
 
94
 
 
95
    def __init__(self, manager, **kwargs):
 
96
        """
 
97
        Initialise the Song Beamer importer.
 
98
        """
 
99
        SongImport.__init__(self, manager, **kwargs)
 
100
 
 
101
    def doImport(self):
 
102
        """
 
103
        Receive a single file or a list of files to import.
 
104
        """
 
105
        self.importWizard.progressBar.setMaximum(len(self.importSource))
 
106
        if not isinstance(self.importSource, list):
 
107
            return
 
108
        for file in self.importSource:
 
109
            # TODO: check that it is a valid SongBeamer file
 
110
            if self.stopImportFlag:
 
111
                return
 
112
            self.setDefaults()
 
113
            self.currentVerse = u''
 
114
            self.currentVerseType = VerseType.Tags[VerseType.Verse]
 
115
            read_verses = False
 
116
            file_name = os.path.split(file)[1]
 
117
            if os.path.isfile(file):
 
118
                detect_file = open(file, u'r')
 
119
                details = chardet.detect(detect_file.read())
 
120
                detect_file.close()
 
121
                infile = codecs.open(file, u'r', details['encoding'])
 
122
                song_data = infile.readlines()
 
123
                infile.close()
 
124
            else:
 
125
                continue
 
126
            self.title = file_name.split('.sng')[0]
 
127
            read_verses = False
 
128
            for line in song_data:
 
129
                # Just make sure that the line is of the type 'Unicode'.
 
130
                line = unicode(line).strip()
 
131
                if line.startswith(u'#') and not read_verses:
 
132
                    self.parseTags(line)
 
133
                elif line.startswith(u'---'):
 
134
                    if self.currentVerse:
 
135
                        self.replaceHtmlTags()
 
136
                        self.addVerse(self.currentVerse,
 
137
                            self.currentVerseType)
 
138
                        self.currentVerse = u''
 
139
                        self.currentVerseType = VerseType.Tags[VerseType.Verse]
 
140
                    read_verses = True
 
141
                    verse_start = True
 
142
                elif read_verses:
 
143
                    if verse_start:
 
144
                        verse_start = False
 
145
                        if not self.checkVerseMarks(line):
 
146
                            self.currentVerse = line + u'\n'
 
147
                    else:
 
148
                        self.currentVerse += line + u'\n'
 
149
            if self.currentVerse:
 
150
                self.replaceHtmlTags()
 
151
                self.addVerse(self.currentVerse, self.currentVerseType)
 
152
            if not self.finish():
 
153
                self.logError(file)
 
154
 
 
155
    def replaceHtmlTags(self):
 
156
        """
 
157
        This can be called to replace SongBeamer's specific (html) tags with
 
158
        OpenLP's specific (html) tags.
 
159
        """
 
160
        for pair in SongBeamerImport.HTML_TAG_PAIRS:
 
161
            self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
 
162
 
 
163
    def parseTags(self, line):
 
164
        """
 
165
        Parses a meta data line.
 
166
 
 
167
        ``line``
 
168
            The line in the file. It should consist of a tag and a value
 
169
            for this tag (unicode)::
 
170
 
 
171
                u'#Title=Nearer my God to Thee'
 
172
        """
 
173
        tag_val = line.split(u'=', 1)
 
174
        if len(tag_val) == 1:
 
175
            return
 
176
        if not tag_val[0] or not tag_val[1]:
 
177
            return
 
178
        if tag_val[0] == u'#(c)':
 
179
            self.addCopyright(tag_val[1])
 
180
        elif tag_val[0] == u'#AddCopyrightInfo':
 
181
            pass
 
182
        elif tag_val[0] == u'#Author':
 
183
            self.parseAuthor(tag_val[1])
 
184
        elif tag_val[0] == u'#BackgroundImage':
 
185
            pass
 
186
        elif tag_val[0] == u'#Bible':
 
187
            pass
 
188
        elif tag_val[0] == u'#Categories':
 
189
            self.topics = tag_val[1].split(',')
 
190
        elif tag_val[0] == u'#CCLI':
 
191
            self.ccliNumber = tag_val[1]
 
192
        elif tag_val[0] == u'#Chords':
 
193
            pass
 
194
        elif tag_val[0] == u'#ChurchSongID':
 
195
            pass
 
196
        elif tag_val[0] == u'#ColorChords':
 
197
            pass
 
198
        elif tag_val[0] == u'#Comments':
 
199
            self.comments = tag_val[1]
 
200
        elif tag_val[0] == u'#Editor':
 
201
            pass
 
202
        elif tag_val[0] == u'#Font':
 
203
            pass
 
204
        elif tag_val[0] == u'#FontLang2':
 
205
            pass
 
206
        elif tag_val[0] == u'#FontSize':
 
207
            pass
 
208
        elif tag_val[0] == u'#Format':
 
209
            pass
 
210
        elif tag_val[0] == u'#Format_PreLine':
 
211
            pass
 
212
        elif tag_val[0] == u'#Format_PrePage':
 
213
            pass
 
214
        elif tag_val[0] == u'#ID':
 
215
            pass
 
216
        elif tag_val[0] == u'#Key':
 
217
            pass
 
218
        elif tag_val[0] == u'#Keywords':
 
219
            pass
 
220
        elif tag_val[0] == u'#LangCount':
 
221
            pass
 
222
        elif tag_val[0] == u'#Melody':
 
223
            self.parseAuthor(tag_val[1])
 
224
        elif tag_val[0] == u'#NatCopyright':
 
225
            pass
 
226
        elif tag_val[0] == u'#OTitle':
 
227
            pass
 
228
        elif tag_val[0] == u'#OutlineColor':
 
229
            pass
 
230
        elif tag_val[0] == u'#OutlinedFont':
 
231
            pass
 
232
        elif tag_val[0] == u'#QuickFind':
 
233
            pass
 
234
        elif tag_val[0] == u'#Rights':
 
235
            song_book_pub = tag_val[1]
 
236
        elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
 
237
            book_data = tag_val[1].split(u'/')
 
238
            self.songBookName = book_data[0].strip()
 
239
            if len(book_data) == 2:
 
240
                number = book_data[1].strip()
 
241
                self.songNumber = number if number.isdigit() else u''
 
242
        elif tag_val[0] == u'#Speed':
 
243
            pass
 
244
        elif tag_val[0] == u'Tempo':
 
245
            pass
 
246
        elif tag_val[0] == u'#TextAlign':
 
247
            pass
 
248
        elif tag_val[0] == u'#Title':
 
249
            self.title = unicode(tag_val[1])
 
250
        elif tag_val[0] == u'#TitleAlign':
 
251
            pass
 
252
        elif tag_val[0] == u'#TitleFontSize':
 
253
            pass
 
254
        elif tag_val[0] == u'#TitleLang2':
 
255
            pass
 
256
        elif tag_val[0] == u'#TitleLang3':
 
257
            pass
 
258
        elif tag_val[0] == u'#TitleLang4':
 
259
            pass
 
260
        elif tag_val[0] == u'#Translation':
 
261
            pass
 
262
        elif tag_val[0] == u'#Transpose':
 
263
            pass
 
264
        elif tag_val[0] == u'#TransposeAccidental':
 
265
            pass
 
266
        elif tag_val[0] == u'#Version':
 
267
            pass
 
268
        elif tag_val[0] == u'#VerseOrder':
 
269
            # TODO: add the verse order.
 
270
            pass
 
271
 
 
272
    def checkVerseMarks(self, line):
 
273
        """
 
274
        Check and add the verse's MarkType. Returns ``True`` if the given line
 
275
        contains a correct verse mark otherwise ``False``.
 
276
 
 
277
        ``line``
 
278
            The line to check for marks (unicode).
 
279
        """
 
280
        marks = line.split(u' ')
 
281
        if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
 
282
            self.currentVerseType = SongBeamerTypes.MarkTypes[marks[0]]
 
283
            if len(marks) == 2:
 
284
                # If we have a digit, we append it to current_verse_type.
 
285
                if marks[1].isdigit():
 
286
                    self.currentVerseType += marks[1]
 
287
            return True
 
288
        return False