Merge lp:~trb143/openlp/servicing2 into lp:openlp

Proposed by Tim Bentley
Status: Merged
Merged at revision: not available
Proposed branch: lp:~trb143/openlp/servicing2
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~trb143/openlp/servicing2
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Review via email: mp+7835@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote :

Mixed bag of changes - Sorry.
Fixed up the song migration code from 1.x to 2 format including getting round SqlAlchemy limitations in 1.x format.
Fixed bug in Theme caused by Unicode work. Import Themes now works again.
Fixed ThemeManager bugs including allowing any file name to be imported for Themes.
Fixed niggle in Topic where Save was disabled.
Start of Presentations work.

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'cnvdb.py'
2--- cnvdb.py 1970-01-01 00:00:00 +0000
3+++ cnvdb.py 2009-06-23 16:25:40 +0000
4@@ -0,0 +1,23 @@
5+import codecs
6+
7+
8+class Convert():
9+ def __init__(self):
10+ pass
11+
12+ def process(self, inname, outname):
13+ infile = codecs.open(inname, 'r', encoding='iso-8859-1')
14+ writefile = codecs.open(outname, 'w', encoding='utf-8')
15+ count = 0
16+ for line in infile:
17+ writefile.write(line)
18+ if count < 150:
19+ print line
20+ count += 1
21+ infile.close()
22+ writefile.close()
23+
24+
25+if __name__ == '__main__':
26+ mig = Convert()
27+ mig.process(u'/home/timali/.local/share/openlp/songs/songs.dmp',u'/home/timali/.local/share/openlp/songs/songs.dmp2')
28
29=== modified file 'openlp/core/lib/themexmlhandler.py'
30--- openlp/core/lib/themexmlhandler.py 2009-05-22 05:14:55 +0000
31+++ openlp/core/lib/themexmlhandler.py 2009-06-24 05:17:41 +0000
32@@ -16,8 +16,6 @@
33 You should have received a copy of the GNU General Public License along with
34 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
35 Place, Suite 330, Boston, MA 02111-1307 USA
36-from xml.dom.minidom import Document
37-from xml.etree.ElementTree import ElementTree, XML, dump
38
39 For XML Schema see wiki.openlp.org
40 """
41@@ -256,5 +254,5 @@
42 s = u''
43 for k in dir(self):
44 if k[0:1] != u'_':
45- s += u'%30s : %s\n' %(k,getattr(self,k))
46+ s += u'%30s : %s\n' %(k, getattr(self, k))
47 return s
48
49=== modified file 'openlp/core/theme/theme.py'
50--- openlp/core/theme/theme.py 2009-06-16 18:21:24 +0000
51+++ openlp/core/theme/theme.py 2009-06-24 05:17:41 +0000
52@@ -1,9 +1,26 @@
53+# -*- coding: utf-8 -*-
54+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
55+"""
56+OpenLP - Open Source Lyrics Projection
57+Copyright (c) 2008 Raoul Snyman
58+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard
59+
60+This program is free software; you can redistribute it and/or modify it under
61+the terms of the GNU General Public License as published by the Free Software
62+Foundation; version 2 of the License.
63+
64+This program is distributed in the hope that it will be useful, but WITHOUT ANY
65+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
66+PARTICULAR PURPOSE. See the GNU General Public License for more details.
67+
68+You should have received a copy of the GNU General Public License along with
69+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
70+Place, Suite 330, Boston, MA 02111-1307 USA
71+
72+"""
73 import platform
74-ver = platform.python_version()
75-if ver >= '2.5':
76- from xml.etree.ElementTree import ElementTree, XML
77-else:
78- from elementtree import ElementTree, XML
79+import types
80+from xml.etree.ElementTree import ElementTree, XML
81
82 from PyQt4 import QtGui
83
84@@ -59,7 +76,7 @@
85 FontName : name of font to use
86 FontColor : color for main font
87 FontProportion : size of font
88- FontUnits : whether size of font is in <pixels> or <points>
89+ FontUnits : whether size of font is in <pixels> or <points>
90
91 Shadow : 0 - no shadow, non-zero use shadow
92 ShadowColor : color for drop shadow
93@@ -78,52 +95,57 @@
94 # init to defaults
95 self._set_from_XML(blankstylexml)
96 self._set_from_XML(xml)
97+# print self.__str__()
98
99 def _get_as_string(self):
100- s=""
101+ s = u''
102 keys=dir(self)
103 keys.sort()
104 for k in keys:
105- if k[0:1] != "_":
106- s+= "_%s_" %(getattr(self,k))
107+ if k[0:1] != u'_':
108+ s += u'_%s_' %(getattr(self,k))
109 return s
110+
111 def _set_from_XML(self, xml):
112- root=ElementTree(element=XML(xml))
113- iter=root.getiterator()
114+ root = ElementTree(element=XML(xml))
115+ iter = root.getiterator()
116 for element in iter:
117- if element.tag != "Theme":
118- t=element.text
119-# print element.tag, t, type(t)
120- if type(t) == type(None): # easy!
121- val=t
122- if type(t) == type(u' '): # strings need special handling to sort the colours out
123-# print "str",
124- if t[0] == "$": # might be a hex number
125-# print "hex",
126+ if element.tag != u'Theme':
127+ t = element.text
128+# print element.tag, t, type(t)
129+ val = 0
130+ # easy!
131+ if type(t) == type(None):
132+ val = t
133+ # strings need special handling to sort the colours out
134+ if type(t) is types.StringType or type(t) is types.UnicodeType:
135+# print u'str',
136+ if t[0] == u'$': # might be a hex number
137+# print u'hex',
138 try:
139- val=int(t[1:], 16)
140+ val = int(t[1:], 16)
141 except ValueError: # nope
142-# print "nope",
143+# print u'nope'
144 pass
145 elif DelphiColors.has_key(t):
146-# print "colour",
147- val=DelphiColors[t]
148+# print u'colour ', t
149+ val = DelphiColors[t]
150 else:
151 try:
152- val=int(t)
153+ val = int(t)
154 except ValueError:
155- val=t
156+ val = t
157 if (element.tag.find(u'Color') > 0 or
158 (element.tag.find(u'BackgroundParameter') == 0 and type(val) == type(0))):
159 # convert to a wx.Colour
160 val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF)
161- # print [val]
162- setattr(self,element.tag, val)
163-
164+# print [val]
165+# print u'>> ', element.tag, val
166+ setattr(self, element.tag, val)
167
168 def __str__(self):
169- s=""
170+ s = u''
171 for k in dir(self):
172- if k[0:1] != "_":
173- s+= "%30s : %s\n" %(k,getattr(self,k))
174- return s
175\ No newline at end of file
176+ if k[0:1] != u'_':
177+ s += u'%30s : %s\n' %(k, getattr(self, k))
178+ return s
179
180=== modified file 'openlp/core/ui/slidecontroller.py'
181--- openlp/core/ui/slidecontroller.py 2009-06-21 19:41:01 +0000
182+++ openlp/core/ui/slidecontroller.py 2009-06-23 16:25:40 +0000
183@@ -231,11 +231,6 @@
184 QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
185 QtCore.QObject.connect(self.PreviewListView,
186 QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected)
187- QtCore.QObject.connect(self.PreviewListView,
188- QtCore.SIGNAL(u'entered(QModelIndex)'), self.onTest)
189-
190- def onTest(self , item):
191- print "found", item
192
193 def onSlideSelectedFirst(self):
194 """
195
196=== modified file 'openlp/core/ui/thememanager.py'
197--- openlp/core/ui/thememanager.py 2009-06-20 19:11:17 +0000
198+++ openlp/core/ui/thememanager.py 2009-06-24 05:17:41 +0000
199@@ -57,9 +57,9 @@
200
201 def insertRow(self, row, filename):
202 self.beginInsertRows(QtCore.QModelIndex(), row, row)
203- log.info(u'insert row %d:%s' % (row, filename))
204+ log.debug(u'insert row %d:%s' % (row, filename))
205 (prefix, shortfilename) = os.path.split(unicode(filename))
206- log.info(u'shortfilename = %s' % shortfilename)
207+ log.debug(u'shortfilename = %s' % shortfilename)
208 theme = shortfilename.split(u'.')
209 # create a preview image
210 if os.path.exists(filename):
211@@ -81,7 +81,7 @@
212 pixmap.fill(QtCore.Qt.black)
213 # finally create the row
214 self.items.insert(row, (filename, pixmap, shortfilename, theme[0]))
215- log.info(u'Items: %s' % self.items)
216+ log.debug(u'Items: %s' % self.items)
217 self.endInsertRows()
218
219 def removeRow(self, row):
220@@ -190,8 +190,13 @@
221 try:
222 os.remove(os.path.join(self.path, th))
223 except:
224- pass #if not present do not worry
225- shutil.rmtree(os.path.join(self.path, theme))
226+ #if not present do not worry
227+ pass
228+ try:
229+ shutil.rmtree(os.path.join(self.path, theme))
230+ except:
231+ #if not present do not worry
232+ pass
233 self.themeData.clearItems()
234 self.loadThemes()
235
236@@ -201,7 +206,7 @@
237 def onImportTheme(self):
238 files = QtGui.QFileDialog.getOpenFileNames(None,
239 translate(u'ThemeManager', u'Select Theme Import File'),
240- self.path, u'Theme (*.theme)')
241+ self.path, u'Theme (*.*)')
242 log.info(u'New Themes %s', unicode(files))
243 if len(files) > 0:
244 for file in files:
245@@ -335,7 +340,7 @@
246 outfile = open(theme_file, u'w')
247 outfile.write(theme_xml)
248 outfile.close()
249- if image_from is not None and image_from is not image_to:
250+ if image_from is not None and image_from != image_to:
251 shutil.copyfile(image_from, image_to)
252 self.generateAndSaveImage(self.path, name, theme_xml)
253 self.themeData.clearItems()
254
255=== modified file 'openlp/migration/display.py'
256--- openlp/migration/display.py 2009-06-16 18:21:24 +0000
257+++ openlp/migration/display.py 2009-06-23 16:25:40 +0000
258@@ -22,14 +22,14 @@
259 global log
260 log=logging.getLogger(u'Display Logger')
261 log.info(u'Display Class loaded')
262-
263+
264 @staticmethod
265 def output(string):
266 log.debug(string);
267 print (string)
268-
269+
270 @staticmethod
271 def sub_output(string):
272 if not string == None:
273- log.debug(u' "+string);
274- print (u' "+string)
275\ No newline at end of file
276+ log.debug(u' '+string);
277+ print (u' '+string)
278
279=== modified file 'openlp/migration/migratefiles.py'
280--- openlp/migration/migratefiles.py 2009-06-16 18:21:24 +0000
281+++ openlp/migration/migratefiles.py 2009-06-23 16:25:40 +0000
282@@ -24,18 +24,18 @@
283 def process(self):
284 self.display.output(u'Files process started');
285 self._initial_setup()
286- self.display.output(u'Files process finished');
287-
288+ self.display.output(u'Files process finished');
289+
290 def _initial_setup(self):
291 self.display.output(u'Initial Setup started');
292 ConfigHelper.get_data_path()
293- self.display.sub_output(u'Config created');
294- ConfigHelper.get_config(u'bible", u'data path')
295- self.display.sub_output(u'Config created');
296- ConfigHelper.get_config(u'videos", u'data path')
297- self.display.sub_output(u'videos created');
298- ConfigHelper.get_config(u'images", u'data path')
299- self.display.sub_output(u'images created');
300- ConfigHelper.get_config(u'presentations", u'data path')
301- self.display.sub_output(u'presentations created');
302- self.display.output(u'Initial Setup finished');
303\ No newline at end of file
304+ self.display.sub_output(u'Config created');
305+ ConfigHelper.get_config(u'bible', u'data path')
306+ self.display.sub_output(u'Config created');
307+ ConfigHelper.get_config(u'videos', u'data path')
308+ self.display.sub_output(u'videos created');
309+ ConfigHelper.get_config(u'images', u'data path')
310+ self.display.sub_output(u'images created');
311+ ConfigHelper.get_config(u'presentations', u'data path')
312+ self.display.sub_output(u'presentations created');
313+ self.display.output(u'Initial Setup finished');
314
315=== modified file 'openlp/migration/migratesongs.py'
316--- openlp/migration/migratesongs.py 2009-06-16 18:21:24 +0000
317+++ openlp/migration/migratesongs.py 2009-06-24 06:11:04 +0000
318@@ -16,6 +16,7 @@
319 Place, Suite 330, Boston, MA 02111-1307 USA
320 """
321 import os
322+import sys
323 import logging
324 import sqlite3
325 from openlp.core.lib import PluginConfig
326@@ -24,20 +25,81 @@
327 from sqlalchemy.sql import select
328 from sqlalchemy import create_engine
329 from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation, clear_mappers
330-
331+from openlp.plugins.songs.lib.models import metadata, session, \
332+ engine, songs_table, Song, Author, Topic, Book
333 from openlp.plugins.songs.lib.tables import *
334 from openlp.plugins.songs.lib.classes import *
335
336-clear_mappers()
337-mapper(Author, authors_table)
338-mapper(Book, song_books_table)
339-mapper(Song, songs_table, properties={
340- 'authors': relation(Author, backref='songs',
341- secondary=authors_songs_table),
342- 'book': relation(Book, backref='songs'),
343- 'topics': relation(Topic, backref='songs',
344- secondary=songs_topics_table)})
345-mapper(Topic, topics_table)
346+def init_models(url):
347+ engine = create_engine(url)
348+ metadata.bind = engine
349+ session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
350+ bind=engine))
351+ mapper(Author, authors_table)
352+ mapper(TAuthor, temp_authors_table)
353+ mapper(Book, song_books_table)
354+ mapper(Song, songs_table,
355+ properties={'authors': relation(Author, backref='songs',
356+ secondary=authors_songs_table),
357+ 'book': relation(Book, backref='songs'),
358+ 'topics': relation(Topic, backref='songs',
359+ secondary=songs_topics_table)})
360+ mapper(TSong, temp_songs_table)
361+ mapper(TSongAuthor, temp_authors_songs_table)
362+ mapper(Topic, topics_table)
363+ return session
364+
365+temp_authors_table = Table(u'authors_temp', metadata,
366+ Column(u'authorid', types.Integer, primary_key=True),
367+ Column(u'authorname', String(40))
368+)
369+
370+temp_songs_table = Table(u'songs_temp', metadata,
371+ Column(u'songid', types.Integer, primary_key=True),
372+ Column(u'songtitle', String(60)),
373+ Column(u'lyrics', types.UnicodeText),
374+ Column(u'copyrightinfo', String(255)),
375+ Column(u'settingsid', types.Integer)
376+)
377+
378+# Definition of the "authors_songs" table
379+temp_authors_songs_table = Table(u'songauthors_temp', metadata,
380+ Column(u'authorid', types.Integer, primary_key=True),
381+ Column(u'songid', types.Integer)
382+)
383+class BaseModel(object):
384+ """
385+ BaseModel provides a base object with a set of generic functions
386+ """
387+
388+ @classmethod
389+ def populate(cls, **kwargs):
390+ """
391+ Creates an instance of a class and populates it, returning the instance
392+ """
393+ me = cls()
394+ keys = kwargs.keys()
395+ for key in keys:
396+ me.__setattr__(key, kwargs[key])
397+ return me
398+
399+class TAuthor(BaseModel):
400+ """
401+ Author model
402+ """
403+ pass
404+
405+class TSong(BaseModel):
406+ """
407+ Author model
408+ """
409+ pass
410+
411+class TSongAuthor(BaseModel):
412+ """
413+ Author model
414+ """
415+ pass
416
417 class MigrateSongs():
418 def __init__(self, display):
419@@ -55,186 +117,70 @@
420
421 def v_1_9_0(self, database):
422 self.display.output(u'Migration 1.9.0 Started for ' + database)
423- self._v1_9_0_authors(database)
424- self._v1_9_0_topics(database)
425- self._v1_9_0_songbook(database)
426- self._v1_9_0_songauthors(database)
427- self._v1_9_0_songtopics(database)
428- self._v1_9_0_songs(database)
429+ self._v1_9_0_old(database)
430+ self._v1_9_0_new(database)
431+ self._v1_9_0_cleanup(database)
432 self.display.output(u'Migration 1.9.0 Finished for ' + database)
433
434- def _v1_9_0_authors(self, database):
435- self.display.sub_output(u'Authors Started for ' + database)
436- conn = sqlite3.connect(self.data_path + os.sep + database)
437- conn.execute(u'""alter table authors rename to authors_temp;""')
438- conn.commit()
439- self.display.sub_output(u'old author renamed to author_temp')
440- conn.execute(u'""create table authors (
441- id integer primary key ASC AUTOINCREMENT,
442- first_name varchar(128),
443- last_name varchar(128),
444- display_name varchar(255)
445- );""')
446- conn.commit()
447- self.display.sub_output(u'authors table created')
448- conn.execute(u'""create index if not exists author1 on authors
449- (display_name ASC,id ASC);""')
450- conn.commit()
451- self.display.sub_output(u'index author1 created')
452- conn.execute(u'""create index if not exists author2 on authors
453- (last_name ASC,id ASC);""')
454- conn.commit()
455- self.display.sub_output(u'index author2 created')
456- conn.execute(u'""create index if not exists author3 on authors
457- (first_name ASC,id ASC);""')
458- conn.commit()
459- self.display.sub_output(u'index author3 created')
460- self.display.sub_output(u'Author Data Migration started')
461- conn.execute(u'""insert into authors (id, display_name)
462- select authorid, authorname from authors_temp;""')
463- conn.commit()
464- self.display.sub_output(u'authors populated')
465- c = conn.cursor()
466- text = c.execute(u'""select * from authors""') .fetchall()
467- for author in text:
468- dispname = author[3]
469- dispname = dispname.replace(u''", u'')
470- pos = dispname.rfind(u' ')
471- authorfirstname = dispname[:pos]
472- authorlastname = dispname[pos + 1:len(dispname)]
473- s = "update authors set first_name = '" \
474- + authorfirstname + "', last_name = '" + authorlastname \
475- + "' where id = " + unicode(author[0])
476- c.execute(s)
477- conn.commit()
478- self.display.sub_output(u'Author Data Migration Completed')
479- conn.execute(u'""drop table authors_temp;""')
480- conn.commit()
481- conn.close()
482- self.display.sub_output(u'author_temp dropped')
483- self.display.sub_output(u'Authors Completed')
484-
485- def _v1_9_0_songbook(self, database):
486- self.display.sub_output(u'SongBook Started for ' + database)
487- conn = sqlite3.connect(self.data_path + os.sep + database)
488- conn.execute(u'""create table if not exists song_books (
489- id integer Primary Key ASC AUTOINCREMENT,
490- name varchar(128),
491- publisher varchar(128)
492- );""')
493- conn.commit()
494- self.display.sub_output(u'songbook table created')
495- conn.execute(u'""create index if not exists songbook1 on song_books (name ASC,id ASC);""')
496- conn.commit()
497- self.display.sub_output(u'index songbook1 created')
498- conn.execute(u'""create index if not exists songbook2 on song_books (publisher ASC,id ASC);""')
499- conn.commit()
500- conn.close()
501- self.display.sub_output(u'index songbook2 created')
502- self.display.sub_output(u'SongBook Completed')
503-
504- def _v1_9_0_songs(self, database):
505- self.display.sub_output(u'Songs Started for ' + database)
506- conn = sqlite3.connect(self.data_path + os.sep + database)
507- conn.execute(u'""alter table songs rename to songs_temp;""')
508- conn.commit()
509- conn.execute(u'""create table if not exists songs (
510- id integer Primary Key ASC AUTOINCREMENT,
511- song_book_id integer,
512- title varchar(255),
513- lyrics text,
514- verse_order varchar(128),
515- copyright varchar(255),
516- comments text,
517- ccli_number varchar(64),
518- song_number varchar(64),
519- theme_name varchar(128),
520- search_title varchar(255),
521- search_lyrics text
522- );""')
523- conn.commit()
524- self.display.sub_output(u'songs table created')
525- conn.execute(u'""create index if not exists songs1 on songs
526- (search_lyrics ASC,id ASC);""')
527- conn.commit()
528- self.display.sub_output(u'index songs1 created')
529- conn.execute(u'""create index if not exists songs2 on songs
530- (search_title ASC,id ASC);""')
531- conn.commit()
532- self.display.sub_output(u'index songs2 created')
533- conn.execute(u'""insert into songs (id, title, lyrics, copyright,
534- search_title, search_lyrics, song_book_id)
535- select songid, songtitle, lyrics, copyrightinfo,
536+ def _v1_9_0_old(self, database):
537+ self.display.sub_output(u'Rename Tables ' + database)
538+ conn = sqlite3.connect(self.data_path + os.sep + database)
539+ conn.execute(u'alter table authors rename to authors_temp;')
540+ conn.commit()
541+ conn.execute(u'alter table songs rename to songs_temp;')
542+ conn.commit()
543+ conn.execute(u'alter table songauthors rename to songauthors_temp;')
544+ conn.commit()
545+
546+ def _v1_9_0_new(self, database):
547+ self.display.sub_output(u'Create new Tables ' + database)
548+ self.db_url = u'sqlite:///' + self.data_path + u'/songs.sqlite'
549+ print self.db_url
550+ self.session = init_models(self.db_url)
551+ if not songs_table.exists():
552+ metadata.create_all()
553+ results = self.session.query(TSong).order_by(TSong.songid).all()
554+ for songs_temp in results:
555+ song = Song()
556+ song.title = songs_temp.songtitle
557+ song.lyrics = songs_temp.lyrics.replace(u'\r\n', u'\n')
558+ song.copyright = songs_temp.copyrightinfo
559+ song.search_title = u''
560+ song.search_lyrics = u''
561+ print songs_temp.songtitle
562+ aa = self.session.execute(u'select * from songauthors_temp where songid =' + unicode(songs_temp.songid) )
563+ for row in aa:
564+ a = row['authorid']
565+ author = Author()
566+ authors_temp = self.session.query(TAuthor).get(a)
567+ author.display_name = authors_temp.authorname
568+ song.authors.append(author)
569+ try:
570+ self.session.add(song)
571+ self.session.commit()
572+ except:
573+ self.session.rollback()
574+ print u'Errow thrown = ', sys.exc_info()[1]
575+
576+ def _v1_9_0_cleanup(self, database):
577+ self.display.sub_output(u'Update Internal Data ' + database)
578+ conn = sqlite3.connect(self.data_path + os.sep + database)
579+ conn.execute("""update songs set search_title =
580 replace(replace(replace(replace(replace(replace(replace(replace(
581- replace(songtitle, '&', 'and'), ',', ''), ';', ''), ':', ''),
582- '(u', ''), ')', ''), '{', ''), '}',''),'?',''),
583+ replace(title, '&', 'and'), ',', ''), ';', ''), ':', ''),
584+ '(u', ''), ')', ''), '{', ''), '}',''),'?','');""")
585+ conn.execute("""update songs set search_lyrics =
586 replace(replace(replace(replace(replace(replace(replace(replace(
587 replace(lyrics, '&', 'and'), ',', ''), ';', ''), ':', ''),
588- '(u', ''), ')', ''), '{', ''), '}',''),'?',''),
589- 0
590- from songs_temp;""')
591- conn.commit()
592- self.display.sub_output(u'songs populated')
593- conn.execute(u'""drop table songs_temp;""')
594- conn.commit()
595- conn.close()
596- self.display.sub_output(u'songs_temp dropped')
597- self.display.sub_output(u'Songs Completed')
598-
599- def _v1_9_0_topics(self, database):
600- self.display.sub_output(u'Topics Started for ' + database)
601- conn = sqlite3.connect(self.data_path+os.sep+database)
602- conn.text_factory = str
603- conn.execute(u'""create table if not exists topics
604- (id integer Primary Key ASC AUTOINCREMENT,
605- name varchar(128));""')
606- conn.commit()
607- self.display.sub_output(u'Topic table created')
608- conn.execute(u'""create index if not exists topic1 on topics (name ASC,id ASC);""')
609- conn.commit()
610- conn.close()
611- self.display.sub_output(u'index topic1 created')
612-
613- self.display.sub_output(u'Topics Completed')
614-
615- def _v1_9_0_songauthors(self, database):
616- self.display.sub_output(u'SongAuthors Started for ' + database);
617- conn = sqlite3.connect(self.data_path + os.sep + database)
618- conn.execute(u'""create table if not exists authors_songs
619- (author_id integer,
620- song_id integer);""')
621- conn.commit()
622- self.display.sub_output(u'authors_songs table created')
623- conn.execute(u'""insert into authors_songs (author_id, song_id)
624- select authorid, songid from songauthors;""')
625- conn.commit()
626- self.display.sub_output(u'authors_songs populated')
627- conn.execute(u'""drop table songauthors;""')
628- conn.commit()
629- self.display.sub_output(u'songauthors dropped')
630- conn.close()
631- self.display.sub_output(u'SongAuthors Completed')
632-
633- def _v1_9_0_songtopics(self, database):
634- self.display.sub_output(u'Songtopics Started for ' + database);
635- conn = sqlite3.connect(self.data_path+os.sep+database)
636- conn.execute(u'""create table if not exists song_topics
637- (song_id integer,
638- topic_id integer);""')
639- conn.commit()
640- self.display.sub_output(u'songtopics table created')
641- conn.execute(u'""create index if not exists songtopic1 on song_topics (topic_id ASC,song_id ASC);""')
642- conn.commit()
643- self.display.sub_output(u'index songtopic1 created')
644- conn.execute(u'""create index if not exists songtopic2 on song_topics (song_id ASC,topic_id ASC);""')
645- conn.commit()
646- conn.close()
647- self.display.sub_output(u'index songtopic2 created')
648- self.display.sub_output(u'SongTopics Completed')
649-
650- def run_cmd(self, cmd):
651- filein, fileout = os.popen4(cmd)
652- out = fileout.readlines()
653- if len(out) > 0:
654- for o in range (0, len(out)):
655- self.display.sub_output(out[o])
656\ No newline at end of file
657+ '(u', ''), ')', ''), '{', ''), '}',''),'?','')
658+ ;""")
659+ conn.commit()
660+ conn.execute(u'drop table authors_temp;')
661+ conn.commit()
662+ conn.execute(u'drop table songs_temp;')
663+ conn.commit()
664+ conn.execute(u'drop table songauthors_temp;')
665+ conn.commit()
666+ conn.execute(u'drop table settings;')
667+
668+ conn.commit()
669
670=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
671--- openlp/plugins/bibles/lib/mediaitem.py 2009-06-17 05:11:16 +0000
672+++ openlp/plugins/bibles/lib/mediaitem.py 2009-06-23 16:25:40 +0000
673@@ -45,7 +45,6 @@
674 if dropAction == QtCore.Qt.CopyAction:
675 self.close()
676
677-
678 class BibleMediaItem(MediaManagerItem):
679 """
680 This is the custom media manager item for Bibles.
681
682=== modified file 'openlp/plugins/presentations/lib/impresscom.py'
683--- openlp/plugins/presentations/lib/impresscom.py 2009-06-16 18:21:24 +0000
684+++ openlp/plugins/presentations/lib/impresscom.py 2009-06-23 16:25:40 +0000
685@@ -1,4 +1,4 @@
686-from win32com.client import Dispatch
687+#from win32com.client import Dispatch
688
689 # OOo API documentation:
690 # http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html
691@@ -33,26 +33,26 @@
692 self._app.Terminate()
693 self._app = None
694 self._sm = None
695-
696+
697 class ImpressCOMPres(object):
698 def __init__(self, oooApp, filename):
699 self.oooApp = oooApp
700 self.filename = filename
701 self.open()
702-
703+
704 def getPres(self):
705 if self._pres == None:
706 self.open()
707 return self._pres
708-
709+
710 pres = property(getPres)
711-
712+
713 def open(self):
714- self.comp = self.oooApp.app.loadComponentFromURL(u'file:///" + self.filename, "_blank", 0, [])
715+ self.comp = self.oooApp.app.loadComponentFromURL(u'file:///' + self.filename, '_blank', 0, [])
716 self.presdoc = self.comp.getPresentation()
717 self.presdoc.start()
718 self._pres = self.presdoc.getController()
719-
720+
721 def close(self):
722 self.pres.deactivate()
723 self.presdoc.end()
724@@ -63,7 +63,7 @@
725
726 def isActive(self):
727 return self.pres.isRunning() and self.pres.isActive()
728-
729+
730 def resume(self):
731 return self.pres.resume()
732
733@@ -72,7 +72,7 @@
734
735 def blankScreen(self):
736 self.pres.blankScreen(0)
737-
738+
739 def stop(self):
740 self.pres.deactivate()
741 # self.presdoc.end()
742@@ -83,7 +83,7 @@
743
744 def getSlideNumber(self):
745 return self.pres.getCurrentSlideIndex
746-
747+
748 def setSlideNumber(self, slideno):
749 self.pres.gotoSlideIndex(slideno)
750
751@@ -112,7 +112,7 @@
752
753 if __name__ == '__main__':
754 ooo = ImpressCOMApp()
755- show = ImpressCOMPres(ooo, "c:/test1.ppt')
756+ show = ImpressCOMPres(ooo, u'c:/test1.ppt')
757 show.go()
758 show.resume()
759- show.nextStep()
760\ No newline at end of file
761+ show.nextStep()
762
763=== modified file 'openlp/plugins/songs/forms/topicsform.py'
764--- openlp/plugins/songs/forms/topicsform.py 2009-06-14 15:12:40 +0000
765+++ openlp/plugins/songs/forms/topicsform.py 2009-06-24 06:15:04 +0000
766@@ -51,7 +51,8 @@
767 Refresh the screen and rest fields
768 """
769 self.TopicsListWidget.clear()
770- self.onClearButtonClick() # tidy up screen
771+ # tidy up screen
772+ self.onClearButtonClick()
773 topics = self.songmanager.get_topics()
774 for topic in topics:
775 topic_name = QtGui.QListWidgetItem(topic.name)
776@@ -77,12 +78,13 @@
777 """
778 Sent New or update details to the database
779 """
780- if self.topic == None:
781- self.topic = Topic()
782- self.topic.name = unicode(self.TopicNameEdit.displayText())
783- self.songmanager.save_topic(self.topic)
784- self.onClearButtonClick()
785- self.load_form()
786+ if self._validate_form():
787+ if self.topic == None:
788+ self.topic = Topic()
789+ self.topic.name = unicode(self.TopicNameEdit.displayText())
790+ self.songmanager.save_topic(self.topic)
791+ self.onClearButtonClick()
792+ self.load_form()
793
794 def onClearButtonClick(self):
795 """
796@@ -91,7 +93,6 @@
797 self.TopicNameEdit.setText(u'')
798 self.MessageLabel.setText(u'')
799 self.DeleteButton.setEnabled(False)
800- self.AddUpdateButton.setEnabled(True)
801 self.topic = None
802 self._validate_form()
803
804@@ -115,7 +116,10 @@
805
806 def _validate_form(self):
807 # We need at lease a display name
808+ valid = True
809 if len(self.TopicNameEdit.displayText()) == 0:
810- self.AddUpdateButton.setEnabled(False)
811+ valid = False
812+ self.TopicNameEdit.setStyleSheet(u'background-color: red; color: white')
813 else:
814- self.AddUpdateButton.setEnabled(True)
815+ self.TopicNameEdit.setStyleSheet(u'')
816+ return valid
817
818=== modified file 'openlp/plugins/songs/lib/tables.py'
819--- openlp/plugins/songs/lib/tables.py 2009-06-16 18:21:24 +0000
820+++ openlp/plugins/songs/lib/tables.py 2009-06-24 06:10:13 +0000
821@@ -16,7 +16,7 @@
822 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
823 Place, Suite 330, Boston, MA 02111-1307 USA
824 """
825-
826+from sqlalchemy import *
827 from sqlalchemy import Column, Table, ForeignKey, types
828
829 from openlp.plugins.songs.lib.meta import metadata
830@@ -68,4 +68,13 @@
831 songs_topics_table = Table(u'songs_topics', metadata,
832 Column(u'song_id', types.Integer, ForeignKey(u'songs.id'), primary_key=True),
833 Column(u'topic_id', types.Integer, ForeignKey(u'topics.id'), primary_key=True)
834-)
835\ No newline at end of file
836+)
837+Index(u'authors_id',authors_table.c.id)
838+Index(u'authors_display_name_id',authors_table.c.display_name, authors_table.c.id)
839+Index(u'song_books_id',song_books_table.c.id)
840+Index(u'songs_id',songs_table.c.id)
841+Index(u'topics_id',topics_table.c.id)
842+Index(u'authors_songs_author',authors_songs_table.c.author_id, authors_songs_table.c.song_id)
843+Index(u'authors_songs_song',authors_songs_table.c.song_id, authors_songs_table.c.author_id)
844+Index(u'topics_song_topic', songs_topics_table.c.topic_id, songs_topics_table.c.song_id)
845+Index(u'topics_song_song',songs_topics_table.c.song_id, songs_topics_table.c.topic_id)
846
847=== modified file 'openlpcnv.pyw'
848--- openlpcnv.pyw 2009-06-16 18:21:24 +0000
849+++ openlpcnv.pyw 2009-06-23 16:25:40 +0000
850@@ -1,6 +1,6 @@
851 #!/usr/bin/env python
852
853-import os
854+import os
855 import sys
856 import logging
857 import time
858@@ -21,25 +21,25 @@
859 def __init__(self):
860 """
861 """
862- self.display = Display()
863- self.stime = time.strftime(u'%Y-%m-%d-%H%M%S", time.localtime())
864- self.display.output(u'OpenLp v1.9.0 Migration Utility Started" )
865-
866+ self.display = Display()
867+ self.stime = time.strftime(u'%Y-%m-%d-%H%M%S', time.localtime())
868+ self.display.output(u'OpenLp v1.9.0 Migration Utility Started')
869+
870 def process(self):
871- MigrateFiles(self.display).process()
872+ #MigrateFiles(self.display).process()
873 MigrateSongs(self.display).process()
874- MigrateBibles(self.display).process()
875-
876+ #MigrateBibles(self.display).process()
877+
878 def move_log_file(self):
879 fname = 'openlp-migration.log'
880 c = os.path.splitext(fname)
881 b = (c[0]+'-'+ unicode(self.stime) + c[1])
882- self.display.output(u'Logfile " +b + " generated')
883+ self.display.output(u'Logfile " +b + " generated')
884 self.display.output(u'Migration Utility Finished ')
885- os.rename(fname, b)
886-
887-
888+ os.rename(fname, b)
889+
890+
891 if __name__ == '__main__':
892 mig = Migration()
893 mig.process()
894- #mig.move_log_file()
895\ No newline at end of file
896+ #mig.move_log_file()