← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/bug-772523 into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/bug-772523 into lp:openlp.

Requested reviews:
  Raoul Snyman (raoul-snyman)
  Andreas Preikschat (googol)
Related bugs:
  Bug #772523 in OpenLP: ""Update service from song edit" does work "too much""
  https://bugs.launchpad.net/openlp/+bug/772523

For more details, see:
https://code.launchpad.net/~trb143/openlp/bug-772523/+merge/85214

This patch changes your song database so back it up!

When a service is imported at present and we do not wish to save the songs we do not.  This prevents the user from editing songs.
This change adds a "temporary" flag on the song database to allow those songs to be save and edited bit not via the plugin as the search will not show them.
On exit the songs will be deleted.

The code works until a service is loaded and then you get sqlalchemy errors. 
I have no idea what is wrong but some help would be appreciated.

Amended code to add songs as per my email.

The code does set a correct value on existing databases.


-- 
https://code.launchpad.net/~trb143/openlp/bug-772523/+merge/85214
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/db.py'
--- openlp/core/lib/db.py	2011-12-03 12:51:40 +0000
+++ openlp/core/lib/db.py	2011-12-10 08:57:25 +0000
@@ -358,10 +358,17 @@
 
     def delete_all_objects(self, object_class, filter_clause=None):
         """
-        Delete all object records
+        Delete all object records.
+        This method should only be used for simple tables and not ones with
+        relationships.  The relationships are not deleted from the database and
+        this will lead to database corruptions.
 
         ``object_class``
             The type of object to delete
+
+        ``filter_clause``
+            The filter governing selection of objects to return. Defaults to
+            None.
         """
         try:
             query = self.session.query(object_class)

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2011-11-13 08:57:29 +0000
+++ openlp/core/lib/serviceitem.py	2011-12-10 08:57:25 +0000
@@ -119,6 +119,7 @@
         self.image_border = u'#000000'
         self.background_audio = []
         self.theme_overwritten = False
+        self.temporary_edit = False
         self._new_item()
 
     def _new_item(self):
@@ -365,6 +366,7 @@
         """
         self._uuid = other._uuid
         self.notes = other.notes
+        self.temporary_edit = other.temporary_edit
         # Copy theme over if present.
         if other.theme is not None:
             self.theme = other.theme

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2011-12-02 20:17:57 +0000
+++ openlp/core/ui/servicemanager.py	2011-12-10 08:57:25 +0000
@@ -37,7 +37,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
-    ItemCapabilities, SettingsManager, translate
+    ItemCapabilities, SettingsManager, translate, str_to_bool
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
     context_menu_action, context_menu_separator, find_and_set_in_combo_box
@@ -670,6 +670,7 @@
                     # if the item has been processed
                     if serviceItem._uuid == self.loadItem_uuid:
                         serviceItem.edit_id = int(self.loadItem_editId)
+                        serviceItem.temporary_edit = self.loadItem_temporary
                     self.addServiceItem(serviceItem, repaint=False)
                 delete_file(p_file)
                 self.setFileName(fileName)
@@ -999,6 +1000,17 @@
                     painter.drawImage(0, 0, overlay)
                     painter.end()
                     treewidgetitem.setIcon(0, build_icon(icon))
+                elif serviceitem.temporary_edit:
+                    icon = QtGui.QImage(serviceitem.icon)
+                    icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
+                        QtCore.Qt.SmoothTransformation)
+                    overlay = QtGui.QImage(':/general/general_export.png')
+                    overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio,
+                        QtCore.Qt.SmoothTransformation)
+                    painter = QtGui.QPainter(icon)
+                    painter.drawImage(40, 0, overlay)
+                    painter.end()
+                    treewidgetitem.setIcon(0, build_icon(icon))
                 else:
                     treewidgetitem.setIcon(0, serviceitem.iconic_representation)
             else:
@@ -1006,6 +1018,11 @@
                     build_icon(u':/general/general_delete.png'))
             treewidgetitem.setText(0, serviceitem.get_display_title())
             tips = []
+            if serviceitem.temporary_edit:
+                tips.append(u'<strong>%s:</strong> <em>%s</em>' %
+                    (unicode(translate('OpenLP.ServiceManager', 'Edit')),
+                    (unicode(translate('OpenLP.ServiceManager',
+                    'Service copy only')))))
             if serviceitem.theme and serviceitem.theme != -1:
                 tips.append(u'<strong>%s:</strong> <em>%s</em>' %
                     (unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
@@ -1127,8 +1144,9 @@
         Triggered from plugins to update service items.
         Save the values as they will be used as part of the service load
         """
-        editId, self.loadItem_uuid = message.split(u':')
+        editId, self.loadItem_uuid, temporary = message.split(u':')
         self.loadItem_editId = int(editId)
