forked from openlp/openlp
openlyrics fixes, add meta data to songs, opensong import fix, signals for openlyrics export
This commit is contained in:
commit
e7b1f88e53
@ -27,11 +27,10 @@
|
||||
The song export function for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.ui.wizard import OpenLPWizard
|
||||
from openlp.plugins.songs.lib.db import Song
|
||||
@ -59,6 +58,16 @@ class SongExportForm(OpenLPWizard):
|
||||
self.plugin = plugin
|
||||
OpenLPWizard.__init__(self, parent, plugin, u'songExportWizard',
|
||||
u':/wizards/wizard_importsong.bmp')
|
||||
self.stop_export_flag = False
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_export)
|
||||
|
||||
def stop_export(self):
|
||||
"""
|
||||
Sets the flag for exporters to stop their export
|
||||
"""
|
||||
log.debug(u'Stopping songs export')
|
||||
self.stop_export_flag = True
|
||||
|
||||
def setupUi(self, image):
|
||||
"""
|
||||
@ -70,25 +79,22 @@ class SongExportForm(OpenLPWizard):
|
||||
"""
|
||||
Song wizard specific initialisation.
|
||||
"""
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
for song in songs:
|
||||
author_list = u''
|
||||
for author in song.authors:
|
||||
if author_list != u'':
|
||||
author_list = author_list + u', '
|
||||
author_list = author_list + author.display_name
|
||||
song_title = unicode(song.title)
|
||||
song_detail = u'%s (%s)' % (song_title, author_list)
|
||||
song_name = QtGui.QListWidgetItem(song_detail)
|
||||
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song))
|
||||
self.availableListWidget.addItem(song_name)
|
||||
self.availableListWidget.selectAll()
|
||||
pass
|
||||
|
||||
def customSignals(self):
|
||||
"""
|
||||
Song wizard specific signals.
|
||||
"""
|
||||
pass
|
||||
QtCore.QObject.connect(self.addSelected,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onAddSelectedClicked)
|
||||
QtCore.QObject.connect(self.removeSelected,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onRemoveSelectedClicked)
|
||||
QtCore.QObject.connect(self.availableListWidget,
|
||||
QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem *)'),
|
||||
self.onAvailableListItemDoubleClicked)
|
||||
QtCore.QObject.connect(self.selectedListWidget,
|
||||
QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem *)'),
|
||||
self.onSelectedListItemDoubleClicked)
|
||||
|
||||
def addCustomPages(self):
|
||||
"""
|
||||
@ -105,6 +111,11 @@ class SongExportForm(OpenLPWizard):
|
||||
self.verticalLayout.setObjectName(u'verticalLayout')
|
||||
self.availableListWidget = QtGui.QListWidget(self.availableGroupBox)
|
||||
self.availableListWidget.setObjectName(u'availableListWidget')
|
||||
self.availableListWidget.setSelectionMode(
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.availableListWidget.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
self.availableListWidget.setSortingEnabled(True)
|
||||
self.verticalLayout.addWidget(self.availableListWidget)
|
||||
self.sourceLayout.addWidget(self.availableGroupBox)
|
||||
self.selectionWidget = QtGui.QWidget(self.sourcePage)
|
||||
@ -138,9 +149,15 @@ class SongExportForm(OpenLPWizard):
|
||||
self.verticalLayout.setObjectName(u'verticalLayout')
|
||||
self.selectedListWidget = QtGui.QListWidget(self.selectedGroupBox)
|
||||
self.selectedListWidget.setObjectName(u'selectedListWidget')
|
||||
self.selectedListWidget.setSelectionMode(
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.selectedListWidget.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
self.selectedListWidget.setSortingEnabled(True)
|
||||
self.verticalLayout.addWidget(self.selectedListWidget)
|
||||
self.sourceLayout.addWidget(self.selectedGroupBox)
|
||||
self.addPage(self.sourcePage)
|
||||
#TODO: Add save dialog
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
@ -151,28 +168,28 @@ class SongExportForm(OpenLPWizard):
|
||||
self.titleLabel.setText(
|
||||
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
|
||||
translate('SongsPlugin.ExportWizardForm',
|
||||
'Welcome to the Song Export Wizard'))
|
||||
'Welcome to the Song Export Wizard'))
|
||||
self.informationLabel.setText(
|
||||
translate('SongsPlugin.ExportWizardForm', 'This wizard will help to '
|
||||
'export your songs to the free and open OpenLyrics worship song '
|
||||
'format. You can import these songs in all lyrics projection '
|
||||
'software, which supports OpenLyrics.'))
|
||||
self.sourcePage.setTitle(
|
||||
translate('SongsPlugin.ExportWizardForm', 'Select Emport Source'))
|
||||
translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
||||
self.sourcePage.setSubTitle(
|
||||
translate('SongsPlugin.ExportWizardForm',
|
||||
'Select the export format, and where to export from.'))
|
||||
'Select the songs, you want to export.'))
|
||||
|
||||
self.progressPage.setTitle(
|
||||
translate('SongsPlugin.ExportWizardForm', 'Exporting'))
|
||||
self.progressPage.setSubTitle(
|
||||
translate('SongsPlugin.ExportWizardForm',
|
||||
'Please wait while your songs are exported.'))
|
||||
'Please wait while your songs are exported.'))
|
||||
self.progressLabel.setText(
|
||||
translate('SongsPlugin.ExportWizardForm', 'Ready.'))
|
||||
self.progressBar.setFormat(
|
||||
translate('SongsPlugin.ExportWizardForm', '%p%'))
|
||||
|
||||
|
||||
self.availableGroupBox.setTitle(
|
||||
translate('SongsPlugin.ExportWizardForm', 'Available Songs'))
|
||||
self.addSelected.setText(
|
||||
@ -187,10 +204,35 @@ class SongExportForm(OpenLPWizard):
|
||||
Validate the current page before moving on to the next page.
|
||||
"""
|
||||
if self.currentPage() == self.welcomePage:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
for song in songs:
|
||||
author_list = u''
|
||||
for author in song.authors:
|
||||
if author_list != u'':
|
||||
author_list = author_list + u', '
|
||||
author_list = author_list + author.display_name
|
||||
song_title = unicode(song.title)
|
||||
song_detail = u'%s (%s)' % (song_title, author_list)
|
||||
song_name = QtGui.QListWidgetItem(song_detail)
|
||||
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song))
|
||||
self.availableListWidget.addItem(song_name)
|
||||
self.availableListWidget.selectAll()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
return True
|
||||
elif self.currentPage() == self.sourcePage:
|
||||
self.selectedListWidget.selectAll()
|
||||
if not self.selectedListWidget.selectedItems():
|
||||
criticalErrorMessageBox(
|
||||
translate('SongsPlugin.ExportWizardForm',
|
||||
'No Song Selected'),
|
||||
translate('SongsPlugin.ImportWizardForm',
|
||||
'You need to add at least one Song to export.'))
|
||||
return False
|
||||
return True
|
||||
elif self.currentPage() == self.progressPage:
|
||||
self.availableListWidget.clear()
|
||||
self.selectedListWidget.clear()
|
||||
return True
|
||||
|
||||
def registerFields(self):
|
||||
@ -222,8 +264,9 @@ class SongExportForm(OpenLPWizard):
|
||||
class, and then runs the ``do_export`` method of the exporter to do
|
||||
the actual exporting.
|
||||
"""
|
||||
exporter = OpenLyricsExport(self.plugin.manager,
|
||||
self.plugin.manager.get_all_objects(Song), u'/tmp/')
|
||||
songs = [item.data(QtCore.Qt.UserRole).toPyObject()
|
||||
for item in self.selectedListWidget.selectedItems()]
|
||||
exporter = OpenLyricsExport(self, songs, u'/tmp/')
|
||||
if exporter.do_export():
|
||||
self.progressLabel.setText(
|
||||
translate('SongsPlugin.SongExportForm', 'Finished export.'))
|
||||
@ -231,3 +274,47 @@ class SongExportForm(OpenLPWizard):
|
||||
self.progressLabel.setText(
|
||||
translate('SongsPlugin.SongExportForm',
|
||||
'Your song export failed.'))
|
||||
|
||||
def onAddSelectedClicked(self):
|
||||
"""
|
||||
Removes the selected items from the list of available songs and add them
|
||||
to the list of selected songs.
|
||||
"""
|
||||
items = self.availableListWidget.selectedItems()
|
||||
# Save a list with tuples which consist of the item row, and the item.
|
||||
items = [(self.availableListWidget.row(item), item) for item in items]
|
||||
items.sort(reverse=True)
|
||||
for item in items:
|
||||
self.availableListWidget.takeItem(item[0])
|
||||
self.selectedListWidget.addItem(item[1])
|
||||
|
||||
def onRemoveSelectedClicked(self):
|
||||
"""
|
||||
Removes the selected items from the list of selected songs and add them
|
||||
back to the list of available songs.
|
||||
"""
|
||||
items = self.selectedListWidget.selectedItems()
|
||||
# Save a list with tuples which consist of the item row, and the item.
|
||||
items = [(self.selectedListWidget.row(item), item) for item in items]
|
||||
items.sort(reverse=True)
|
||||
for item in items:
|
||||
self.selectedListWidget.takeItem(item[0])
|
||||
self.availableListWidget.addItem(item[1])
|
||||
|
||||
def onAvailableListItemDoubleClicked(self, item):
|
||||
"""
|
||||
Adds the double clicked item to the list of selected songs and removes
|
||||
it from the list of availables songs.
|
||||
"""
|
||||
row = self.availableListWidget.row(item)
|
||||
self.availableListWidget.takeItem(row)
|
||||
self.selectedListWidget.addItem(item)
|
||||
|
||||
def onSelectedListItemDoubleClicked(self, item):
|
||||
"""
|
||||
Adds the double clicked item back to the list of available songs and
|
||||
removes it from the list of selected songs.
|
||||
"""
|
||||
row = self.selectedListWidget.row(item)
|
||||
self.selectedListWidget.takeItem(row)
|
||||
self.availableListWidget.addItem(item)
|
||||
|
@ -27,13 +27,12 @@
|
||||
The :mod:`openlyricsexport` module provides the functionality for exporting
|
||||
songs from the database.
|
||||
"""
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
|
||||
from lxml import etree, objectify
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.plugins.songs.lib import OpenLyrics
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -42,42 +41,34 @@ class OpenLyricsExport(object):
|
||||
"""
|
||||
This provides the Openlyrics export.
|
||||
"""
|
||||
def __init__(self, master_manager, song_ids, save_path):
|
||||
def __init__(self, parent, songs, save_path):
|
||||
"""
|
||||
Initialise the export.
|
||||
"""
|
||||
log.debug(u'initialise OpenLyricsExport')
|
||||
self.master_manager = master_manager
|
||||
self.songs = song_ids
|
||||
self.parent = parent
|
||||
self.manager = parent.plugin.manager
|
||||
self.songs = songs
|
||||
self.save_path = save_path
|
||||
|
||||
def do_export(self):
|
||||
"""
|
||||
Export the songs.
|
||||
"""
|
||||
openLyrics = OpenLyrics(self.master_manager)
|
||||
# self.export_wizard.exportProgressBar.setMaximum(len(songs))
|
||||
openLyrics = OpenLyrics(self.manager)
|
||||
self.parent.progressBar.setMaximum(len(self.songs))
|
||||
for song in self.songs:
|
||||
# if self.stop_export_flag:
|
||||
# return False
|
||||
# self.export_wizard.incrementProgressBar(unicode(translate(
|
||||
# 'SongsPlugin.OpenLyricsExport', 'Exporting %s...')) %
|
||||
# song.title)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
if self.parent.stop_export_flag:
|
||||
return False
|
||||
self.parent.incrementProgressBar(unicode(translate(
|
||||
'SongsPlugin.OpenLyricsExport', 'Exporting %s...')) %
|
||||
song.title)
|
||||
# Check if path exists. If not, create the directories!
|
||||
# What do we do with songs with the same title? I do not want to
|
||||
# overwrite them!
|
||||
path = os.path.join(self.save_path, song.title + u'.xml')
|
||||
# Convert the song object to an unicode string.
|
||||
xml = openLyrics.song_to_xml(song)
|
||||
song_xml = objectify.fromstring(xml)
|
||||
# Append the necessary meta data to the song.
|
||||
# (Maybe move this to the xml module?
|
||||
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
|
||||
song_xml.set(u'createdIn', u'OpenLP 1.9.4') # Use variable
|
||||
song_xml.set(u'modifiedIn', u'OpenLP 1.9.4') # Use variable
|
||||
song_xml.set(u'modifiedDate',
|
||||
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
|
||||
xml = etree.tostring(song_xml)
|
||||
tree = etree.ElementTree(etree.fromstring(xml))
|
||||
tree.write(path, encoding=u'utf-8', xml_declaration=True,
|
||||
pretty_print=True)
|
||||
|
@ -39,6 +39,7 @@ log = logging.getLogger(__name__)
|
||||
class OpenSongImportError(Exception):
|
||||
pass
|
||||
|
||||
#TODO: Use lxml for parsing and make sure we use methods of "SongImport" .
|
||||
class OpenSongImport(SongImport):
|
||||
"""
|
||||
Import songs exported from OpenSong
|
||||
@ -149,7 +150,7 @@ class OpenSongImport(SongImport):
|
||||
log.info(u'Zip importing %s', parts[-1])
|
||||
self.import_wizard.incrementProgressBar(
|
||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||
'Importing %s...')) % parts[-1])
|
||||
'Importing %s...')) % parts[-1])
|
||||
songfile = z.open(song)
|
||||
self.do_import_file(songfile)
|
||||
if self.commit:
|
||||
@ -279,7 +280,7 @@ class OpenSongImport(SongImport):
|
||||
for num in versenums:
|
||||
versetag = u'%s%s' % (our_verse_type, num)
|
||||
lines = u'\n'.join(verses[versetype][num])
|
||||
self.verses.append([versetag, lines])
|
||||
self.add_verse(lines, versetag)
|
||||
# Keep track of what we have for error checking later
|
||||
versetags[versetag] = 1
|
||||
# now figure out the presentation order
|
||||
@ -295,6 +296,8 @@ class OpenSongImport(SongImport):
|
||||
else:
|
||||
log.warn(u'No verse order available for %s, skipping.',
|
||||
self.title)
|
||||
# TODO: make sure that the default order list will be overwritten, if
|
||||
# the songs provides its own order list.
|
||||
for tag in order:
|
||||
if tag[0].isdigit():
|
||||
# Assume it's a verse if it has no prefix
|
||||
|
@ -60,6 +60,7 @@ The XML of `OpenLyrics <http://openlyrics.info/>`_ songs is of the format::
|
||||
</song>
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import re
|
||||
|
||||
@ -207,7 +208,8 @@ class OpenLyrics(object):
|
||||
This property is not supported.
|
||||
|
||||
*<verse name="v1a" lang="he" translit="en">*
|
||||
The attribute *translit* is not supported.
|
||||
The attribute *translit* is not supported. Note, the attribute *lang* is
|
||||
considered, but there is not further functionality implemented yet.
|
||||
|
||||
*<verseOrder>*
|
||||
OpenLP supports this property.
|
||||
@ -222,8 +224,14 @@ class OpenLyrics(object):
|
||||
"""
|
||||
sxml = SongXML()
|
||||
verse_list = sxml.get_verses(song.lyrics)
|
||||
song_xml = objectify.fromstring(
|
||||
u'<song version="0.7" createdIn="OpenLP 2.0"/>')
|
||||
song_xml = objectify.fromstring(u'<song/>')
|
||||
# Append the necessary meta data to the song.
|
||||
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
|
||||
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
|
||||
song_xml.set(u'createdIn', u'OpenLP 1.9.4') # Use variable
|
||||
song_xml.set(u'modifiedIn', u'OpenLP 1.9.4') # Use variable
|
||||
song_xml.set(u'modifiedDate',
|
||||
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
|
||||
properties = etree.SubElement(song_xml, u'properties')
|
||||
titles = etree.SubElement(properties, u'titles')
|
||||
self._add_text_to_element(u'title', titles, song.title.strip())
|
||||
@ -237,7 +245,7 @@ class OpenLyrics(object):
|
||||
self._add_text_to_element(u'copyright', properties, song.copyright)
|
||||
if song.verse_order:
|
||||
self._add_text_to_element(
|
||||
u'verseOrder', properties, song.verse_order)
|
||||
u'verseOrder', properties, song.verse_order.lower())
|
||||
if song.ccli_number:
|
||||
self._add_text_to_element(u'ccliNo', properties, song.ccli_number)
|
||||
if song.authors:
|
||||
@ -450,7 +458,7 @@ class OpenLyrics(object):
|
||||
text += u'\n'
|
||||
text += u'\n'.join([unicode(line) for line in lines.line])
|
||||
verse_name = self._get(verse, u'name')
|
||||
verse_type = unicode(VerseType.to_string(verse_name[0]))[0]
|
||||
verse_type = unicode(VerseType.to_string(verse_name[0]))
|
||||
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
|
||||
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
|
||||
# OpenLyrics allows e. g. "c", but we need "c1".
|
||||
|
Loading…
Reference in New Issue
Block a user