This commit is contained in:
Tomas Groth 2015-12-18 21:13:21 +01:00
commit 6eb17b561d
26 changed files with 96 additions and 74 deletions

View File

@ -90,14 +90,15 @@ class Ui_ExceptionDialog(object):
"""
exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred'))
self.description_explanation.setText(
translate('OpenLP.ExceptionDialog', 'Please enter a description of what you were doing to cause this error '
translate('OpenLP.ExceptionDialog', 'Please enter a description of what you were doing to cause this error.'
' If possible, write in English.'
'\n(Minimum 20 characters)'))
self.message_label.setText(
translate('OpenLP.ExceptionDialog', 'Oops! OpenLP hit a problem, and couldn\'t recover. The text in the '
'box below contains information that might be helpful to the OpenLP '
'developers, so please e-mail it to bugs@openlp.org, along with a '
'detailed description of what you were doing when the problem '
'occurred.'))
'occurred. Also attach any files that triggered the problem.'))
self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail'))
self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File'))
self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File'))

View File

@ -97,6 +97,12 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
super(ExceptionForm, self).__init__()
self.setupUi(self)
self.settings_section = 'crashreport'
self.report_text = '**OpenLP Bug Report**\n' \
'Version: %s\n\n' \
'--- Details of the Exception. ---\n\n%s\n\n ' \
'--- Exception Traceback ---\n%s\n' \
'--- System information ---\n%s\n' \
'--- Library Versions ---\n%s\n'
def exec_(self):
"""
@ -143,13 +149,6 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
"""
Saving exception log and system information to a file.
"""
report_text = translate('OpenLP.ExceptionForm',
'**OpenLP Bug Report**\n'
'Version: %s\n\n'
'--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n')
filename = QtGui.QFileDialog.getSaveFileName(
self,
translate('OpenLP.ExceptionForm', 'Save Crash Report'),
@ -158,7 +157,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
if filename:
filename = str(filename).replace('/', os.path.sep)
Settings().setValue(self.settings_section + '/last directory', os.path.dirname(filename))
report_text = report_text % self._create_report()
report_text = self.report_text % self._create_report()
try:
report_file = open(filename, 'w')
try:
@ -178,14 +177,6 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
"""
Opening systems default email client and inserting exception log and system information.
"""
body = translate('OpenLP.ExceptionForm',
'*OpenLP Bug Report*\n'
'Version: %s\n\n'
'--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n',
'Please add the information that bug reports are favoured written in English.')
content = self._create_report()
source = ''
exception = ''
@ -197,7 +188,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
subject = 'Bug report: %s in %s' % (exception, source)
mail_to_url = QtCore.QUrl('mailto:bugs@openlp.org')
mail_to_url.addQueryItem('subject', subject)
mail_to_url.addQueryItem('body', body % content)
mail_to_url.addQueryItem('body', self.report_text % content)
if self.file_attachment:
mail_to_url.addQueryItem('attach', self.file_attachment)
QtGui.QDesktopServices.openUrl(mail_to_url)

View File

@ -166,5 +166,6 @@ class FormattingTagController(object):
return None, end
if end and end != end_html:
return translate('OpenLP.FormattingTagForm',
'End tag %s does not match end tag for start tag %s') % (end, start_html), None
'End tag %(end)s does not match end tag for start tag %(start)s') % \
{'end': end, 'start': start_html}, None
return None, None

View File