+        self.loadItem_temporary = str_to_bool(temporary)
 
     def replaceServiceItem(self, newItem):
         """

=== modified file 'openlp/plugins/songs/forms/songexportform.py'
--- openlp/plugins/songs/forms/songexportform.py	2011-08-26 15:48:58 +0000
+++ openlp/plugins/songs/forms/songexportform.py	2011-12-10 08:57:25 +0000
@@ -252,6 +252,9 @@
         songs = self.plugin.manager.get_all_objects(Song)
         songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
         for song in songs:
+            # No need to export temporary songs.
+            if song.temporary:
+                continue
             authors = u', '.join([author.display_name
                 for author in song.authors])
             title = u'%s (%s)' % (unicode(song.title), authors)

=== modified file 'openlp/plugins/songs/lib/db.py'
--- openlp/plugins/songs/lib/db.py	2011-08-26 23:04:54 +0000
+++ openlp/plugins/songs/lib/db.py	2011-12-10 08:57:25 +0000
@@ -199,7 +199,8 @@
         Column(u'search_lyrics', types.UnicodeText, nullable=False),
         Column(u'create_date', types.DateTime(), default=func.now()),
         Column(u'last_modified', types.DateTime(), default=func.now(),
-            onupdate=func.now())
+            onupdate=func.now()),
+        Column(u'temporary', types.Boolean(), default=False)
     )
 
     # Definition of the "topics" table

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2011-11-24 22:34:27 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2011-12-10 08:57:25 +0000
@@ -270,6 +270,9 @@
         searchresults.sort(
             cmp=locale.strcoll, key=lambda song: song.title.lower())
         for song in searchresults:
+            # Do not display temporary songs
+            if song.temporary:
+                continue
             author_list = [author.display_name for author in song.authors]
             song_title = unicode(song.title)
             song_detail = u'%s (%s)' % (song_title, u', '.join(author_list))
@@ -286,6 +289,9 @@
         self.listView.clear()
         for author in searchresults:
             for song in author.songs:
+                # Do not display temporary songs
+                if song.temporary:
+                    continue
                 song_detail = u'%s (%s)' % (author.display_name, song.title)
                 song_name = QtGui.QListWidgetItem(song_detail)
                 song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
@@ -534,6 +540,7 @@
                 Song.search_title.asc())
         editId = 0
         add_song = True
+        temporary = False
         if search_results:
             for song in search_results:
                 author_list = item.data_string[u'authors']
@@ -559,13 +566,18 @@
                 self._updateBackgroundAudio(song, item)
             editId = song.id
             self.onSearchTextButtonClick()
-        else:
+        elif add_song and not self.addSongFromService:
             # Make sure we temporary import formatting tags.
-            self.openLyrics.xml_to_song(item.xml_version, True)
+            song = self.openLyrics.xml_to_song(item.xml_version, True)
+            # If there's any backing tracks, copy them over.
+            if len(item.background_audio) > 0:
+                self._updateBackgroundAudio(song, item)
+            editId = song.id
+            temporary = True
         # Update service with correct song id.
         if editId:
             Receiver.send_message(u'service_item_update',
-                u'%s:%s' % (editId, item._uuid))
+                u'%s:%s:%s' % (editId, item._uuid, temporary))
 
     def search(self, string):
         """

=== modified file 'openlp/plugins/songs/lib/upgrade.py'
--- openlp/plugins/songs/lib/upgrade.py	2011-12-02 20:17:57 +0000
+++ openlp/plugins/songs/lib/upgrade.py	2011-12-10 08:57:25 +0000
@@ -33,7 +33,9 @@
 from sqlalchemy.sql.expression import func
 from migrate.changeset.constraint import ForeignKeyConstraint
 
-__version__ = 2
+from openlp.plugins.songs.lib.db import Song
+
+__version__ = 3
 
 def upgrade_setup(metadata):
     """
@@ -86,3 +88,12 @@
     Column(u'last_modified', types.DateTime(), default=func.now())\
         .create(table=tables[u'songs'])
 
+def upgrade_3(session, metadata, tables):
+    """
+    Version 3 upgrade.
+
+    This upgrade adds a temporary song flag to the songs table
+    """
+    Column(u'temporary', types.Boolean(), default=False)\
+        .create(table=tables[u'songs'])
+

=== modified file 'openlp/plugins/songs/lib/xml.py'
--- openlp/plugins/songs/lib/xml.py	2011-10-09 19:51:44 +0000
+++ openlp/plugins/songs/lib/xml.py	2011-12-10 08:57:25 +0000
@@ -346,7 +346,7 @@
                     lines_element.set(u'break', u'optional')
         return self._extract_xml(song_xml)
 
-    def xml_to_song(self, xml, parse_and_not_save=False):
+    def xml_to_song(self, xml, parse_and_temporary_save=False):
         """
         Create and save a song from OpenLyrics format xml to the database. Since
         we also export XML from external sources (e. g. OpenLyrics import), we
@@ -355,9 +355,9 @@
         ``xml``
             The XML to parse (unicode).
 
-        ``parse_and_not_save``
-            Switch to skip processing the whole song and to prevent storing the
-            songs to the database. Defaults to ``False``.
+        ``parse_and_temporary_save``
+            Switch to skip processing the whole song and storing the songs in
+            the database with a temporary flag. Defaults to ``False``.
         """
         # No xml get out of here.
         if not xml:
@@ -371,14 +371,13 @@
             return None
         # Formatting tags are new in OpenLyrics 0.8
         if float(song_xml.get(u'version')) > 0.7:
-            self._process_formatting_tags(song_xml, parse_and_not_save)
-        if parse_and_not_save:
-            return
+            self._process_formatting_tags(song_xml, parse_and_temporary_save)
         song = Song()
         # Values will be set when cleaning the song.
         song.search_lyrics = u''
         song.verse_order = u''
         song.search_title = u''
+        song.temporary = parse_and_temporary_save
         self._process_copyright(properties, song)
         self._process_cclinumber(properties, song)
         self._process_titles(properties, song)

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2011-12-03 13:32:19 +0000
+++ openlp/plugins/songs/songsplugin.py	2011-12-10 08:57:25 +0000
@@ -264,6 +264,11 @@
         Time to tidy up on exit
         """
         log.info(u'Songs Finalising')
+        # Remove temporary songs
+        songs = self.manager.get_all_objects(Song, Song.temporary == True)
+        for song in songs:
+            self.manager.delete_object(Song, song.id)
+        # Clean up files and connections
         self.manager.finalise()
         self.songImportItem.setVisible(False)
         self.songExportItem.setVisible(False)