forked from openlp/openlp
HEAD r1601
This commit is contained in:
commit
e87bb1114a
@ -133,6 +133,7 @@ class OpenLP(QtGui.QApplication):
|
||||
u'general/update check', QtCore.QVariant(True)).toBool()
|
||||
if update_check:
|
||||
VersionThread(self.mainWindow).start()
|
||||
self.mainWindow.appStartup()
|
||||
DelayStartThread(self.mainWindow).start()
|
||||
return self.exec_()
|
||||
|
||||
|
@ -34,6 +34,7 @@ from PyQt4 import QtCore
|
||||
from sqlalchemy import create_engine, MetaData
|
||||
from sqlalchemy.exc import InvalidRequestError
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
from sqlalchemy.pool import NullPool
|
||||
|
||||
from openlp.core.utils import AppLocation, delete_file
|
||||
|
||||
@ -52,7 +53,7 @@ def init_db(url, auto_flush=True, auto_commit=False):
|
||||
``auto_commit``
|
||||
Sets the commit behaviour of the session
|
||||
"""
|
||||
engine = create_engine(url)
|
||||
engine = create_engine(url, poolclass=NullPool)
|
||||
metadata = MetaData(bind=engine)
|
||||
session = scoped_session(sessionmaker(autoflush=auto_flush,
|
||||
autocommit=auto_commit, bind=engine))
|
||||
|
@ -47,7 +47,6 @@ class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
"""
|
||||
log.debug(u'Initialise the %s widget' % name)
|
||||
QtGui.QDockWidget.__init__(self, parent)
|
||||
self.parent = parent
|
||||
if name:
|
||||
self.setObjectName(name)
|
||||
if icon:
|
||||
|
@ -90,11 +90,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
Constructor to create the media manager item.
|
||||
"""
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.parent = parent
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.whitespace = re.compile(r'\W+', re.UNICODE)
|
||||
#TODO: plugin should not be the parent in future
|
||||
self.plugin = parent # plugin
|
||||
self.plugin = plugin
|
||||
visible_title = self.plugin.getString(StringContent.VisibleName)
|
||||
self.title = unicode(visible_title[u'title'])
|
||||
self.settingsSection = self.plugin.name.lower()
|
||||
@ -114,7 +112,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.retranslateUi()
|
||||
self.auto_select_id = -1
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_service_load' % self.parent.name.lower()),
|
||||
QtCore.SIGNAL(u'%s_service_load' % self.plugin.name.lower()),
|
||||
self.serviceLoad)
|
||||
|
||||
def requiredIcons(self):
|
||||
@ -472,7 +470,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
serviceItem = self.buildServiceItem()
|
||||
if serviceItem:
|
||||
serviceItem.from_plugin = True
|
||||
self.parent.previewController.addServiceItem(serviceItem)
|
||||
self.plugin.previewController.addServiceItem(serviceItem)
|
||||
if keepFocus:
|
||||
self.listView.setFocus()
|
||||
|
||||
@ -497,7 +495,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
if serviceItem:
|
||||
if not item_id:
|
||||
serviceItem.from_plugin = True
|
||||
self.parent.liveController.addServiceItem(serviceItem)
|
||||
self.plugin.liveController.addServiceItem(serviceItem)
|
||||
|
||||
def createItemFromId(self, item_id):
|
||||
item = QtGui.QListWidgetItem()
|
||||
@ -527,7 +525,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
serviceItem = self.buildServiceItem(item, True)
|
||||
if serviceItem:
|
||||
serviceItem.from_plugin = False
|
||||
self.parent.serviceManager.addServiceItem(serviceItem,
|
||||
self.plugin.serviceManager.addServiceItem(serviceItem,
|
||||
replace=replace)
|
||||
|
||||
def onAddEditClick(self):
|
||||
@ -540,14 +538,14 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
'You must select one or more items.'))
|
||||
else:
|
||||
log.debug(u'%s Add requested', self.plugin.name)
|
||||
serviceItem = self.parent.serviceManager.getServiceItem()
|
||||
serviceItem = self.plugin.serviceManager.getServiceItem()
|
||||
if not serviceItem:
|
||||
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select an existing service item to add to.'))
|
||||
elif self.plugin.name.lower() == serviceItem.name.lower():
|
||||
self.generateSlideData(serviceItem)
|
||||
self.parent.serviceManager.addServiceItem(serviceItem,
|
||||
self.plugin.serviceManager.addServiceItem(serviceItem,
|
||||
replace=True)
|
||||
else:
|
||||
# Turn off the remote edit update message indicator
|
||||
@ -561,8 +559,8 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
Common method for generating a service item
|
||||
"""
|
||||
serviceItem = ServiceItem(self.parent)
|
||||
serviceItem.add_icon(self.parent.icon_path)
|
||||
serviceItem = ServiceItem(self.plugin)
|
||||
serviceItem.add_icon(self.plugin.icon_path)
|
||||
if self.generateSlideData(serviceItem, item, xmlVersion):
|
||||
return serviceItem
|
||||
else:
|
||||
|
@ -215,7 +215,8 @@ class Plugin(QtCore.QObject):
|
||||
you need, and return it for integration into openlp.org.
|
||||
"""
|
||||
if self.media_item_class:
|
||||
return self.media_item_class(self, self, self.icon)
|
||||
return self.media_item_class(self.mediadock.media_dock, self,
|
||||
self.icon)
|
||||
return None
|
||||
|
||||
def addImportMenuItem(self, importMenu):
|
||||
|
@ -77,7 +77,7 @@ class Renderer(object):
|
||||
self.theme_data = None
|
||||
self.bg_frame = None
|
||||
self.force_page = False
|
||||
self.display = MainDisplay(self, self.image_manager, False)
|
||||
self.display = MainDisplay(None, self.image_manager, False)
|
||||
self.display.setup()
|
||||
|
||||
def update_display(self):
|
||||
@ -86,7 +86,7 @@ class Renderer(object):
|
||||
"""
|
||||
log.debug(u'Update Display')
|
||||
self._calculate_default(self.screens.current[u'size'])
|
||||
self.display = MainDisplay(self, self.image_manager, False)
|
||||
self.display = MainDisplay(None, self.image_manager, False)
|
||||
self.display.setup()
|
||||
self.bg_frame = None
|
||||
self.theme_data = None
|
||||
|
@ -147,6 +147,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
DisplayTags.remove_html_tag(self.selected)
|
||||
self.selected = -1
|
||||
self._resetTable()
|
||||
self._saveTable()
|
||||
|
||||
def onSavedPushed(self):
|
||||
"""
|
||||
@ -171,14 +172,19 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
html[u'end tag'] = u'{/%s}' % tag
|
||||
self.selected = -1
|
||||
self._resetTable()
|
||||
temp = []
|
||||
self._saveTable()
|
||||
|
||||
def _saveTable(self):
|
||||
"""
|
||||
Saves all display tags except protected ones.
|
||||
"""
|
||||
tags = []
|
||||
for tag in DisplayTags.get_html_tags():
|
||||
if not tag[u'protected']:
|
||||
temp.append(tag)
|
||||
if temp:
|
||||
ctemp = cPickle.dumps(temp)
|
||||
tags.append(tag)
|
||||
if tags:
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(ctemp))
|
||||
QtCore.QVariant(cPickle.dumps(tags)))
|
||||
else:
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(u''))
|
||||
|
@ -49,8 +49,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||
This is the display screen.
|
||||
"""
|
||||
def __init__(self, parent, image_manager, live):
|
||||
QtGui.QGraphicsView.__init__(self)
|
||||
self.parent = parent
|
||||
QtGui.QGraphicsView.__init__(self, parent)
|
||||
self.isLive = live
|
||||
self.image_manager = image_manager
|
||||
self.screens = ScreenList.get_instance()
|
||||
|
@ -179,7 +179,7 @@ class Ui_MainWindow(object):
|
||||
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
|
||||
self.serviceManagerContents.printServiceOrder,
|
||||
category=UiStrings().File)
|
||||
self.fileExitItem = shortcut_action(mainWindow, u'FileExitItem',
|
||||
self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
|
||||
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
|
||||
u':/system/system_exit.png', category=UiStrings().File)
|
||||
action_list.add_category(UiStrings().Import, CategoryOrder.standardMenu)
|
||||
@ -651,6 +651,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.setViewMode(False, True, False, False, True)
|
||||
self.modeLiveItem.setChecked(True)
|
||||
|
||||
def appStartup(self):
|
||||
# Give all the plugins a chance to perform some tasks at startup
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
for plugin in self.pluginManager.plugins:
|
||||
if hasattr(plugin, u'appStartup'):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
plugin.appStartup()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def firstTime(self):
|
||||
# Import themes if first time
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
@ -40,7 +40,6 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.activePlugin = None
|
||||
self.programaticChange = False
|
||||
self.setupUi(self)
|
||||
@ -65,7 +64,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
self._clearDetails()
|
||||
self.programaticChange = True
|
||||
pluginListWidth = 0
|
||||
for plugin in self.parent.pluginManager.plugins:
|
||||
for plugin in self.parent().pluginManager.plugins:
|
||||
item = QtGui.QListWidgetItem(self.pluginListWidget)
|
||||
# We do this just to make 100% sure the status is an integer as
|
||||
# sometimes when it's loaded from the config, it isn't cast to int.
|
||||
@ -117,7 +116,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
plugin_name_singular = \
|
||||
self.pluginListWidget.currentItem().text().split(u' ')[0]
|
||||
self.activePlugin = None
|
||||
for plugin in self.parent.pluginManager.plugins:
|
||||
for plugin in self.parent().pluginManager.plugins:
|
||||
if plugin.nameStrings[u'singular'] == plugin_name_singular:
|
||||
self.activePlugin = plugin
|
||||
break
|
||||
|
@ -42,42 +42,44 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
|
||||
*/
|
||||
|
||||
.serviceTitle {
|
||||
font-weight:600;
|
||||
font-size:x-large;
|
||||
color:black;
|
||||
font-weight: 600;
|
||||
font-size: x-large;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.item {
|
||||
color:black;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.itemTitle {
|
||||
font-weight:600;
|
||||
font-size:large;
|
||||
font-weight: 600;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.itemText {}
|
||||
.itemText {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.itemFooter {
|
||||
font-size:8px;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.itemNotes {}
|
||||
|
||||
.itemNotesTitle {
|
||||
font-weight:bold;
|
||||
font-size:12px;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.itemNotesText {
|
||||
font-size:11px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.media {}
|
||||
|
||||
.mediaTitle {
|
||||
font-weight:bold;
|
||||
font-size:11px;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.mediaText {}
|
||||
@ -89,16 +91,16 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
|
||||
}
|
||||
|
||||
.customNotesTitle {
|
||||
font-weight:bold;
|
||||
font-size:11px;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.customNotesText {
|
||||
font-size:11px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.newPage {
|
||||
page-break-before:always;
|
||||
page-break-before: always;
|
||||
}
|
||||
"""
|
||||
|
||||
@ -212,11 +214,11 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
verse_def = None
|
||||
for slide in item.get_frames():
|
||||
if not verse_def or verse_def != slide[u'verseTag']:
|
||||
p = self._addElement(u'div', parent=div,
|
||||
text_div = self._addElement(u'div', parent=div,
|
||||
classId=u'itemText')
|
||||
else:
|
||||
self._addElement(u'br', parent=p)
|
||||
self._addElement(u'p', slide[u'html'], p)
|
||||
self._addElement(u'br', parent=text_div)
|
||||
self._addElement(u'span', slide[u'html'], text_div)
|
||||
verse_def = slide[u'verseTag']
|
||||
# Break the page before the div element.
|
||||
if index != 0 and self.pageBreakAfterText.isChecked():
|
||||
|
@ -46,7 +46,6 @@ class SlideList(QtGui.QTableWidget):
|
||||
"""
|
||||
def __init__(self, parent=None, name=None):
|
||||
QtGui.QTableWidget.__init__(self, parent.controller)
|
||||
self.parent = parent
|
||||
|
||||
|
||||
class SlideController(QtGui.QWidget):
|
||||
@ -60,11 +59,10 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.isLive = isLive
|
||||
self.parent = parent
|
||||
self.screens = ScreenList.get_instance()
|
||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||
float(self.screens.current[u'size'].height())
|
||||
self.image_manager = self.parent.image_manager
|
||||
self.image_manager = self.parent().image_manager
|
||||
self.loopList = [
|
||||
u'Play Slides Menu',
|
||||
u'Loop Separator',
|
||||
@ -201,7 +199,7 @@ class SlideController(QtGui.QWidget):
|
||||
u':/media/media_time.png', False, UiStrings().LiveToolbar)
|
||||
self.playSlidesOnce.setText(
|
||||
translate('OpenLP.SlideController', 'Play Slides to End'))
|
||||
if QtCore.QSettings().value(self.parent.generalSettingsSection +
|
||||
if QtCore.QSettings().value(self.parent().generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
|
||||
else:
|
||||
@ -468,7 +466,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.previewListWidget.resizeRowsToContents()
|
||||
else:
|
||||
# Sort out image heights.
|
||||
width = self.parent.controlSplitter.sizes()[self.split]
|
||||
width = self.parent().controlSplitter.sizes()[self.split]
|
||||
for framenumber in range(len(self.serviceItem.get_frames())):
|
||||
self.previewListWidget.setRowHeight(
|
||||
framenumber, width / self.ratio)
|
||||
@ -505,7 +503,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
||||
if item.is_text():
|
||||
if QtCore.QSettings().value(
|
||||
self.parent.songsSettingsSection + u'/display songbar',
|
||||
self.parent().songsSettingsSection + u'/display songbar',
|
||||
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
|
||||
self.toolbar.makeWidgetsVisible([u'Song Menu'])
|
||||
if item.is_capable(ItemCapabilities.AllowsLoop) and \
|
||||
@ -591,7 +589,7 @@ class SlideController(QtGui.QWidget):
|
||||
Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
|
||||
[serviceItem, self.isLive, self.hideMode(), slideno])
|
||||
self.slideList = {}
|
||||
width = self.parent.controlSplitter.sizes()[self.split]
|
||||
width = self.parent().controlSplitter.sizes()[self.split]
|
||||
self.previewListWidget.clear()
|
||||
self.previewListWidget.setRowCount(0)
|
||||
self.previewListWidget.setColumnWidth(0, width)
|
||||
@ -625,8 +623,8 @@ class SlideController(QtGui.QWidget):
|
||||
label.setScaledContents(True)
|
||||
if self.serviceItem.is_command():
|
||||
image = resize_image(frame[u'image'],
|
||||
self.parent.renderer.width,
|
||||
self.parent.renderer.height)
|
||||
self.parent().renderer.width,
|
||||
self.parent().renderer.height)
|
||||
else:
|
||||
# If current slide set background to image
|
||||
if framenumber == slideno:
|
||||
@ -635,7 +633,7 @@ class SlideController(QtGui.QWidget):
|
||||
image = self.image_manager.get_image(frame[u'title'])
|
||||
label.setPixmap(QtGui.QPixmap.fromImage(image))
|
||||
self.previewListWidget.setCellWidget(framenumber, 0, label)
|
||||
slideHeight = width * self.parent.renderer.screen_ratio
|
||||
slideHeight = width * self.parent().renderer.screen_ratio
|
||||
row += 1
|
||||
text.append(unicode(row))
|
||||
self.previewListWidget.setItem(framenumber, 0, item)
|
||||
@ -736,7 +734,7 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
log.debug(u'mainDisplaySetBackground live = %s' % self.isLive)
|
||||
display_type = QtCore.QSettings().value(
|
||||
self.parent.generalSettingsSection + u'/screen blank',
|
||||
self.parent().generalSettingsSection + u'/screen blank',
|
||||
QtCore.QVariant(u'')).toString()
|
||||
if not self.display.primary:
|
||||
# Order done to handle initial conversion
|
||||
@ -772,11 +770,11 @@ class SlideController(QtGui.QWidget):
|
||||
self.desktopScreen.setChecked(False)
|
||||
if checked:
|
||||
QtCore.QSettings().setValue(
|
||||
self.parent.generalSettingsSection + u'/screen blank',
|
||||
self.parent().generalSettingsSection + u'/screen blank',
|
||||
QtCore.QVariant(u'blanked'))
|
||||
else:
|
||||
QtCore.QSettings().remove(
|
||||
self.parent.generalSettingsSection + u'/screen blank')
|
||||
self.parent().generalSettingsSection + u'/screen blank')
|
||||
self.blankPlugin()
|
||||
self.updatePreview()
|
||||
|
||||
@ -793,11 +791,11 @@ class SlideController(QtGui.QWidget):
|
||||
self.desktopScreen.setChecked(False)
|
||||
if checked:
|
||||
QtCore.QSettings().setValue(
|
||||
self.parent.generalSettingsSection + u'/screen blank',
|
||||
self.parent().generalSettingsSection + u'/screen blank',
|
||||
QtCore.QVariant(u'themed'))
|
||||
else:
|
||||
QtCore.QSettings().remove(
|
||||
self.parent.generalSettingsSection + u'/screen blank')
|
||||
self.parent().generalSettingsSection + u'/screen blank')
|
||||
self.blankPlugin()
|
||||
self.updatePreview()
|
||||
|
||||
@ -814,11 +812,11 @@ class SlideController(QtGui.QWidget):
|
||||
self.desktopScreen.setChecked(checked)
|
||||
if checked:
|
||||
QtCore.QSettings().setValue(
|
||||
self.parent.generalSettingsSection + u'/screen blank',
|
||||
self.parent().generalSettingsSection + u'/screen blank',
|
||||
QtCore.QVariant(u'hidden'))
|
||||
else:
|
||||
QtCore.QSettings().remove(
|
||||
self.parent.generalSettingsSection + u'/screen blank')
|
||||
self.parent().generalSettingsSection + u'/screen blank')
|
||||
self.hidePlugin(checked)
|
||||
self.updatePreview()
|
||||
|
||||
@ -958,7 +956,7 @@ class SlideController(QtGui.QWidget):
|
||||
if row == self.previewListWidget.rowCount():
|
||||
if wrap is None:
|
||||
wrap = QtCore.QSettings().value(
|
||||
self.parent.generalSettingsSection +
|
||||
self.parent().generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool()
|
||||
if wrap:
|
||||
row = 0
|
||||
@ -980,8 +978,8 @@ class SlideController(QtGui.QWidget):
|
||||
else:
|
||||
row = self.previewListWidget.currentRow() - 1
|
||||
if row == -1:
|
||||
if QtCore.QSettings().value(self.parent.generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
if QtCore.QSettings().value(self.parent().generalSettingsSection
|
||||
+ u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
row = self.previewListWidget.rowCount() - 1
|
||||
else:
|
||||
row = 0
|
||||
@ -1080,7 +1078,8 @@ class SlideController(QtGui.QWidget):
|
||||
From the preview display request the Item to be added to service
|
||||
"""
|
||||
if self.serviceItem:
|
||||
self.parent.serviceManagerContents.addServiceItem(self.serviceItem)
|
||||
self.parent().serviceManagerContents.addServiceItem(
|
||||
self.serviceItem)
|
||||
|
||||
def onGoLiveClick(self):
|
||||
"""
|
||||
@ -1108,7 +1107,7 @@ class SlideController(QtGui.QWidget):
|
||||
Receiver.send_message('servicemanager_preview_live',
|
||||
u'%s:%s' % (self.serviceItem._uuid, row))
|
||||
else:
|
||||
self.parent.liveController.addServiceManagerItem(
|
||||
self.parent().liveController.addServiceManagerItem(
|
||||
self.serviceItem, row)
|
||||
|
||||
def onMediaStart(self, item):
|
||||
|
@ -41,7 +41,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
Initialise the alert form
|
||||
"""
|
||||
self.manager = plugin.manager
|
||||
self.parent = plugin
|
||||
self.plugin = plugin
|
||||
self.item_id = None
|
||||
QtGui.QDialog.__init__(self, plugin.formparent)
|
||||
self.setupUi(self)
|
||||
@ -195,7 +195,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.parameterEdit.setFocus()
|
||||
return False
|
||||
text = text.replace(u'<>', unicode(self.parameterEdit.text()))
|
||||
self.parent.alertsmanager.displayAlert(text)
|
||||
self.plugin.alertsmanager.displayAlert(text)
|
||||
return True
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
|
@ -40,8 +40,7 @@ class AlertsManager(QtCore.QObject):
|
||||
log.info(u'Alert Manager loaded')
|
||||
|
||||
def __init__(self, parent):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.parent = parent
|
||||
QtCore.QObject.__init__(self, parent)
|
||||
self.screen = None
|
||||
self.timer_id = 0
|
||||
self.alertList = []
|
||||
@ -85,8 +84,8 @@ class AlertsManager(QtCore.QObject):
|
||||
if len(self.alertList) == 0:
|
||||
return
|
||||
text = self.alertList.pop(0)
|
||||
alertTab = self.parent.settings_tab
|
||||
self.parent.liveController.display.alert(text)
|
||||
alertTab = self.parent().settings_tab
|
||||
self.parent().liveController.display.alert(text)
|
||||
# Check to see if we have a timer running.
|
||||
if self.timer_id == 0:
|
||||
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
|
||||
@ -101,7 +100,7 @@ class AlertsManager(QtCore.QObject):
|
||||
"""
|
||||
log.debug(u'timer event')
|
||||
if event.timerId() == self.timer_id:
|
||||
self.parent.liveController.display.alert(u'')
|
||||
self.parent().liveController.display.alert(u'')
|
||||
self.killTimer(self.timer_id)
|
||||
self.timer_id = 0
|
||||
self.generateAlert()
|
||||
|
@ -33,6 +33,7 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||
from openlp.core.lib.ui import base_action, UiStrings
|
||||
from openlp.core.utils.actions import ActionList
|
||||
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
||||
from openlp.plugins.bibles.forms import BibleUpgradeForm
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -59,6 +60,8 @@ class BiblePlugin(Plugin):
|
||||
#action_list.add_action(self.exportBibleItem, UiStrings().Export)
|
||||
# Set to invisible until we can export bibles
|
||||
self.exportBibleItem.setVisible(False)
|
||||
if len(self.manager.old_bible_databases):
|
||||
self.toolsUpgradeItem.setVisible(True)
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
@ -73,6 +76,19 @@ class BiblePlugin(Plugin):
|
||||
#action_list.remove_action(self.exportBibleItem, UiStrings().Export)
|
||||
self.exportBibleItem.setVisible(False)
|
||||
|
||||
def appStartup(self):
|
||||
"""
|
||||
Perform tasks on application starup
|
||||
"""
|
||||
if len(self.manager.old_bible_databases):
|
||||
if QtGui.QMessageBox.information(self.formparent,
|
||||
translate('OpenLP', 'Information'), translate('OpenLP',
|
||||
'Bible format has changed.\nYou have to upgrade your '
|
||||
'existing Bibles.\nShould OpenLP upgrade now?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||
QtGui.QMessageBox.No)) == QtGui.QMessageBox.Yes:
|
||||
self.onToolsUpgradeItemTriggered()
|
||||
|
||||
def addImportMenuItem(self, import_menu):
|
||||
self.importBibleItem = base_action(import_menu, u'importBibleItem')
|
||||
self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
|
||||
@ -88,6 +104,39 @@ class BiblePlugin(Plugin):
|
||||
export_menu.addAction(self.exportBibleItem)
|
||||
self.exportBibleItem.setVisible(False)
|
||||
|
||||
def addToolsMenuItem(self, tools_menu):
|
||||
"""
|
||||
Give the bible plugin the opportunity to add items to the
|
||||
**Tools** menu.
|
||||
|
||||
``tools_menu``
|
||||
The actual **Tools** menu item, so that your actions can
|
||||
use it as their parent.
|
||||
"""
|
||||
log.debug(u'add tools menu')
|
||||
self.toolsUpgradeItem = QtGui.QAction(tools_menu)
|
||||
self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
|
||||
self.toolsUpgradeItem.setText(
|
||||
translate('BiblePlugin', '&Upgrade older Bibles'))
|
||||
self.toolsUpgradeItem.setStatusTip(
|
||||
translate('BiblePlugin', 'Upgrade the Bible databases to the '
|
||||
'latest format'))
|
||||
tools_menu.addAction(self.toolsUpgradeItem)
|
||||
QtCore.QObject.connect(self.toolsUpgradeItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
|
||||
self.toolsUpgradeItem.setVisible(False)
|
||||
|
||||
def onToolsUpgradeItemTriggered(self):
|
||||
"""
|
||||
Upgrade older bible databases.
|
||||
"""
|
||||
if not hasattr(self, u'upgrade_wizard'):
|
||||
self.upgrade_wizard = BibleUpgradeForm(self.formparent,
|
||||
self.manager, self)
|
||||
# If the import was not cancelled then reload.
|
||||
if self.upgrade_wizard.exec_():
|
||||
self.mediaItem.reloadBibles()
|
||||
|
||||
def onBibleImportClick(self):
|
||||
if self.mediaItem:
|
||||
self.mediaItem.onImportClick()
|
||||
@ -149,4 +198,3 @@ class BiblePlugin(Plugin):
|
||||
'Add the selected Bible to the service.')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
||||
|
@ -51,7 +51,10 @@ This allows OpenLP to use ``self.object`` for all the GUI elements while keeping
|
||||
them separate from the functionality, so that it is easier to recreate the GUI
|
||||
from the .ui files later if necessary.
|
||||
"""
|
||||
|
||||
from booknameform import BookNameForm
|
||||
from languageform import LanguageForm
|
||||
from bibleimportform import BibleImportForm
|
||||
from bibleupgradeform import BibleUpgradeForm
|
||||
|
||||
__all__ = ['BibleImportForm']
|
||||
__all__ = [u'BookNameForm', u'LanguageForm', u'BibleImportForm',
|
||||
u'BibleUpgradeForm']
|
||||
|
@ -41,6 +41,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import AppLocation, string_is_unicode
|
||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -125,9 +126,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
QtCore.QObject.connect(self.osisBrowseButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onOsisBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.csvTestamentsButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onCsvTestamentsBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.csvBooksButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onCsvBooksBrowseButtonClicked)
|
||||
@ -188,18 +186,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.csvLayout = QtGui.QFormLayout(self.csvWidget)
|
||||
self.csvLayout.setMargin(0)
|
||||
self.csvLayout.setObjectName(u'CsvLayout')
|
||||
self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
|
||||
self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
|
||||
self.csvTestamentsLayout = QtGui.QHBoxLayout()
|
||||
self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
|
||||
self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
|
||||
self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
|
||||
self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
|
||||
self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
|
||||
self.csvTestamentsButton.setIcon(self.openIcon)
|
||||
self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
|
||||
self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
|
||||
self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
|
||||
self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
|
||||
self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
|
||||
self.csvBooksLayout = QtGui.QHBoxLayout()
|
||||
@ -384,8 +370,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.osisFileLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.csvTestamentsLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
|
||||
self.csvBooksLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
|
||||
self.csvVersesLabel.setText(
|
||||
@ -436,7 +420,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
# Align all QFormLayouts towards each other.
|
||||
labelWidth = max(self.formatLabel.minimumSizeHint().width(),
|
||||
self.osisFileLabel.minimumSizeHint().width(),
|
||||
self.csvTestamentsLabel.minimumSizeHint().width(),
|
||||
self.csvBooksLabel.minimumSizeHint().width(),
|
||||
self.csvVersesLabel.minimumSizeHint().width(),
|
||||
self.openSongFileLabel.minimumSizeHint().width(),
|
||||
@ -458,14 +441,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.osisFileEdit.setFocus()
|
||||
return False
|
||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
||||
if not self.field(u'csv_testamentsfile').toString():
|
||||
answer = critical_error_message_box(UiStrings().NFSs,
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'You have not specified a testaments file. Do you '
|
||||
'want to proceed with the import?'), question=True)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
self.csvTestamentsEdit.setFocus()
|
||||
return False
|
||||
if not self.field(u'csv_booksfile').toString():
|
||||
critical_error_message_box(UiStrings().NFSs,
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -498,6 +473,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
license_version = unicode(self.field(u'license_version').toString())
|
||||
license_copyright = \
|
||||
unicode(self.field(u'license_copyright').toString())
|
||||
path = AppLocation.get_section_data_path(u'bibles')
|
||||
if not license_version:
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -519,6 +495,15 @@ class BibleImportForm(OpenLPWizard):
|
||||
'a different Bible or first delete the existing one.'))
|
||||
self.versionNameEdit.setFocus()
|
||||
return False
|
||||
elif os.path.exists(os.path.join(path, clean_filename(
|
||||
license_version))):
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'This Bible already exists. Please import '
|
||||
'a different Bible or first delete the existing one.'))
|
||||
self.versionNameEdit.setFocus()
|
||||
return False
|
||||
return True
|
||||
if self.currentPage() == self.progressPage:
|
||||
return True
|
||||
@ -543,14 +528,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OSIS,
|
||||
self.osisFileEdit)
|
||||
|
||||
def onCsvTestamentsBrowseButtonClicked(self):
|
||||
"""
|
||||
Show the file open dialog for the testaments CSV file.
|
||||
"""
|
||||
self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV,
|
||||
self.csvTestamentsEdit, u'%s (*.csv)'
|
||||
% translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
|
||||
|
||||
def onCsvBooksBrowseButtonClicked(self):
|
||||
"""
|
||||
Show the file open dialog for the books CSV file.
|
||||
@ -589,8 +566,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
"""
|
||||
self.selectPage.registerField(u'source_format', self.formatComboBox)
|
||||
self.selectPage.registerField(u'osis_location', self.osisFileEdit)
|
||||
self.selectPage.registerField(
|
||||
u'csv_testamentsfile', self.csvTestamentsEdit)
|
||||
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
|
||||
self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
|
||||
self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
|
||||
@ -619,7 +594,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.cancelButton.setVisible(True)
|
||||
self.setField(u'source_format', QtCore.QVariant(0))
|
||||
self.setField(u'osis_location', QtCore.QVariant(''))
|
||||
self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
|
||||
self.setField(u'csv_booksfile', QtCore.QVariant(''))
|
||||
self.setField(u'csv_versefile', QtCore.QVariant(''))
|
||||
self.setField(u'opensong_file', QtCore.QVariant(''))
|
||||
@ -646,46 +620,27 @@ class BibleImportForm(OpenLPWizard):
|
||||
"""
|
||||
Load the lists of Crosswalk, BibleGateway and Bibleserver bibles.
|
||||
"""
|
||||
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
|
||||
filepath = os.path.join(filepath, u'bibles', u'resources')
|
||||
# Load Crosswalk Bibles.
|
||||
self.loadBibleResourceFile(
|
||||
os.path.join(filepath, u'crosswalkbooks.csv'),
|
||||
WebDownload.Crosswalk)
|
||||
self.loadBibleResource(WebDownload.Crosswalk)
|
||||
# Load BibleGateway Bibles.
|
||||
self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'),
|
||||
WebDownload.BibleGateway)
|
||||
self.loadBibleResource(WebDownload.BibleGateway)
|
||||
# Load and Bibleserver Bibles.
|
||||
self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'),
|
||||
WebDownload.Bibleserver)
|
||||
self.loadBibleResource(WebDownload.Bibleserver)
|
||||
|
||||
def loadBibleResourceFile(self, file_path_name, download_type):
|
||||
def loadBibleResource(self, download_type):
|
||||
"""
|
||||
Loads a web bible resource file.
|
||||
|
||||
``file_path_name``
|
||||
The file to load including the file's path.
|
||||
Loads a web bible from bible_resources.sqlite.
|
||||
|
||||
``download_type``
|
||||
The WebDownload type this file is for.
|
||||
The WebDownload type e.g. bibleserver.
|
||||
"""
|
||||
self.web_bible_list[download_type] = {}
|
||||
books_file = None
|
||||
try:
|
||||
books_file = open(file_path_name, 'rb')
|
||||
dialect = csv.Sniffer().sniff(books_file.read(1024))
|
||||
books_file.seek(0)
|
||||
books_reader = csv.reader(books_file, dialect)
|
||||
for line in books_reader:
|
||||
ver = string_is_unicode(line[0])
|
||||
name = string_is_unicode(line[1])
|
||||
self.web_bible_list[download_type][ver] = name.strip()
|
||||
except IOError:
|
||||
log.exception(u'%s resources missing' %
|
||||
WebDownload.Names[download_type])
|
||||
finally:
|
||||
if books_file:
|
||||
books_file.close()
|
||||
bibles = BiblesResourcesDB.get_webbibles(
|
||||
WebDownload.Names[download_type])
|
||||
for bible in bibles:
|
||||
version = bible[u'name']
|
||||
name = bible[u'abbreviation']
|
||||
self.web_bible_list[download_type][version] = name.strip()
|
||||
|
||||
def preWizard(self):
|
||||
"""
|
||||
@ -720,8 +675,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
elif bible_type == BibleFormat.CSV:
|
||||
# Import a CSV bible.
|
||||
importer = self.manager.import_bible(BibleFormat.CSV,
|
||||
name=license_version, testamentsfile=unicode(
|
||||
self.field(u'csv_testamentsfile').toString()),
|
||||
name=license_version,
|
||||
booksfile=unicode(self.field(u'csv_booksfile').toString()),
|
||||
versefile=unicode(self.field(u'csv_versefile').toString())
|
||||
)
|
||||
@ -752,7 +706,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
name=license_version,
|
||||
filename=unicode(self.field(u'openlp1_location').toString())
|
||||
)
|
||||
if importer.do_import():
|
||||
if importer.do_import(license_version):
|
||||
self.manager.save_meta_data(license_version, license_version,
|
||||
license_copyright, license_permissions)
|
||||
self.manager.reload_bibles()
|
||||
|
779
openlp/plugins/bibles/forms/bibleupgradeform.py
Normal file
779
openlp/plugins/bibles/forms/bibleupgradeform.py
Normal file
@ -0,0 +1,779 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, 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 bible import functions for OpenLP
|
||||
"""
|
||||
import logging
|
||||
import os.path
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||
from openlp.core.lib.db import delete_database
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import AppLocation, delete_file
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB,\
|
||||
BiblesResourcesDB, clean_filename
|
||||
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BibleUpgradeForm(OpenLPWizard):
|
||||
"""
|
||||
This is the Bible Upgrade Wizard, which allows easy importing of Bibles
|
||||
into OpenLP from older OpenLP2 database versions.
|
||||
"""
|
||||
log.info(u'BibleUpgradeForm loaded')
|
||||
|
||||
def __init__(self, parent, manager, bibleplugin):
|
||||
"""
|
||||
Instantiate the wizard, and run any extra setup we need to.
|
||||
|
||||
``parent``
|
||||
The QWidget-derived parent of the wizard.
|
||||
|
||||
``manager``
|
||||
The Bible manager.
|
||||
|
||||
``bibleplugin``
|
||||
The Bible plugin.
|
||||
"""
|
||||
self.manager = manager
|
||||
self.mediaItem = bibleplugin.mediaItem
|
||||
self.suffix = u'.sqlite'
|
||||
self.settingsSection = u'bibles'
|
||||
self.path = AppLocation.get_section_data_path(
|
||||
self.settingsSection)
|
||||
self.files = self.manager.old_bible_databases
|
||||
self.success = {}
|
||||
self.newbibles = {}
|
||||
OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleUpgradeWizard',
|
||||
u':/wizards/wizard_importbible.bmp')
|
||||
|
||||
def setupUi(self, image):
|
||||
"""
|
||||
Set up the UI for the bible wizard.
|
||||
"""
|
||||
OpenLPWizard.setupUi(self, image)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
||||
|
||||
def stop_import(self):
|
||||
"""
|
||||
Stops the import of the Bible.
|
||||
"""
|
||||
log.debug(u'Stopping import')
|
||||
self.stop_import_flag = True
|
||||
|
||||
def onCheckBoxIndexChanged(self, index):
|
||||
"""
|
||||
Show/ Hide warnings if CheckBox state has changed
|
||||
"""
|
||||
for number, filename in enumerate(self.files):
|
||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
self.verticalWidget[number].hide()
|
||||
self.formWidget[number].hide()
|
||||
else:
|
||||
version_name = unicode(self.versionNameEdit[number].text())
|
||||
if self.manager.exists(version_name):
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
Stop the wizard on cancel button, close button or ESC key.
|
||||
"""
|
||||
log.debug(u'Wizard cancelled by user')
|
||||
self.stop_import_flag = True
|
||||
if not self.currentPage() == self.progressPage:
|
||||
self.done(QtGui.QDialog.Rejected)
|
||||
|
||||
def onCurrentIdChanged(self, pageId):
|
||||
"""
|
||||
Perform necessary functions depending on which wizard page is active.
|
||||
"""
|
||||
if self.page(pageId) == self.progressPage:
|
||||
self.preWizard()
|
||||
self.performWizard()
|
||||
self.postWizard()
|
||||
elif self.page(pageId) == self.selectPage and self.maxBibles == 0:
|
||||
self.next()
|
||||
|
||||
def onFinishButton(self):
|
||||
"""
|
||||
Some cleanup while finishing
|
||||
"""
|
||||
for number, filename in enumerate(self.files):
|
||||
if number in self.success and self.success[number] == True:
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
|
||||
def onBackupBrowseButtonClicked(self):
|
||||
"""
|
||||
Show the file open dialog for the OSIS file.
|
||||
"""
|
||||
filename = QtGui.QFileDialog.getExistingDirectory(self, translate(
|
||||
'BiblesPlugin.UpgradeWizardForm', 'Select a Backup Directory'),
|
||||
os.path.dirname(SettingsManager.get_last_dir(
|
||||
self.plugin.settingsSection, 1)))
|
||||
if filename:
|
||||
self.backupDirectoryEdit.setText(filename)
|
||||
SettingsManager.set_last_dir(self.plugin.settingsSection,
|
||||
filename, 1)
|
||||
|
||||
def onNoBackupCheckBoxToggled(self, checked):
|
||||
"""
|
||||
Enable or disable the backup directory widgets.
|
||||
"""
|
||||
self.backupDirectoryEdit.setEnabled(not checked)
|
||||
self.backupBrowseButton.setEnabled(not checked)
|
||||
|
||||
def backupOldBibles(self, backupdirectory):
|
||||
"""
|
||||
Backup old bible databases in a given folder.
|
||||
"""
|
||||
for filename in self.files:
|
||||
try:
|
||||
shutil.copy(os.path.join(self.path, filename[0]),
|
||||
backupdirectory)
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
def customInit(self):
|
||||
"""
|
||||
Perform any custom initialisation for bible upgrading.
|
||||
"""
|
||||
self.manager.set_process_dialog(self)
|
||||
self.restart()
|
||||
|
||||
def customSignals(self):
|
||||
"""
|
||||
Set up the signals used in the bible importer.
|
||||
"""
|
||||
QtCore.QObject.connect(self.finishButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onFinishButton)
|
||||
QtCore.QObject.connect(self.backupBrowseButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onBackupBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.noBackupCheckBox,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.onNoBackupCheckBoxToggled)
|
||||
|
||||
def addCustomPages(self):
|
||||
"""
|
||||
Add the bible import specific wizard pages.
|
||||
"""
|
||||
# Backup Page
|
||||
self.backupPage = QtGui.QWizardPage()
|
||||
self.backupPage.setObjectName(u'BackupPage')
|
||||
self.backupLayout = QtGui.QVBoxLayout(self.backupPage)
|
||||
self.backupLayout.setObjectName(u'BackupLayout')
|
||||
self.backupInfoLabel = QtGui.QLabel(self.backupPage)
|
||||
self.backupInfoLabel.setOpenExternalLinks(True)
|
||||
self.backupInfoLabel.setTextFormat(QtCore.Qt.RichText)
|
||||
self.backupInfoLabel.setWordWrap(True)
|
||||
self.backupInfoLabel.setObjectName(u'backupInfoLabel')
|
||||
self.backupLayout.addWidget(self.backupInfoLabel)
|
||||
self.selectLabel = QtGui.QLabel(self.backupPage)
|
||||
self.selectLabel.setObjectName(u'selectLabel')
|
||||
self.backupLayout.addWidget(self.selectLabel)
|
||||
self.formLayout = QtGui.QFormLayout()
|
||||
self.formLayout.setMargin(0)
|
||||
self.formLayout.setObjectName(u'FormLayout')
|
||||
self.backupDirectoryLabel = QtGui.QLabel(self.backupPage)
|
||||
self.backupDirectoryLabel.setObjectName(u'backupDirectoryLabel')
|
||||
self.backupDirectoryLayout = QtGui.QHBoxLayout()
|
||||
self.backupDirectoryLayout.setObjectName(u'BackupDirectoryLayout')
|
||||
self.backupDirectoryEdit = QtGui.QLineEdit(self.backupPage)
|
||||
self.backupDirectoryEdit.setObjectName(u'BackupFolderEdit')
|
||||
self.backupDirectoryLayout.addWidget(self.backupDirectoryEdit)
|
||||
self.backupBrowseButton = QtGui.QToolButton(self.backupPage)
|
||||
self.backupBrowseButton.setIcon(self.openIcon)
|
||||
self.backupBrowseButton.setObjectName(u'BackupBrowseButton')
|
||||
self.backupDirectoryLayout.addWidget(self.backupBrowseButton)
|
||||
self.formLayout.addRow(self.backupDirectoryLabel,
|
||||
self.backupDirectoryLayout)
|
||||
self.backupLayout.addLayout(self.formLayout)
|
||||
self.noBackupCheckBox = QtGui.QCheckBox(self.backupPage)
|
||||
self.noBackupCheckBox.setObjectName('NoBackupCheckBox')
|
||||
self.backupLayout.addWidget(self.noBackupCheckBox)
|
||||
self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.backupLayout.addItem(self.spacer)
|
||||
self.addPage(self.backupPage)
|
||||
# Select Page
|
||||
self.selectPage = QtGui.QWizardPage()
|
||||
self.selectPage.setObjectName(u'SelectPage')
|
||||
self.pageLayout = QtGui.QVBoxLayout(self.selectPage)
|
||||
self.pageLayout.setObjectName(u'pageLayout')
|
||||
self.scrollArea = QtGui.QScrollArea(self.selectPage)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setObjectName(u'scrollArea')
|
||||
self.scrollArea.setHorizontalScrollBarPolicy(
|
||||
QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.scrollAreaContents = QtGui.QWidget(self.scrollArea)
|
||||
self.scrollAreaContents.setObjectName(u'scrollAreaContents')
|
||||
self.formLayout = QtGui.QVBoxLayout(self.scrollAreaContents)
|
||||
self.formLayout.setSpacing(2)
|
||||
self.formLayout.setObjectName(u'formLayout')
|
||||
self.addScrollArea()
|
||||
self.pageLayout.addWidget(self.scrollArea)
|
||||
self.addPage(self.selectPage)
|
||||
|
||||
def addScrollArea(self):
|
||||
"""
|
||||
Add the content to the scrollArea.
|
||||
"""
|
||||
self.checkBox = {}
|
||||
self.versionNameEdit = {}
|
||||
self.versionNameLabel = {}
|
||||
self.versionInfoLabel = {}
|
||||
self.versionInfoPixmap = {}
|
||||
self.verticalWidget = {}
|
||||
self.horizontalLayout = {}
|
||||
self.formWidget = {}
|
||||
self.formLayoutAttention = {}
|
||||
for number, filename in enumerate(self.files):
|
||||
bible = OldBibleDB(self.mediaItem, path=self.path, file=filename[0])
|
||||
self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
|
||||
checkBoxName = u'checkBox[%d]' % number
|
||||
self.checkBox[number].setObjectName(checkBoxName)
|
||||
self.checkBox[number].setText(bible.get_name())
|
||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||
self.formLayout.addWidget(self.checkBox[number])
|
||||
self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
||||
verticalWidgetName = u'verticalWidget[%d]' % number
|
||||
self.verticalWidget[number].setObjectName(verticalWidgetName)
|
||||
self.horizontalLayout[number] = QtGui.QHBoxLayout(
|
||||
self.verticalWidget[number])
|
||||
self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0)
|
||||
horizontalLayoutName = u'horizontalLayout[%d]' % number
|
||||
self.horizontalLayout[number].setObjectName(horizontalLayoutName)
|
||||
self.versionInfoPixmap[number] = QtGui.QLabel(
|
||||
self.verticalWidget[number])
|
||||
versionInfoPixmapName = u'versionInfoPixmap[%d]' % number
|
||||
self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName)
|
||||
self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap(
|
||||
u':/bibles/bibles_upgrade_alert.png'))
|
||||
self.versionInfoPixmap[number].setAlignment(QtCore.Qt.AlignRight)
|
||||
self.horizontalLayout[number].addWidget(
|
||||
self.versionInfoPixmap[number])
|
||||
self.versionInfoLabel[number] = QtGui.QLabel(
|
||||
self.verticalWidget[number])
|
||||
versionInfoLabelName = u'versionInfoLabel[%d]' % number
|
||||
self.versionInfoLabel[number].setObjectName(versionInfoLabelName)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
|
||||
QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(
|
||||
self.versionInfoLabel[number].sizePolicy().hasHeightForWidth())
|
||||
self.versionInfoLabel[number].setSizePolicy(sizePolicy)
|
||||
self.horizontalLayout[number].addWidget(
|
||||
self.versionInfoLabel[number])
|
||||
self.formLayout.addWidget(self.verticalWidget[number])
|
||||
self.formWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
||||
formWidgetName = u'formWidget[%d]' % number
|
||||
self.formWidget[number].setObjectName(formWidgetName)
|
||||
self.formLayoutAttention[number] = QtGui.QFormLayout(
|
||||
self.formWidget[number])
|
||||
self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5)
|
||||
formLayoutAttentionName = u'formLayoutAttention[%d]' % number
|
||||
self.formLayoutAttention[number].setObjectName(
|
||||
formLayoutAttentionName)
|
||||
self.versionNameLabel[number] = QtGui.QLabel(
|
||||
self.formWidget[number])
|
||||
self.versionNameLabel[number].setObjectName(u'VersionNameLabel')
|
||||
self.formLayoutAttention[number].setWidget(0,
|
||||
QtGui.QFormLayout.LabelRole, self.versionNameLabel[number])
|
||||
self.versionNameEdit[number] = QtGui.QLineEdit(
|
||||
self.formWidget[number])
|
||||
self.versionNameEdit[number].setObjectName(u'VersionNameEdit')
|
||||
self.formLayoutAttention[number].setWidget(0,
|
||||
QtGui.QFormLayout.FieldRole, self.versionNameEdit[number])
|
||||
self.versionNameEdit[number].setText(bible.get_name())
|
||||
self.formLayout.addWidget(self.formWidget[number])
|
||||
#Set up the Signal for the checkbox
|
||||
QtCore.QObject.connect(self.checkBox[number],
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onCheckBoxIndexChanged)
|
||||
self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum,
|
||||
QtGui.QSizePolicy.Expanding)
|
||||
self.formLayout.addItem(self.spacerItem)
|
||||
self.scrollArea.setWidget(self.scrollAreaContents)
|
||||
|
||||
def clearScrollArea(self):
|
||||
"""
|
||||
Remove the content from the scrollArea.
|
||||
"""
|
||||
for number, filename in enumerate(self.files):
|
||||
self.formLayout.removeWidget(self.checkBox[number])
|
||||
self.checkBox[number].setParent(None)
|
||||
self.horizontalLayout[number].removeWidget(
|
||||
self.versionInfoPixmap[number])
|
||||
self.versionInfoPixmap[number].setParent(None)
|
||||
self.horizontalLayout[number].removeWidget(
|
||||
self.versionInfoLabel[number])
|
||||
self.versionInfoLabel[number].setParent(None)
|
||||
self.formLayout.removeWidget(self.verticalWidget[number])
|
||||
self.verticalWidget[number].setParent(None)
|
||||
self.formLayoutAttention[number].removeWidget(
|
||||
self.versionNameLabel[number])
|
||||
self.versionNameLabel[number].setParent(None)
|
||||
self.formLayoutAttention[number].removeWidget(
|
||||
self.versionNameEdit[number])
|
||||
self.formLayoutAttention[number].deleteLater()
|
||||
self.versionNameEdit[number].setParent(None)
|
||||
self.formLayout.removeWidget(self.formWidget[number])
|
||||
self.formWidget[number].setParent(None)
|
||||
self.formLayout.removeItem(self.spacerItem)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
Allow for localisation of the bible import wizard.
|
||||
"""
|
||||
self.setWindowTitle(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Upgrade Wizard'))
|
||||
self.titleLabel.setText(WizardStrings.HeaderStyle %
|
||||
translate('OpenLP.Ui', 'Welcome to the Bible Upgrade Wizard'))
|
||||
self.informationLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This wizard will help you to upgrade your existing Bibles from a '
|
||||
'prior version of OpenLP 2. Click the next button below to start '
|
||||
'the upgrade process.'))
|
||||
self.backupPage.setTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Select Backup Directory'))
|
||||
self.backupPage.setSubTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Please select a backup directory for your Bibles'))
|
||||
self.backupInfoLabel.setText(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Previous releases of OpenLP 2.0 are unable to use upgraded Bibles.'
|
||||
' This will create a backup of your current Bibles so that you can '
|
||||
'simply copy the files back to your OpenLP data directory if you '
|
||||
'need to revert to a previous release of OpenLP. Instructions on '
|
||||
'how to restore the files can be found in our <a href="'
|
||||
'http://wiki.openlp.org/faq">Frequently Asked Questions</a>.'))
|
||||
self.selectLabel.setText(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Please select a backup location for your Bibles.'))
|
||||
self.backupDirectoryLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Backup Directory:'))
|
||||
self.noBackupCheckBox.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'There is no need to backup my Bibles'))
|
||||
self.selectPage.setTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Select Bibles'))
|
||||
self.selectPage.setSubTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Please select the Bibles to upgrade'))
|
||||
for number, bible in enumerate(self.files):
|
||||
self.versionNameLabel[number].setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Version name:'))
|
||||
self.versionInfoLabel[number].setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'This '
|
||||
'Bible still exists. Please change the name or uncheck it.'))
|
||||
self.progressPage.setTitle(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading'))
|
||||
self.progressPage.setSubTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Please wait while your Bibles are upgraded.'))
|
||||
self.progressLabel.setText(WizardStrings.Ready)
|
||||
self.progressBar.setFormat(u'%p%')
|
||||
|
||||
def validateCurrentPage(self):
|
||||
"""
|
||||
Validate the current page before moving on to the next page.
|
||||
"""
|
||||
if self.currentPage() == self.welcomePage:
|
||||
return True
|
||||
elif self.currentPage() == self.backupPage:
|
||||
if not self.noBackupCheckBox.checkState() == QtCore.Qt.Checked:
|
||||
if not unicode(self.backupDirectoryEdit.text()):
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'You need to specify a Backup Directory for your '
|
||||
'Bibles.'))
|
||||
self.backupDirectoryEdit.setFocus()
|
||||
return False
|
||||
elif not os.path.exists(unicode(
|
||||
self.backupDirectoryEdit.text())):
|
||||
critical_error_message_box(UiStrings().Error,
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'The given path is not an existing directory.'))
|
||||
self.backupDirectoryEdit.setFocus()
|
||||
return False
|
||||
else:
|
||||
if not self.backupOldBibles(unicode(
|
||||
self.backupDirectoryEdit.text())):
|
||||
critical_error_message_box(UiStrings().Error,
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'The backup was not successfull.\nTo backup your '
|
||||
'Bibles you need the permission to write in the given '
|
||||
'directory. If you have a permissions to write and '
|
||||
'this error still occurs, please report a bug.'))
|
||||
return False
|
||||
return True
|
||||
elif self.currentPage() == self.selectPage:
|
||||
for number, filename in enumerate(self.files):
|
||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
continue
|
||||
version_name = unicode(self.versionNameEdit[number].text())
|
||||
if not version_name:
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'You need to specify a version name for your Bible.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif self.manager.exists(version_name):
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif os.path.exists(os.path.join(self.path, clean_filename(
|
||||
version_name))) and version_name == filename[1]:
|
||||
newfilename = u'old_database_%s' % filename[0]
|
||||
if not os.path.exists(os.path.join(self.path,
|
||||
newfilename)):
|
||||
os.rename(os.path.join(self.path, filename[0]),
|
||||
os.path.join(self.path, newfilename))
|
||||
self.files[number] = [newfilename, filename[1]]
|
||||
continue
|
||||
else:
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif os.path.exists(os.path.join(self.path,
|
||||
clean_filename(version_name))):
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
return True
|
||||
if self.currentPage() == self.progressPage:
|
||||
return True
|
||||
|
||||
def setDefaults(self):
|
||||
"""
|
||||
Set default values for the wizard pages.
|
||||
"""
|
||||
log.debug(u'BibleUpgrade setDefaults')
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.plugin.settingsSection)
|
||||
self.stop_import_flag = False
|
||||
self.success.clear()
|
||||
self.newbibles.clear()
|
||||
self.clearScrollArea()
|
||||
self.files = self.manager.old_bible_databases
|
||||
self.addScrollArea()
|
||||
self.retranslateUi()
|
||||
self.maxBibles = len(self.files)
|
||||
for number, filename in enumerate(self.files):
|
||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||
oldname = filename[1]
|
||||
if self.manager.exists(oldname):
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
else:
|
||||
self.verticalWidget[number].hide()
|
||||
self.formWidget[number].hide()
|
||||
self.progressBar.show()
|
||||
self.restart()
|
||||
self.finishButton.setVisible(False)
|
||||
self.cancelButton.setVisible(True)
|
||||
settings.endGroup()
|
||||
|
||||
def preWizard(self):
|
||||
"""
|
||||
Prepare the UI for the upgrade.
|
||||
"""
|
||||
OpenLPWizard.preWizard(self)
|
||||
self.progressLabel.setText(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Starting upgrading Bible(s)...'))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def performWizard(self):
|
||||
"""
|
||||
Perform the actual upgrade.
|
||||
"""
|
||||
include_webbible = False
|
||||
proxy_server = None
|
||||
if self.maxBibles == 0:
|
||||
self.progressLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'There are no '
|
||||
'Bibles available to upgrade.'))
|
||||
self.progressBar.hide()
|
||||
return
|
||||
self.maxBibles = 0
|
||||
for number, file in enumerate(self.files):
|
||||
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
self.maxBibles += 1
|
||||
number = 0
|
||||
for biblenumber, filename in enumerate(self.files):
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
break
|
||||
bible_failed = False
|
||||
self.success[biblenumber] = False
|
||||
if not self.checkBox[biblenumber].checkState() == QtCore.Qt.Checked:
|
||||
continue
|
||||
self.progressBar.reset()
|
||||
oldbible = OldBibleDB(self.mediaItem, path=self.path,
|
||||
file=filename[0])
|
||||
name = filename[1]
|
||||
if name is None:
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
continue
|
||||
self.progressLabel.setText(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nUpgrading ...')) %
|
||||
(number + 1, self.maxBibles, name))
|
||||
if os.path.exists(os.path.join(self.path, filename[0])):
|
||||
name = unicode(self.versionNameEdit[biblenumber].text())
|
||||
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
|
||||
name=name)
|
||||
metadata = oldbible.get_metadata()
|
||||
webbible = False
|
||||
meta_data = {}
|
||||
for meta in metadata:
|
||||
meta_data[meta[u'key']] = meta[u'value']
|
||||
if not meta[u'key'] == u'Version':
|
||||
self.newbibles[number].create_meta(meta[u'key'],
|
||||
meta[u'value'])
|
||||
else:
|
||||
self.newbibles[number].create_meta(meta[u'key'], name)
|
||||
if meta[u'key'] == u'download source':
|
||||
webbible = True
|
||||
include_webbible = True
|
||||
if meta.has_key(u'proxy server'):
|
||||
proxy_server = meta[u'proxy server']
|
||||
if webbible:
|
||||
if meta_data[u'download source'].lower() == u'crosswalk':
|
||||
handler = CWExtract(proxy_server)
|
||||
elif meta_data[u'download source'].lower() == u'biblegateway':
|
||||
handler = BGExtract(proxy_server)
|
||||
elif meta_data[u'download source'].lower() == u'bibleserver':
|
||||
handler = BSExtract(proxy_server)
|
||||
books = handler.get_books_from_http(meta_data[u'download name'])
|
||||
if not books:
|
||||
log.exception(u'Upgrading books from %s - download '\
|
||||
u'name: "%s" failed' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
delete_database(self.path,
|
||||
clean_filename(self.newbibles[number].get_name()))
|
||||
del self.newbibles[number]
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Download Error'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'To upgrade your Web Bibles an Internet connection is '
|
||||
'required. If you have a working Internet connection '
|
||||
'and this error still occurs, please report a bug.'))
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
continue
|
||||
bible = BiblesResourcesDB.get_webbible(
|
||||
meta_data[u'download name'],
|
||||
meta_data[u'download source'].lower())
|
||||
if bible[u'language_id']:
|
||||
language_id = bible[u'language_id']
|
||||
self.newbibles[number].create_meta(u'language_id',
|
||||
language_id)
|
||||
else:
|
||||
language_id = self.newbibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.exception(u'Upgrading from "%s" failed' % filename[0])
|
||||
delete_database(self.path,
|
||||
clean_filename(self.newbibles[number].get_name()))
|
||||
del self.newbibles[number]
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
continue
|
||||
self.progressBar.setMaximum(len(books))
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
break
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Upgrading %s ...')) %
|
||||
(number + 1, self.maxBibles, name, book))
|
||||
book_ref_id = self.newbibles[number].\
|
||||
get_book_ref_id_by_name(book, len(books), language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Upgrading books from %s - download '\
|
||||
u'name: "%s" aborted by user' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
delete_database(self.path,
|
||||
clean_filename(self.newbibles[number].get_name()))
|
||||
del self.newbibles[number]
|
||||
bible_failed = True
|
||||
break
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
self.newbibles[number].create_book(book, book_ref_id,
|
||||
book_details[u'testament_id'])
|
||||
else:
|
||||
language_id = self.newbibles[number].get_object(BibleMeta,
|
||||
u'language_id')
|
||||
if not language_id:
|
||||
language_id = self.newbibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.exception(u'Upgrading books from "%s" failed' % name)
|
||||
delete_database(self.path,
|
||||
clean_filename(self.newbibles[number].get_name()))
|
||||
del self.newbibles[number]
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
continue
|
||||
books = oldbible.get_books()
|
||||
self.progressBar.setMaximum(len(books))
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
break
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Upgrading %s ...')) %
|
||||
(number + 1, self.maxBibles, name, book[u'name']))
|
||||
book_ref_id = self.newbibles[number].\
|
||||
get_book_ref_id_by_name(book[u'name'], len(books),
|
||||
language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Upgrading books from %s " '\
|
||||
'failed - aborted by user' % name)
|
||||
delete_database(self.path,
|
||||
clean_filename(self.newbibles[number].get_name()))
|
||||
del self.newbibles[number]
|
||||
bible_failed = True
|
||||
break
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.newbibles[number].create_book(book[u'name'],
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
verses = oldbible.get_verses(book[u'id'])
|
||||
if not verses:
|
||||
log.exception(u'No verses found to import for book '
|
||||
u'"%s"', book[u'name'])
|
||||
self.newbibles[number].delete_book(db_book)
|
||||
continue
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
break
|
||||
self.newbibles[number].create_verse(db_book.id,
|
||||
int(verse[u'chapter']),
|
||||
int(verse[u'verse']), unicode(verse[u'text']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.newbibles[number].session.commit()
|
||||
if not bible_failed:
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Done')) %
|
||||
(number + 1, self.maxBibles, name))
|
||||
self.success[biblenumber] = True
|
||||
else:
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
delete_database(self.path,
|
||||
clean_filename(name))
|
||||
number += 1
|
||||
self.mediaItem.reloadBibles()
|
||||
successful_import = 0
|
||||
failed_import = 0
|
||||
for number, filename in enumerate(self.files):
|
||||
if number in self.success and self.success[number] == True:
|
||||
successful_import += 1
|
||||
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
failed_import += 1
|
||||
if failed_import > 0:
|
||||
failed_import_text = unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
', %s failed')) % failed_import
|
||||
else:
|
||||
failed_import_text = u''
|
||||
if successful_import > 0:
|
||||
if include_webbible:
|
||||
self.progressLabel.setText(unicode(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
|
||||
'Bible(s): %s successful%s\nPlease note, that verses from '
|
||||
'Web Bibles will be downloaded\non demand and so an '
|
||||
'Internet connection is required.')) %
|
||||
(successful_import, failed_import_text))
|
||||
else:
|
||||
self.progressLabel.setText(unicode(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
|
||||
'Bible(s): %s successful%s')) % (successful_import,
|
||||
failed_import_text))
|
||||
else:
|
||||
self.progressLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
|
||||
'failed.'))
|
114
openlp/plugins/bibles/forms/booknamedialog.py
Normal file
114
openlp/plugins/bibles/forms/booknamedialog.py
Normal file
@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, 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 #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
|
||||
class Ui_BookNameDialog(object):
|
||||
def setupUi(self, bookNameDialog):
|
||||
bookNameDialog.setObjectName(u'bookNameDialog')
|
||||
bookNameDialog.resize(400, 271)
|
||||
self.bookNameLayout = QtGui.QVBoxLayout(bookNameDialog)
|
||||
self.bookNameLayout.setSpacing(8)
|
||||
self.bookNameLayout.setMargin(8)
|
||||
self.bookNameLayout.setObjectName(u'bookNameLayout')
|
||||
self.infoLabel = QtGui.QLabel(bookNameDialog)
|
||||
self.infoLabel.setWordWrap(True)
|
||||
self.infoLabel.setObjectName(u'infoLabel')
|
||||
self.bookNameLayout.addWidget(self.infoLabel)
|
||||
self.correspondingLayout = QtGui.QGridLayout()
|
||||
self.correspondingLayout.setColumnStretch(1, 1)
|
||||
self.correspondingLayout.setSpacing(8)
|
||||
self.correspondingLayout.setObjectName(u'correspondingLayout')
|
||||
self.currentLabel = QtGui.QLabel(bookNameDialog)
|
||||
self.currentLabel.setObjectName(u'currentLabel')
|
||||
self.correspondingLayout.addWidget(self.currentLabel, 0, 0, 1, 1)
|
||||
self.currentBookLabel = QtGui.QLabel(bookNameDialog)
|
||||
self.currentBookLabel.setObjectName(u'currentBookLabel')
|
||||
self.correspondingLayout.addWidget(self.currentBookLabel, 0, 1, 1, 1)
|
||||
self.correspondingLabel = QtGui.QLabel(bookNameDialog)
|
||||
self.correspondingLabel.setObjectName(u'correspondingLabel')
|
||||
self.correspondingLayout.addWidget(
|
||||
self.correspondingLabel, 1, 0, 1, 1)
|
||||
self.correspondingComboBox = QtGui.QComboBox(bookNameDialog)
|
||||
self.correspondingComboBox.setObjectName(u'correspondingComboBox')
|
||||
self.correspondingLayout.addWidget(
|
||||
self.correspondingComboBox, 1, 1, 1, 1)
|
||||
self.bookNameLayout.addLayout(self.correspondingLayout)
|
||||
self.optionsGroupBox = QtGui.QGroupBox(bookNameDialog)
|
||||
self.optionsGroupBox.setObjectName(u'optionsGroupBox')
|
||||
self.optionsLayout = QtGui.QVBoxLayout(self.optionsGroupBox)
|
||||
self.optionsLayout.setSpacing(8)
|
||||
self.optionsLayout.setMargin(8)
|
||||
self.optionsLayout.setObjectName(u'optionsLayout')
|
||||
self.oldTestamentCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
|
||||
self.oldTestamentCheckBox.setObjectName(u'oldTestamentCheckBox')
|
||||
self.oldTestamentCheckBox.setCheckState(QtCore.Qt.Checked)
|
||||
self.optionsLayout.addWidget(self.oldTestamentCheckBox)
|
||||
self.newTestamentCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
|
||||
self.newTestamentCheckBox.setObjectName(u'newTestamentCheckBox')
|
||||
self.newTestamentCheckBox.setCheckState(QtCore.Qt.Checked)
|
||||
self.optionsLayout.addWidget(self.newTestamentCheckBox)
|
||||
self.apocryphaCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
|
||||
self.apocryphaCheckBox.setObjectName(u'apocryphaCheckBox')
|
||||
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Checked)
|
||||
self.optionsLayout.addWidget(self.apocryphaCheckBox)
|
||||
self.bookNameLayout.addWidget(self.optionsGroupBox)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(bookNameDialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(
|
||||
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.bookNameLayout.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(bookNameDialog)
|
||||
QtCore.QObject.connect(
|
||||
self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
bookNameDialog.accept)
|
||||
QtCore.QObject.connect(
|
||||
self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
bookNameDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(bookNameDialog)
|
||||
|
||||
def retranslateUi(self, bookNameDialog):
|
||||
bookNameDialog.setWindowTitle(translate('BiblesPlugin.BookNameDialog',
|
||||
'Select Book Name'))
|
||||
self.infoLabel.setText(translate('BiblesPlugin.BookNameDialog',
|
||||
'The following book name cannot be matched up internally. Please '
|
||||
'select the corresponding English name from the list.'))
|
||||
self.currentLabel.setText(translate('BiblesPlugin.BookNameDialog',
|
||||
'Current name:'))
|
||||
self.correspondingLabel.setText(translate(
|
||||
'BiblesPlugin.BookNameDialog', 'Corresponding name:'))
|
||||
self.optionsGroupBox.setTitle(translate('BiblesPlugin.BookNameDialog',
|
||||
'Show Books From'))
|
||||
self.oldTestamentCheckBox.setText(translate(
|
||||
'BiblesPlugin.BookNameDialog', 'Old Testament'))
|
||||
self.newTestamentCheckBox.setText(translate(
|
||||
'BiblesPlugin.BookNameDialog', 'New Testament'))
|
||||
self.apocryphaCheckBox.setText(translate('BiblesPlugin.BookNameDialog',
|
||||
'Apocrypha'))
|
123
openlp/plugins/bibles/forms/booknameform.py
Normal file
123
openlp/plugins/bibles/forms/booknameform.py
Normal file
@ -0,0 +1,123 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, 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 #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
Module implementing BookNameForm.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4.QtGui import QDialog
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.forms.booknamedialog import \
|
||||
Ui_BookNameDialog
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class BookNameForm(QDialog, Ui_BookNameDialog):
|
||||
"""
|
||||
Class to manage a dialog which help the user to refer a book name a
|
||||
to a english book name
|
||||
"""
|
||||
log.info(u'BookNameForm loaded')
|
||||
|
||||
def __init__(self, parent = None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.customSignals()
|
||||
|
||||
def customSignals(self):
|
||||
"""
|
||||
Set up the signals used in the booknameform.
|
||||
"""
|
||||
QtCore.QObject.connect(self.oldTestamentCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onCheckBoxIndexChanged)
|
||||
QtCore.QObject.connect(self.newTestamentCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onCheckBoxIndexChanged)
|
||||
QtCore.QObject.connect(self.apocryphaCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onCheckBoxIndexChanged)
|
||||
|
||||
def onCheckBoxIndexChanged(self, index):
|
||||
'''
|
||||
Reload Combobox if CheckBox state has changed
|
||||
'''
|
||||
self.reloadComboBox()
|
||||
|
||||
def reloadComboBox(self):
|
||||
'''
|
||||
Reload the Combobox items
|
||||
'''
|
||||
self.correspondingComboBox.clear()
|
||||
items = BiblesResourcesDB.get_books()
|
||||
for item in items:
|
||||
addBook = True
|
||||
for book in self.books:
|
||||
if book.book_reference_id == item[u'id']:
|
||||
addBook = False
|
||||
break
|
||||
if self.oldTestamentCheckBox.checkState() == QtCore.Qt.Unchecked \
|
||||
and item[u'testament_id'] == 1:
|
||||
addBook = False
|
||||
elif self.newTestamentCheckBox.checkState() == QtCore.Qt.Unchecked \
|
||||
and item[u'testament_id'] == 2:
|
||||
addBook = False
|
||||
elif self.apocryphaCheckBox.checkState() == QtCore.Qt.Unchecked \
|
||||
and item[u'testament_id'] == 3:
|
||||
addBook = False
|
||||
if addBook:
|
||||
self.correspondingComboBox.addItem(item[u'name'])
|
||||
|
||||
def exec_(self, name, books, maxbooks):
|
||||
self.books = books
|
||||
log.debug(maxbooks)
|
||||
if maxbooks <= 27:
|
||||
self.oldTestamentCheckBox.setCheckState(QtCore.Qt.Unchecked)
|
||||
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Unchecked)
|
||||
elif maxbooks <= 66:
|
||||
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Unchecked)
|
||||
self.reloadComboBox()
|
||||
self.currentBookLabel.setText(unicode(name))
|
||||
self.correspondingComboBox.setFocus()
|
||||
return QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
if self.correspondingComboBox.currentText() == u'':
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.BookNameForm',
|
||||
'You need to select a book.'))
|
||||
self.correspondingComboBox.setFocus()
|
||||
return False
|
||||
else:
|
||||
return QDialog.accept(self)
|
84
openlp/plugins/bibles/forms/languagedialog.py
Normal file
84
openlp/plugins/bibles/forms/languagedialog.py
Normal file
@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, 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 #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
|
||||
class Ui_LanguageDialog(object):
|
||||
def setupUi(self, languageDialog):
|
||||
languageDialog.setObjectName(u'languageDialog')
|
||||
languageDialog.resize(400, 165)
|
||||
self.languageLayout = QtGui.QVBoxLayout(languageDialog)
|
||||
self.languageLayout.setSpacing(8)
|
||||
self.languageLayout.setMargin(8)
|
||||
self.languageLayout.setObjectName(u'languageLayout')
|
||||
self.bibleLabel = QtGui.QLabel(languageDialog)
|
||||
self.bibleLabel.setObjectName(u'bibleLabel')
|
||||
self.languageLayout.addWidget(self.bibleLabel)
|
||||
self.infoLabel = QtGui.QLabel(languageDialog)
|
||||
self.infoLabel.setWordWrap(True)
|
||||
self.infoLabel.setObjectName(u'infoLabel')
|
||||
self.languageLayout.addWidget(self.infoLabel)
|
||||
self.languageHBoxLayout = QtGui.QHBoxLayout()
|
||||
self.languageHBoxLayout.setSpacing(8)
|
||||
self.languageHBoxLayout.setObjectName(u'languageHBoxLayout')
|
||||
self.languageLabel = QtGui.QLabel(languageDialog)
|
||||
self.languageLabel.setObjectName(u'languageLabel')
|
||||
self.languageHBoxLayout.addWidget(self.languageLabel)
|
||||
self.languageComboBox = QtGui.QComboBox(languageDialog)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding,
|
||||
QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(
|
||||
self.languageComboBox.sizePolicy().hasHeightForWidth())
|
||||
self.languageComboBox.setSizePolicy(sizePolicy)
|
||||
self.languageComboBox.setObjectName(u'languageComboBox')
|
||||
self.languageHBoxLayout.addWidget(self.languageComboBox)
|
||||
self.languageLayout.addLayout(self.languageHBoxLayout)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(languageDialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
|
||||
QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.languageLayout.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(languageDialog)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
languageDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
languageDialog.reject)
|
||||
|
||||
def retranslateUi(self, languageDialog):
|
||||
languageDialog.setWindowTitle(
|
||||
translate('BiblesPlugin.LanguageDialog', 'Select Language'))
|
||||
self.bibleLabel.setText(translate('BiblesPlugin.LanguageDialog', ''))
|
||||
self.infoLabel.setText(translate('BiblesPlugin.LanguageDialog',
|
||||
'OpenLP is unable to determine the language of this translation '
|
||||
'of the Bible. Please select the language from the list below.'))
|
||||
self.languageLabel.setText(translate('BiblesPlugin.LanguageDialog',
|
||||
'Language:'))
|
72
openlp/plugins/bibles/forms/languageform.py
Normal file
72
openlp/plugins/bibles/forms/languageform.py
Normal file
@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
|
||||
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
|
||||
# Tibble, Carsten Tinggaard, 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 #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
Module implementing LanguageForm.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4.QtGui import QDialog
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.forms.languagedialog import \
|
||||
Ui_LanguageDialog
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class LanguageForm(QDialog, Ui_LanguageDialog):
|
||||
"""
|
||||
Class to manage a dialog which ask the user for a language.
|
||||
"""
|
||||
log.info(u'LanguageForm loaded')
|
||||
|
||||
def __init__(self, parent = None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
def exec_(self, bible_name):
|
||||
self.languageComboBox.addItem(u'')
|
||||
if bible_name:
|
||||
self.bibleLabel.setText(unicode(bible_name))
|
||||
items = BiblesResourcesDB.get_languages()
|
||||
for item in items:
|
||||
self.languageComboBox.addItem(item[u'name'])
|
||||
return QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
if self.languageComboBox.currentText() == u'':
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.LanguageForm',
|
||||
'You need to choose a language.'))
|
||||
self.languageComboBox.setFocus()
|
||||
return False
|
||||
else:
|
||||
return QDialog.accept(self)
|
@ -71,7 +71,7 @@ import chardet
|
||||
import csv
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, Testament
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -79,6 +79,8 @@ class CSVBible(BibleDB):
|
||||
"""
|
||||
This class provides a specialisation for importing of CSV Bibles.
|
||||
"""
|
||||
log.info(u'CSVBible loaded')
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
Loads a Bible from a set of CVS files.
|
||||
@ -87,48 +89,10 @@ class CSVBible(BibleDB):
|
||||
"""
|
||||
log.info(self.__class__.__name__)
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
try:
|
||||
self.testamentsfile = kwargs[u'testamentsfile']
|
||||
except KeyError:
|
||||
self.testamentsfile = None
|
||||
self.booksfile = kwargs[u'booksfile']
|
||||
self.versesfile = kwargs[u'versefile']
|
||||
|
||||
def setup_testaments(self):
|
||||
"""
|
||||
Overrides parent method so we can handle importing a testament file.
|
||||
"""
|
||||
if self.testamentsfile:
|
||||
self.wizard.progressBar.setMinimum(0)
|
||||
self.wizard.progressBar.setMaximum(2)
|
||||
self.wizard.progressBar.setValue(0)
|
||||
testaments_file = None
|
||||
try:
|
||||
details = get_file_encoding(self.testamentsfile)
|
||||
testaments_file = open(self.testamentsfile, 'rb')
|
||||
testaments_reader = csv.reader(testaments_file, delimiter=',',
|
||||
quotechar='"')
|
||||
for line in testaments_reader:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.incrementProgressBar(unicode(
|
||||
translate('BibleDB.Wizard',
|
||||
'Importing testaments... %s')) %
|
||||
unicode(line[1], details['encoding']), 0)
|
||||
self.save_object(Testament.populate(
|
||||
name=unicode(line[1], details['encoding'])))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
except (IOError, IndexError):
|
||||
log.exception(u'Loading testaments from file failed')
|
||||
finally:
|
||||
if testaments_file:
|
||||
testaments_file.close()
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BibleDB.Wizard', 'Importing testaments... done.')), 2)
|
||||
else:
|
||||
BibleDB.setup_testaments(self)
|
||||
|
||||
def do_import(self):
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Import the bible books and verses.
|
||||
"""
|
||||
@ -136,6 +100,10 @@ class CSVBible(BibleDB):
|
||||
self.wizard.progressBar.setMinimum(0)
|
||||
self.wizard.progressBar.setMaximum(66)
|
||||
success = True
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from "%s" failed' % self.filename)
|
||||
return False
|
||||
books_file = None
|
||||
book_list = {}
|
||||
# Populate the Tables
|
||||
@ -149,8 +117,15 @@ class CSVBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(unicode(
|
||||
translate('BibleDB.Wizard', 'Importing books... %s')) %
|
||||
unicode(line[2], details['encoding']))
|
||||
book_ref_id = self.get_book_ref_id_by_name(
|
||||
unicode(line[2], details['encoding']), 67, language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.booksfile)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
self.create_book(unicode(line[2], details['encoding']),
|
||||
unicode(line[3], details['encoding']), int(line[1]))
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
book_list[int(line[0])] = unicode(line[2], details['encoding'])
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
except (IOError, IndexError):
|
||||
|
@ -27,16 +27,19 @@
|
||||
|
||||
import logging
|
||||
import chardet
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from sqlalchemy import Column, ForeignKey, or_, Table, types
|
||||
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import Receiver, translate, check_directory_exists
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -47,13 +50,6 @@ class BibleMeta(BaseModel):
|
||||
pass
|
||||
|
||||
|
||||
class Testament(BaseModel):
|
||||
"""
|
||||
Bible Testaments
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Book(BaseModel):
|
||||
"""
|
||||
Song model
|
||||
@ -67,6 +63,18 @@ class Verse(BaseModel):
|
||||
"""
|
||||
pass
|
||||
|
||||
def clean_filename(filename):
|
||||
"""
|
||||
Clean up the version name of the Bible and convert it into a valid
|
||||
file name.
|
||||
|
||||
``filename``
|
||||
The "dirty" file name or version name.
|
||||
"""
|
||||
if not isinstance(filename, unicode):
|
||||
filename = unicode(filename, u'utf-8')
|
||||
filename = re.sub(r'[^\w]+', u'_', filename).strip(u'_')
|
||||
return filename + u'.sqlite'
|
||||
|
||||
def init_schema(url):
|
||||
"""
|
||||
@ -81,19 +89,17 @@ def init_schema(url):
|
||||
Column(u'key', types.Unicode(255), primary_key=True, index=True),
|
||||
Column(u'value', types.Unicode(255)),
|
||||
)
|
||||
testament_table = Table(u'testament', metadata,
|
||||
Column(u'id', types.Integer, primary_key=True),
|
||||
Column(u'name', types.Unicode(50)),
|
||||
)
|
||||
|
||||
book_table = Table(u'book', metadata,
|
||||
Column(u'id', types.Integer, primary_key=True),
|
||||
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
|
||||
Column(u'book_reference_id', types.Integer, index=True),
|
||||
Column(u'testament_reference_id', types.Integer),
|
||||
Column(u'name', types.Unicode(50), index=True),
|
||||
Column(u'abbreviation', types.Unicode(5), index=True),
|
||||
)
|
||||
verse_table = Table(u'verse', metadata,
|
||||
Column(u'id', types.Integer, primary_key=True, index=True),
|
||||
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
|
||||
Column(u'book_id', types.Integer, ForeignKey(
|
||||
u'book.id'), index=True),
|
||||
Column(u'chapter', types.Integer, index=True),
|
||||
Column(u'verse', types.Integer, index=True),
|
||||
Column(u'text', types.UnicodeText, index=True),
|
||||
@ -103,11 +109,6 @@ def init_schema(url):
|
||||
class_mapper(BibleMeta)
|
||||
except UnmappedClassError:
|
||||
mapper(BibleMeta, meta_table)
|
||||
try:
|
||||
class_mapper(Testament)
|
||||
except UnmappedClassError:
|
||||
mapper(Testament, testament_table,
|
||||
properties={'books': relation(Book, backref='testament')})
|
||||
try:
|
||||
class_mapper(Book)
|
||||
except UnmappedClassError:
|
||||
@ -129,6 +130,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
methods, but benefit from the database methods in here via inheritance,
|
||||
rather than depending on yet another object.
|
||||
"""
|
||||
log.info(u'BibleDB loaded')
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
@ -156,12 +158,14 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
self.name = kwargs[u'name']
|
||||
if not isinstance(self.name, unicode):
|
||||
self.name = unicode(self.name, u'utf-8')
|
||||
self.file = self.clean_filename(self.name)
|
||||
self.file = clean_filename(self.name)
|
||||
if u'file' in kwargs:
|
||||
self.file = kwargs[u'file']
|
||||
Manager.__init__(self, u'bibles', init_schema, self.file)
|
||||
if u'file' in kwargs:
|
||||
self.get_name()
|
||||
if u'path' in kwargs:
|
||||
self.path = kwargs[u'path']
|
||||
self.wizard = None
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
||||
@ -181,19 +185,6 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
self.name = version_name.value if version_name else None
|
||||
return self.name
|
||||
|
||||
def clean_filename(self, old_filename):
|
||||
"""
|
||||
Clean up the version name of the Bible and convert it into a valid
|
||||
file name.
|
||||
|
||||
``old_filename``
|
||||
The "dirty" file name or version name.
|
||||
"""
|
||||
if not isinstance(old_filename, unicode):
|
||||
old_filename = unicode(old_filename, u'utf-8')
|
||||
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
|
||||
return old_filename + u'.sqlite'
|
||||
|
||||
def register(self, wizard):
|
||||
"""
|
||||
This method basically just initialialises the database. It is called
|
||||
@ -206,36 +197,40 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
self.wizard = wizard
|
||||
self.create_meta(u'dbversion', u'2')
|
||||
self.setup_testaments()
|
||||
return self.name
|
||||
|
||||
def setup_testaments(self):
|
||||
"""
|
||||
Initialise the testaments section of a bible with suitable defaults.
|
||||
"""
|
||||
self.save_object(Testament.populate(name=u'Old Testament'))
|
||||
self.save_object(Testament.populate(name=u'New Testament'))
|
||||
self.save_object(Testament.populate(name=u'Apocrypha'))
|
||||
|
||||
def create_book(self, name, abbrev, testament=1):
|
||||
def create_book(self, name, bk_ref_id, testament=1):
|
||||
"""
|
||||
Add a book to the database.
|
||||
|
||||
``name``
|
||||
The name of the book.
|
||||
|
||||
``abbrev``
|
||||
The abbreviation of the book.
|
||||
``bk_ref_id``
|
||||
The book_reference_id from bibles_resources.sqlite of the book.
|
||||
|
||||
``testament``
|
||||
*Defaults to 1.* The id of the testament this book belongs to.
|
||||
*Defaults to 1.* The testament_reference_id from
|
||||
bibles_resources.sqlite of the testament this book belongs to.
|
||||
"""
|
||||
log.debug(u'create_book %s,%s', name, abbrev)
|
||||
book = Book.populate(name=name, abbreviation=abbrev,
|
||||
testament_id=testament)
|
||||
log.debug(u'BibleDB.create_book("%s", "%s")', name, bk_ref_id)
|
||||
book = Book.populate(name=name, book_reference_id=bk_ref_id,
|
||||
testament_reference_id=testament)
|
||||
self.save_object(book)
|
||||
return book
|
||||
|
||||
def delete_book(self, db_book):
|
||||
"""
|
||||
Delete a book from the database.
|
||||
|
||||
``db_book``
|
||||
The book object.
|
||||
"""
|
||||
log.debug(u'BibleDB.delete_book("%s")', db_book.name)
|
||||
if self.delete_object(Book, db_book.id):
|
||||
return True
|
||||
return False
|
||||
|
||||
def create_chapter(self, book_id, chapter, textlist):
|
||||
"""
|
||||
Add a chapter and its verses to a book.
|
||||
@ -250,7 +245,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
A dict of the verses to be inserted. The key is the verse number,
|
||||
and the value is the verse text.
|
||||
"""
|
||||
log.debug(u'create_chapter %s,%s', book_id, chapter)
|
||||
log.debug(u'BibleDBcreate_chapter("%s", "%s")', book_id, chapter)
|
||||
# Text list has book and chapter as first two elements of the array.
|
||||
for verse_number, verse_text in textlist.iteritems():
|
||||
verse = Verse.populate(
|
||||
@ -300,7 +295,9 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
``value``
|
||||
The value for this instance.
|
||||
"""
|
||||
log.debug(u'save_meta %s/%s', key, value)
|
||||
if not isinstance(value, unicode):
|
||||
value = unicode(value)
|
||||
log.debug(u'BibleDB.save_meta("%s/%s")', key, value)
|
||||
self.save_object(BibleMeta.populate(key=key, value=value))
|
||||
|
||||
def get_book(self, book):
|
||||
@ -310,20 +307,60 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
``book``
|
||||
The name of the book to return.
|
||||
"""
|
||||
log.debug(u'BibleDb.get_book("%s")', book)
|
||||
db_book = self.get_object_filtered(Book, Book.name.like(book + u'%'))
|
||||
if db_book is None:
|
||||
db_book = self.get_object_filtered(Book,
|
||||
Book.abbreviation.like(book + u'%'))
|
||||
return db_book
|
||||
log.debug(u'BibleDB.get_book("%s")', book)
|
||||
return self.get_object_filtered(Book, Book.name.like(book + u'%'))
|
||||
|
||||
def get_books(self):
|
||||
"""
|
||||
A wrapper so both local and web bibles have a get_books() method that
|
||||
manager can call. Used in the media manager advanced search tab.
|
||||
"""
|
||||
log.debug(u'BibleDB.get_books()')
|
||||
return self.get_all_objects(Book, order_by_ref=Book.id)
|
||||
|
||||
def get_book_by_book_ref_id(self, id):
|
||||
"""
|
||||
Return a book object from the database.
|
||||
|
||||
``id``
|
||||
The reference id of the book to return.
|
||||
"""
|
||||
log.debug(u'BibleDB.get_book_by_book_ref_id("%s")', id)
|
||||
return self.get_object_filtered(Book, Book.book_reference_id.like(id))
|
||||
|
||||
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
||||
log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book,
|
||||
language_id)
|
||||
if BiblesResourcesDB.get_book(book, True):
|
||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||
book_id = book_temp[u'id']
|
||||
elif BiblesResourcesDB.get_alternative_book_name(book):
|
||||
book_id = BiblesResourcesDB.get_alternative_book_name(book)
|
||||
elif AlternativeBookNamesDB.get_book_reference_id(book):
|
||||
book_id = AlternativeBookNamesDB.get_book_reference_id(book)
|
||||
else:
|
||||
from openlp.plugins.bibles.forms import BookNameForm
|
||||
book_ref = None
|
||||
book_name = BookNameForm(self.wizard)
|
||||
if book_name.exec_(book, self.get_books(), maxbooks):
|
||||
book_ref = unicode(
|
||||
book_name.correspondingComboBox.currentText())
|
||||
if not book_ref:
|
||||
return None
|
||||
else:
|
||||
book_temp = BiblesResourcesDB.get_book(book_ref)
|
||||
if book_temp:
|
||||
book_id = book_temp[u'id']
|
||||
else:
|
||||
return None
|
||||
if book_id:
|
||||
AlternativeBookNamesDB.create_alternative_book_name(
|
||||
book, book_id, language_id)
|
||||
if book_id:
|
||||
return book_id
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_verses(self, reference_list, show_error=True):
|
||||
"""
|
||||
This is probably the most used function. It retrieves the list of
|
||||
@ -333,24 +370,24 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
This is the list of references the media manager item wants. It is
|
||||
a list of tuples, with the following format::
|
||||
|
||||
(book, chapter, start_verse, end_verse)
|
||||
(book_reference_id, chapter, start_verse, end_verse)
|
||||
|
||||
Therefore, when you are looking for multiple items, simply break
|
||||
them up into references like this, bundle them into a list. This
|
||||
function then runs through the list, and returns an amalgamated
|
||||
list of ``Verse`` objects. For example::
|
||||
|
||||
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
|
||||
[(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
|
||||
"""
|
||||
log.debug(u'BibleDB.get_verses: %s', reference_list)
|
||||
log.debug(u'BibleDB.get_verses("%s")', reference_list)
|
||||
verse_list = []
|
||||
for book, chapter, start_verse, end_verse in reference_list:
|
||||
db_book = self.get_book(book)
|
||||
for book_id, chapter, start_verse, end_verse in reference_list:
|
||||
db_book = self.get_book_by_book_ref_id(book_id)
|
||||
if db_book:
|
||||
book = db_book.name
|
||||
log.debug(u'Book name corrected to "%s"', book)
|
||||
book_id = db_book.book_reference_id
|
||||
log.debug(u'Book name corrected to "%s"', db_book.name)
|
||||
if end_verse == -1:
|
||||
end_verse = self.get_verse_count(book, chapter)
|
||||
end_verse = self.get_verse_count(book_id, chapter)
|
||||
verses = self.session.query(Verse)\
|
||||
.filter_by(book_id=db_book.id)\
|
||||
.filter_by(chapter=chapter)\
|
||||
@ -360,7 +397,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
.all()
|
||||
verse_list.extend(verses)
|
||||
else:
|
||||
log.debug(u'OpenLP failed to find book %s', book)
|
||||
log.debug(u'OpenLP failed to find book with id "%s"', book_id)
|
||||
if show_error:
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
@ -399,18 +436,18 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
Return the number of chapters in a book.
|
||||
|
||||
``book``
|
||||
The book to get the chapter count for.
|
||||
The book object to get the chapter count for.
|
||||
"""
|
||||
log.debug(u'BibleDB.get_chapter_count("%s")', book)
|
||||
log.debug(u'BibleDB.get_chapter_count("%s")', book.name)
|
||||
count = self.session.query(Verse.chapter).join(Book)\
|
||||
.filter(Book.name == book)\
|
||||
.filter(Book.book_reference_id==book.book_reference_id)\
|
||||
.distinct().count()
|
||||
if not count:
|
||||
return 0
|
||||
else:
|
||||
return count
|
||||
|
||||
def get_verse_count(self, book, chapter):
|
||||
def get_verse_count(self, book_id, chapter):
|
||||
"""
|
||||
Return the number of verses in a chapter.
|
||||
|
||||
@ -420,16 +457,49 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
``chapter``
|
||||
The chapter to get the verse count for.
|
||||
"""
|
||||
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
|
||||
log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_id, chapter)
|
||||
count = self.session.query(Verse).join(Book)\
|
||||
.filter(Book.name == book)\
|
||||
.filter(Verse.chapter == chapter)\
|
||||
.filter(Book.book_reference_id==book_id)\
|
||||
.filter(Verse.chapter==chapter)\
|
||||
.count()
|
||||
if not count:
|
||||
return 0
|
||||
else:
|
||||
return count
|
||||
|
||||
def get_language(self, bible_name=None):
|
||||
"""
|
||||
If no language is given it calls a dialog window where the user could
|
||||
select the bible language.
|
||||
Return the language id of a bible.
|
||||
|
||||
``book``
|
||||
The language the bible is.
|
||||
"""
|
||||
log.debug(u'BibleDB.get_language()')
|
||||
from openlp.plugins.bibles.forms import LanguageForm
|
||||
language = None
|
||||
language_form = LanguageForm(self.wizard)
|
||||
if language_form.exec_(bible_name):
|
||||
language = unicode(language_form.languageComboBox.currentText())
|
||||
if not language:
|
||||
return False
|
||||
language = BiblesResourcesDB.get_language(language)
|
||||
language_id = language[u'id']
|
||||
self.create_meta(u'language_id', language_id)
|
||||
return language_id
|
||||
|
||||
def is_old_database(self):
|
||||
"""
|
||||
Returns ``True`` if it is a bible database, which has been created
|
||||
prior to 1.9.6.
|
||||
"""
|
||||
try:
|
||||
columns = self.session.query(Book).all()
|
||||
except:
|
||||
return True
|
||||
return False
|
||||
|
||||
def dump_bible(self):
|
||||
"""
|
||||
Utility debugging method to dump the contents of a bible.
|
||||
@ -441,3 +511,569 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
log.debug(u'...............................Verses ')
|
||||
verses = self.session.query(Verse).all()
|
||||
log.debug(verses)
|
||||
|
||||
|
||||
class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
This class represents the database-bound Bible Resources. It provide
|
||||
some resources which are used in the Bibles plugin.
|
||||
A wrapper class around a small SQLite database which contains the download
|
||||
resources, a biblelist from the different download resources, the books,
|
||||
chapter counts and verse counts for the web download Bibles, a language
|
||||
reference, the testament reference and some alternative book names. This
|
||||
class contains a singleton "cursor" so that only one connection to the
|
||||
SQLite database is ever used.
|
||||
"""
|
||||
cursor = None
|
||||
|
||||
@staticmethod
|
||||
def get_cursor():
|
||||
"""
|
||||
Return the cursor object. Instantiate one if it doesn't exist yet.
|
||||
"""
|
||||
if BiblesResourcesDB.cursor is None:
|
||||
filepath = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
|
||||
u'resources', u'bibles_resources.sqlite')
|
||||
conn = sqlite3.connect(filepath)
|
||||
BiblesResourcesDB.cursor = conn.cursor()
|
||||
return BiblesResourcesDB.cursor
|
||||
|
||||
@staticmethod
|
||||
def run_sql(query, parameters=()):
|
||||
"""
|
||||
Run an SQL query on the database, returning the results.
|
||||
|
||||
``query``
|
||||
The actual SQL query to run.
|
||||
|
||||
``parameters``
|
||||
Any variable parameters to add to the query.
|
||||
"""
|
||||
cursor = BiblesResourcesDB.get_cursor()
|
||||
cursor.execute(query, parameters)
|
||||
return cursor.fetchall()
|
||||
|
||||
@staticmethod
|
||||
def get_books():
|
||||
"""
|
||||
Return a list of all the books of the Bible.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_books()')
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM book_reference ORDER BY id')
|
||||
return [
|
||||
{
|
||||
u'id': book[0],
|
||||
u'testament_id': book[1],
|
||||
u'name': unicode(book[2]),
|
||||
u'abbreviation': unicode(book[3]),
|
||||
u'chapters': book[4]
|
||||
}
|
||||
for book in books
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_book(name, lower=False):
|
||||
"""
|
||||
Return a book by name or abbreviation.
|
||||
|
||||
``name``
|
||||
The name or abbreviation of the book.
|
||||
|
||||
``lower``
|
||||
True if the comparsion should be only lowercase
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_book("%s")', name)
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name)
|
||||
if lower:
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM book_reference WHERE '
|
||||
u'LOWER(name) = ? OR LOWER(abbreviation) = ?',
|
||||
(name.lower(), name.lower()))
|
||||
else:
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM book_reference WHERE name = ?'
|
||||
u' OR abbreviation = ?', (name, name))
|
||||
if books:
|
||||
return {
|
||||
u'id': books[0][0],
|
||||
u'testament_id': books[0][1],
|
||||
u'name': unicode(books[0][2]),
|
||||
u'abbreviation': unicode(books[0][3]),
|
||||
u'chapters': books[0][4]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_book_by_id(id):
|
||||
"""
|
||||
Return a book by id.
|
||||
|
||||
``id``
|
||||
The id of the book.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_book_by_id("%s")', id)
|
||||
if not isinstance(id, int):
|
||||
id = int(id)
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM book_reference WHERE id = ?',
|
||||
(id, ))
|
||||
if books:
|
||||
return {
|
||||
u'id': books[0][0],
|
||||
u'testament_id': books[0][1],
|
||||
u'name': unicode(books[0][2]),
|
||||
u'abbreviation': unicode(books[0][3]),
|
||||
u'chapters': books[0][4]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_chapter(book_id, chapter):
|
||||
"""
|
||||
Return the chapter details for a specific chapter of a book.
|
||||
|
||||
``book_id``
|
||||
The id of a book.
|
||||
|
||||
``chapter``
|
||||
The chapter number.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id,
|
||||
chapter)
|
||||
if not isinstance(chapter, int):
|
||||
chapter = int(chapter)
|
||||
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
|
||||
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
|
||||
(book_id,))
|
||||
if chapters:
|
||||
return {
|
||||
u'id': chapters[chapter-1][0],
|
||||
u'book_reference_id': chapters[chapter-1][1],
|
||||
u'chapter': chapters[chapter-1][2],
|
||||
u'verse_count': chapters[chapter-1][3]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_chapter_count(book_id):
|
||||
"""
|
||||
Return the number of chapters in a book.
|
||||
|
||||
``book_id``
|
||||
The id of the book.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_id)
|
||||
details = BiblesResourcesDB.get_book_by_id(book_id)
|
||||
if details:
|
||||
return details[u'chapters']
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def get_verse_count(book_id, chapter):
|
||||
"""
|
||||
Return the number of verses in a chapter.
|
||||
|
||||
``book``
|
||||
The id of the book.
|
||||
|
||||
``chapter``
|
||||
The number of the chapter.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,
|
||||
chapter)
|
||||
details = BiblesResourcesDB.get_chapter(book_id, chapter)
|
||||
if details:
|
||||
return details[u'verse_count']
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def get_download_source(source):
|
||||
"""
|
||||
Return a download_source_id by source.
|
||||
|
||||
``name``
|
||||
The name or abbreviation of the book.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_download_source("%s")', source)
|
||||
if not isinstance(source, unicode):
|
||||
source = unicode(source)
|
||||
source = source.title()
|
||||
dl_source = BiblesResourcesDB.run_sql(u'SELECT id, source FROM '
|
||||
u'download_source WHERE source = ?', (source.lower(),))
|
||||
if dl_source:
|
||||
return {
|
||||
u'id': dl_source[0][0],
|
||||
u'source': dl_source[0][1]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_webbibles(source):
|
||||
"""
|
||||
Return the bibles a webbible provide for download.
|
||||
|
||||
``source``
|
||||
The source of the webbible.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_webbibles("%s")', source)
|
||||
if not isinstance(source, unicode):
|
||||
source = unicode(source)
|
||||
source = BiblesResourcesDB.get_download_source(source)
|
||||
bibles = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
|
||||
u'language_id, download_source_id FROM webbibles WHERE '
|
||||
u'download_source_id = ?', (source[u'id'],))
|
||||
if bibles:
|
||||
return [
|
||||
{
|
||||
u'id': bible[0],
|
||||
u'name': bible[1],
|
||||
u'abbreviation': bible[2],
|
||||
u'language_id': bible[3],
|
||||
u'download_source_id': bible[4]
|
||||
}
|
||||
for bible in bibles
|
||||
]
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_webbible(abbreviation, source):
|
||||
"""
|
||||
Return the bibles a webbible provide for download.
|
||||
|
||||
``abbreviation``
|
||||
The abbreviation of the webbible.
|
||||
|
||||
``source``
|
||||
The source of the webbible.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation,
|
||||
source)
|
||||
if not isinstance(abbreviation, unicode):
|
||||
abbreviation = unicode(abbreviation)
|
||||
if not isinstance(source, unicode):
|
||||
source = unicode(source)
|
||||
source = BiblesResourcesDB.get_download_source(source)
|
||||
bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
|
||||
u'language_id, download_source_id FROM webbibles WHERE '
|
||||
u'download_source_id = ? AND abbreviation = ?', (source[u'id'],
|
||||
abbreviation))
|
||||
if bible:
|
||||
return {
|
||||
u'id': bible[0][0],
|
||||
u'name': bible[0][1],
|
||||
u'abbreviation': bible[0][2],
|
||||
u'language_id': bible[0][3],
|
||||
u'download_source_id': bible[0][4]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_alternative_book_name(name, language_id=None):
|
||||
"""
|
||||
Return a book_reference_id if the name matches.
|
||||
|
||||
``name``
|
||||
The name to search the id.
|
||||
|
||||
``language_id``
|
||||
The language_id for which language should be searched
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_alternative_book_name("%s", "%s")',
|
||||
name, language_id)
|
||||
if language_id:
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
|
||||
u'FROM alternative_book_names WHERE language_id = ? ORDER BY '
|
||||
u'id', (language_id, ))
|
||||
else:
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
|
||||
u'FROM alternative_book_names ORDER BY id')
|
||||
for book in books:
|
||||
if book[1].lower() == name.lower():
|
||||
return book[0]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_language(name):
|
||||
"""
|
||||
Return a dict containing the language id, name and code by name or
|
||||
abbreviation.
|
||||
|
||||
``name``
|
||||
The name or abbreviation of the language.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_language("%s")', name)
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name)
|
||||
language = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
|
||||
u'language WHERE name = ? OR code = ?', (name, name.lower()))
|
||||
if language:
|
||||
return {
|
||||
u'id': language[0][0],
|
||||
u'name': unicode(language[0][1]),
|
||||
u'code': unicode(language[0][2])
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_languages():
|
||||
"""
|
||||
Return a dict containing all languages with id, name and code.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_languages()')
|
||||
languages = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
|
||||
u'language ORDER by name')
|
||||
if languages:
|
||||
return [
|
||||
{
|
||||
u'id': language[0],
|
||||
u'name': unicode(language[1]),
|
||||
u'code': unicode(language[2])
|
||||
}
|
||||
for language in languages
|
||||
]
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_testament_reference():
|
||||
"""
|
||||
Return a list of all testaments and their id of the Bible.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_testament_reference()')
|
||||
testaments = BiblesResourcesDB.run_sql(u'SELECT id, name FROM '
|
||||
u'testament_reference ORDER BY id')
|
||||
return [
|
||||
{
|
||||
u'id': testament[0],
|
||||
u'name': unicode(testament[1])
|
||||
}
|
||||
for testament in testaments
|
||||
]
|
||||
|
||||
|
||||
class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
This class represents a database-bound alternative book names system.
|
||||
"""
|
||||
cursor = None
|
||||
conn = None
|
||||
|
||||
@staticmethod
|
||||
def get_cursor():
|
||||
"""
|
||||
Return the cursor object. Instantiate one if it doesn't exist yet.
|
||||
If necessary loads up the database and creates the tables if the
|
||||
database doesn't exist.
|
||||
"""
|
||||
if AlternativeBookNamesDB.cursor is None:
|
||||
filepath = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.DataDir), u'bibles',
|
||||
u'alternative_book_names.sqlite')
|
||||
if not os.path.exists(filepath):
|
||||
#create new DB, create table alternative_book_names
|
||||
AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
|
||||
AlternativeBookNamesDB.conn.execute(u'CREATE TABLE '
|
||||
u'alternative_book_names(id INTEGER NOT NULL, '
|
||||
u'book_reference_id INTEGER, language_id INTEGER, name '
|
||||
u'VARCHAR(50), PRIMARY KEY (id))')
|
||||
else:
|
||||
#use existing DB
|
||||
AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
|
||||
AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
|
||||
return AlternativeBookNamesDB.cursor
|
||||
|
||||
@staticmethod
|
||||
def run_sql(query, parameters=(), commit=None):
|
||||
"""
|
||||
Run an SQL query on the database, returning the results.
|
||||
|
||||
``query``
|
||||
The actual SQL query to run.
|
||||
|
||||
``parameters``
|
||||
Any variable parameters to add to the query
|
||||
|
||||
``commit``
|
||||
If a commit statement is necessary this should be True.
|
||||
"""
|
||||
cursor = AlternativeBookNamesDB.get_cursor()
|
||||
cursor.execute(query, parameters)
|
||||
if commit:
|
||||
AlternativeBookNamesDB.conn.commit()
|
||||
return cursor.fetchall()
|
||||
|
||||
@staticmethod
|
||||
def get_book_reference_id(name, language_id=None):
|
||||
"""
|
||||
Return a book_reference_id if the name matches.
|
||||
|
||||
``name``
|
||||
The name to search the id.
|
||||
|
||||
``language_id``
|
||||
The language_id for which language should be searched
|
||||
"""
|
||||
log.debug(u'AlternativeBookNamesDB.get_book_reference_id("%s", "%s")',
|
||||
name, language_id)
|
||||
if language_id:
|
||||
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
|
||||
u'name FROM alternative_book_names WHERE language_id = ?',
|
||||
(language_id, ))
|
||||
else:
|
||||
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
|
||||
u'name FROM alternative_book_names')
|
||||
for book in books:
|
||||
if book[1].lower() == name.lower():
|
||||
return book[0]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def create_alternative_book_name(name, book_reference_id, language_id):
|
||||
"""
|
||||
Add an alternative book name to the database.
|
||||
|
||||
``name``
|
||||
The name of the alternative book name.
|
||||
|
||||
``book_reference_id``
|
||||
The book_reference_id of the book.
|
||||
|
||||
``language_id``
|
||||
The language to which the alternative book name belong.
|
||||
"""
|
||||
log.debug(u'AlternativeBookNamesDB.create_alternative_book_name("%s", '
|
||||
'"%s", "%s"', name, book_reference_id, language_id)
|
||||
return AlternativeBookNamesDB.run_sql(u'INSERT INTO '
|
||||
u'alternative_book_names(book_reference_id, language_id, name) '
|
||||
u'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True)
|
||||
|
||||
|
||||
class OldBibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
This class conects to the old bible databases to reimport them to the new
|
||||
database scheme.
|
||||
"""
|
||||
cursor = None
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
The constructor loads up the database and creates and initialises the
|
||||
tables if the database doesn't exist.
|
||||
|
||||
**Required keyword arguments:**
|
||||
|
||||
``path``
|
||||
The path to the bible database file.
|
||||
|
||||
``name``
|
||||
The name of the database. This is also used as the file name for
|
||||
SQLite databases.
|
||||
"""
|
||||
log.info(u'OldBibleDB loaded')
|
||||
QtCore.QObject.__init__(self)
|
||||
if u'path' not in kwargs:
|
||||
raise KeyError(u'Missing keyword argument "path".')
|
||||
if u'file' not in kwargs:
|
||||
raise KeyError(u'Missing keyword argument "file".')
|
||||
if u'path' in kwargs:
|
||||
self.path = kwargs[u'path']
|
||||
if u'file' in kwargs:
|
||||
self.file = kwargs[u'file']
|
||||
|
||||
def get_cursor(self):
|
||||
"""
|
||||
Return the cursor object. Instantiate one if it doesn't exist yet.
|
||||
"""
|
||||
if self.cursor is None:
|
||||
filepath = os.path.join(self.path, self.file)
|
||||
self.connection = sqlite3.connect(filepath)
|
||||
self.cursor = self.connection.cursor()
|
||||
return self.cursor
|
||||
|
||||
def run_sql(self, query, parameters=()):
|
||||
"""
|
||||
Run an SQL query on the database, returning the results.
|
||||
|
||||
``query``
|
||||
The actual SQL query to run.
|
||||
|
||||
``parameters``
|
||||
Any variable parameters to add to the query.
|
||||
"""
|
||||
cursor = self.get_cursor()
|
||||
cursor.execute(query, parameters)
|
||||
return cursor.fetchall()
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Returns the version name of the Bible.
|
||||
"""
|
||||
version_name = self.run_sql(u'SELECT value FROM '
|
||||
u'metadata WHERE key = "Version"')
|
||||
if version_name:
|
||||
self.name = version_name[0][0]
|
||||
else:
|
||||
self.name = None
|
||||
return self.name
|
||||
|
||||
def get_metadata(self):
|
||||
"""
|
||||
Returns the metadata of the Bible.
|
||||
"""
|
||||
metadata = self.run_sql(u'SELECT key, value FROM metadata '
|
||||
u'ORDER BY rowid')
|
||||
if metadata:
|
||||
return [
|
||||
{
|
||||
u'key': unicode(meta[0]),
|
||||
u'value': unicode(meta[1])
|
||||
}
|
||||
for meta in metadata
|
||||
]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_books(self):
|
||||
"""
|
||||
Returns the books of the Bible.
|
||||
"""
|
||||
books = self.run_sql(u'SELECT name, id FROM book ORDER BY id')
|
||||
if books:
|
||||
return [
|
||||
{
|
||||
u'name': unicode(book[0]),
|
||||
u'id':int(book[1])
|
||||
}
|
||||
for book in books
|
||||
]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_verses(self, book_id):
|
||||
"""
|
||||
Returns the verses of the Bible.
|
||||
"""
|
||||
verses = self.run_sql(u'SELECT book_id, chapter, verse, text FROM '
|
||||
u'verse WHERE book_id = ? ORDER BY id', (book_id, ))
|
||||
if verses:
|
||||
return [
|
||||
{
|
||||
u'book_id': int(verse[0]),
|
||||
u'chapter': int(verse[1]),
|
||||
u'verse': int(verse[2]),
|
||||
u'text': unicode(verse[3])
|
||||
}
|
||||
for verse in verses
|
||||
]
|
||||
else:
|
||||
return None
|
||||
|
@ -42,161 +42,26 @@ from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, get_web_page
|
||||
from openlp.plugins.bibles.lib import SearchResults
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, Book
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
|
||||
Book
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class HTTPBooks(object):
|
||||
"""
|
||||
A wrapper class around a small SQLite database which contains the books,
|
||||
chapter counts and verse counts for the web download Bibles. This class
|
||||
contains a singleton "cursor" so that only one connection to the SQLite
|
||||
database is ever used.
|
||||
"""
|
||||
cursor = None
|
||||
|
||||
@staticmethod
|
||||
def get_cursor():
|
||||
"""
|
||||
Return the cursor object. Instantiate one if it doesn't exist yet.
|
||||
"""
|
||||
if HTTPBooks.cursor is None:
|
||||
filepath = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
|
||||
u'resources', u'httpbooks.sqlite')
|
||||
conn = sqlite3.connect(filepath)
|
||||
HTTPBooks.cursor = conn.cursor()
|
||||
return HTTPBooks.cursor
|
||||
|
||||
@staticmethod
|
||||
def run_sql(query, parameters=()):
|
||||
"""
|
||||
Run an SQL query on the database, returning the results.
|
||||
|
||||
``query``
|
||||
The actual SQL query to run.
|
||||
|
||||
``parameters``
|
||||
Any variable parameters to add to the query.
|
||||
"""
|
||||
cursor = HTTPBooks.get_cursor()
|
||||
cursor.execute(query, parameters)
|
||||
return cursor.fetchall()
|
||||
|
||||
@staticmethod
|
||||
def get_books():
|
||||
"""
|
||||
Return a list of all the books of the Bible.
|
||||
"""
|
||||
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM books ORDER BY id')
|
||||
book_list = []
|
||||
for book in books:
|
||||
book_list.append({
|
||||
u'id': book[0],
|
||||
u'testament_id': book[1],
|
||||
u'name': unicode(book[2]),
|
||||
u'abbreviation': unicode(book[3]),
|
||||
u'chapters': book[4]
|
||||
})
|
||||
return book_list
|
||||
|
||||
@staticmethod
|
||||
def get_book(name):
|
||||
"""
|
||||
Return a book by name or abbreviation.
|
||||
|
||||
``name``
|
||||
The name or abbreviation of the book.
|
||||
"""
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name)
|
||||
name = name.title()
|
||||
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM books WHERE name = ? OR '
|
||||
u'abbreviation = ?', (name, name))
|
||||
if books:
|
||||
return {
|
||||
u'id': books[0][0],
|
||||
u'testament_id': books[0][1],
|
||||
u'name': unicode(books[0][2]),
|
||||
u'abbreviation': unicode(books[0][3]),
|
||||
u'chapters': books[0][4]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_chapter(name, chapter):
|
||||
"""
|
||||
Return the chapter details for a specific chapter of a book.
|
||||
|
||||
``name``
|
||||
The name or abbreviation of a book.
|
||||
|
||||
``chapter``
|
||||
The chapter number.
|
||||
"""
|
||||
if not isinstance(name, int):
|
||||
chapter = int(chapter)
|
||||
book = HTTPBooks.get_book(name)
|
||||
chapters = HTTPBooks.run_sql(u'SELECT id, book_id, chapter, '
|
||||
u'verses FROM chapters WHERE book_id = ?', (book[u'id'],))
|
||||
if chapters:
|
||||
return {
|
||||
u'id': chapters[chapter-1][0],
|
||||
u'book_id': chapters[chapter-1][1],
|
||||
u'chapter': chapters[chapter-1][2],
|
||||
u'verses': chapters[chapter-1][3]
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_chapter_count(book):
|
||||
"""
|
||||
Return the number of chapters in a book.
|
||||
|
||||
``book``
|
||||
The name or abbreviation of the book.
|
||||
"""
|
||||
details = HTTPBooks.get_book(book)
|
||||
if details:
|
||||
return details[u'chapters']
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def get_verse_count(book, chapter):
|
||||
"""
|
||||
Return the number of verses in a chapter.
|
||||
|
||||
``book``
|
||||
The name or abbreviation of the book.
|
||||
|
||||
``chapter``
|
||||
The number of the chapter.
|
||||
"""
|
||||
details = HTTPBooks.get_chapter(book, chapter)
|
||||
if details:
|
||||
return details[u'verses']
|
||||
return 0
|
||||
|
||||
|
||||
class BGExtract(object):
|
||||
"""
|
||||
Extract verses from BibleGateway
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'init %s', proxyurl)
|
||||
log.debug(u'BGExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
def get_bible_chapter(self, version, bookname, chapter):
|
||||
"""
|
||||
Access and decode bibles via the BibleGateway website.
|
||||
Access and decode Bibles via the BibleGateway website.
|
||||
|
||||
``version``
|
||||
The version of the bible like 31 for New International version.
|
||||
The version of the Bible like 31 for New International version.
|
||||
|
||||
``bookname``
|
||||
Name of the Book.
|
||||
@ -204,9 +69,11 @@ class BGExtract(object):
|
||||
``chapter``
|
||||
Chapter number.
|
||||
"""
|
||||
log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
|
||||
log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlbookname = urllib.quote(bookname.encode("utf-8"))
|
||||
url_params = urllib.urlencode(
|
||||
{u'search': u'%s %s' % (bookname, chapter),
|
||||
{u'search': u'%s %s' % (urlbookname, chapter),
|
||||
u'version': u'%s' % version})
|
||||
cleaner = [(re.compile(' |<br />|\'\+\''), lambda match: '')]
|
||||
soup = get_soup_for_bible_ref(
|
||||
@ -264,13 +131,57 @@ class BGExtract(object):
|
||||
return None
|
||||
return SearchResults(bookname, chapter, verse_list)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
Load a list of all books a Bible contaions from BibleGateway website.
|
||||
|
||||
``version``
|
||||
The version of the Bible like NIV for New International Version
|
||||
"""
|
||||
log.debug(u'BGExtract.get_books_from_http("%s")', version)
|
||||
url_params = urllib.urlencode(
|
||||
{u'search': 'Bible-List', u'version': u'%s' % version})
|
||||
reference_url = u'http://www.biblegateway.com/passage/?%s' % url_params
|
||||
page = get_web_page(reference_url)
|
||||
if not page:
|
||||
send_error_message(u'download')
|
||||
return None
|
||||
page_source = page.read()
|
||||
page_source = unicode(page_source, 'utf8')
|
||||
page_source_temp = re.search(u'<table id="booklist".*?>.*?</table>', \
|
||||
page_source, re.DOTALL)
|
||||
if page_source_temp:
|
||||
soup = page_source_temp.group(0)
|
||||
else:
|
||||
soup = None
|
||||
try:
|
||||
soup = BeautifulSoup(soup)
|
||||
except HTMLParseError:
|
||||
log.exception(u'BeautifulSoup could not parse the Bible page.')
|
||||
if not soup:
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
content = soup.find(u'table', {u'id': u'booklist'})
|
||||
content = content.findAll(u'tr')
|
||||
if not content:
|
||||
log.exception(u'No books found in the Biblegateway response.')
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
books = []
|
||||
for book in content:
|
||||
book = book.find(u'td')
|
||||
if book:
|
||||
books.append(book.contents[0])
|
||||
return books
|
||||
|
||||
|
||||
class BSExtract(object):
|
||||
"""
|
||||
Extract verses from Bibleserver.com
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'init %s', proxyurl)
|
||||
log.debug(u'BSExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
@ -287,9 +198,11 @@ class BSExtract(object):
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
|
||||
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlbookname = urllib.quote(bookname.encode("utf-8"))
|
||||
chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \
|
||||
(version, bookname, chapter)
|
||||
(version, urlbookname, chapter)
|
||||
header = (u'Accept-Language', u'en')
|
||||
soup = get_soup_for_bible_ref(chapter_url, header)
|
||||
if not soup:
|
||||
@ -309,13 +222,37 @@ class BSExtract(object):
|
||||
verses[versenumber] = verse.contents[1].rstrip(u'\n')
|
||||
return SearchResults(bookname, chapter, verses)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
Load a list of all books a Bible contains from Bibleserver mobile
|
||||
website.
|
||||
|
||||
``version``
|
||||
The version of the Bible like NIV for New International Version
|
||||
"""
|
||||
log.debug(u'BSExtract.get_books_from_http("%s")', version)
|
||||
chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
|
||||
'translation=%s' % (version)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
content = soup.find(u'ul')
|
||||
if not content:
|
||||
log.exception(u'No books found in the Bibleserver response.')
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
content = content.findAll(u'li')
|
||||
return [
|
||||
book.contents[0].contents[0] for book in content
|
||||
]
|
||||
|
||||
|
||||
class CWExtract(object):
|
||||
"""
|
||||
Extract verses from CrossWalk/BibleStudyTools
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'init %s', proxyurl)
|
||||
log.debug(u'CWExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
@ -324,7 +261,7 @@ class CWExtract(object):
|
||||
Access and decode bibles via the Crosswalk website
|
||||
|
||||
``version``
|
||||
The version of the bible like niv for New International Version
|
||||
The version of the Bible like niv for New International Version
|
||||
|
||||
``bookname``
|
||||
Text name of in english e.g. 'gen' for Genesis
|
||||
@ -332,10 +269,13 @@ class CWExtract(object):
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
|
||||
log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlbookname = bookname.replace(u' ', u'-')
|
||||
urlbookname = urlbookname.lower()
|
||||
urlbookname = urllib.quote(urlbookname.encode("utf-8"))
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
|
||||
(version, urlbookname.lower(), chapter)
|
||||
(version, urlbookname, chapter)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
@ -378,6 +318,32 @@ class CWExtract(object):
|
||||
verses[versenumber] = versetext
|
||||
return SearchResults(bookname, chapter, verses)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
Load a list of all books a Bible contain from the Crosswalk website.
|
||||
|
||||
``version``
|
||||
The version of the bible like NIV for New International Version
|
||||
"""
|
||||
log.debug(u'CWExtract.get_books_from_http("%s")', version)
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/'\
|
||||
% (version)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
content = soup.find(u'div', {u'class': u'Body'})
|
||||
content = content.find(u'ul', {u'class': u'parent'})
|
||||
if not content:
|
||||
log.exception(u'No books found in the Crosswalk response.')
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
content = content.findAll(u'li')
|
||||
books = []
|
||||
for book in content:
|
||||
book = book.find(u'a')
|
||||
books.append(book.contents[0])
|
||||
return books
|
||||
|
||||
|
||||
class HTTPBible(BibleDB):
|
||||
log.info(u'%s HTTPBible loaded' , __name__)
|
||||
@ -400,6 +366,8 @@ class HTTPBible(BibleDB):
|
||||
self.proxy_server = None
|
||||
self.proxy_username = None
|
||||
self.proxy_password = None
|
||||
if u'path' in kwargs:
|
||||
self.path = kwargs[u'path']
|
||||
if u'proxy_server' in kwargs:
|
||||
self.proxy_server = kwargs[u'proxy_server']
|
||||
if u'proxy_username' in kwargs:
|
||||
@ -407,13 +375,15 @@ class HTTPBible(BibleDB):
|
||||
if u'proxy_password' in kwargs:
|
||||
self.proxy_password = kwargs[u'proxy_password']
|
||||
|
||||
def do_import(self):
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Run the import. This method overrides the parent class method. Returns
|
||||
``True`` on success, ``False`` on failure.
|
||||
"""
|
||||
self.wizard.progressBar.setMaximum(2)
|
||||
self.wizard.incrementProgressBar('Registering bible...')
|
||||
self.wizard.progressBar.setMaximum(68)
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.HTTPBible',
|
||||
'Registering Bible and loading books...')))
|
||||
self.create_meta(u'download source', self.download_source)
|
||||
self.create_meta(u'download name', self.download_name)
|
||||
if self.proxy_server:
|
||||
@ -424,7 +394,51 @@ class HTTPBible(BibleDB):
|
||||
if self.proxy_password:
|
||||
# Store the proxy password.
|
||||
self.create_meta(u'proxy password', self.proxy_password)
|
||||
return True
|
||||
if self.download_source.lower() == u'crosswalk':
|
||||
handler = CWExtract(self.proxy_server)
|
||||
elif self.download_source.lower() == u'biblegateway':
|
||||
handler = BGExtract(self.proxy_server)
|
||||
elif self.download_source.lower() == u'bibleserver':
|
||||
handler = BSExtract(self.proxy_server)
|
||||
books = handler.get_books_from_http(self.download_name)
|
||||
if not books:
|
||||
log.exception(u'Importing books from %s - download name: "%s" '\
|
||||
'failed' % (self.download_source, self.download_name))
|
||||
return False
|
||||
self.wizard.progressBar.setMaximum(len(books)+2)
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.HTTPBible', 'Registering Language...')))
|
||||
bible = BiblesResourcesDB.get_webbible(self.download_name,
|
||||
self.download_source.lower())
|
||||
if bible[u'language_id']:
|
||||
language_id = bible[u'language_id']
|
||||
self.create_meta(u'language_id', language_id)
|
||||
else:
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from %s " '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.HTTPBible', 'Importing %s...',
|
||||
'Importing <book name>...')) % book)
|
||||
book_ref_id = self.get_book_ref_id_by_name(book, len(books),
|
||||
language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from %s - download name: "%s" '\
|
||||
'failed' % (self.download_source, self.download_name))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
log.debug(u'Book details: Name:%s; id:%s; testament_id:%s',
|
||||
book, book_ref_id, book_details[u'testament_id'])
|
||||
self.create_book(book, book_ref_id, book_details[u'testament_id'])
|
||||
if self.stop_import_flag:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_verses(self, reference_list, show_error=True):
|
||||
"""
|
||||
@ -438,34 +452,29 @@ class HTTPBible(BibleDB):
|
||||
This is the list of references the media manager item wants. It is
|
||||
a list of tuples, with the following format::
|
||||
|
||||
(book, chapter, start_verse, end_verse)
|
||||
(book_reference_id, chapter, start_verse, end_verse)
|
||||
|
||||
Therefore, when you are looking for multiple items, simply break
|
||||
them up into references like this, bundle them into a list. This
|
||||
function then runs through the list, and returns an amalgamated
|
||||
list of ``Verse`` objects. For example::
|
||||
|
||||
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
|
||||
[(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
|
||||
"""
|
||||
log.debug(u'HTTPBible.get_verses("%s")', reference_list)
|
||||
for reference in reference_list:
|
||||
log.debug(u'Reference: %s', reference)
|
||||
book = reference[0]
|
||||
db_book = self.get_book(book)
|
||||
book_id = reference[0]
|
||||
db_book = self.get_book_by_book_ref_id(book_id)
|
||||
if not db_book:
|
||||
book_details = HTTPBooks.get_book(book)
|
||||
if not book_details:
|
||||
if show_error:
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
translate('BiblesPlugin', 'No matching '
|
||||
'book could be found in this Bible. Check that you '
|
||||
'have spelled the name of the book correctly.'))
|
||||
return []
|
||||
db_book = self.create_book(book_details[u'name'],
|
||||
book_details[u'abbreviation'],
|
||||
book_details[u'testament_id'])
|
||||
if show_error:
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
translate('BiblesPlugin', 'No matching '
|
||||
'book could be found in this Bible. Check that you '
|
||||
'have spelled the name of the book correctly.'))
|
||||
return []
|
||||
book = db_book.name
|
||||
if BibleDB.get_verse_count(self, book, reference[1]) == 0:
|
||||
if BibleDB.get_verse_count(self, book_id, reference[1]) == 0:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
search_results = self.get_chapter(book, reference[1])
|
||||
if search_results and search_results.has_verselist():
|
||||
@ -488,7 +497,7 @@ class HTTPBible(BibleDB):
|
||||
"""
|
||||
Receive the request and call the relevant handler methods.
|
||||
"""
|
||||
log.debug(u'get_chapter %s, %s', book, chapter)
|
||||
log.debug(u'HTTPBible.get_chapter("%s", "%s")', book, chapter)
|
||||
log.debug(u'source = %s', self.download_source)
|
||||
if self.download_source.lower() == u'crosswalk':
|
||||
handler = CWExtract(self.proxy_server)
|
||||
@ -502,16 +511,20 @@ class HTTPBible(BibleDB):
|
||||
"""
|
||||
Return the list of books.
|
||||
"""
|
||||
return [Book.populate(name=book['name'])
|
||||
for book in HTTPBooks.get_books()]
|
||||
log.debug(u'HTTPBible.get_books("%s")', Book.name)
|
||||
return self.get_all_objects(Book, order_by_ref=Book.id)
|
||||
|
||||
def get_chapter_count(self, book):
|
||||
"""
|
||||
Return the number of chapters in a particular book.
|
||||
|
||||
``book``
|
||||
The book object to get the chapter count for.
|
||||
"""
|
||||
return HTTPBooks.get_chapter_count(book)
|
||||
log.debug(u'HTTPBible.get_chapter_count("%s")', book.name)
|
||||
return BiblesResourcesDB.get_chapter_count(book.book_reference_id)
|
||||
|
||||
def get_verse_count(self, book, chapter):
|
||||
def get_verse_count(self, book_id, chapter):
|
||||
"""
|
||||
Return the number of verses for the specified chapter and book.
|
||||
|
||||
@ -521,7 +534,8 @@ class HTTPBible(BibleDB):
|
||||
``chapter``
|
||||
The chapter whose verses are being counted.
|
||||
"""
|
||||
return HTTPBooks.get_verse_count(book, chapter)
|
||||
log.debug(u'HTTPBible.get_verse_count("%s", %s)', book_id, chapter)
|
||||
return BiblesResourcesDB.get_verse_count(book_id, chapter)
|
||||
|
||||
def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
|
||||
pre_parse_substitute=None, cleaner=None):
|
||||
|
@ -31,9 +31,10 @@ import os
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, delete_file
|
||||
from openlp.plugins.bibles.lib import parse_reference
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB
|
||||
from csvbible import CSVBible
|
||||
from http import HTTPBible
|
||||
from opensong import OpenSongBible
|
||||
@ -140,8 +141,11 @@ class BibleManager(object):
|
||||
"""
|
||||
log.debug(u'Reload bibles')
|
||||
files = SettingsManager.get_files(self.settingsSection, self.suffix)
|
||||
if u'alternative_book_names.sqlite' in files:
|
||||
files.remove(u'alternative_book_names.sqlite')
|
||||
log.debug(u'Bible Files %s', files)
|
||||
self.db_cache = {}
|
||||
self.old_bible_databases = []
|
||||
for filename in files:
|
||||
bible = BibleDB(self.parent, path=self.path, file=filename)
|
||||
name = bible.get_name()
|
||||
@ -149,6 +153,11 @@ class BibleManager(object):
|
||||
if name is None:
|
||||
delete_file(os.path.join(self.path, filename))
|
||||
continue
|
||||
# Find old database versions
|
||||
if bible.is_old_database():
|
||||
self.old_bible_databases.append([filename, name])
|
||||
bible.session.close()
|
||||
continue
|
||||
log.debug(u'Bible Name: "%s"', name)
|
||||
self.db_cache[name] = bible
|
||||
# Look to see if lazy load bible exists and get create getter.
|
||||
@ -211,7 +220,8 @@ class BibleManager(object):
|
||||
return [
|
||||
{
|
||||
u'name': book.name,
|
||||
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
|
||||
u'book_reference_id': book.book_reference_id,
|
||||
u'chapters': self.db_cache[bible].get_chapter_count(book)
|
||||
}
|
||||
for book in self.db_cache[bible].get_books()
|
||||
]
|
||||
@ -219,8 +229,15 @@ class BibleManager(object):
|
||||
def get_chapter_count(self, bible, book):
|
||||
"""
|
||||
Returns the number of Chapters for a given book.
|
||||
|
||||
``bible``
|
||||
Unicode. The Bible to get the list of books from.
|
||||
|
||||
``book``
|
||||
The book object to get the chapter count for.
|
||||
"""
|
||||
log.debug(u'get_book_chapter_count %s', book)
|
||||
log.debug(u'BibleManager.get_book_chapter_count ("%s", "%s")', bible,
|
||||
book.name)
|
||||
return self.db_cache[bible].get_chapter_count(book)
|
||||
|
||||
def get_verse_count(self, bible, book, chapter):
|
||||
@ -230,9 +247,11 @@ class BibleManager(object):
|
||||
"""
|
||||
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
|
||||
bible, book, chapter)
|
||||
return self.db_cache[bible].get_verse_count(book, chapter)
|
||||
db_book = self.db_cache[bible].get_book(book)
|
||||
book_ref_id = db_book.book_reference_id
|
||||
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
|
||||
|
||||
def get_verses(self, bible, versetext, show_error=True):
|
||||
def get_verses(self, bible, versetext, firstbible=False, show_error=True):
|
||||
"""
|
||||
Parses a scripture reference, fetches the verses from the Bible
|
||||
specified, and returns a list of ``Verse`` objects.
|
||||
@ -264,6 +283,28 @@ class BibleManager(object):
|
||||
return None
|
||||
reflist = parse_reference(versetext)
|
||||
if reflist:
|
||||
new_reflist = []
|
||||
for item in reflist:
|
||||
if item:
|
||||
if firstbible:
|
||||
db_book = self.db_cache[firstbible].get_book(item[0])
|
||||
db_book = self.db_cache[bible].get_book_by_book_ref_id(
|
||||
db_book.book_reference_id)
|
||||
else:
|
||||
db_book = self.db_cache[bible].get_book(item[0])
|
||||
if db_book:
|
||||
book_id = db_book.book_reference_id
|
||||
log.debug(u'Book name corrected to "%s"', db_book.name)
|
||||
new_reflist.append((book_id, item[1], item[2],
|
||||
item[3]))
|
||||
else:
|
||||
log.debug(u'OpenLP failed to find book %s', item[0])
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
translate('BiblesPlugin', 'No matching book '
|
||||
'could be found in this Bible. Check that you have '
|
||||
'spelled the name of the book correctly.'))
|
||||
reflist = new_reflist
|
||||
return self.db_cache[bible].get_verses(reflist, show_error)
|
||||
else:
|
||||
if show_error:
|
||||
|
@ -61,7 +61,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.unlockIcon = QtGui.QIcon(u':/bibles/bibles_search_unlock.png')
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
# Place to store the search results for both bibles.
|
||||
self.settings = self.parent.settings_tab
|
||||
self.settings = self.plugin.settings_tab
|
||||
self.quickPreviewAllowed = True
|
||||
self.hasSearch = True
|
||||
self.search_results = {}
|
||||
@ -239,8 +239,14 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedLayout.addWidget(self.advancedToVerse, 4, 2)
|
||||
self.addSearchFields(u'advanced', UiStrings().Advanced)
|
||||
# Combo Boxes
|
||||
QtCore.QObject.connect(self.quickVersionComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onQuickVersionComboBox)
|
||||
QtCore.QObject.connect(self.quickSecondComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onQuickSecondComboBox)
|
||||
QtCore.QObject.connect(self.advancedVersionComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedVersionComboBox)
|
||||
QtCore.QObject.connect(self.advancedSecondComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedSecondComboBox)
|
||||
QtCore.QObject.connect(self.advancedBookComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedBookComboBox)
|
||||
QtCore.QObject.connect(self.advancedFromChapter,
|
||||
@ -338,7 +344,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
|
||||
def initialise(self):
|
||||
log.debug(u'bible manager initialise')
|
||||
self.parent.manager.media = self
|
||||
self.plugin.manager.media = self
|
||||
self.loadBibles()
|
||||
bible = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/quick bible', QtCore.QVariant(
|
||||
@ -365,7 +371,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.quickSecondComboBox.addItem(u'')
|
||||
self.advancedSecondComboBox.addItem(u'')
|
||||
# Get all bibles and sort the list.
|
||||
bibles = self.parent.manager.get_bibles().keys()
|
||||
bibles = self.plugin.manager.get_bibles().keys()
|
||||
bibles.sort(cmp=locale.strcoll)
|
||||
# Load the bibles into the combo boxes.
|
||||
for bible in bibles:
|
||||
@ -386,7 +392,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
|
||||
def reloadBibles(self):
|
||||
log.debug(u'Reloading Bibles')
|
||||
self.parent.manager.reload_bibles()
|
||||
self.plugin.manager.reload_bibles()
|
||||
self.loadBibles()
|
||||
|
||||
def initialiseAdvancedBible(self, bible):
|
||||
@ -400,7 +406,17 @@ class BibleMediaItem(MediaManagerItem):
|
||||
The bible to initialise (unicode).
|
||||
"""
|
||||
log.debug(u'initialiseAdvancedBible %s', bible)
|
||||
book_data = self.parent.manager.get_books(bible)
|
||||
book_data = self.plugin.manager.get_books(bible)
|
||||
secondbible = unicode(self.advancedSecondComboBox.currentText())
|
||||
if secondbible != u'':
|
||||
secondbook_data = self.plugin.manager.get_books(secondbible)
|
||||
book_data_temp = []
|
||||
for book in book_data:
|
||||
for secondbook in secondbook_data:
|
||||
if book['book_reference_id'] == \
|
||||
secondbook['book_reference_id']:
|
||||
book_data_temp.append(book)
|
||||
book_data = book_data_temp
|
||||
self.advancedBookComboBox.clear()
|
||||
first = True
|
||||
for book in book_data:
|
||||
@ -416,7 +432,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
def initialiseChapterVerse(self, bible, book, chapter_count):
|
||||
log.debug(u'initialiseChapterVerse %s, %s', bible, book)
|
||||
self.chapter_count = chapter_count
|
||||
verse_count = self.parent.manager.get_verse_count(bible, book, 1)
|
||||
verse_count = self.plugin.manager.get_verse_count(bible, book, 1)
|
||||
if verse_count == 0:
|
||||
self.advancedSearchButton.setEnabled(False)
|
||||
critical_error_message_box(
|
||||
@ -445,18 +461,34 @@ class BibleMediaItem(MediaManagerItem):
|
||||
books = []
|
||||
# We have to do a 'Reference Search'.
|
||||
if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
|
||||
bibles = self.parent.manager.get_bibles()
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
if bible:
|
||||
book_data = bibles[bible].get_books()
|
||||
secondbible = unicode(self.quickSecondComboBox.currentText())
|
||||
if secondbible != u'':
|
||||
secondbook_data = bibles[secondbible].get_books()
|
||||
book_data_temp = []
|
||||
for book in book_data:
|
||||
for secondbook in secondbook_data:
|
||||
if book.book_reference_id == \
|
||||
secondbook.book_reference_id:
|
||||
book_data_temp.append(book)
|
||||
book_data = book_data_temp
|
||||
books = [book.name + u' ' for book in book_data]
|
||||
books.sort(cmp=locale.strcoll)
|
||||
add_widget_completer(books, self.quickSearchEdit)
|
||||
|
||||
def onQuickVersionComboBox(self):
|
||||
self.updateAutoCompleter()
|
||||
|
||||
def onQuickSecondComboBox(self):
|
||||
self.updateAutoCompleter()
|
||||
|
||||
def onImportClick(self):
|
||||
if not hasattr(self, u'import_wizard'):
|
||||
self.import_wizard = BibleImportForm(self, self.parent.manager,
|
||||
self.parent)
|
||||
self.import_wizard = BibleImportForm(self, self.plugin.manager,
|
||||
self.plugin)
|
||||
# If the import was not cancelled then reload.
|
||||
if self.import_wizard.exec_():
|
||||
self.reloadBibles()
|
||||
@ -501,6 +533,10 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.initialiseAdvancedBible(
|
||||
unicode(self.advancedVersionComboBox.currentText()))
|
||||
|
||||
def onAdvancedSecondComboBox(self):
|
||||
self.initialiseAdvancedBible(
|
||||
unicode(self.advancedVersionComboBox.currentText()))
|
||||
|
||||
def onAdvancedBookComboBox(self):
|
||||
item = int(self.advancedBookComboBox.currentIndex())
|
||||
self.initialiseChapterVerse(
|
||||
@ -515,7 +551,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
bible = unicode(self.advancedVersionComboBox.currentText())
|
||||
book = unicode(self.advancedBookComboBox.currentText())
|
||||
verse_from = int(self.advancedFromVerse.currentText())
|
||||
verse_count = self.parent.manager.get_verse_count(bible, book,
|
||||
verse_count = self.plugin.manager.get_verse_count(bible, book,
|
||||
chapter_to)
|
||||
self.adjustComboBox(verse_from, verse_count,
|
||||
self.advancedToVerse, True)
|
||||
@ -527,7 +563,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
chapter_to = int(self.advancedToChapter.currentText())
|
||||
verse_from = int(self.advancedFromVerse.currentText())
|
||||
verse_to = int(self.advancedToVerse.currentText())
|
||||
verse_count = self.parent.manager.get_verse_count(bible, book,
|
||||
verse_count = self.plugin.manager.get_verse_count(bible, book,
|
||||
chapter_to)
|
||||
if chapter_from == chapter_to and verse_from > verse_to:
|
||||
self.adjustComboBox(verse_from, verse_count, self.advancedToVerse)
|
||||
@ -539,7 +575,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
book = unicode(self.advancedBookComboBox.currentText())
|
||||
chapter_from = int(self.advancedFromChapter.currentText())
|
||||
chapter_to = int(self.advancedToChapter.currentText())
|
||||
verse_count = self.parent.manager.get_verse_count(bible, book,
|
||||
verse_count = self.plugin.manager.get_verse_count(bible, book,
|
||||
chapter_from)
|
||||
self.adjustComboBox(1, verse_count, self.advancedFromVerse)
|
||||
if chapter_from > chapter_to:
|
||||
@ -599,10 +635,10 @@ class BibleMediaItem(MediaManagerItem):
|
||||
range_separator + chapter_to + verse_separator + verse_to
|
||||
versetext = u'%s %s' % (book, verse_range)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.search_results = self.parent.manager.get_verses(bible, versetext)
|
||||
self.search_results = self.plugin.manager.get_verses(bible, versetext)
|
||||
if second_bible:
|
||||
self.second_search_results = self.parent.manager.get_verses(
|
||||
second_bible, versetext)
|
||||
self.second_search_results = self.plugin.manager.get_verses(
|
||||
second_bible, versetext, bible)
|
||||
if not self.advancedLockButton.isChecked():
|
||||
self.listView.clear()
|
||||
if self.listView.count() != 0:
|
||||
@ -627,15 +663,15 @@ class BibleMediaItem(MediaManagerItem):
|
||||
text = unicode(self.quickSearchEdit.text())
|
||||
if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
|
||||
# We are doing a 'Reference Search'.
|
||||
self.search_results = self.parent.manager.get_verses(bible, text)
|
||||
self.search_results = self.plugin.manager.get_verses(bible, text)
|
||||
if second_bible and self.search_results:
|
||||
self.second_search_results = self.parent.manager.get_verses(
|
||||
second_bible, text)
|
||||
self.second_search_results = self.plugin.manager.get_verses(
|
||||
second_bible, text, bible)
|
||||
else:
|
||||
# We are doing a 'Text Search'.
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
bibles = self.parent.manager.get_bibles()
|
||||
self.search_results = self.parent.manager.verse_search(bible,
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
self.search_results = self.plugin.manager.verse_search(bible,
|
||||
second_bible, text)
|
||||
if second_bible and self.search_results:
|
||||
text = []
|
||||
@ -674,19 +710,19 @@ class BibleMediaItem(MediaManagerItem):
|
||||
further action is saved for/in each row.
|
||||
"""
|
||||
verse_separator = get_reference_match(u'sep_v_display')
|
||||
version = self.parent.manager.get_meta_data(bible, u'Version').value
|
||||
copyright = self.parent.manager.get_meta_data(bible, u'Copyright').value
|
||||
version = self.plugin.manager.get_meta_data(bible, u'Version').value
|
||||
copyright = self.plugin.manager.get_meta_data(bible, u'Copyright').value
|
||||
permissions = \
|
||||
self.parent.manager.get_meta_data(bible, u'Permissions').value
|
||||
self.plugin.manager.get_meta_data(bible, u'Permissions').value
|
||||
second_version = u''
|
||||
second_copyright = u''
|
||||
second_permissions = u''
|
||||
if second_bible:
|
||||
second_version = self.parent.manager.get_meta_data(
|
||||
second_version = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Version').value
|
||||
second_copyright = self.parent.manager.get_meta_data(
|
||||
second_copyright = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Copyright').value
|
||||
second_permissions = self.parent.manager.get_meta_data(
|
||||
second_permissions = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Permissions').value
|
||||
items = []
|
||||
for count, verse in enumerate(search_results):
|
||||
@ -879,7 +915,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
# We are still in the same chapter, but a verse has been skipped.
|
||||
return True
|
||||
elif old_chapter + 1 == chapter and (verse != 1 or
|
||||
old_verse != self.parent.manager.get_verse_count(
|
||||
old_verse != self.plugin.manager.get_verse_count(
|
||||
old_bible, old_book, old_chapter)):
|
||||
# We are in the following chapter, but the last verse was not the
|
||||
# last verse of the chapter or the current verse is not the
|
||||
@ -923,7 +959,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
Search for some Bible verses (by reference).
|
||||
"""
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
search_results = self.parent.manager.get_verses(bible, string, False)
|
||||
search_results = self.plugin.manager.get_verses(bible, string, False)
|
||||
results = []
|
||||
if search_results:
|
||||
versetext = u' '.join([verse.text for verse in search_results])
|
||||
@ -933,6 +969,6 @@ class BibleMediaItem(MediaManagerItem):
|
||||
def createItemFromId(self, item_id):
|
||||
item = QtGui.QListWidgetItem()
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
search_results = self.parent.manager.get_verses(bible, item_id, False)
|
||||
search_results = self.plugin.manager.get_verses(bible, item_id, False)
|
||||
items = self.buildDisplayResults(bible, u'', search_results)
|
||||
return items
|
||||
|
@ -30,7 +30,7 @@ import sqlite
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.core.ui.wizard import WizardStrings
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -46,7 +46,7 @@ class OpenLP1Bible(BibleDB):
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
self.filename = kwargs[u'filename']
|
||||
|
||||
def do_import(self):
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Imports an openlp.org v1 bible.
|
||||
"""
|
||||
@ -57,6 +57,11 @@ class OpenLP1Bible(BibleDB):
|
||||
cursor = connection.cursor()
|
||||
except:
|
||||
return False
|
||||
#Create the bible language
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from "%s" failed' % self.filename)
|
||||
return False
|
||||
# Create all books.
|
||||
cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
|
||||
books = cursor.fetchall()
|
||||
@ -69,7 +74,15 @@ class OpenLP1Bible(BibleDB):
|
||||
testament_id = int(book[1])
|
||||
name = unicode(book[2], u'cp1252')
|
||||
abbreviation = unicode(book[3], u'cp1252')
|
||||
self.create_book(name, abbreviation, testament_id)
|
||||
book_ref_id = self.get_book_ref_id_by_name(name, len(books),
|
||||
language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(name, book_ref_id,
|
||||
book_details[u'testament_id'])
|
||||
# Update the progess bar.
|
||||
self.wizard.incrementProgressBar(WizardStrings.ImportingType % name)
|
||||
# Import the verses for this book.
|
||||
@ -83,7 +96,7 @@ class OpenLP1Bible(BibleDB):
|
||||
chapter = int(verse[0])
|
||||
verse_number = int(verse[1])
|
||||
text = unicode(verse[2], u'cp1252')
|
||||
self.create_verse(book_id, chapter, verse_number, text)
|
||||
self.create_verse(db_book.id, chapter, verse_number, text)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.session.commit()
|
||||
connection.close()
|
||||
|
@ -29,7 +29,7 @@ import logging
|
||||
from lxml import objectify
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -46,7 +46,7 @@ class OpenSongBible(BibleDB):
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
self.filename = kwargs['filename']
|
||||
|
||||
def do_import(self):
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
@ -62,11 +62,23 @@ class OpenSongBible(BibleDB):
|
||||
file = open(self.filename, u'r')
|
||||
opensong = objectify.parse(file)
|
||||
bible = opensong.getroot()
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
for book in bible.b:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
db_book = self.create_book(unicode(book.attrib[u'n']),
|
||||
unicode(book.attrib[u'n'][:4]))
|
||||
book_ref_id = self.get_book_ref_id_by_name(
|
||||
unicode(book.attrib[u'n']), len(bible.b), language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(unicode(book.attrib[u'n']),
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
for chapter in book.c:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
|
@ -34,7 +34,7 @@ import re
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -86,7 +86,7 @@ class OSISBible(BibleDB):
|
||||
if fbibles:
|
||||
fbibles.close()
|
||||
|
||||
def do_import(self):
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
@ -96,7 +96,6 @@ class OSISBible(BibleDB):
|
||||
osis = None
|
||||
success = True
|
||||
last_chapter = 0
|
||||
testament = 1
|
||||
match_count = 0
|
||||
self.wizard.incrementProgressBar(translate('BiblesPlugin.OsisImport',
|
||||
'Detecting encoding (this may take a few minutes)...'))
|
||||
@ -109,6 +108,11 @@ class OSISBible(BibleDB):
|
||||
finally:
|
||||
if detect_file:
|
||||
detect_file.close()
|
||||
# Set meta language_id
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from "%s" failed' % self.filename)
|
||||
return False
|
||||
try:
|
||||
osis = codecs.open(self.filename, u'r', details['encoding'])
|
||||
repl = replacement
|
||||
@ -123,13 +127,19 @@ class OSISBible(BibleDB):
|
||||
verse = int(match.group(3))
|
||||
verse_text = match.group(4)
|
||||
if not db_book or db_book.name != self.books[book][0]:
|
||||
log.debug(u'New book: "%s"', self.books[book][0])
|
||||
if book == u'Matt' or book == u'Jdt':
|
||||
testament += 1
|
||||
log.debug(u'New book: "%s"' % self.books[book][0])
|
||||
book_ref_id = self.get_book_ref_id_by_name(unicode(
|
||||
self.books[book][0]), 67, language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(
|
||||
book_ref_id)
|
||||
db_book = self.create_book(
|
||||
unicode(self.books[book][0]),
|
||||
unicode(self.books[book][1]),
|
||||
testament)
|
||||
book_ref_id,
|
||||
book_details[u'testament_id'])
|
||||
if last_chapter == 0:
|
||||
if book == u'Gen':
|
||||
self.wizard.progressBar.setMaximum(1188)
|
||||
|
@ -1,81 +0,0 @@
|
||||
João Ferreira de Almeida Atualizada,AA
|
||||
التفسير التطبيقى للكتاب المقدس,ALAB
|
||||
Shqip,ALB
|
||||
Amplified Bible,AMP
|
||||
Amuzgo de Guerrero,AMU
|
||||
American Standard Version,ASV
|
||||
La Bible du Semeur,BDS
|
||||
Български 1940,BG1940
|
||||
Български,BULG
|
||||
Chinanteco de Comaltepec,CCO
|
||||
Contemporary English Version,CEV
|
||||
Cakchiquel Occidental,CKW
|
||||
Hrvatski,CRO
|
||||
Castilian,CST
|
||||
聖經和合本 (简体中文),CUVS
|
||||
聖經和合本 (繁体中文),CUV
|
||||
Darby Translation,DARBY
|
||||
Dette er Biblen på dansk,DN1933
|
||||
Det Norsk Bibelselskap 1930,DNB1930
|
||||
English Standard Version,ESV
|
||||
GOD’S WORD Translation,GW
|
||||
Holman Christian Standard Bible,HCSB
|
||||
Kreyòl ayisyen bib,HCV
|
||||
Hiligaynon Bible,HLGN
|
||||
Hoffnung für Alle,HOF
|
||||
Het Boek,HTB
|
||||
Icelandic Bible,ICELAND
|
||||
Jacalteco – Oriental,JAC
|
||||
Károlyi-biblia,KAR
|
||||
Kekchi,KEK
|
||||
21st Century King James Version,KJ21
|
||||
King James Version,KJV
|
||||
La Biblia de las Américas,LBLA
|
||||
Levande Bibeln,LB
|
||||
La Parola è Vita,LM
|
||||
La Nuova Diodati,LND
|
||||
Louis Segond,LSG
|
||||
Luther Bibel 1545,LUTH1545
|
||||
Māori Bible,MAORI
|
||||
Македонски Новиот Завет,MNT
|
||||
The Message,MSG
|
||||
Mam de Comitancillo Central,MVC
|
||||
Mam de Todos Santos Cuchumatán,MVJ
|
||||
New American Standard Bible,NASB
|
||||
New Century Version,NCV
|
||||
Náhuatl de Guerrero,NGU
|
||||
New International Reader's Version,NIRV
|
||||
New International Version 1984,NIV1984
|
||||
New International Version 2010,NIV
|
||||
New International Version - UK,NIVUK
|
||||
New King James Version,NKJV
|
||||
New Living Translation,NLT
|
||||
Nádej pre kazdého,NPK
|
||||
Nueva Versión Internacional,NVI
|
||||
O Livro,OL
|
||||
Quiché – Centro Occidental,QUT
|
||||
Reimer 2001,REIMER
|
||||
Română Cornilescu,RMNN
|
||||
Новый перевод на русский язык,RUSV
|
||||
Reina-Valera Antigua,RVA
|
||||
Reina-Valera 1960,RVR1960
|
||||
Reina-Valera 1995,RVR1995
|
||||
Slovo na cestu,SNC
|
||||
Ang Salita ng Diyos,SND
|
||||
Swahili New Testament,SNT
|
||||
Svenska 1917,SV1917
|
||||
Levande Bibeln,SVL
|
||||
Создать страницу,SZ
|
||||
Traducción en lenguaje actual,TLA
|
||||
New Romanian Translation,TLCR
|
||||
Today’s New International Version 2005,TNIV
|
||||
Textus Receptus Stephanus 1550,TR1550
|
||||
Textus Receptus Scrivener 1894,TR1894
|
||||
Українська Біблія. Переклад Івана Огієнка,UKR
|
||||
Uspanteco,USP
|
||||
Kinh Thánh tiếng Việt 1934,VIET
|
||||
Worldwide English (New Testament),WE
|
||||
Codex Vaticanus Westcott-Hort 1881,WHNU
|
||||
Westminster Leningrad Codex,WLC
|
||||
Wycliffe New Testament,WYC
|
||||
Young's Literal Translation,YLT
|
|
BIN
openlp/plugins/bibles/resources/bibles_resources.sqlite
Normal file
BIN
openlp/plugins/bibles/resources/bibles_resources.sqlite
Normal file
Binary file not shown.
@ -1,39 +0,0 @@
|
||||
عربي, ARA
|
||||
Bible – překlad 21. století, B21
|
||||
Bible du Semeur, BDS
|
||||
Българската Библия, BLG
|
||||
Český ekumenický překlad, CEP
|
||||
Hrvatski, CRO
|
||||
Священное Писание, CRS
|
||||
Version La Biblia al Dia, CST
|
||||
中文和合本(简体), CUVS
|
||||
Bibelen på hverdagsdansk, DK
|
||||
Revidierte Elberfelder, ELB
|
||||
Einheitsübersetzung, EU
|
||||
Gute Nachricht Bibel, GNB
|
||||
Hoffnung für alle, HFA
|
||||
Hungarian, HUN
|
||||
Het Boek, HTB
|
||||
La Parola è Vita, ITA
|
||||
IBS-fordítás (Új Károli), KAR
|
||||
King James Version, KJV
|
||||
Luther 1984, LUT
|
||||
Septuaginta, LXX
|
||||
Neue Genfer Übersetzung, NGU
|
||||
New International Readers Version, NIRV
|
||||
New International Version, NIV
|
||||
Neues Leben, NL
|
||||
En Levende Bok (NOR), NOR
|
||||
Nádej pre kazdého, NPK
|
||||
Noua traducere în limba românã, NTR
|
||||
Nueva Versión Internacional, NVI
|
||||
הברית הישנה, OT
|
||||
Słowo Życia, POL
|
||||
O Livro, PRT
|
||||
Новый перевод на русский язык, RUS
|
||||
Slovo na cestu, SNC
|
||||
Schlachter 2000, SLT
|
||||
En Levande Bok (SWE), SVL
|
||||
Today's New International Version, TNIV
|
||||
Türkçe, TR
|
||||
Biblia Vulgata, VUL
|
|
@ -1,27 +0,0 @@
|
||||
New American Standard,nas
|
||||
American Standard Version,asv
|
||||
English Standard Version,esv
|
||||
New King James Version,nkj
|
||||
King James Version,kjv
|
||||
Holman Christian Standard Bible,csb
|
||||
Third Millennium Bible,tmb
|
||||
New International Version,niv
|
||||
New Living Translation,nlt
|
||||
New Revised Standard,nrs
|
||||
Revised Standard Version,rsv
|
||||
Good News Translation,gnt
|
||||
Douay-Rheims Bible,rhe
|
||||
The Message,msg
|
||||
The Complete Jewish Bible,cjb
|
||||
New Century Version,ncv
|
||||
GOD'S WORD Translation,gwd
|
||||
Hebrew Names Version,hnv
|
||||
World English Bible,web
|
||||
The Bible in Basic English,bbe
|
||||
Young's Literal Translation,ylt
|
||||
Today's New International Version,tnv
|
||||
New International Reader's Version,nrv
|
||||
The Darby Translation,dby
|
||||
The Webster Bible,wbt
|
||||
The Latin Vulgate,vul
|
||||
Weymouth New Testament,wnt
|
|
Binary file not shown.
@ -43,13 +43,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
Class documentation goes here.
|
||||
"""
|
||||
log.info(u'Custom Editor loaded')
|
||||
def __init__(self, parent, manager):
|
||||
def __init__(self, mediaitem, parent, manager):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self)
|
||||
self.parent = parent
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.manager = manager
|
||||
self.mediaitem = mediaitem
|
||||
self.setupUi(self)
|
||||
# Create other objects and forms.
|
||||
self.editSlideForm = EditCustomSlideForm(self)
|
||||
@ -137,7 +137,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.customSlide.credits = unicode(self.creditEdit.text())
|
||||
self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
|
||||
success = self.manager.save_object(self.customSlide)
|
||||
self.parent.auto_select_id = self.customSlide.id
|
||||
self.mediaitem.auto_select_id = self.customSlide.id
|
||||
return success
|
||||
|
||||
def onUpButtonClicked(self):
|
||||
|
@ -57,15 +57,16 @@ class CustomMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'custom/custom'
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
self.edit_custom_form = EditCustomForm(self, self.parent.manager)
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.edit_custom_form = EditCustomForm(self, self.plugin.formparent,
|
||||
self.plugin.manager)
|
||||
self.singleServiceItem = False
|
||||
self.quickPreviewAllowed = True
|
||||
self.hasSearch = True
|
||||
# Holds information about whether the edit is remotly triggered and
|
||||
# which Custom is required.
|
||||
self.remoteCustom = -1
|
||||
self.manager = parent.manager
|
||||
self.manager = plugin.manager
|
||||
|
||||
def addEndHeaderBar(self):
|
||||
self.addToolbarSeparator()
|
||||
@ -200,7 +201,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
for item in self.listView.selectedIndexes()]
|
||||
for id in id_list:
|
||||
self.parent.manager.delete_object(CustomSlide, id)
|
||||
self.plugin.manager.delete_object(CustomSlide, id)
|
||||
for row in row_list:
|
||||
self.listView.takeItem(row)
|
||||
|
||||
@ -216,7 +217,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||
service_item.add_capability(ItemCapabilities.AllowsVirtualSplit)
|
||||
customSlide = self.parent.manager.get_object(CustomSlide, item_id)
|
||||
customSlide = self.plugin.manager.get_object(CustomSlide, item_id)
|
||||
title = customSlide.title
|
||||
credit = customSlide.credits
|
||||
service_item.edit_id = item_id
|
||||
@ -248,13 +249,13 @@ class CustomMediaItem(MediaManagerItem):
|
||||
search_type = self.searchTextEdit.currentSearchType()
|
||||
if search_type == CustomSearch.Titles:
|
||||
log.debug(u'Titles Search')
|
||||
search_results = self.parent.manager.get_all_objects(CustomSlide,
|
||||
search_results = self.plugin.manager.get_all_objects(CustomSlide,
|
||||
CustomSlide.title.like(u'%' + self.whitespace.sub(u' ',
|
||||
search_keywords) + u'%'), order_by_ref=CustomSlide.title)
|
||||
self.loadList(search_results)
|
||||
elif search_type == CustomSearch.Themes:
|
||||
log.debug(u'Theme Search')
|
||||
search_results = self.parent.manager.get_all_objects(CustomSlide,
|
||||
search_results = self.plugin.manager.get_all_objects(CustomSlide,
|
||||
CustomSlide.theme_name.like(u'%' + self.whitespace.sub(u' ',
|
||||
search_keywords) + u'%'), order_by_ref=CustomSlide.title)
|
||||
self.loadList(search_results)
|
||||
|
@ -47,7 +47,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'images/image'
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.quickPreviewAllowed = True
|
||||
self.hasSearch = True
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -112,14 +112,14 @@ class ImageMediaItem(MediaManagerItem):
|
||||
|
||||
def loadList(self, list, initialLoad=False):
|
||||
if not initialLoad:
|
||||
self.parent.formparent.displayProgressBar(len(list))
|
||||
self.plugin.formparent.displayProgressBar(len(list))
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
list.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
for imageFile in list:
|
||||
if not initialLoad:
|
||||
self.parent.formparent.incrementProgressBar()
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
filename = os.path.split(unicode(imageFile))[1]
|
||||
thumb = os.path.join(self.servicePath, filename)
|
||||
if os.path.exists(thumb):
|
||||
@ -134,7 +134,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||
self.listView.addItem(item_name)
|
||||
if not initialLoad:
|
||||
self.parent.formparent.finishedProgressBar()
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
|
||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||
if item:
|
||||
@ -188,7 +188,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
Called to reset the Live backgound with the image selected,
|
||||
"""
|
||||
self.resetAction.setVisible(False)
|
||||
self.parent.liveController.display.resetImage()
|
||||
self.plugin.liveController.display.resetImage()
|
||||
|
||||
def liveThemeChanged(self):
|
||||
"""
|
||||
@ -208,7 +208,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
(path, name) = os.path.split(filename)
|
||||
self.parent.liveController.display.directImage(name, filename)
|
||||
self.plugin.liveController.display.directImage(name, filename)
|
||||
self.resetAction.setVisible(True)
|
||||
else:
|
||||
critical_error_message_box(UiStrings().LiveBGError,
|
||||
|
@ -50,7 +50,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.background = False
|
||||
self.PreviewFunction = QtGui.QPixmap(
|
||||
u':/media/media_video.png').toImage()
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.singleServiceItem = False
|
||||
self.hasSearch = True
|
||||
self.mediaObject = None
|
||||
@ -65,8 +65,8 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||
self.onNewFileMasks = unicode(translate('MediaPlugin.MediaItem',
|
||||
'Videos (%s);;Audio (%s);;%s (*)')) % (
|
||||
u' '.join(self.parent.video_extensions_list),
|
||||
u' '.join(self.parent.audio_extensions_list), UiStrings().AllFiles)
|
||||
u' '.join(self.plugin.video_extensions_list),
|
||||
u' '.join(self.plugin.audio_extensions_list), UiStrings().AllFiles)
|
||||
self.replaceAction.setText(UiStrings().ReplaceBG)
|
||||
self.replaceAction.setToolTip(UiStrings().ReplaceLiveBG)
|
||||
self.resetAction.setText(UiStrings().ResetBG)
|
||||
@ -95,7 +95,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
Called to reset the Live backgound with the media selected,
|
||||
"""
|
||||
self.resetAction.setVisible(False)
|
||||
self.parent.liveController.display.resetVideo()
|
||||
self.plugin.liveController.display.resetVideo()
|
||||
|
||||
def videobackgroundReplaced(self):
|
||||
"""
|
||||
@ -114,7 +114,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
(path, name) = os.path.split(filename)
|
||||
self.parent.liveController.display.video(filename, 0, True)
|
||||
self.plugin.liveController.display.video(filename, 0, True)
|
||||
self.resetAction.setVisible(True)
|
||||
else:
|
||||
critical_error_message_box(UiStrings().LiveBGError,
|
||||
|
@ -46,14 +46,14 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
"""
|
||||
log.info(u'Presentations Media Item loaded')
|
||||
|
||||
def __init__(self, parent, icon, title, controllers):
|
||||
def __init__(self, parent, plugin, icon, controllers):
|
||||
"""
|
||||
Constructor. Setup defaults
|
||||
"""
|
||||
self.controllers = controllers
|
||||
self.IconPath = u'presentations/presentation'
|
||||
self.Automatic = u''
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.message_listener = MessageListener(self)
|
||||
self.hasSearch = True
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -82,7 +82,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
for type in types:
|
||||
if fileType.find(type) == -1:
|
||||
fileType += u'*.%s ' % type
|
||||
self.parent.serviceManager.supportedSuffixes(type)
|
||||
self.plugin.serviceManager.supportedSuffixes(type)
|
||||
self.onNewFileMasks = unicode(translate('PresentationPlugin.MediaItem',
|
||||
'Presentations (%s)')) % fileType
|
||||
|
||||
@ -161,14 +161,14 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
titles = [os.path.split(file)[1] for file in currlist]
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.displayProgressBar(len(files))
|
||||
self.plugin.formparent.displayProgressBar(len(files))
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
files.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
for file in files:
|
||||
if not initialLoad:
|
||||
self.parent.formparent.incrementProgressBar()
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
if currlist.count(file) > 0:
|
||||
continue
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
@ -208,7 +208,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
self.listView.addItem(item_name)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.finishedProgressBar()
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
|
||||
def onDeleteClick(self):
|
||||
"""
|
||||
|
@ -99,7 +99,7 @@ class PresentationPlugin(Plugin):
|
||||
Create the Media Manager List
|
||||
"""
|
||||
return PresentationMediaItem(
|
||||
self, self.icon, self.name, self.controllers)
|
||||
self.mediadock.media_dock, self, self.icon, self.controllers)
|
||||
|
||||
def registerControllers(self, controller):
|
||||
"""
|
||||
|
@ -27,91 +27,109 @@
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>OpenLP 2.0 Remote</title>
|
||||
<title>${app_title}</title>
|
||||
<link rel="stylesheet" href="/files/jquery.mobile.css" />
|
||||
<link rel="stylesheet" href="/files/openlp.css" />
|
||||
<script type="text/javascript" src="/files/jquery.js"></script>
|
||||
<script type="text/javascript" src="/files/openlp.js"></script>
|
||||
<script type="text/javascript" src="/files/jquery.mobile.js"></script>
|
||||
<script type="text/javascript">
|
||||
translationStrings = {
|
||||
"go_live": "${go_live}",
|
||||
"add_to_service": "${add_to_service}",
|
||||
"no_results": "${no_results}",
|
||||
"back": "${back}"
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div data-role="page" id="home">
|
||||
<div data-role="header">
|
||||
<h1>OpenLP 2.0 Remote</h1>
|
||||
<h1>${app_title}</h1>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div data-role="controlgroup">
|
||||
<a href="#service-manager" data-role="button" data-icon="arrow-r" data-iconpos="right">Service Manager</a>
|
||||
<a href="#slide-controller" data-role="button" data-icon="arrow-r" data-iconpos="right">Slide Controller</a>
|
||||
<a href="#alerts" data-role="button" data-icon="arrow-r" data-iconpos="right">Alerts</a>
|
||||
<a href="#search" data-role="button" data-icon="arrow-r" data-iconpos="right">Search</a>
|
||||
<a href="#service-manager" data-role="button" data-icon="arrow-r" data-iconpos="right">${service_manager}</a>
|
||||
<a href="#slide-controller" data-role="button" data-icon="arrow-r" data-iconpos="right">${slide_controller}</a>
|
||||
<a href="#alerts" data-role="button" data-icon="arrow-r" data-iconpos="right">${alerts}</a>
|
||||
<a href="#search" data-role="button" data-icon="arrow-r" data-iconpos="right">${search}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="page" id="service-manager">
|
||||
<div data-role="header">
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">Back</a>
|
||||
<h1>Service Manager</h1>
|
||||
<a href="#" id="service-refresh" data-role="button" data-icon="refresh">Refresh</a>
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
|
||||
<h1>${service_manager}</h1>
|
||||
<a href="#" id="service-refresh" data-role="button" data-icon="refresh">${refresh}</a>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<ul data-role="listview" data-inset="true">
|
||||
</ul>
|
||||
</div>
|
||||
<div data-role="footer" data-theme="b" class="ui-bar">
|
||||
<a href="#" id="service-blank" data-role="button" data-icon="blank">Blank</a>
|
||||
<a href="#" id="service-unblank" data-role="button" data-icon="unblank">Show</a>
|
||||
<a href="#" id="service-previous" data-role="button" data-icon="arrow-l">Prev</a>
|
||||
<a href="#" id="service-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
|
||||
<a href="#" id="service-blank" data-role="button" data-icon="blank">${blank}</a>
|
||||
<a href="#" id="service-unblank" data-role="button" data-icon="unblank">${show}</a>
|
||||
<a href="#" id="service-previous" data-role="button" data-icon="arrow-l">${prev}</a>
|
||||
<a href="#" id="service-next" data-role="button" data-icon="arrow-r" data-iconpos="right">${next}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="page" id="slide-controller">
|
||||
<div data-role="header">
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">Back</a>
|
||||
<h1>Slide Controller</h1>
|
||||
<a href="#" id="controller-refresh" data-role="button" data-icon="refresh">Refresh</a>
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
|
||||
<h1>${slide_controller}</h1>
|
||||
<a href="#" id="controller-refresh" data-role="button" data-icon="refresh">${refresh}</a>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<ul data-role="listview" data-inset="true">
|
||||
</ul>
|
||||
</div>
|
||||
<div data-role="footer" data-theme="b" class="ui-bar">
|
||||
<a href="#" id="controller-blank" data-role="button" data-icon="blank">Blank</a>
|
||||
<a href="#" id="controller-unblank" data-role="button" data-icon="unblank">Show</a>
|
||||
<a href="#" id="controller-previous" data-role="button" data-icon="arrow-l">Prev</a>
|
||||
<a href="#" id="controller-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
|
||||
<a href="#" id="controller-blank" data-role="button" data-icon="blank">${blank}</a>
|
||||
<a href="#" id="controller-unblank" data-role="button" data-icon="unblank">${show}</a>
|
||||
<a href="#" id="controller-previous" data-role="button" data-icon="arrow-l">${prev}</a>
|
||||
<a href="#" id="controller-next" data-role="button" data-icon="arrow-r" data-iconpos="right">${next}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="page" id="alerts">
|
||||
<div data-role="header">
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">Back</a>
|
||||
<h1>Alerts</h1>
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
|
||||
<h1>${alerts}</h1>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div data-role="fieldcontain">
|
||||
<label for="alert-text">Text:</label>
|
||||
<label for="alert-text">${text}:</label>
|
||||
<input type="text" name="alert-text" id="alert-text" value="" />
|
||||
</div>
|
||||
<a href="#" id="alert-submit" data-role="button">Show Alert</a>
|
||||
<a href="#" id="alert-submit" data-role="button">${show_alert}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="page" id="search">
|
||||
<div data-role="header">
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">Back</a>
|
||||
<h1>Search</h1>
|
||||
<a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
|
||||
<h1>${search}</h1>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div data-role="fieldcontain">
|
||||
<label for="search-plugin">Search:</label>
|
||||
<label for="search-plugin">${search}:</label>
|
||||
<select name="search-plugin" id="search-plugin" data-native-menu="false"></select>
|
||||
</div>
|
||||
<div data-role="fieldcontain">
|
||||
<label for="search-text">Text:</label>
|
||||
<label for="search-text">${text}:</label>
|
||||
<input type="search" name="search-text" id="search-text" value="" />
|
||||
</div>
|
||||
<a href="#" id="search-submit" data-role="button">Search</a>
|
||||
<a href="#" id="search-submit" data-role="button">${search}</a>
|
||||
<ul data-role="listview" data-inset="true">
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="page" id="options">
|
||||
<div data-role="header" data-position="inline" data-theme="b">
|
||||
<h1>${options}</h1>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<input type="hidden" id="selected-item" value="" />
|
||||
<a href="#" id="go-live" data-role="button">${go_live}</a>
|
||||
<a href="#" id="add-to-service" data-role="button">${add_to_service}</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
0
openlp/plugins/remotes/html/json2.js
Executable file → Normal file
0
openlp/plugins/remotes/html/json2.js
Executable file → Normal file
@ -47,7 +47,7 @@ window.OpenLP = {
|
||||
var select = $("#search-plugin");
|
||||
select.html("");
|
||||
$.each(data.results.items, function (idx, value) {
|
||||
select.append("<option value='" + value + "'>" + value + "</option>");
|
||||
select.append("<option value='" + value[0] + "'>" + value[1] + "</option>");
|
||||
});
|
||||
select.selectmenu("refresh");
|
||||
}
|
||||
@ -215,16 +215,15 @@ window.OpenLP = {
|
||||
var ul = $("#search > div[data-role=content] > ul[data-role=listview]");
|
||||
ul.html("");
|
||||
if (data.results.items.length == 0) {
|
||||
var li = $("<li data-icon=\"false\">").text('No results');
|
||||
var li = $("<li data-icon=\"false\">").text(translationStrings["no_results"]);
|
||||
ul.append(li);
|
||||
}
|
||||
else {
|
||||
$.each(data.results.items, function (idx, value) {
|
||||
var item = $("<li>").text(value[1]);
|
||||
var golive = $("<a href=\"#\">Go Live</a>").attr("value", value[0]).click(OpenLP.goLive);
|
||||
var additem = $("<a href=\"#\">Add To Service</a>").attr("value", value[0]).click(OpenLP.addToService);
|
||||
item.append($("<ul>").append($("<li>").append(golive)).append($("<li>").append(additem)));
|
||||
ul.append(item);
|
||||
ul.append($("<li>").append($("<a>").attr("href", "#options")
|
||||
.attr("data-rel", "dialog").attr("data-transition", "pop")
|
||||
.attr("value", value[0]).click(OpenLP.showOptions)
|
||||
.text(value[1])));
|
||||
});
|
||||
}
|
||||
ul.listview("refresh");
|
||||
@ -232,19 +231,23 @@ window.OpenLP = {
|
||||
);
|
||||
return false;
|
||||
},
|
||||
showOptions: function (event) {
|
||||
var element = OpenLP.getElement(event);
|
||||
console.log(element);
|
||||
$("#selected-item").val(element.attr("value"));
|
||||
},
|
||||
goLive: function (event) {
|
||||
var item = OpenLP.getElement(event);
|
||||
var id = item.attr("value");
|
||||
var id = $("#selected-item").val();
|
||||
var text = JSON.stringify({"request": {"id": id}});
|
||||
$.getJSON(
|
||||
"/api/" + $("#search-plugin").val() + "/live",
|
||||
{"data": text})
|
||||
$.mobile.changePage("slide-controller");
|
||||
{"data": text}
|
||||
);
|
||||
$.mobile.changePage("#slide-controller");
|
||||
return false;
|
||||
},
|
||||
addToService: function (event) {
|
||||
var item = OpenLP.getElement(event);
|
||||
var id = item.attr("value");
|
||||
var id = $("#selected-item").val();
|
||||
var text = JSON.stringify({"request": {"id": id}});
|
||||
$.getJSON(
|
||||
"/api/" + $("#search-plugin").val() + "/add",
|
||||
@ -253,6 +256,7 @@ window.OpenLP = {
|
||||
history.back();
|
||||
}
|
||||
);
|
||||
$("#options").dialog("close");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -274,6 +278,8 @@ $("#controller-unblank").live("click", OpenLP.unblankDisplay);
|
||||
$("#alert-submit").live("click", OpenLP.showAlert);
|
||||
// Search
|
||||
$("#search-submit").live("click", OpenLP.search);
|
||||
$("#go-live").live("click", OpenLP.goLive);
|
||||
$("#add-to-service").live("click", OpenLP.addToService);
|
||||
// Poll the server twice a second to get any updates.
|
||||
OpenLP.getSearchablePlugins();
|
||||
$.ajaxSetup({ cache: false });
|
||||
|
@ -6,8 +6,8 @@
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode #
|
||||
# Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
@ -27,12 +27,13 @@
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>OpenLP 2.0 Stage View</title>
|
||||
<title>${stage_title}</title>
|
||||
<link rel="stylesheet" href="/files/stage.css" />
|
||||
<script type="text/javascript" src="/files/jquery.js"></script>
|
||||
<script type="text/javascript" src="/files/stage.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="hidden" id="next-text" value="${next}" />
|
||||
<div id="right">
|
||||
<div id="clock"></div>
|
||||
<div id="notes"></div>
|
||||
|
@ -100,24 +100,24 @@ window.OpenLP = {
|
||||
$("#tag" + OpenLP.currentTags[OpenLP.currentSlide]).addClass("currenttag");
|
||||
var slide = OpenLP.currentSlides[OpenLP.currentSlide];
|
||||
var text = slide["text"];
|
||||
text = text.replace(/\n/g, '<br />');
|
||||
text = text.replace(/\n/g, "<br />");
|
||||
$("#currentslide").html(text);
|
||||
text = "";
|
||||
if (OpenLP.currentSlide < OpenLP.currentSlides.length - 1) {
|
||||
for (var idx = OpenLP.currentSlide + 1; idx < OpenLP.currentSlides.length; idx++) {
|
||||
if (OpenLP.currentTags[idx] != OpenLP.currentTags[idx - 1])
|
||||
text = text + '<p class="nextslide">';
|
||||
text = text + "<p class=\"nextslide\">";
|
||||
text = text + OpenLP.currentSlides[idx]["text"];
|
||||
if (OpenLP.currentTags[idx] != OpenLP.currentTags[idx - 1])
|
||||
text = text + '</p>';
|
||||
text = text + "</p>";
|
||||
else
|
||||
text = text + '<br />';
|
||||
text = text + "<br />";
|
||||
}
|
||||
text = text.replace(/\n/g, '<br />');
|
||||
text = text.replace(/\n/g, "<br />");
|
||||
$("#nextslide").html(text);
|
||||
}
|
||||
else {
|
||||
text = '<p class="nextslide">Next: ' + OpenLP.nextSong + '</p>';
|
||||
text = "<p class=\"nextslide\">" + $("#next-text").val() + ": " + OpenLP.nextSong + "</p>";
|
||||
$("#nextslide").html(text);
|
||||
}
|
||||
},
|
||||
|
@ -115,7 +115,6 @@ import logging
|
||||
import os
|
||||
import urlparse
|
||||
import re
|
||||
from pprint import pformat
|
||||
|
||||
try:
|
||||
import json
|
||||
@ -123,10 +122,11 @@ except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
from PyQt4 import QtCore, QtNetwork
|
||||
from mako.template import Template
|
||||
|
||||
from openlp.core.lib import Receiver, PluginStatus
|
||||
from openlp.core.lib import Receiver, PluginStatus, StringContent
|
||||
from openlp.core.ui import HideMode
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.core.utils import AppLocation, translate
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -154,12 +154,12 @@ class HttpServer(object):
|
||||
e.g. http://localhost:4316/send/slidecontroller_live_next
|
||||
http://localhost:4316/send/alerts_text?q=your%20alert%20text
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
def __init__(self, plugin):
|
||||
"""
|
||||
Initialise the httpserver, and start the server
|
||||
"""
|
||||
log.debug(u'Initialise httpserver')
|
||||
self.parent = parent
|
||||
self.plugin = plugin
|
||||
self.html_dir = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.PluginsDir),
|
||||
u'remotes', u'html')
|
||||
@ -176,10 +176,10 @@ class HttpServer(object):
|
||||
"""
|
||||
log.debug(u'Start TCP server')
|
||||
port = QtCore.QSettings().value(
|
||||
self.parent.settingsSection + u'/port',
|
||||
self.plugin.settingsSection + u'/port',
|
||||
QtCore.QVariant(4316)).toInt()[0]
|
||||
address = QtCore.QSettings().value(
|
||||
self.parent.settingsSection + u'/ip address',
|
||||
self.plugin.settingsSection + u'/ip address',
|
||||
QtCore.QVariant(u'0.0.0.0')).toString()
|
||||
self.server = QtNetwork.QTcpServer()
|
||||
self.server.listen(QtNetwork.QHostAddress(address), port)
|
||||
@ -261,10 +261,11 @@ class HttpConnection(object):
|
||||
self.ready_read)
|
||||
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'),
|
||||
self.disconnected)
|
||||
self.translate()
|
||||
|
||||
def _get_service_items(self):
|
||||
service_items = []
|
||||
service_manager = self.parent.parent.serviceManager
|
||||
service_manager = self.parent.plugin.serviceManager
|
||||
if self.parent.current_item:
|
||||
cur_uuid = self.parent.current_item._uuid
|
||||
else:
|
||||
@ -280,6 +281,31 @@ class HttpConnection(object):
|
||||
})
|
||||
return service_items
|
||||
|
||||
def translate(self):
|
||||
"""
|
||||
Translate various strings in the mobile app.
|
||||
"""
|
||||
self.template_vars = {
|
||||
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Remote'),
|
||||
'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Stage View'),
|
||||
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
|
||||
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
|
||||
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
||||
'search': translate('RemotePlugin.Mobile', 'Search'),
|
||||
'back': translate('RemotePlugin.Mobile', 'Back'),
|
||||
'refresh': translate('RemotePlugin.Mobile', 'Refresh'),
|
||||
'blank': translate('RemotePlugin.Mobile', 'Blank'),
|
||||
'show': translate('RemotePlugin.Mobile', 'Show'),
|
||||
'prev': translate('RemotePlugin.Mobile', 'Prev'),
|
||||
'next': translate('RemotePlugin.Mobile', 'Next'),
|
||||
'text': translate('RemotePlugin.Mobile', 'Text'),
|
||||
'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'),
|
||||
'go_live': translate('RemotePlugin.Mobile', 'Go Live'),
|
||||
'add_to_service': translate('RemotePlugin.Mobile', 'Add To Service'),
|
||||
'no_results': translate('RemotePlugin.Mobile', 'No Results'),
|
||||
'options': translate('RemotePlugin.Mobile', 'Options')
|
||||
}
|
||||
|
||||
def ready_read(self):
|
||||
"""
|
||||
Data has been sent from the client. Respond to it
|
||||
@ -327,8 +353,11 @@ class HttpConnection(object):
|
||||
if not path.startswith(self.parent.html_dir):
|
||||
return HttpResponse(code=u'404 Not Found')
|
||||
ext = os.path.splitext(filename)[1]
|
||||
html = None
|
||||
if ext == u'.html':
|
||||
mimetype = u'text/html'
|
||||
variables = self.template_vars
|
||||
html = Template(filename=path, input_encoding=u'utf-8', output_encoding=u'utf-8').render(**variables)
|
||||
elif ext == u'.css':
|
||||
mimetype = u'text/css'
|
||||
elif ext == u'.js':
|
||||
@ -343,9 +372,12 @@ class HttpConnection(object):
|
||||
mimetype = u'text/plain'
|
||||
file_handle = None
|
||||
try:
|
||||
file_handle = open(path, u'rb')
|
||||
log.debug(u'Opened %s' % path)
|
||||
content = file_handle.read()
|
||||
if html:
|
||||
content = html
|
||||
else:
|
||||
file_handle = open(path, u'rb')
|
||||
log.debug(u'Opened %s' % path)
|
||||
content = file_handle.read()
|
||||
except IOError:
|
||||
log.exception(u'Failed to open %s' % path)
|
||||
return HttpResponse(code=u'404 Not Found')
|
||||
@ -457,10 +489,11 @@ class HttpConnection(object):
|
||||
"""
|
||||
if action == u'search':
|
||||
searches = []
|
||||
for plugin in self.parent.parent.pluginManager.plugins:
|
||||
for plugin in self.parent.plugin.pluginManager.plugins:
|
||||
if plugin.status == PluginStatus.Active and \
|
||||
plugin.mediaItem and plugin.mediaItem.hasSearch:
|
||||
searches.append(plugin.name)
|
||||
searches.append([plugin.name, unicode(
|
||||
plugin.textStrings[StringContent.Name][u'plural'])])
|
||||
return HttpResponse(
|
||||
json.dumps({u'results': {u'items': searches}}),
|
||||
{u'Content-Type': u'application/json'})
|
||||
@ -473,10 +506,10 @@ class HttpConnection(object):
|
||||
The plugin name to search in.
|
||||
"""
|
||||
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
||||
plugin = self.parent.parent.pluginManager.get_plugin_by_name(type)
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and \
|
||||
plugin.mediaItem and plugin.mediaItem.hasSearch:
|
||||
results =plugin.mediaItem.search(text)
|
||||
results = plugin.mediaItem.search(text)
|
||||
else:
|
||||
results = []
|
||||
return HttpResponse(
|
||||
@ -488,7 +521,7 @@ class HttpConnection(object):
|
||||
Go live on an item of type ``type``.
|
||||
"""
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
plugin = self.parent.parent.pluginManager.get_plugin_by_name(type)
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||
plugin.mediaItem.goLive(id)
|
||||
|
||||
@ -497,7 +530,7 @@ class HttpConnection(object):
|
||||
Add item of type ``type`` to the end of the service
|
||||
"""
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
plugin = self.parent.parent.pluginManager.get_plugin_by_name(type)
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||
item_id = plugin.mediaItem.createItemFromId(id)
|
||||
plugin.mediaItem.addToService(item_id)
|
||||
|
@ -47,12 +47,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
"""
|
||||
log.info(u'%s EditSongForm loaded', __name__)
|
||||
|
||||
def __init__(self, parent, manager):
|
||||
def __init__(self, mediaitem, parent, manager):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.mediaitem = mediaitem
|
||||
self.song = None
|
||||
# can this be automated?
|
||||
self.width = 400
|
||||
@ -90,7 +90,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
self.onVerseListViewPressed)
|
||||
QtCore.QObject.connect(self.themeAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.parent.parent.renderer.theme_manager.onAddTheme)
|
||||
self.mediaitem.plugin.renderer.theme_manager.onAddTheme)
|
||||
QtCore.QObject.connect(self.maintenanceButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -649,7 +649,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
text = unicode(self.songBookComboBox.currentText())
|
||||
if item == 0 and text:
|
||||
temp_song_book = text
|
||||
self.parent.song_maintenance_form.exec_()
|
||||
self.mediaitem.song_maintenance_form.exec_()
|
||||
self.loadAuthors()
|
||||
self.loadBooks()
|
||||
self.loadTopics()
|
||||
@ -755,7 +755,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
self.song.topics.append(self.manager.get_object(Topic, topicId))
|
||||
clean_song(self.manager, self.song)
|
||||
self.manager.save_object(self.song)
|
||||
self.parent.auto_select_id = self.song.id
|
||||
self.mediaitem.auto_select_id = self.song.id
|
||||
|
||||
def _processLyrics(self):
|
||||
"""
|
||||
|
@ -265,52 +265,57 @@ def clean_song(manager, song):
|
||||
whitespace = re.compile(r'\W+', re.UNICODE)
|
||||
song.search_title = (whitespace.sub(u' ', song.title).strip() + u'@' +
|
||||
whitespace.sub(u' ', song.alternate_title).strip()).strip().lower()
|
||||
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5). This
|
||||
# is not very important, but this keeps the database clean. This can be
|
||||
# removed when everybody has cleaned his songs.
|
||||
song.lyrics = song.lyrics.replace(u'<lyrics language="en">', u'<lyrics>')
|
||||
verses = SongXML().get_verses(song.lyrics)
|
||||
lyrics = u' '.join([whitespace.sub(u' ', verse[1]) for verse in verses])
|
||||
song.search_lyrics = lyrics.lower()
|
||||
# We need a new and clean SongXML instance.
|
||||
sxml = SongXML()
|
||||
# Rebuild the song's verses, to remove any wrong verse names (for example
|
||||
# translated ones), which might have been added prior to 1.9.5.
|
||||
# List for later comparison.
|
||||
compare_order = []
|
||||
for verse in verses:
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(
|
||||
verse[0][u'type'])]
|
||||
sxml.add_verse_to_lyrics(
|
||||
verse_type,
|
||||
verse[0][u'label'],
|
||||
verse[1],
|
||||
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
||||
)
|
||||
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])
|
||||
).upper())
|
||||
if verse[0][u'label'] == u'1':
|
||||
compare_order.append(verse_type.upper())
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
# Rebuild the verse order, to convert translated verse tags, which might
|
||||
# have been added prior to 1.9.5.
|
||||
if song.verse_order:
|
||||
order = song.verse_order.strip().split()
|
||||
else:
|
||||
order = []
|
||||
new_order = []
|
||||
for verse_def in order:
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(verse_def[0])]
|
||||
if len(verse_def) > 1:
|
||||
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
|
||||
# Only do this, if we the song is a 1.9.4 song (or older).
|
||||
if song.lyrics.find(u'<lyrics language="en">') != -1:
|
||||
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
|
||||
# This is not very important, but this keeps the database clean. This
|
||||
# can be removed when everybody has cleaned his songs.
|
||||
song.lyrics = song.lyrics.replace(
|
||||
u'<lyrics language="en">', u'<lyrics>')
|
||||
verses = SongXML().get_verses(song.lyrics)
|
||||
lyrics = u' '.join([whitespace.sub(u' ', verse[1]) for verse in verses])
|
||||
song.search_lyrics = lyrics.lower()
|
||||
# We need a new and clean SongXML instance.
|
||||
sxml = SongXML()
|
||||
# Rebuild the song's verses, to remove any wrong verse names (for
|
||||
# example translated ones), which might have been added prior to 1.9.5.
|
||||
# List for later comparison.
|
||||
compare_order = []
|
||||
for verse in verses:
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(
|
||||
verse[0][u'type'])]
|
||||
sxml.add_verse_to_lyrics(
|
||||
verse_type,
|
||||
verse[0][u'label'],
|
||||
verse[1],
|
||||
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
||||
)
|
||||
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])
|
||||
).upper())
|
||||
if verse[0][u'label'] == u'1':
|
||||
compare_order.append(verse_type.upper())
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
# Rebuild the verse order, to convert translated verse tags, which might
|
||||
# have been added prior to 1.9.5.
|
||||
if song.verse_order:
|
||||
order = song.verse_order.strip().split()
|
||||
else:
|
||||
new_order.append(verse_type.upper())
|
||||
song.verse_order = u' '.join(new_order)
|
||||
# Check if the verse order contains tags for verses which do not exist.
|
||||
for order in new_order:
|
||||
if order not in compare_order:
|
||||
song.verse_order = u''
|
||||
break
|
||||
order = []
|
||||
new_order = []
|
||||
for verse_def in order:
|
||||
verse_type = VerseType.Tags[
|
||||
VerseType.from_loose_input(verse_def[0])]
|
||||
if len(verse_def) > 1:
|
||||
new_order.append(
|
||||
(u'%s%s' % (verse_type, verse_def[1:])).upper())
|
||||
else:
|
||||
new_order.append(verse_type.upper())
|
||||
song.verse_order = u' '.join(new_order)
|
||||
# Check if the verse order contains tags for verses which do not exist.
|
||||
for order in new_order:
|
||||
if order not in compare_order:
|
||||
song.verse_order = u''
|
||||
break
|
||||
# The song does not have any author, add one.
|
||||
if not song.authors:
|
||||
name = SongStrings.AuthorUnknown
|
||||
|
@ -165,7 +165,7 @@ def init_schema(url):
|
||||
Column(u'id', types.Integer, primary_key=True),
|
||||
Column(u'first_name', types.Unicode(128)),
|
||||
Column(u'last_name', types.Unicode(128)),
|
||||
Column(u'display_name', types.Unicode(255), nullable=False)
|
||||
Column(u'display_name', types.Unicode(255), index=True, nullable=False)
|
||||
)
|
||||
|
||||
# Definition of the "media_files" table
|
||||
@ -186,7 +186,7 @@ def init_schema(url):
|
||||
songs_table = Table(u'songs', metadata,
|
||||
Column(u'id', types.Integer, primary_key=True),
|
||||
Column(u'song_book_id', types.Integer,
|
||||
ForeignKey(u'song_books.id'), default=0),
|
||||
ForeignKey(u'song_books.id'), default=None),
|
||||
Column(u'title', types.Unicode(255), nullable=False),
|
||||
Column(u'alternate_title', types.Unicode(255)),
|
||||
Column(u'lyrics', types.UnicodeText, nullable=False),
|
||||
@ -203,7 +203,7 @@ def init_schema(url):
|
||||
# Definition of the "topics" table
|
||||
topics_table = Table(u'topics', metadata,
|
||||
Column(u'id', types.Integer, primary_key=True),
|
||||
Column(u'name', types.Unicode(128), nullable=False)
|
||||
Column(u'name', types.Unicode(128), index=True, nullable=False)
|
||||
)
|
||||
|
||||
# Definition of the "authors_songs" table
|
||||
@ -230,27 +230,6 @@ def init_schema(url):
|
||||
ForeignKey(u'topics.id'), primary_key=True)
|
||||
)
|
||||
|
||||
# Define table indexes
|
||||
Index(u'authors_id', authors_table.c.id)
|
||||
Index(u'authors_display_name_id', authors_table.c.display_name,
|
||||
authors_table.c.id)
|
||||
Index(u'media_files_id', media_files_table.c.id)
|
||||
Index(u'song_books_id', song_books_table.c.id)
|
||||
Index(u'songs_id', songs_table.c.id)
|
||||
Index(u'topics_id', topics_table.c.id)
|
||||
Index(u'authors_songs_author', authors_songs_table.c.author_id,
|
||||
authors_songs_table.c.song_id)
|
||||
Index(u'authors_songs_song', authors_songs_table.c.song_id,
|
||||
authors_songs_table.c.author_id)
|
||||
Index(u'media_files_songs_file', media_files_songs_table.c.media_file_id,
|
||||
media_files_songs_table.c.song_id)
|
||||
Index(u'media_files_songs_song', media_files_songs_table.c.song_id,
|
||||
media_files_songs_table.c.media_file_id)
|
||||
Index(u'topics_song_topic', songs_topics_table.c.topic_id,
|
||||
songs_topics_table.c.song_id)
|
||||
Index(u'topics_song_song', songs_topics_table.c.song_id,
|
||||
songs_topics_table.c.topic_id)
|
||||
|
||||
mapper(Author, authors_table)
|
||||
mapper(Book, song_books_table)
|
||||
mapper(MediaFile, media_files_table)
|
||||
|
@ -27,6 +27,7 @@
|
||||
"""
|
||||
The :mod:`importer` modules provides the general song import functionality.
|
||||
"""
|
||||
import logging
|
||||
from opensongimport import OpenSongImport
|
||||
from easislidesimport import EasiSlidesImport
|
||||
from olpimport import OpenLPSongImport
|
||||
@ -38,20 +39,24 @@ from songbeamerimport import SongBeamerImport
|
||||
from songshowplusimport import SongShowPlusImport
|
||||
from foilpresenterimport import FoilPresenterImport
|
||||
# Imports that might fail
|
||||
log = logging.getLogger(__name__)
|
||||
try:
|
||||
from olp1import import OpenLP1SongImport
|
||||
HAS_OPENLP1 = True
|
||||
except ImportError:
|
||||
log.exception('Error importing %s', 'OpenLP1SongImport')
|
||||
HAS_OPENLP1 = False
|
||||
try:
|
||||
from sofimport import SofImport
|
||||
HAS_SOF = True
|
||||
except ImportError:
|
||||
log.exception('Error importing %s', 'SofImport')
|
||||
HAS_SOF = False
|
||||
try:
|
||||
from oooimport import OooImport
|
||||
HAS_OOO = True
|
||||
except ImportError:
|
||||
log.exception('Error importing %s', 'OooImport')
|
||||
HAS_OOO = False
|
||||
|
||||
class SongFormat(object):
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
import logging
|
||||
import locale
|
||||
import re
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from sqlalchemy.sql import or_
|
||||
@ -62,12 +63,13 @@ class SongMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'songs/song'
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
self.edit_song_form = EditSongForm(self, self.parent.manager)
|
||||
self.openLyrics = OpenLyrics(self.parent.manager)
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.edit_song_form = EditSongForm(self, self.plugin.formparent,
|
||||
self.plugin.manager)
|
||||
self.openLyrics = OpenLyrics(self.plugin.manager)
|
||||
self.singleServiceItem = False
|
||||
self.song_maintenance_form = SongMaintenanceForm(
|
||||
self.parent.manager, self)
|
||||
self.plugin.manager, self)
|
||||
# Holds information about whether the edit is remotly triggered and
|
||||
# which Song is required.
|
||||
self.remoteSong = -1
|
||||
@ -178,31 +180,31 @@ class SongMediaItem(MediaManagerItem):
|
||||
self.displayResultsSong(search_results)
|
||||
elif search_type == SongSearch.Titles:
|
||||
log.debug(u'Titles Search')
|
||||
search_results = self.parent.manager.get_all_objects(Song,
|
||||
search_results = self.plugin.manager.get_all_objects(Song,
|
||||
Song.search_title.like(u'%' + self.whitespace.sub(u' ',
|
||||
search_keywords.lower()) + u'%'))
|
||||
self.displayResultsSong(search_results)
|
||||
elif search_type == SongSearch.Lyrics:
|
||||
log.debug(u'Lyrics Search')
|
||||
search_results = self.parent.manager.get_all_objects(Song,
|
||||
search_results = self.plugin.manager.get_all_objects(Song,
|
||||
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'))
|
||||
self.displayResultsSong(search_results)
|
||||
elif search_type == SongSearch.Authors:
|
||||
log.debug(u'Authors Search')
|
||||
search_results = self.parent.manager.get_all_objects(Author,
|
||||
search_results = self.plugin.manager.get_all_objects(Author,
|
||||
Author.display_name.like(u'%' + search_keywords + u'%'),
|
||||
Author.display_name.asc())
|
||||
self.displayResultsAuthor(search_results)
|
||||
elif search_type == SongSearch.Themes:
|
||||
log.debug(u'Theme Search')
|
||||
search_results = self.parent.manager.get_all_objects(Song,
|
||||
search_results = self.plugin.manager.get_all_objects(Song,
|
||||
Song.theme_name.like(u'%' + self.whitespace.sub(u' ',
|
||||
search_keywords) + u'%'))
|
||||
self.displayResultsSong(search_results)
|
||||
self.check_search_result()
|
||||
|
||||
def searchEntire(self, search_keywords):
|
||||
return self.parent.manager.get_all_objects(Song,
|
||||
return self.plugin.manager.get_all_objects(Song,
|
||||
or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ',
|
||||
search_keywords.lower()) + u'%'),
|
||||
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'),
|
||||
@ -225,7 +227,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
if self.editItem and self.updateServiceOnEdit and \
|
||||
not self.remoteTriggered:
|
||||
item = self.buildServiceItem(self.editItem)
|
||||
self.parent.serviceManager.replaceServiceItem(item)
|
||||
self.plugin.serviceManager.replaceServiceItem(item)
|
||||
self.onRemoteEditClear()
|
||||
self.onSearchTextButtonClick()
|
||||
log.debug(u'onSongListLoad - finished')
|
||||
@ -286,12 +288,12 @@ class SongMediaItem(MediaManagerItem):
|
||||
|
||||
def onImportClick(self):
|
||||
if not hasattr(self, u'import_wizard'):
|
||||
self.import_wizard = SongImportForm(self, self.parent)
|
||||
self.import_wizard = SongImportForm(self, self.plugin)
|
||||
if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
|
||||
Receiver.send_message(u'songs_load_list')
|
||||
|
||||
def onExportClick(self):
|
||||
export_wizard = SongExportForm(self, self.parent)
|
||||
export_wizard = SongExportForm(self, self.plugin)
|
||||
export_wizard.exec_()
|
||||
|
||||
def onNewClick(self):
|
||||
@ -316,7 +318,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
log.debug(u'onRemoteEdit %s' % message)
|
||||
remote_type, song_id = message.split(u':')
|
||||
song_id = int(song_id)
|
||||
valid = self.parent.manager.get_object(Song, song_id)
|
||||
valid = self.plugin.manager.get_object(Song, song_id)
|
||||
if valid:
|
||||
self.remoteSong = song_id
|
||||
self.remoteTriggered = remote_type
|
||||
@ -352,7 +354,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
return
|
||||
for item in items:
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
self.parent.manager.delete_object(Song, item_id)
|
||||
self.plugin.manager.delete_object(Song, item_id)
|
||||
self.onSearchTextButtonClick()
|
||||
|
||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||
@ -364,7 +366,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
|
||||
service_item.add_capability(ItemCapabilities.AddIfNewItem)
|
||||
service_item.add_capability(ItemCapabilities.AllowsVirtualSplit)
|
||||
song = self.parent.manager.get_object(Song, item_id)
|
||||
song = self.plugin.manager.get_object(Song, item_id)
|
||||
service_item.theme = song.theme_name
|
||||
service_item.edit_id = item_id
|
||||
if song.lyrics.startswith(u'<?xml version='):
|
||||
@ -448,12 +450,12 @@ class SongMediaItem(MediaManagerItem):
|
||||
# that the search title (data_string[u'title']) is probably wrong.
|
||||
# We add "@" to search title and hope that we do not add any
|
||||
# duplicate. This should work for songs without alternate title.
|
||||
search_results = self.parent.manager.get_all_objects(Song,
|
||||
search_results = self.plugin.manager.get_all_objects(Song,
|
||||
Song.search_title == (re.compile(r'\W+', re.UNICODE).sub(u' ',
|
||||
item.data_string[u'title'].strip()) + u'@').strip().lower(),
|
||||
Song.search_title.asc())
|
||||
else:
|
||||
search_results = self.parent.manager.get_all_objects(Song,
|
||||
search_results = self.plugin.manager.get_all_objects(Song,
|
||||
Song.search_title == item.data_string[u'title'],
|
||||
Song.search_title.asc())
|
||||
author_list = item.data_string[u'authors'].split(u', ')
|
||||
|
@ -30,6 +30,7 @@ import os
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.utils import get_uno_command, get_uno_instance
|
||||
from openlp.core.lib import translate
|
||||
from songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -39,8 +40,10 @@ if os.name == u'nt':
|
||||
PAGE_BEFORE = 4
|
||||
PAGE_AFTER = 5
|
||||
PAGE_BOTH = 6
|
||||
NoConnectException = Exception
|
||||
else:
|
||||
import uno
|
||||
from com.sun.star.connection import NoConnectException
|
||||
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
|
||||
|
||||
class OooImport(SongImport):
|
||||
@ -57,7 +60,17 @@ class OooImport(SongImport):
|
||||
self.process_started = False
|
||||
|
||||
def do_import(self):
|
||||
self.start_ooo()
|
||||
if not isinstance(self.import_source, list):
|
||||
return
|
||||
try:
|
||||
self.start_ooo()
|
||||
except NoConnectException as exc:
|
||||
self.log_error(
|
||||
self.import_source[0],
|
||||
translate('SongsPlugin.SongImport',
|
||||
'Unable to open OpenOffice.org or LibreOffice'))
|
||||
log.error(exc)
|
||||
return
|
||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||
for filename in self.import_source:
|
||||
if self.stop_import_flag:
|
||||
@ -68,6 +81,13 @@ class OooImport(SongImport):
|
||||
if self.document:
|
||||
self.process_ooo_document()
|
||||
self.close_ooo_file()
|
||||
else:
|
||||
self.log_error(self.filepath,
|
||||
translate('SongsPlugin.SongImport',
|
||||
'Unable to open file'))
|
||||
else:
|
||||
self.log_error(self.filepath,
|
||||
translate('SongsPlugin.SongImport', 'File not found'))
|
||||
self.close_ooo()
|
||||
|
||||
def process_ooo_document(self):
|
||||
@ -99,13 +119,16 @@ class OooImport(SongImport):
|
||||
while uno_instance is None and loop < 5:
|
||||
try:
|
||||
uno_instance = get_uno_instance(resolver)
|
||||
except:
|
||||
except NoConnectException:
|
||||
log.exception("Failed to resolve uno connection")
|
||||
self.start_ooo_process()
|
||||
loop += 1
|
||||
manager = uno_instance.ServiceManager
|
||||
self.desktop = manager.createInstanceWithContext(
|
||||
"com.sun.star.frame.Desktop", uno_instance)
|
||||
else:
|
||||
manager = uno_instance.ServiceManager
|
||||
self.desktop = manager.createInstanceWithContext(
|
||||
"com.sun.star.frame.Desktop", uno_instance)
|
||||
return
|
||||
raise
|
||||
|
||||
def start_ooo_process(self):
|
||||
try:
|
||||
@ -145,8 +168,8 @@ class OooImport(SongImport):
|
||||
else:
|
||||
self.import_wizard.incrementProgressBar(
|
||||
u'Processing file ' + filepath, 0)
|
||||
except:
|
||||
log.exception("open_ooo_file failed")
|
||||
except AttributeError:
|
||||
log.exception("open_ooo_file failed: %s", url)
|
||||
return
|
||||
|
||||
def close_ooo_file(self):
|
||||
|
@ -31,21 +31,27 @@
|
||||
# http://www.oooforum.org/forum/viewtopic.phtml?t=14409
|
||||
# http://wiki.services.openoffice.org/wiki/Python
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
from oooimport import OooImport
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
if os.name == u'nt':
|
||||
BOLD = 150.0
|
||||
ITALIC = 2
|
||||
from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
|
||||
RuntimeException = Exception
|
||||
else:
|
||||
try:
|
||||
from com.sun.star.awt.FontWeight import BOLD
|
||||
from com.sun.star.awt.FontSlant import ITALIC
|
||||
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \
|
||||
PAGE_BOTH
|
||||
from com.sun.star.uno import RuntimeException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@ -86,16 +92,18 @@ class SofImport(OooImport):
|
||||
"""
|
||||
self.blanklines = 0
|
||||
self.new_song()
|
||||
paragraphs = self.document.getText().createEnumeration()
|
||||
while paragraphs.hasMoreElements():
|
||||
if self.stop_import_flag:
|
||||
return
|
||||
paragraph = paragraphs.nextElement()
|
||||
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
||||
self.process_paragraph(paragraph)
|
||||
if self.song:
|
||||
self.finish()
|
||||
self.song = False
|
||||
try:
|
||||
paragraphs = self.document.getText().createEnumeration()
|
||||
while paragraphs.hasMoreElements():
|
||||
if self.stop_import_flag:
|
||||
return
|
||||
paragraph = paragraphs.nextElement()
|
||||
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
||||
self.process_paragraph(paragraph)
|
||||
except RuntimeException as exc:
|
||||
log.exception(u'Error processing file: %s', exc)
|
||||
if not self.finish():
|
||||
self.log_error(self.filepath)
|
||||
|
||||
def process_paragraph(self, paragraph):
|
||||
"""
|
||||
|
@ -514,7 +514,7 @@ class OpenLyrics(object):
|
||||
``song``
|
||||
The song object.
|
||||
"""
|
||||
song.song_book_id = 0
|
||||
song.song_book_id = None
|
||||
song.song_number = u''
|
||||
if hasattr(properties, u'songbooks'):
|
||||
for songbook in properties.songbooks.songbook:
|
||||
|
@ -62,44 +62,44 @@ class SongUsagePlugin(Plugin):
|
||||
"""
|
||||
log.info(u'add tools menu')
|
||||
self.toolsMenu = tools_menu
|
||||
self.SongUsageMenu = QtGui.QMenu(tools_menu)
|
||||
self.SongUsageMenu.setObjectName(u'SongUsageMenu')
|
||||
self.SongUsageMenu.setTitle(translate(
|
||||
self.songUsageMenu = QtGui.QMenu(tools_menu)
|
||||
self.songUsageMenu.setObjectName(u'songUsageMenu')
|
||||
self.songUsageMenu.setTitle(translate(
|
||||
'SongUsagePlugin', '&Song Usage Tracking'))
|
||||
# SongUsage Delete
|
||||
self.SongUsageDelete = base_action(tools_menu, u'SongUsageDelete')
|
||||
self.SongUsageDelete.setText(translate('SongUsagePlugin',
|
||||
self.songUsageDelete = base_action(tools_menu, u'songUsageDelete')
|
||||
self.songUsageDelete.setText(translate('SongUsagePlugin',
|
||||
'&Delete Tracking Data'))
|
||||
self.SongUsageDelete.setStatusTip(translate('SongUsagePlugin',
|
||||
self.songUsageDelete.setStatusTip(translate('SongUsagePlugin',
|
||||
'Delete song usage data up to a specified date.'))
|
||||
# SongUsage Report
|
||||
self.SongUsageReport = base_action(tools_menu, u'SongUsageReport')
|
||||
self.SongUsageReport.setText(
|
||||
self.songUsageReport = base_action(tools_menu, u'songUsageReport')
|
||||
self.songUsageReport.setText(
|
||||
translate('SongUsagePlugin', '&Extract Tracking Data'))
|
||||
self.SongUsageReport.setStatusTip(
|
||||
self.songUsageReport.setStatusTip(
|
||||
translate('SongUsagePlugin', 'Generate a report on song usage.'))
|
||||
# SongUsage activation
|
||||
self.SongUsageStatus = shortcut_action(tools_menu, u'SongUsageStatus',
|
||||
self.songUsageStatus = shortcut_action(tools_menu, u'songUsageStatus',
|
||||
[QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False)
|
||||
self.SongUsageStatus.setText(translate(
|
||||
self.songUsageStatus.setText(translate(
|
||||
'SongUsagePlugin', 'Toggle Tracking'))
|
||||
self.SongUsageStatus.setStatusTip(translate('SongUsagePlugin',
|
||||
self.songUsageStatus.setStatusTip(translate('SongUsagePlugin',
|
||||
'Toggle the tracking of song usage.'))
|
||||
#Add Menus together
|
||||
self.toolsMenu.addAction(self.SongUsageMenu.menuAction())
|
||||
self.SongUsageMenu.addAction(self.SongUsageStatus)
|
||||
self.SongUsageMenu.addSeparator()
|
||||
self.SongUsageMenu.addAction(self.SongUsageDelete)
|
||||
self.SongUsageMenu.addAction(self.SongUsageReport)
|
||||
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
|
||||
self.songUsageMenu.addAction(self.songUsageStatus)
|
||||
self.songUsageMenu.addSeparator()
|
||||
self.songUsageMenu.addAction(self.songUsageDelete)
|
||||
self.songUsageMenu.addAction(self.songUsageReport)
|
||||
# Signals and slots
|
||||
QtCore.QObject.connect(self.SongUsageStatus,
|
||||
QtCore.QObject.connect(self.songUsageStatus,
|
||||
QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
self.SongUsageStatus.setChecked)
|
||||
QtCore.QObject.connect(self.SongUsageDelete,
|
||||
self.songUsageStatus.setChecked)
|
||||
QtCore.QObject.connect(self.songUsageDelete,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
|
||||
QtCore.QObject.connect(self.SongUsageReport,
|
||||
QtCore.QObject.connect(self.songUsageReport,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onSongUsageReport)
|
||||
self.SongUsageMenu.menuAction().setVisible(False)
|
||||
self.songUsageMenu.menuAction().setVisible(False)
|
||||
|
||||
def initialise(self):
|
||||
log.info(u'SongUsage Initialising')
|
||||
@ -110,20 +110,20 @@ class SongUsagePlugin(Plugin):
|
||||
self.SongUsageActive = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/active',
|
||||
QtCore.QVariant(False)).toBool()
|
||||
self.SongUsageStatus.setChecked(self.SongUsageActive)
|
||||
self.songUsageStatus.setChecked(self.SongUsageActive)
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.add_action(self.SongUsageDelete,
|
||||
action_list.add_action(self.songUsageDelete,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
action_list.add_action(self.SongUsageReport,
|
||||
action_list.add_action(self.songUsageReport,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
action_list.add_action(self.SongUsageStatus,
|
||||
action_list.add_action(self.songUsageStatus,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
if self.manager is None:
|
||||
self.manager = Manager(u'songusage', init_schema)
|
||||
self.SongUsagedeleteform = SongUsageDeleteForm(self.manager,
|
||||
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
|
||||
self.formparent)
|
||||
self.SongUsagedetailform = SongUsageDetailForm(self, self.formparent)
|
||||
self.SongUsageMenu.menuAction().setVisible(True)
|
||||
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
|
||||
self.songUsageMenu.menuAction().setVisible(True)
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
@ -132,13 +132,13 @@ class SongUsagePlugin(Plugin):
|
||||
log.info(u'Plugin Finalise')
|
||||
self.manager.finalise()
|
||||
Plugin.finalise(self)
|
||||
self.SongUsageMenu.menuAction().setVisible(False)
|
||||
self.songUsageMenu.menuAction().setVisible(False)
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.remove_action(self.SongUsageDelete,
|
||||
action_list.remove_action(self.songUsageDelete,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
action_list.remove_action(self.SongUsageReport,
|
||||
action_list.remove_action(self.songUsageReport,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
action_list.remove_action(self.SongUsageStatus,
|
||||
action_list.remove_action(self.songUsageStatus,
|
||||
translate('SongUsagePlugin', 'Song Usage'))
|
||||
#stop any events being processed
|
||||
self.SongUsageActive = False
|
||||
@ -160,17 +160,15 @@ class SongUsagePlugin(Plugin):
|
||||
song_usage_item.title = audit[0]
|
||||
song_usage_item.copyright = audit[2]
|
||||
song_usage_item.ccl_number = audit[3]
|
||||
song_usage_item.authors = u''
|
||||
for author in audit[1]:
|
||||
song_usage_item.authors += author + u' '
|
||||
song_usage_item.authors = u' '.join(audit[1])
|
||||
self.manager.save_object(song_usage_item)
|
||||
|
||||
def onSongUsageDelete(self):
|
||||
self.SongUsagedeleteform.exec_()
|
||||
self.songUsageDeleteForm.exec_()
|
||||
|
||||
def onSongUsageReport(self):
|
||||
self.SongUsagedetailform.initialise()
|
||||
self.SongUsagedetailform.exec_()
|
||||
self.songUsageDetailForm.initialise()
|
||||
self.songUsageDetailForm.exec_()
|
||||
|
||||
def about(self):
|
||||
about_text = translate('SongUsagePlugin', '<strong>SongUsage Plugin'
|
||||
|
BIN
resources/images/bibles_upgrade_alert.png
Normal file
BIN
resources/images/bibles_upgrade_alert.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 762 B |
@ -24,6 +24,7 @@
|
||||
<qresource prefix="bibles">
|
||||
<file>bibles_search_text.png</file>
|
||||
<file>bibles_search_reference.png</file>
|
||||
<file>bibles_upgrade_alert.png</file>
|
||||
<file>bibles_search_unlock.png</file>
|
||||
<file>bibles_search_lock.png</file>
|
||||
</qresource>
|
||||
|
Loading…
Reference in New Issue
Block a user