@ -566,7 +566,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.application.set_busy_cursor()
# Simple message boxes
Registry().register_function('theme_update_global', self.default_theme_changed)
QtCore.QObject.connect(self, QtCore.SIGNAL('openlp_version_check'), self.version_notice)
QtCore.QObject.connect(self, QtCore.SIGNAL('openlp_version_check'), self.version_notice)
Registry().register_function('config_screen_changed', self.screen_changed)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
# Reset the cursor
@ -1089,13 +1089,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
event.ignore()
else:
if Settings().value('advanced/enable exit confirmation'):
ret = QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'Close OpenLP'),
translate('OpenLP.MainWindow', 'Are you sure you want to close '
'OpenLP?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes)
if ret == QtGui.QMessageBox.Yes:
msg_box = QtGui.QMessageBox(QtGui.QMessageBox.Question, translate('OpenLP.MainWindow', 'Exit OpenLP'),
translate('OpenLP.MainWindow', 'Are you sure you want to exit OpenLP?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Close |
QtGui.QMessageBox.Cancel), self)
msg_box.setButtonText(QtGui.QMessageBox.Close, translate('OpenLP.MainWindow', '&Exit OpenLP'))
msg_box.setDefaultButton(QtGui.QMessageBox.Close)
if msg_box.exec() == QtGui.QMessageBox.Close:
self.clean_up()
event.accept()
else:

View File

@ -476,9 +476,9 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
controller.media_info.media_type = MediaType.CD
else:
controller.media_info.media_type = MediaType.DVD
controller.media_info.start_time = start/1000
controller.media_info.end_time = end/1000
controller.media_info.length = (end - start)/1000
controller.media_info.start_time = start / 1000
controller.media_info.end_time = end / 1000
controller.media_info.length = (end - start) / 1000
controller.media_info.title_track = title
controller.media_info.audio_track = audio_track
controller.media_info.subtitle_track = subtitle_track

View File

@ -45,18 +45,18 @@ from openlp.core.ui.projector.editform import ProjectorEditForm
from openlp.core.ui.projector.sourceselectform import SourceSelectTabs, SourceSelectSingle
# Dict for matching projector status to display icon
STATUS_ICONS = {S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png',
S_CONNECTING: ':/projector/projector_item_connect.png',
S_CONNECTED: ':/projector/projector_off.png',
S_OFF: ':/projector/projector_off.png',
S_INITIALIZE: ':/projector/projector_off.png',
S_STANDBY: ':/projector/projector_off.png',
S_WARMUP: ':/projector/projector_warmup.png',
S_ON: ':/projector/projector_on.png',
S_COOLDOWN: ':/projector/projector_cooldown.png',
E_ERROR: ':/projector/projector_error.png',
E_NETWORK: ':/projector/projector_not_connected_error.png',
E_AUTHENTICATION: ':/projector/projector_not_connected_error.png',
STATUS_ICONS = {S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png',
S_CONNECTING: ':/projector/projector_item_connect.png',
S_CONNECTED: ':/projector/projector_off.png',
S_OFF: ':/projector/projector_off.png',
S_INITIALIZE: ':/projector/projector_off.png',
S_STANDBY: ':/projector/projector_off.png',
S_WARMUP: ':/projector/projector_warmup.png',
S_ON: ':/projector/projector_on.png',
S_COOLDOWN: ':/projector/projector_cooldown.png',
E_ERROR: ':/projector/projector_error.png',
E_NETWORK: ':/projector/projector_not_connected_error.png',
E_AUTHENTICATION: ':/projector/projector_not_connected_error.png',
E_UNKNOWN_SOCKET_ERROR: ':/projector/projector_not_connected_error.png',
E_NOT_CONNECTED: ':/projector/projector_not_connected_error.png'
}

View File

@ -443,7 +443,7 @@ class SourceSelectSingle(QDialog):
QtGui.QDialogButtonBox.Cancel)
self.button_box.clicked.connect(self.button_clicked)
self.layout.addWidget(self.button_box)
self.setMinimumHeight(key_count*25)
self.setMinimumHeight(key_count * 25)
set_button_tooltip(self.button_box)
selected = super(SourceSelectSingle, self).exec_()
return selected

View File

@ -277,7 +277,7 @@ class OpenLPWizard(QtGui.QWizard, RegistryProperties):
:param filters: The file extension filters. It should contain the file description
as well as the file extension. For example::
'OpenLP 2.0 Databases (*.sqlite)'
'OpenLP 2 Databases (*.sqlite)'
"""
if filters:
filters += ';;'

View File

@ -547,9 +547,9 @@ class BibleUpgradeForm(OpenLPWizard):
if self.includeWebBible:
self.progress_label.setText(
translate('BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible(s): %s successful%s\nPlease note that verses from Web Bibles will be '
'downloaded on demand and so an Internet connection is required.') %
(successful_import, failed_import_text))
'Upgrading Bible(s): %(success)d successful%(failed_text)s\nPlease note that verses '
'from Web Bibles will be downloaded on demand and so an Internet connection is required.')
% {'success': successful_import, 'failed_text': failed_import_text})
else:
self.progress_label.setText(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %s successful%s') % (

View File

@ -184,13 +184,13 @@ class PptviewDocument(PresentationDocument):
# check if it is a slide
match = re.search("slides/slide(.+)\.xml", zip_info.filename)
if match:
index = int(match.group(1))-1
index = int(match.group(1)) - 1
node_type = 'ctrTitle'
list_to_add = titles
# or a note
match = re.search("notesSlides/notesSlide(.+)\.xml", zip_info.filename)
if match:
index = int(match.group(1))-1
index = int(match.group(1)) - 1
node_type = 'body'
list_to_add = notes
# if it is one of our files, index shouldn't be -1

View File

@ -280,9 +280,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
return True
if len(tags) % 2 != 0:
return False
for i in range(len(tags)-1):
if tags[i+1] == "{/" + tags[i][1:]:
del tags[i:i+2]
for i in range(len(tags) - 1):
if tags[i + 1] == "{/" + tags[i][1:]:
del tags[i:i + 2]
return self._validate_tags(tags, False)
return False

View File

@ -191,14 +191,14 @@ class SongFormat(object):
'name': 'OpenLyrics',
'prefix': 'openLyrics',
'filter': '%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', 'OpenLyrics Files'),
'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'OpenLyrics or OpenLP 2.0 Exported Song')
'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'OpenLyrics or OpenLP 2 Exported Song')
},
OpenLP2: {
'class': OpenLPSongImport,
'name': UiStrings().OLPV2,
'prefix': 'openLP2',
'selectMode': SongFormatSelect.SingleFile,
'filter': '%s (*.sqlite)' % (translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0 Databases'))
'filter': '%s (*.sqlite)' % (translate('SongsPlugin.ImportWizardForm', 'OpenLP 2 Databases'))
},
Generic: {
'name': translate('SongsPlugin.ImportWizardForm', 'Generic Document/Presentation'),

View File

@ -123,7 +123,7 @@ class EasyWorshipSongImport(SongImport):
log.debug('Given ews file is of unknown version.')
return
entry_count = self.get_i32(file_pos)
entry_length = self.get_i16(file_pos+4)
entry_length = self.get_i16(file_pos + 4)
file_pos += 6
self.import_wizard.progress_bar.setMaximum(entry_count)
# Loop over songs

View File

@ -94,7 +94,7 @@ class OpenLPSongImport(SongImport):
# Check the file type
if not self.import_source.endswith('.sqlite'):
self.log_error(self.import_source, translate('SongsPlugin.OpenLPSongImport',
'Not a valid OpenLP 2.0 song database.'))
'Not a valid OpenLP 2 song database.'))
return
self.import_source = 'sqlite:///%s' % self.import_source
# Load the db file

View File

@ -171,12 +171,12 @@ class OpenSongImport(SongImport):
topics = set(self.topics)
if 'theme' in fields:
theme = str(root.theme)
subthemes = theme[theme.find(':')+1:].split('/')
subthemes = theme[theme.find(':') + 1:].split('/')
for topic in subthemes:
topics.add(topic.strip())
if 'alttheme' in fields:
theme = str(root.alttheme)
subthemes = theme[theme.find(':')+1:].split('/')
subthemes = theme[theme.find(':') + 1:].split('/')
for topic in subthemes:
topics.add(topic.strip())
self.topics = list(topics)

View File

@ -108,8 +108,8 @@ class WordsOfWorshipImport(SongImport):
if song_data.read(19).decode() != 'WoW File\nSong Words':
self.log_error(source,
str(translate('SongsPlugin.WordsofWorshipSongImport',
'Invalid Words of Worship song file. Missing "WoW File\\nSong '
'Words" header.')))
'Invalid Words of Worship song file. Missing "%s" header.'
% 'WoW File\\nSong Words')))
continue
# Seek to byte which stores number of blocks in the song
song_data.seek(56)
@ -118,8 +118,8 @@ class WordsOfWorshipImport(SongImport):
if song_data.read(16).decode() != 'CSongDoc::CBlock':
self.log_error(source,
str(translate('SongsPlugin.WordsofWorshipSongImport',
'Invalid Words of Worship song file. Missing "CSongDoc::CBlock" '
'string.')))
'Invalid Words of Worship song file. Missing "%s" '
'string.' % 'CSongDoc::CBlock')))
continue
# Seek to the beginning of the first block
song_data.seek(82)

View File

@ -93,7 +93,7 @@ OPTIONAL_MODULES = [
('mysql.connector', '(MySQL support)', True),
('psycopg2', '(PostgreSQL support)', True),
('nose', '(testing framework)', True),
('mock', '(testing module)', sys.version_info[1] < 3),
('mock', '(testing module)', sys.version_info[1] < 3),
('jenkins', '(access jenkins api - package name: jenkins-webapi)', True),
]

View File

@ -96,7 +96,7 @@ for row in bug_rows:
# <div class="context-publication"><h1>Merge ... into...
div_branches = soup.find('div', class_='context-publication')
branches = div_branches.h1.contents[0]
target_branch = '+branch/' + branches[(branches.find(' into lp:')+9):]
target_branch = '+branch/' + branches[(branches.find(' into lp:') + 9):]
# Check that we are in the right branch
bzr_info_output = subprocess.check_output(['bzr', 'info'])

View File

@ -1,3 +1,4 @@
[pep8]
exclude=resources.py,vlc.py
max-line-length = 120
ignore = E402

View File

@ -43,7 +43,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertFalse(args.portable, 'The portable flag should be set to false')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, [], 'The service file should be blank')
def parse_options_debug_test(self):
@ -60,7 +60,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertFalse(args.portable, 'The portable flag should be set to false')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, [], 'The service file should be blank')
def parse_options_debug_and_portable_test(self):
@ -77,7 +77,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertTrue(args.portable, 'The portable flag should be set to true')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, [], 'The service file should be blank')
def parse_options_all_no_file_test(self):
@ -94,7 +94,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertFalse(args.portable, 'The portable flag should be set to false')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, [], 'The service file should be blank')
def parse_options_file_test(self):
@ -111,7 +111,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertFalse(args.portable, 'The portable flag should be set to false')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
def parse_options_file_and_debug_test(self):
@ -128,7 +128,7 @@ class TestInitFunctions(TestMixin, TestCase):
self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
self.assertFalse(args.portable, 'The portable flag should be set to false')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.style, None, 'There are no style flags to be processed')
self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
def parse_options_two_files_test(self):

View File

@ -119,7 +119,7 @@ class TestFieldDesc:
TEST_DATA_ENCODING = 'cp1252'
CODE_PAGE_MAPPINGS = [
(852, 'cp1250'), (737, 'cp1253'), (775, 'cp1257'), (855, 'cp1251'), (857, 'cp1254'),
(866, 'cp1251'), (869, 'cp1253'), (862, 'cp1255'), (874, 'cp874')]
(866, 'cp1251'), (869, 'cp1253'), (862, 'cp1255'), (874, 'cp874')]
TEST_FIELD_DESCS = [
TestFieldDesc('Title', FieldType.String, 50),
TestFieldDesc('Text Percentage Bottom', FieldType.Int16, 2), TestFieldDesc('RecID', FieldType.Int32, 4),

View File

@ -119,7 +119,7 @@ class TestMediaItem(TestCase, TestMixin):
# THEN: I get the following Array returned
self.assertEqual(service_item.raw_footer, ['My Song', 'Words: another author', 'Music: my author',
'Translation: translator', 'My copyright'],
'Translation: translator', 'My copyright'],
'The array should be returned correctly with a song, two authors and copyright')
self.assertEqual(author_list, ['another author', 'my author', 'translator'],
'The author list should be returned correctly with two authors')

View File

@ -82,7 +82,7 @@ class TestSongSelectImport(TestCase, TestMixin):
self.assertFalse(result, 'The login method should have returned False')
@patch('openlp.plugins.songs.lib.songselect.build_opener')
def login_except_test(self, mocked_build_opener):
def login_except_test(self, mocked_build_opener):
"""
Test that when logging in to SongSelect fails, the login method raises URLError
"""

View File

@ -47,3 +47,6 @@ class TestWordsOfWorshipFileImport(SongImportTestHelper):
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace (6 Verses).json')))
self.file_import([os.path.join(TEST_PATH, 'When morning gilds the skies.wsg')],
self.load_external_result_data(os.path.join(TEST_PATH, 'When morning gilds the skies.json')))
self.file_import([os.path.join(TEST_PATH, 'Holy Holy Holy Lord God Almighty.wow-song')],
self.load_external_result_data(os.path.join(TEST_PATH,
'Holy Holy Holy Lord God Almighty.json')))

View File

@ -0,0 +1,25 @@
{
"authors": [
"Words: Reginald Heber (1783-1826). Music: John B. Dykes (1823-1876)"
],
"title": "Holy Holy Holy Lord God Almighty",
"verse_order_list": [],
"verses": [
[
"Holy, holy, holy, Lord God Almighty\nEarly in the morning\nOur song shall rise to Thee:\nHoly, holy, holy, merciful and mighty,\nGod in three Persons, blessed Trinity!",
"V"
],
[
"Holy, holy, holy! all the saints adore Thee,\nCasting down their golden crowns\nAround the glassy sea;\nCherubim and seraphim falling down before Thee,\nWho were and are and evermore shall be.",
"V"
],
[
"Holy, holy, holy! though the darkness hide Thee,\nThough the eye of sinful man\nThy glory may not see;\nOnly Thou art holy, there is none beside Thee,\nPerfect in power, in love and purity.",
"V"
],
[
"Holy, holy, holy, Lord God Almighty!\nAll Thy works shall praise Thy name\nIn earth, and sky, and sea;\nHoly, holy, holy, merciful and mighty\nGod in three Persons, blessed Trinity!",
"V"
]
]
}