1
# -*- coding: utf-8 -*-
2
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
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. #
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 #
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
###############################################################################
28
The :mod:`songbeamerimport` module provides the functionality for importing
29
SongBeamer songs into the OpenLP database.
37
from openlp.plugins.songs.lib import VerseType
38
from openlp.plugins.songs.lib.songimport import SongImport
40
log = logging.getLogger(__name__)
42
class SongBeamerTypes(object):
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]
65
class SongBeamerImport(SongImport):
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
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'')
95
def __init__(self, manager, **kwargs):
97
Initialise the Song Beamer importer.
99
SongImport.__init__(self, manager, **kwargs)
103
Receive a single file or a list of files to import.
105
self.importWizard.progressBar.setMaximum(len(self.importSource))
106
if not isinstance(self.importSource, list):
108
for file in self.importSource:
109
# TODO: check that it is a valid SongBeamer file
110
if self.stopImportFlag:
113
self.currentVerse = u''
114
self.currentVerseType = VerseType.Tags[VerseType.Verse]
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())
121
infile = codecs.open(file, u'r', details['encoding'])
122
song_data = infile.readlines()
126
self.title = file_name.split('.sng')[0]
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:
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]
145
if not self.checkVerseMarks(line):
146
self.currentVerse = line + u'\n'
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():
155
def replaceHtmlTags(self):
157
This can be called to replace SongBeamer's specific (html) tags with
158
OpenLP's specific (html) tags.
160
for pair in SongBeamerImport.HTML_TAG_PAIRS:
161
self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
163
def parseTags(self, line):
165
Parses a meta data line.
168
The line in the file. It should consist of a tag and a value
169
for this tag (unicode)::
171
u'#Title=Nearer my God to Thee'
173
tag_val = line.split(u'=', 1)
174
if len(tag_val) == 1:
176
if not tag_val[0] or not tag_val[1]:
178
if tag_val[0] == u'#(c)':
179
self.addCopyright(tag_val[1])
180
elif tag_val[0] == u'#AddCopyrightInfo':
182
elif tag_val[0] == u'#Author':
183
self.parseAuthor(tag_val[1])
184
elif tag_val[0] == u'#BackgroundImage':
186
elif tag_val[0] == u'#Bible':
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':
194
elif tag_val[0] == u'#ChurchSongID':
196
elif tag_val[0] == u'#ColorChords':
198
elif tag_val[0] == u'#Comments':
199
self.comments = tag_val[1]
200
elif tag_val[0] == u'#Editor':
202
elif tag_val[0] == u'#Font':
204
elif tag_val[0] == u'#FontLang2':
206
elif tag_val[0] == u'#FontSize':
208
elif tag_val[0] == u'#Format':
210
elif tag_val[0] == u'#Format_PreLine':
212
elif tag_val[0] == u'#Format_PrePage':
214
elif tag_val[0] == u'#ID':
216
elif tag_val[0] == u'#Key':
218
elif tag_val[0] == u'#Keywords':
220
elif tag_val[0] == u'#LangCount':
222
elif tag_val[0] == u'#Melody':
223
self.parseAuthor(tag_val[1])
224
elif tag_val[0] == u'#NatCopyright':
226
elif tag_val[0] == u'#OTitle':
228
elif tag_val[0] == u'#OutlineColor':
230
elif tag_val[0] == u'#OutlinedFont':
232
elif tag_val[0] == u'#QuickFind':
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':
244
elif tag_val[0] == u'Tempo':
246
elif tag_val[0] == u'#TextAlign':
248
elif tag_val[0] == u'#Title':
249
self.title = unicode(tag_val[1])
250
elif tag_val[0] == u'#TitleAlign':
252
elif tag_val[0] == u'#TitleFontSize':
254
elif tag_val[0] == u'#TitleLang2':
256
elif tag_val[0] == u'#TitleLang3':
258
elif tag_val[0] == u'#TitleLang4':
260
elif tag_val[0] == u'#Translation':
262
elif tag_val[0] == u'#Transpose':
264
elif tag_val[0] == u'#TransposeAccidental':
266
elif tag_val[0] == u'#Version':
268
elif tag_val[0] == u'#VerseOrder':
269
# TODO: add the verse order.
272
def checkVerseMarks(self, line):
274
Check and add the verse's MarkType. Returns ``True`` if the given line
275
contains a correct verse mark otherwise ``False``.
278
The line to check for marks (unicode).
280
marks = line.split(u' ')
281
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
282
self.currentVerseType = SongBeamerTypes.MarkTypes[marks[0]]
284
# If we have a digit, we append it to current_verse_type.
285
if marks[1].isdigit():
286
self.currentVerseType += marks[1]