forked from openlp/openlp
r2024
This commit is contained in:
commit
f83d48293f
@ -39,7 +39,8 @@ log = logging.getLogger(__name__)
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
|
||||
ItemCapabilities, SettingsManager, translate, str_to_bool
|
||||
ItemCapabilities, SettingsManager, translate, str_to_bool, \
|
||||
check_directory_exists
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
||||
@ -556,8 +557,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
audio_from = os.path.join(self.servicePath, audio_from)
|
||||
save_file = os.path.join(self.servicePath, audio_to)
|
||||
save_path = os.path.split(save_file)[0]
|
||||
if not os.path.exists(save_path):
|
||||
os.makedirs(save_path)
|
||||
check_directory_exists(save_path)
|
||||
if not os.path.exists(save_file):
|
||||
shutil.copy(audio_from, save_file)
|
||||
zip.write(audio_from, audio_to.encode(u'utf-8'))
|
||||
|
@ -226,7 +226,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
|
||||
def onCurrentIdChanged(self, pageId):
|
||||
"""
|
||||
Detects Page changes and updates as approprate.
|
||||
Detects Page changes and updates as appropriate.
|
||||
"""
|
||||
enabled = self.page(pageId) == self.areaPositionPage
|
||||
self.setOption(QtGui.QWizard.HaveCustomButton1, enabled)
|
||||
|
@ -172,6 +172,11 @@ def _get_os_dir_path(dir_type):
|
||||
u'Library', u'Application Support', u'openlp')
|
||||
else:
|
||||
if dir_type == AppLocation.LanguageDir:
|
||||
prefixes = [u'/usr/local', u'/usr']
|
||||
for prefix in prefixes:
|
||||
directory = os.path.join(prefix, u'share', u'openlp')
|
||||
if os.path.exists(directory):
|
||||
return directory
|
||||
return os.path.join(u'/usr', u'share', u'openlp')
|
||||
if XDG_BASE_AVAILABLE:
|
||||
if dir_type == AppLocation.ConfigDir:
|
||||
|
@ -227,9 +227,6 @@ class ImpressDocument(PresentationDocument):
|
||||
OpenOffice task started earlier. If OpenOffice is not present is is
|
||||
started. Once the environment is available the presentation is loaded
|
||||
and started.
|
||||
|
||||
``presentation``
|
||||
The file name of the presentatios to the run.
|
||||
"""
|
||||
log.debug(u'Load Presentation OpenOffice')
|
||||
if os.name == u'nt':
|
||||
|
@ -119,10 +119,7 @@ class PowerpointDocument(PresentationDocument):
|
||||
def load_presentation(self):
|
||||
"""
|
||||
Called when a presentation is added to the SlideController.
|
||||
Opens the PowerPoint file using the process created earlier
|
||||
|
||||
``presentation``
|
||||
The file name of the presentations to run.
|
||||
Opens the PowerPoint file using the process created earlier.
|
||||
"""
|
||||
log.debug(u'load_presentation')
|
||||
if not self.controller.process or not self.controller.process.Visible:
|
||||
|
@ -118,9 +118,6 @@ class PptviewDocument(PresentationDocument):
|
||||
Called when a presentation is added to the SlideController.
|
||||
It builds the environment, starts communcations with the background
|
||||
PptView task started earlier.
|
||||
|
||||
``presentation``
|
||||
The file name of the presentations to run.
|
||||
"""
|
||||
log.debug(u'LoadPresentation')
|
||||
renderer = self.controller.plugin.renderer
|
||||
|
@ -47,7 +47,7 @@ class PresentationDocument(object):
|
||||
|
||||
**Hook Functions**
|
||||
|
||||
``load_presentation(presentation)``
|
||||
``load_presentation()``
|
||||
Load a presentation file
|
||||
|
||||
``close_presentation()``
|
||||
@ -104,11 +104,8 @@ class PresentationDocument(object):
|
||||
|
||||
def load_presentation(self):
|
||||
"""
|
||||
Called when a presentation is added to the SlideController.
|
||||
Loads the presentation and starts it
|
||||
|
||||
``presentation``
|
||||
The file name of the presentations to the run.
|
||||
Called when a presentation is added to the SlideController. Loads the
|
||||
presentation and starts it.
|
||||
|
||||
Returns False if the file could not be opened
|
||||
"""
|
||||
|
@ -61,14 +61,14 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
||||
def onFirstNameEditTextEdited(self, display_name):
|
||||
if not self._autoDisplayName:
|
||||
return
|
||||
if not self.lastNameEdit.text():
|
||||
if self.lastNameEdit.text():
|
||||
display_name = display_name + u' ' + self.lastNameEdit.text()
|
||||
self.displayEdit.setText(display_name)
|
||||
|
||||
def onLastNameEditTextEdited(self, display_name):
|
||||
if not self._autoDisplayName:
|
||||
return
|
||||
if not self.firstNameEdit.text():
|
||||
if self.firstNameEdit.text():
|
||||
display_name = self.firstNameEdit.text() + u' ' + display_name
|
||||
self.displayEdit.setText(display_name)
|
||||
|
||||
|
@ -34,7 +34,7 @@ import shutil
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, \
|
||||
create_separated_list
|
||||
create_separated_list, check_directory_exists
|
||||
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \
|
||||
critical_error_message_box, find_and_set_in_combo_box
|
||||
from openlp.core.utils import AppLocation
|
||||
@ -880,8 +880,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
save_path = os.path.join(
|
||||
AppLocation.get_section_data_path(self.mediaitem.plugin.name),
|
||||
'audio', str(self.song.id))
|
||||
if not os.path.exists(save_path):
|
||||
os.makedirs(save_path)
|
||||
check_directory_exists(save_path)
|
||||
self.song.media_files = []
|
||||
files = []
|
||||
for row in xrange(self.audioListWidget.count()):
|
||||
|
@ -541,12 +541,13 @@ class SongImportSourcePage(QtGui.QWizardPage):
|
||||
if wizard.formatWidgets[format][u'fileListWidget'].count() > 0:
|
||||
return True
|
||||
else:
|
||||
filepath = wizard.formatWidgets[format][u'filepathEdit'].text()
|
||||
if not filepath.isEmpty():
|
||||
if select_mode == SongFormatSelect.SingleFile \
|
||||
and os.path.isfile(filepath):
|
||||
filepath = unicode(
|
||||
wizard.formatWidgets[format][u'filepathEdit'].text())
|
||||
if filepath:
|
||||
if select_mode == SongFormatSelect.SingleFile and \
|
||||
os.path.isfile(filepath):
|
||||
return True
|
||||
elif select_mode == SongFormatSelect.SingleFolder \
|
||||
and os.path.isdir(filepath):
|
||||
elif select_mode == SongFormatSelect.SingleFolder and \
|
||||
os.path.isdir(filepath):
|
||||
return True
|
||||
return False
|
||||
|
@ -476,7 +476,7 @@ def get_encoding(font, font_table, default_encoding, failed=False):
|
||||
Dictionary of fonts and respective encodings.
|
||||
|
||||
``default_encoding``
|
||||
The defaul encoding to use when font_table is empty or no font is used.
|
||||
The default encoding to use when font_table is empty or no font is used.
|
||||
|
||||
``failed``
|
||||
A boolean indicating whether the previous encoding didn't work.
|
||||
|
@ -48,15 +48,8 @@ class EasySlidesImport(SongImport):
|
||||
Initialise the class.
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
self.commit = True
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Import either each of the files in self.importSources - each element of
|
||||
which can be either a single opensong file, or a zipfile containing
|
||||
multiple opensong files. If `self.commit` is set False, the
|
||||
import will not be committed to the database (useful for test scripts).
|
||||
"""
|
||||
log.info(u'Importing EasySlides XML file %s', self.importSource)
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
parsed_file = etree.parse(self.importSource, parser)
|
||||
|
@ -28,6 +28,7 @@
|
||||
"""
|
||||
The :mod:`importer` modules provides the general song import functionality.
|
||||
"""
|
||||
import os
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import translate
|
||||
@ -44,6 +45,7 @@ from powersongimport import PowerSongImport
|
||||
from ewimport import EasyWorshipSongImport
|
||||
from songbeamerimport import SongBeamerImport
|
||||
from songshowplusimport import SongShowPlusImport
|
||||
from songproimport import SongProImport
|
||||
from sundayplusimport import SundayPlusImport
|
||||
from foilpresenterimport import FoilPresenterImport
|
||||
from zionworximport import ZionWorxImport
|
||||
@ -67,6 +69,13 @@ try:
|
||||
except ImportError:
|
||||
log.exception('Error importing %s', 'OooImport')
|
||||
HAS_OOO = False
|
||||
HAS_MEDIASHOUT = False
|
||||
if os.name == u'nt':
|
||||
try:
|
||||
from mediashoutimport import MediaShoutImport
|
||||
HAS_MEDIASHOUT = True
|
||||
except ImportError:
|
||||
log.exception('Error importing %s', 'MediaShoutImport')
|
||||
|
||||
|
||||
class SongFormatSelect(object):
|
||||
@ -100,6 +109,7 @@ class SongFormat(object):
|
||||
|
||||
``u'canDisable'``
|
||||
Whether song format importer is disablable.
|
||||
If ``True``, then ``u'disabledLabelText'`` must also be defined.
|
||||
|
||||
``u'availability'``
|
||||
Whether song format importer is available.
|
||||
@ -141,15 +151,16 @@ class SongFormat(object):
|
||||
EasySlides = 6
|
||||
EasyWorship = 7
|
||||
FoilPresenter = 8
|
||||
OpenSong = 9
|
||||
PowerSong = 10
|
||||
SongBeamer = 11
|
||||
SongShowPlus = 12
|
||||
SongsOfFellowship = 13
|
||||
SundayPlus = 14
|
||||
WordsOfWorship = 15
|
||||
ZionWorx = 16
|
||||
#CSV = 17
|
||||
MediaShout = 9
|
||||
OpenSong = 10
|
||||
PowerSong = 11
|
||||
SongBeamer = 12
|
||||
SongPro = 13
|
||||
SongShowPlus = 14
|
||||
SongsOfFellowship = 15
|
||||
SundayPlus = 16
|
||||
WordsOfWorship = 17
|
||||
ZionWorx = 18
|
||||
|
||||
# Set optional attribute defaults
|
||||
__defaults__ = {
|
||||
@ -240,6 +251,14 @@ class SongFormat(object):
|
||||
u'filter': u'%s (*.foil)' % translate(
|
||||
'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
|
||||
},
|
||||
MediaShout: {
|
||||
u'name': u'MediaShout',
|
||||
u'prefix': u'mediaShout',
|
||||
u'canDisable': True,
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.mdb)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'MediaShout Database')
|
||||
},
|
||||
OpenSong: {
|
||||
u'class': OpenSongImport,
|
||||
u'name': WizardStrings.OS,
|
||||
@ -260,6 +279,18 @@ class SongFormat(object):
|
||||
u'filter': u'%s (*.sng)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'SongBeamer Files')
|
||||
},
|
||||
SongPro: {
|
||||
u'class': SongProImport,
|
||||
u'name': u'SongPro',
|
||||
u'prefix': u'songPro',
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.txt)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'SongPro Text Files'),
|
||||
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
|
||||
'SongPro (Export File)'),
|
||||
u'descriptionText': translate('SongsPlugin.ImportWizardForm',
|
||||
'In SongPro, export your songs using the File -> Export menu')
|
||||
},
|
||||
SongShowPlus: {
|
||||
u'class': SongShowPlusImport,
|
||||
u'name': u'SongShow Plus',
|
||||
@ -302,12 +333,6 @@ class SongFormat(object):
|
||||
'First convert your ZionWorx database to a CSV text file, as '
|
||||
'explained in the <a href="http://manual.openlp.org/songs.html'
|
||||
'#importing-from-zionworx">User Manual</a>.')
|
||||
# },
|
||||
# CSV: {
|
||||
# u'class': CSVImport,
|
||||
# u'name': WizardStrings.CSV,
|
||||
# u'prefix': u'csv',
|
||||
# u'selectMode': SongFormatSelect.SingleFile
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,9 +351,11 @@ class SongFormat(object):
|
||||
SongFormat.EasySlides,
|
||||
SongFormat.EasyWorship,
|
||||
SongFormat.FoilPresenter,
|
||||
SongFormat.MediaShout,
|
||||
SongFormat.OpenSong,
|
||||
SongFormat.PowerSong,
|
||||
SongFormat.SongBeamer,
|
||||
SongFormat.SongPro,
|
||||
SongFormat.SongShowPlus,
|
||||
SongFormat.SongsOfFellowship,
|
||||
SongFormat.SundayPlus,
|
||||
@ -383,5 +410,8 @@ if HAS_SOF:
|
||||
SongFormat.set(SongFormat.Generic, u'availability', HAS_OOO)
|
||||
if HAS_OOO:
|
||||
SongFormat.set(SongFormat.Generic, u'class', OooImport)
|
||||
SongFormat.set(SongFormat.MediaShout, u'availability', HAS_MEDIASHOUT)
|
||||
if HAS_MEDIASHOUT:
|
||||
SongFormat.set(SongFormat.MediaShout, u'class', MediaShoutImport)
|
||||
|
||||
__all__ = [u'SongFormat', u'SongFormatSelect']
|
||||
|
@ -36,7 +36,8 @@ from PyQt4 import QtCore, QtGui
|
||||
from sqlalchemy.sql import or_
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
|
||||
translate, check_item_selected, PluginStatus, create_separated_list
|
||||
translate, check_item_selected, PluginStatus, create_separated_list, \
|
||||
check_directory_exists
|
||||
from openlp.core.lib.ui import UiStrings, create_widget_action
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.utils import AppLocation
|
||||
@ -89,8 +90,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
dest_file = os.path.join(
|
||||
AppLocation.get_section_data_path(self.plugin.name),
|
||||
u'audio', str(song.id), os.path.split(bga)[1])
|
||||
if not os.path.exists(os.path.split(dest_file)[0]):
|
||||
os.makedirs(os.path.split(dest_file)[0])
|
||||
check_directory_exists(os.path.split(dest_file)[0])
|
||||
shutil.copyfile(os.path.join(
|
||||
AppLocation.get_section_data_path(
|
||||
u'servicemanager'), bga),
|
||||
|
112
openlp/plugins/songs/lib/mediashoutimport.py
Normal file
112
openlp/plugins/songs/lib/mediashoutimport.py
Normal file
@ -0,0 +1,112 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Edwin Lunando, Joshua Miller, Stevan Pettit, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Dave Warnock, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`mediashoutimport` module provides the functionality for importing
|
||||
a MediaShout database into the OpenLP database.
|
||||
"""
|
||||
import re
|
||||
import os
|
||||
import pyodbc
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
VERSE_TAGS = [u'V', u'C', u'B', u'O', u'P', u'I', u'E']
|
||||
|
||||
class MediaShoutImport(SongImport):
|
||||
"""
|
||||
The :class:`MediaShoutImport` class provides the ability to import the
|
||||
MediaShout Access Database
|
||||
"""
|
||||
def __init__(self, manager, **kwargs):
|
||||
"""
|
||||
Initialise the MediaShout importer.
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Receive a single file to import.
|
||||
"""
|
||||
try:
|
||||
conn = pyodbc.connect(u'DRIVER={Microsoft Access Driver (*.mdb)};'
|
||||
u'DBQ=%s;PWD=6NOZ4eHK7k' % self.importSource)
|
||||
except:
|
||||
# Unfortunately no specific exception type
|
||||
self.logError(self.importSource,
|
||||
translate('SongsPlugin.MediaShoutImport',
|
||||
'Unable to open the MediaShout database.'))
|
||||
return
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(u'SELECT Record, Title, Author, Copyright, '
|
||||
u'SongID, CCLI, Notes FROM Songs ORDER BY Title')
|
||||
songs = cursor.fetchall()
|
||||
self.importWizard.progressBar.setMaximum(len(songs))
|
||||
for song in songs:
|
||||
if self.stopImportFlag:
|
||||
break
|
||||
cursor.execute(u'SELECT Type, Number, Text FROM Verses '
|
||||
u'WHERE Record = %s ORDER BY Type, Number' % song.Record)
|
||||
verses = cursor.fetchall()
|
||||
cursor.execute(u'SELECT Type, Number, POrder FROM PlayOrder '
|
||||
u'WHERE Record = %s ORDER BY POrder' % song.Record)
|
||||
verse_order = cursor.fetchall()
|
||||
cursor.execute(u'SELECT Name FROM Themes INNER JOIN SongThemes '
|
||||
u'ON SongThemes.ThemeId = Themes.ThemeId '
|
||||
u'WHERE SongThemes.Record = %s' % song.Record)
|
||||
topics = cursor.fetchall()
|
||||
cursor.execute(u'SELECT Name FROM Groups INNER JOIN SongGroups '
|
||||
u'ON SongGroups.GroupId = Groups.GroupId '
|
||||
u'WHERE SongGroups.Record = %s' % song.Record)
|
||||
topics += cursor.fetchall()
|
||||
self.processSong(song, verses, verse_order, topics)
|
||||
|
||||
def processSong(self, song, verses, verse_order, topics):
|
||||
"""
|
||||
Create the song, i.e. title, verse etc.
|
||||
"""
|
||||
self.setDefaults()
|
||||
self.title = song.Title
|
||||
self.parseAuthor(song.Author)
|
||||
self.addCopyright(song.Copyright)
|
||||
self.comments = song.Notes
|
||||
for topic in topics:
|
||||
self.topics.append(topic.Name)
|
||||
if u'-' in song.SongID:
|
||||
self.songBookName, self.songNumber = song.SongID.split(u'-', 1)
|
||||
else:
|
||||
self.songBookName = song.SongID
|
||||
for verse in verses:
|
||||
tag = VERSE_TAGS[verse.Type] + unicode(verse.Number) \
|
||||
if verse.Type < len(VERSE_TAGS) else u'O'
|
||||
self.addVerse(verse.Text, tag)
|
||||
for order in verse_order:
|
||||
if order.Type < len(VERSE_TAGS):
|
||||
self.verseOrderList.append(VERSE_TAGS[order.Type]
|
||||
+ unicode(order.Number))
|
||||
self.finish()
|
@ -33,7 +33,7 @@ import os
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import Receiver, translate, check_directory_exists
|
||||
from openlp.core.ui.wizard import WizardStrings
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||
@ -388,8 +388,7 @@ class SongImport(QtCore.QObject):
|
||||
AppLocation.get_section_data_path(
|
||||
self.importWizard.plugin.name),
|
||||
'audio', str(song_id))
|
||||
if not os.path.exists(self.save_path):
|
||||
os.makedirs(self.save_path)
|
||||
check_directory_exists(self.save_path)
|
||||
if not filename.startswith(self.save_path):
|
||||
oldfile, filename = filename, os.path.join(self.save_path,
|
||||
os.path.split(filename)[1])
|
||||
|
143
openlp/plugins/songs/lib/songproimport.py
Normal file
143
openlp/plugins/songs/lib/songproimport.py
Normal file
@ -0,0 +1,143 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Edwin Lunando, Joshua Miller, Stevan Pettit, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Dave Warnock, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`songproimport` module provides the functionality for importing SongPro
|
||||
songs into the OpenLP database.
|
||||
"""
|
||||
import re
|
||||
import os
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.songs.lib import strip_rtf
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
class SongProImport(SongImport):
|
||||
"""
|
||||
The :class:`SongProImport` class provides the ability to import song files
|
||||
from SongPro export files.
|
||||
|
||||
**SongPro Song File Format:**
|
||||
|
||||
SongPro has the option to export under its File menu
|
||||
This produces files containing single or multiple songs
|
||||
The file is text with lines tagged with # followed by an identifier.
|
||||
This is documented here: http://creationsoftware.com/ImportIdentifiers.php
|
||||
An example here: http://creationsoftware.com/ExampleImportingManySongs.txt
|
||||
|
||||
#A - next line is the Song Author
|
||||
#B - the lines following until next tagged line are the "Bridge" words
|
||||
(can be in rtf or plain text) which we map as B1
|
||||
#C - the lines following until next tagged line are the chorus words
|
||||
(can be in rtf or plain text)
|
||||
which we map as C1
|
||||
#D - the lines following until next tagged line are the "Ending" words
|
||||
(can be in rtf or plain text) which we map as E1
|
||||
#E - this song ends here, so we process the song -
|
||||
and start again at the next line
|
||||
#G - next line is the Group
|
||||
#M - next line is the Song Number
|
||||
#N - next line are Notes
|
||||
#R - next line is the SongCopyright
|
||||
#O - next line is the Verse Sequence
|
||||
#T - next line is the Song Title
|
||||
#1 - #7 the lines following until next tagged line are the verse x words
|
||||
(can be in rtf or plain text)
|
||||
"""
|
||||
def __init__(self, manager, **kwargs):
|
||||
"""
|
||||
Initialise the SongPro importer.
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Receive a single file or a list of files to import.
|
||||
"""
|
||||
self.encoding = None
|
||||
with open(self.importSource, 'r') as songs_file:
|
||||
self.importWizard.progressBar.setMaximum(0)
|
||||
tag = u''
|
||||
text = u''
|
||||
for file_line in songs_file:
|
||||
if self.stopImportFlag:
|
||||
break
|
||||
file_line = unicode(file_line, u'cp1252')
|
||||
file_text = file_line.rstrip()
|
||||
if file_text and file_text[0] == u'#':
|
||||
self.processSection(tag, text.rstrip())
|
||||
tag = file_text[1:]
|
||||
text = u''
|
||||
else:
|
||||
text += file_line
|
||||
|
||||
def processSection(self, tag, text):
|
||||
"""
|
||||
Process a section of the song, i.e. title, verse etc.
|
||||
"""
|
||||
if tag == u'T':
|
||||
self.setDefaults()
|
||||
if text:
|
||||
self.title = text
|
||||
return
|
||||
elif tag == u'E':
|
||||
self.finish()
|
||||
return
|
||||
if u'rtf1' in text:
|
||||
text, self.encoding = strip_rtf(text, self.encoding)
|
||||
text = text.rstrip()
|
||||
if not text:
|
||||
return
|
||||
if tag == u'A':
|
||||
self.parseAuthor(text)
|
||||
elif tag in [u'B', u'C']:
|
||||
self.addVerse(text, tag)
|
||||
elif tag == u'D':
|
||||
self.addVerse(text, u'E')
|
||||
elif tag == u'G':
|
||||
self.topics.append(text)
|
||||
elif tag == u'M':
|
||||
matches = re.findall(r'\d+', text)
|
||||
if matches:
|
||||
self.songNumber = matches[-1]
|
||||
self.songBookName = text[:text.rfind(self.songNumber)]
|
||||
elif tag == u'N':
|
||||
self.comments = text
|
||||
elif tag == u'O':
|
||||
for char in text:
|
||||
if char == u'C':
|
||||
self.verseOrderList.append(u'C1')
|
||||
elif char == u'B':
|
||||
self.verseOrderList.append(u'B1')
|
||||
elif char == u'D':
|
||||
self.verseOrderList.append(u'E1')
|
||||
elif u'1' <= char <= u'7':
|
||||
self.verseOrderList.append(u'V' + char)
|
||||
elif tag == u'R':
|
||||
self.addCopyright(text)
|
||||
elif u'1' <= tag <= u'7':
|
||||
self.addVerse(text, u'V' + tag[1:])
|
@ -37,6 +37,9 @@ from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Used to strip control chars (except 10=LF, 13=CR)
|
||||
CONTROL_CHARS_MAP = dict.fromkeys(range(10) + [11, 12] + range(14,32) + [127])
|
||||
|
||||
class ZionWorxImport(SongImport):
|
||||
"""
|
||||
The :class:`ZionWorxImport` class provides the ability to import songs
|
||||
@ -78,13 +81,10 @@ class ZionWorxImport(SongImport):
|
||||
"""
|
||||
Receive a CSV file (from a ZionWorx database dump) to import.
|
||||
"""
|
||||
# Used to strip control chars (10=LF, 13=CR, 127=DEL)
|
||||
self.control_chars_map = dict.fromkeys(
|
||||
range(10) + [11, 12] + range(14,32) + [127])
|
||||
with open(self.importSource, 'rb') as songs_file:
|
||||
fieldnames = [u'SongNum', u'Title1', u'Title2', u'Lyrics',
|
||||
field_names = [u'SongNum', u'Title1', u'Title2', u'Lyrics',
|
||||
u'Writer', u'Copyright', u'Keywords', u'DefaultStyle']
|
||||
songs_reader = csv.DictReader(songs_file, fieldnames)
|
||||
songs_reader = csv.DictReader(songs_file, field_names)
|
||||
try:
|
||||
records = list(songs_reader)
|
||||
except csv.Error, e:
|
||||
@ -140,4 +140,4 @@ class ZionWorxImport(SongImport):
|
||||
"""
|
||||
# This encoding choice seems OK. ZionWorx has no option for setting the
|
||||
# encoding for its songs, so we assume encoding is always the same.
|
||||
return unicode(str, u'cp1252').translate(self.control_chars_map)
|
||||
return unicode(str, u'cp1252').translate(CONTROL_CHARS_MAP)
|
||||
|
34
resources/__init__.py
Normal file
34
resources/__init__.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Edwin Lunando, Joshua Miller, Stevan Pettit, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Dave Warnock, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`resources` module contains a bunch of resources for OpenLP.
|
||||
|
||||
DO NOT REMOVE THIS FILE, IT IS REQUIRED FOR INCLUDING THE RESOURCES ON SOME
|
||||
PLATFORMS!
|
||||
"""
|
||||
|
2645
resources/i18n/af.ts
2645
resources/i18n/af.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/cs.ts
2645
resources/i18n/cs.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/da.ts
2645
resources/i18n/da.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/de.ts
2645
resources/i18n/de.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/el.ts
2645
resources/i18n/el.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/en.ts
2645
resources/i18n/en.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2706
resources/i18n/es.ts
2706
resources/i18n/es.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/et.ts
2645
resources/i18n/et.ts
File diff suppressed because it is too large
Load Diff
2653
resources/i18n/fi.ts
2653
resources/i18n/fi.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/fr.ts
2645
resources/i18n/fr.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/hu.ts
2645
resources/i18n/hu.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/id.ts
2645
resources/i18n/id.ts
File diff suppressed because it is too large
Load Diff
2653
resources/i18n/it.ts
2653
resources/i18n/it.ts
File diff suppressed because it is too large
Load Diff
2756
resources/i18n/ja.ts
2756
resources/i18n/ja.ts
File diff suppressed because it is too large
Load Diff
2689
resources/i18n/ko.ts
2689
resources/i18n/ko.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/nb.ts
2645
resources/i18n/nb.ts
File diff suppressed because it is too large
Load Diff
2831
resources/i18n/nl.ts
2831
resources/i18n/nl.ts
File diff suppressed because it is too large
Load Diff
2653
resources/i18n/pl.ts
2653
resources/i18n/pl.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/ru.ts
2645
resources/i18n/ru.ts
File diff suppressed because it is too large
Load Diff
2653
resources/i18n/sq.ts
2653
resources/i18n/sq.ts
File diff suppressed because it is too large
Load Diff
2645
resources/i18n/sv.ts
2645
resources/i18n/sv.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -199,7 +199,11 @@ def download_translations():
|
||||
request = urllib2.Request(url + '?details')
|
||||
request.add_header('Authorization', auth_header)
|
||||
print_verbose(u'Downloading list of languages from: %s' % url)
|
||||
json_response = urllib2.urlopen(request)
|
||||
try:
|
||||
json_response = urllib2.urlopen(request)
|
||||
except urllib2.HTTPError:
|
||||
print_quiet(u'Username or password incorrect.')
|
||||
return False
|
||||
json_dict = json.loads(json_response.read())
|
||||
languages = [lang[u'code'] for lang in json_dict[u'available_languages']]
|
||||
for language in languages:
|
||||
@ -214,6 +218,7 @@ def download_translations():
|
||||
fd.write(response.read())
|
||||
fd.close()
|
||||
print_quiet(u' Done.')
|
||||
return True
|
||||
|
||||
def prepare_project():
|
||||
"""
|
||||
@ -310,7 +315,8 @@ def process_stack(command_stack):
|
||||
for command in command_stack:
|
||||
print_quiet(u'%d.' % (command_stack.current_index), False)
|
||||
if command == Command.Download:
|
||||
download_translations()
|
||||
if not download_translations():
|
||||
return
|
||||
elif command == Command.Prepare:
|
||||
prepare_project()
|
||||
elif command == Command.Update:
|
||||
|
Loading…
Reference in New Issue
Block a user