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

Proposed by Tim Bentley
Status: Superseded
Proposed branch: lp:~trb143/openlp/bug-772523
Merge into: lp:openlp
Diff against target: 273 lines (+73/-15)
9 files modified
openlp/core/lib/db.py (+8/-1)
openlp/core/lib/serviceitem.py (+2/-0)
openlp/core/ui/servicemanager.py (+20/-2)
openlp/plugins/songs/forms/songexportform.py (+3/-0)
openlp/plugins/songs/lib/db.py (+2/-1)
openlp/plugins/songs/lib/mediaitem.py (+15/-3)
openlp/plugins/songs/lib/upgrade.py (+12/-1)
openlp/plugins/songs/lib/xml.py (+6/-7)
openlp/plugins/songs/songsplugin.py (+5/-0)
To merge this branch: bzr merge lp:~trb143/openlp/bug-772523
Reviewer Review Type Date Requested Status
Andreas Preikschat (community) Needs Fixing
Raoul Snyman Approve
Review via email: mp+85026@code.launchpad.net

This proposal supersedes a proposal from 2011-12-05.

This proposal has been superseded by a proposal from 2011-12-10.

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Well, first remove your print statement.

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

You will need to set the default of the new column, something like this:

110 Column(u'temporary', types.Boolean(), default=False)\
111 .create(table=tables[u'songs'])
        connection = metadata.bind.connect()
        update_statement = tables[u'songs'].update().values(temporary=False)
        connection.execute(update_statement)

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Are you going to add the setting of the default value of the new column?

review: Needs Information
Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

This looks fine, I'll approve it, but I haven't tested it.

review: Approve
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote :

1) delete your db
2) Open a service file ("Add missing songs ..." + "Update service...." enabled)
3) Disable "Add missing songs ..."
4) Restart OpenLP
5) Open the same service file
6) Edit the song in the media manager.

Result: Song in service manager is not updated.

review: Needs Fixing
lp:~trb143/openlp/bug-772523 updated
1776. By Tim Bentley

Fixes and notifications

1777. By Tim Bentley

Lost temporary edit flag

1778. By Tim Bentley

clean up service

1779. By Tim Bentley

Head

1780. By Tim Bentley

Fix review comments

1781. By Tim Bentley

Fix review comments

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/lib/db.py'
2--- openlp/core/lib/db.py 2011-12-03 12:51:40 +0000
3+++ openlp/core/lib/db.py 2011-12-10 08:55:28 +0000
4@@ -358,10 +358,17 @@
5
6 def delete_all_objects(self, object_class, filter_clause=None):
7 """
8- Delete all object records
9+ Delete all object records.
10+ This method should only be used for simple tables and not ones with
11+ relationships. The relationships are not deleted from the database and
12+ this will lead to database corruptions.
13
14 ``object_class``
15 The type of object to delete
16+
17+ ``filter_clause``
18+ The filter governing selection of objects to return. Defaults to
19+ None.
20 """
21 try:
22 query = self.session.query(object_class)
23
24=== modified file 'openlp/core/lib/serviceitem.py'
25--- openlp/core/lib/serviceitem.py 2011-11-13 08:57:29 +0000
26+++ openlp/core/lib/serviceitem.py 2011-12-10 08:55:28 +0000
27@@ -119,6 +119,7 @@
28 self.image_border = u'#000000'
29 self.background_audio = []
30 self.theme_overwritten = False
31+ self.temporary_edit = False
32 self._new_item()
33
34 def _new_item(self):
35@@ -365,6 +366,7 @@
36 """
37 self._uuid = other._uuid
38 self.notes = other.notes
39+ self.temporary_edit = other.temporary_edit
40 # Copy theme over if present.
41 if other.theme is not None:
42 self.theme = other.theme
43
44=== modified file 'openlp/core/ui/servicemanager.py'
45--- openlp/core/ui/servicemanager.py 2011-12-02 20:17:57 +0000
46+++ openlp/core/ui/servicemanager.py 2011-12-10 08:55:28 +0000
47@@ -37,7 +37,7 @@
48 from PyQt4 import QtCore, QtGui
49
50 from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
51- ItemCapabilities, SettingsManager, translate
52+ ItemCapabilities, SettingsManager, translate, str_to_bool
53 from openlp.core.lib.theme import ThemeLevel
54 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
55 context_menu_action, context_menu_separator, find_and_set_in_combo_box
56@@ -670,6 +670,7 @@
57 # if the item has been processed
58 if serviceItem._uuid == self.loadItem_uuid:
59 serviceItem.edit_id = int(self.loadItem_editId)
60+ serviceItem.temporary_edit = self.loadItem_temporary
61 self.addServiceItem(serviceItem, repaint=False)
62 delete_file(p_file)
63 self.setFileName(fileName)
64@@ -999,6 +1000,17 @@
65 painter.drawImage(0, 0, overlay)
66 painter.end()
67 treewidgetitem.setIcon(0, build_icon(icon))
68+ elif serviceitem.temporary_edit:
69+ icon = QtGui.QImage(serviceitem.icon)
70+ icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
71+ QtCore.Qt.SmoothTransformation)
72+ overlay = QtGui.QImage(':/general/general_export.png')
73+ overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio,
74+ QtCore.Qt.SmoothTransformation)
75+ painter = QtGui.QPainter(icon)
76+ painter.drawImage(40, 0, overlay)
77+ painter.end()
78+ treewidgetitem.setIcon(0, build_icon(icon))
79 else:
80 treewidgetitem.setIcon(0, serviceitem.iconic_representation)
81 else:
82@@ -1006,6 +1018,11 @@
83 build_icon(u':/general/general_delete.png'))
84 treewidgetitem.setText(0, serviceitem.get_display_title())
85 tips = []
86+ if serviceitem.temporary_edit:
87+ tips.append(u'<strong>%s:</strong> <em>%s</em>' %
88+ (unicode(translate('OpenLP.ServiceManager', 'Edit')),
89+ (unicode(translate('OpenLP.ServiceManager',
90+ 'Service copy only')))))
91 if serviceitem.theme and serviceitem.theme != -1:
92 tips.append(u'<strong>%s:</strong> <em>%s</em>' %
93 (unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
94@@ -1127,8 +1144,9 @@
95 Triggered from plugins to update service items.
96 Save the values as they will be used as part of the service load
97 """
98- editId, self.loadItem_uuid = message.split(u':')
99+ editId, self.loadItem_uuid, temporary = message.split(u':')
100 self.loadItem_editId = int(editId)
101+ self.loadItem_temporary = str_to_bool(temporary)
102
103 def replaceServiceItem(self, newItem):
104 """
105
106=== modified file 'openlp/plugins/songs/forms/songexportform.py'
107--- openlp/plugins/songs/forms/songexportform.py 2011-08-26 15:48:58 +0000
108+++ openlp/plugins/songs/forms/songexportform.py 2011-12-10 08:55:28 +0000
109@@ -252,6 +252,9 @@
110 songs = self.plugin.manager.get_all_objects(Song)
111 songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
112 for song in songs:
113+ # No need to export temporary songs.
114+ if song.temporary:
115+ continue
116 authors = u', '.join([author.display_name
117 for author in song.authors])
118 title = u'%s (%s)' % (unicode(song.title), authors)
119
120=== modified file 'openlp/plugins/songs/lib/db.py'
121--- openlp/plugins/songs/lib/db.py 2011-08-26 23:04:54 +0000
122+++ openlp/plugins/songs/lib/db.py 2011-12-10 08:55:28 +0000
123@@ -199,7 +199,8 @@
124 Column(u'search_lyrics', types.UnicodeText, nullable=False),
125 Column(u'create_date', types.DateTime(), default=func.now()),
126 Column(u'last_modified', types.DateTime(), default=func.now(),
127- onupdate=func.now())
128+ onupdate=func.now()),
129+ Column(u'temporary', types.Boolean(), default=False)
130 )
131
132 # Definition of the "topics" table
133
134=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
135--- openlp/plugins/songs/lib/mediaitem.py 2011-11-24 22:34:27 +0000
136+++ openlp/plugins/songs/lib/mediaitem.py 2011-12-10 08:55:28 +0000
137@@ -270,6 +270,9 @@
138 searchresults.sort(
139 cmp=locale.strcoll, key=lambda song: song.title.lower())
140 for song in searchresults:
141+ # Do not display temporary songs
142+ if song.temporary:
143+ continue
144 author_list = [author.display_name for author in song.authors]
145 song_title = unicode(song.title)
146 song_detail = u'%s (%s)' % (song_title, u', '.join(author_list))
147@@ -286,6 +289,9 @@
148 self.listView.clear()
149 for author in searchresults:
150 for song in author.songs:
151+ # Do not display temporary songs
152+ if song.temporary:
153+ continue
154 song_detail = u'%s (%s)' % (author.display_name, song.title)
155 song_name = QtGui.QListWidgetItem(song_detail)
156 song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
157@@ -534,6 +540,7 @@
158 Song.search_title.asc())
159 editId = 0
160 add_song = True
161+ temporary = False
162 if search_results:
163 for song in search_results:
164 author_list = item.data_string[u'authors']
165@@ -559,13 +566,18 @@
166 self._updateBackgroundAudio(song, item)
167 editId = song.id
168 self.onSearchTextButtonClick()
169- else:
170+ elif add_song and not self.addSongFromService:
171 # Make sure we temporary import formatting tags.
172- self.openLyrics.xml_to_song(item.xml_version, True)
173+ song = self.openLyrics.xml_to_song(item.xml_version, True)
174+ # If there's any backing tracks, copy them over.
175+ if len(item.background_audio) > 0:
176+ self._updateBackgroundAudio(song, item)
177+ editId = song.id
178+ temporary = True
179 # Update service with correct song id.
180 if editId:
181 Receiver.send_message(u'service_item_update',
182- u'%s:%s' % (editId, item._uuid))
183+ u'%s:%s:%s' % (editId, item._uuid, temporary))
184
185 def search(self, string):
186 """
187
188=== modified file 'openlp/plugins/songs/lib/upgrade.py'
189--- openlp/plugins/songs/lib/upgrade.py 2011-12-02 20:17:57 +0000
190+++ openlp/plugins/songs/lib/upgrade.py 2011-12-10 08:55:28 +0000
191@@ -33,7 +33,9 @@
192 from sqlalchemy.sql.expression import func
193 from migrate.changeset.constraint import ForeignKeyConstraint
194
195-__version__ = 2
196+from openlp.plugins.songs.lib.db import Song
197+
198+__version__ = 3
199
200 def upgrade_setup(metadata):
201 """
202@@ -86,3 +88,12 @@
203 Column(u'last_modified', types.DateTime(), default=func.now())\
204 .create(table=tables[u'songs'])
205
206+def upgrade_3(session, metadata, tables):
207+ """
208+ Version 3 upgrade.
209+
210+ This upgrade adds a temporary song flag to the songs table
211+ """
212+ Column(u'temporary', types.Boolean(), default=False)\
213+ .create(table=tables[u'songs'])
214+
215
216=== modified file 'openlp/plugins/songs/lib/xml.py'
217--- openlp/plugins/songs/lib/xml.py 2011-10-09 19:51:44 +0000
218+++ openlp/plugins/songs/lib/xml.py 2011-12-10 08:55:28 +0000
219@@ -346,7 +346,7 @@
220 lines_element.set(u'break', u'optional')
221 return self._extract_xml(song_xml)
222
223- def xml_to_song(self, xml, parse_and_not_save=False):
224+ def xml_to_song(self, xml, parse_and_temporary_save=False):
225 """
226 Create and save a song from OpenLyrics format xml to the database. Since
227 we also export XML from external sources (e. g. OpenLyrics import), we
228@@ -355,9 +355,9 @@
229 ``xml``
230 The XML to parse (unicode).
231
232- ``parse_and_not_save``
233- Switch to skip processing the whole song and to prevent storing the
234- songs to the database. Defaults to ``False``.
235+ ``parse_and_temporary_save``
236+ Switch to skip processing the whole song and storing the songs in
237+ the database with a temporary flag. Defaults to ``False``.
238 """
239 # No xml get out of here.
240 if not xml:
241@@ -371,14 +371,13 @@
242 return None
243 # Formatting tags are new in OpenLyrics 0.8
244 if float(song_xml.get(u'version')) > 0.7:
245- self._process_formatting_tags(song_xml, parse_and_not_save)
246- if parse_and_not_save:
247- return
248+ self._process_formatting_tags(song_xml, parse_and_temporary_save)
249 song = Song()
250 # Values will be set when cleaning the song.
251 song.search_lyrics = u''
252 song.verse_order = u''
253 song.search_title = u''
254+ song.temporary = parse_and_temporary_save
255 self._process_copyright(properties, song)
256 self._process_cclinumber(properties, song)
257 self._process_titles(properties, song)
258
259=== modified file 'openlp/plugins/songs/songsplugin.py'
260--- openlp/plugins/songs/songsplugin.py 2011-12-03 13:32:19 +0000
261+++ openlp/plugins/songs/songsplugin.py 2011-12-10 08:55:28 +0000
262@@ -264,6 +264,11 @@
263 Time to tidy up on exit
264 """
265 log.info(u'Songs Finalising')
266+ # Remove temporary songs
267+ songs = self.manager.get_all_objects(Song, Song.temporary == True)
268+ for song in songs:
269+ self.manager.delete_object(Song, song.id)
270+ # Clean up files and connections
271 self.manager.finalise()
272 self.songImportItem.setVisible(False)
273 self.songExportItem.setVisible(False)