Merge lp:~alisonken1/openlp/strings-lib into lp:openlp

Proposed by Ken Roberts
Status: Merged
Merged at revision: 2664
Proposed branch: lp:~alisonken1/openlp/strings-lib
Merge into: lp:openlp
Diff against target: 975 lines (+233/-125)
15 files modified
openlp/core/lib/db.py (+22/-18)
openlp/core/lib/filedialog.py (+2/-1)
openlp/core/lib/htmlbuilder.py (+51/-35)
openlp/core/lib/imagemanager.py (+3/-3)
openlp/core/lib/mediamanageritem.py (+19/-12)
openlp/core/lib/plugin.py (+5/-5)
openlp/core/lib/pluginmanager.py (+14/-11)
openlp/core/lib/renderer.py (+7/-5)
openlp/core/lib/screen.py (+9/-7)
openlp/core/lib/searchedit.py (+3/-2)
openlp/core/lib/serviceitem.py (+12/-9)
openlp/core/lib/theme.py (+2/-1)
openlp/core/lib/ui.py (+3/-3)
openlp/core/lib/webpagereader.py (+9/-9)
tests/functional/openlp_core_lib/test_projector_pjlink1.py (+72/-4)
To merge this branch: bzr merge lp:~alisonken1/openlp/strings-lib
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman Approve
Review via email: mp+294907@code.launchpad.net

This proposal supersedes a proposal from 2016-05-16.

Commit message

openlp/core/lib/*.py files convert strings to python3 format

Description of the change

Convert strings from python2 to python3 format

- Strings converted except as noted
- Updated projector pjlink test
- Simplify lines with multiple references to single variable

--------------------------------
lp:~alisonken1/openlp/strings-lib (revision 2665)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1559/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1470/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1408/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1188/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/778/
[SUCCESS] https://ci.openlp.io/job/Branch-05a-Code_Analysis/846/
[SUCCESS] https://ci.openlp.io/job/Branch-05b-Test_Coverage/714/

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

Just one question

review: Needs Information
Revision history for this message
Raoul Snyman (raoul-snyman) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
Revision history for this message
Tim Bentley (trb143) :
review: Approve

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 2016-04-05 17:10:51 +0000
3+++ openlp/core/lib/db.py 2016-05-17 13:27:53 +0000
4@@ -68,9 +68,11 @@
5 :return: The path to the database as type str
6 """
7 if db_file_name is None:
8- return 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name)
9+ return 'sqlite:///{path}/{plugin}.sqlite'.format(path=AppLocation.get_section_data_path(plugin_name),
10+ plugin=plugin_name)
11 else:
12- return 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name)
13+ return 'sqlite:///{path}/{name}'.format(path=AppLocation.get_section_data_path(plugin_name),
14+ name=db_file_name)
15
16
17 def handle_db_error(plugin_name, db_file_name):
18@@ -82,10 +84,10 @@
19 :return: None
20 """
21 db_path = get_db_path(plugin_name, db_file_name)
22- log.exception('Error loading database: %s', db_path)
23+ log.exception('Error loading database: {db}'.format(db=db_path))
24 critical_error_message_box(translate('OpenLP.Manager', 'Database Error'),
25- translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s')
26- % db_path)
27+ translate('OpenLP.Manager',
28+ 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path))
29
30
31 def init_url(plugin_name, db_file_name=None):
32@@ -101,10 +103,11 @@
33 if db_type == 'sqlite':
34 db_url = get_db_path(plugin_name, db_file_name)
35 else:
36- db_url = '%s://%s:%s@%s/%s' % (db_type, urlquote(settings.value('db username')),
37- urlquote(settings.value('db password')),
38- urlquote(settings.value('db hostname')),
39- urlquote(settings.value('db database')))
40+ db_url = '{type}://{user}:{password}@{host}/{db}'.format(type=db_type,
41+ user=urlquote(settings.value('db username')),
42+ password=urlquote(settings.value('db password')),
43+ host=urlquote(settings.value('db hostname')),
44+ db=urlquote(settings.value('db database')))
45 settings.endGroup()
46 return db_url
47
48@@ -157,10 +160,10 @@
49 return version, upgrade.__version__
50 version += 1
51 try:
52- while hasattr(upgrade, 'upgrade_%d' % version):
53- log.debug('Running upgrade_%d', version)
54+ while hasattr(upgrade, 'upgrade_{version:d}'.format(version=version)):
55+ log.debug('Running upgrade_{version:d}'.format(version=version))
56 try:
57- upgrade_func = getattr(upgrade, 'upgrade_%d' % version)
58+ upgrade_func = getattr(upgrade, 'upgrade_{version:d}'.format(version=version))
59 upgrade_func(session, metadata)
60 session.commit()
61 # Update the version number AFTER a commit so that we are sure the previous transaction happened
62@@ -168,8 +171,8 @@
63 session.commit()
64 version += 1
65 except (SQLAlchemyError, DBAPIError):
66- log.exception('Could not run database upgrade script "upgrade_%s", upgrade process has been halted.',
67- version)
68+ log.exception('Could not run database upgrade script '
69+ '"upgrade_{version:d}", upgrade process has been halted.'.format(version=version))
70 break
71 except (SQLAlchemyError, DBAPIError):
72 version_meta = Metadata.populate(key='version', value=int(upgrade.__version__))
73@@ -242,9 +245,10 @@
74 critical_error_message_box(
75 translate('OpenLP.Manager', 'Database Error'),
76 translate('OpenLP.Manager', 'The database being loaded was created in a more recent version of '
77- 'OpenLP. The database is version %d, while OpenLP expects version %d. The database will '
78- 'not be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url)
79- )
80+ 'OpenLP. The database is version {db_ver}, while OpenLP expects version {db_up}. '
81+ 'The database will not be loaded.\n\nDatabase: {db_name}').format(db_ver=db_ver,
82+ db_up=up_ver,
83+ db_name=self.db_url))
84 return
85 if not session:
86 try:
87@@ -460,7 +464,7 @@
88 raise
89 except InvalidRequestError:
90 self.session.rollback()
91- log.exception('Failed to delete %s records', object_class.__name__)
92+ log.exception('Failed to delete {name} records'.format(name=object_class.__name__))
93 return False
94 except:
95 self.session.rollback()
96
97=== modified file 'openlp/core/lib/filedialog.py'
98--- openlp/core/lib/filedialog.py 2015-12-31 22:46:06 +0000
99+++ openlp/core/lib/filedialog.py 2016-05-17 13:27:53 +0000
100@@ -50,7 +50,8 @@
101 log.info('File not found. Attempting to unquote.')
102 file = parse.unquote(file)
103 if not os.path.exists(file):
104- log.error('File %s not found.' % file)
105+ log.error('File {text} not found.'.format(text=file))
106+ # TODO: Test with UiStrings() before converting to python3 strings
107 QtWidgets.QMessageBox.information(parent, UiStrings().FileNotFound,
108 UiStrings().FileNotFoundMessage % file)
109 continue
110
111=== modified file 'openlp/core/lib/htmlbuilder.py'
112--- openlp/core/lib/htmlbuilder.py 2015-12-31 22:46:06 +0000
113+++ openlp/core/lib/htmlbuilder.py 2016-05-17 13:27:53 +0000
114@@ -396,6 +396,7 @@
115
116 log = logging.getLogger(__name__)
117
118+# TODO: Verify where this is used before converting to python3
119 HTMLSRC = """
120 <!DOCTYPE html>
121 <html>
122@@ -564,13 +565,13 @@
123 theme_data = item.theme_data
124 # Image generated and poked in
125 if background:
126- bgimage_src = 'src="data:image/png;base64,%s"' % background
127+ bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=background)
128 elif item.bg_image_bytes:
129- bgimage_src = 'src="data:image/png;base64,%s"' % item.bg_image_bytes
130+ bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=item.bg_image_bytes)
131 else:
132 bgimage_src = 'style="display:none;"'
133 if image:
134- image_src = 'src="data:image/png;base64,%s"' % image
135+ image_src = 'src="data:image/png;base64,{image}"'.format(image=image)
136 else:
137 image_src = 'style="display:none;"'
138 css_additions = ''
139@@ -601,7 +602,7 @@
140 """
141 try:
142 webkit_ver = float(QtWebKit.qWebKitVersion())
143- log.debug('Webkit version = %s' % webkit_ver)
144+ log.debug('Webkit version = {version}'.format(version=webkit_ver))
145 except AttributeError:
146 webkit_ver = 0
147 return webkit_ver
148@@ -621,23 +622,25 @@
149 if theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
150 background = ''
151 elif theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
152- background = 'background-color: %s' % theme.background_color
153+ background = 'background-color: {theme}'.format(theme=theme.background_color)
154 else:
155 if theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
156- background = 'background: -webkit-gradient(linear, left top, left bottom, from(%s), to(%s)) fixed' \
157- % (theme.background_start_color, theme.background_end_color)
158+ background = 'background: -webkit-gradient(linear, left top, left bottom, from({start}), to({end})) ' \
159+ 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
160 elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftTop):
161- background = 'background: -webkit-gradient(linear, left top, right bottom, from(%s), to(%s)) fixed' \
162- % (theme.background_start_color, theme.background_end_color)
163+ background = 'background: -webkit-gradient(linear, left top, right bottom, from({start}), to({end})) ' \
164+ 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
165 elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftBottom):
166- background = 'background: -webkit-gradient(linear, left bottom, right top, from(%s), to(%s)) fixed' \
167- % (theme.background_start_color, theme.background_end_color)
168+ background = 'background: -webkit-gradient(linear, left bottom, right top, from({start}), to({end})) ' \
169+ 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
170 elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Vertical):
171- background = 'background: -webkit-gradient(linear, left top, right top, from(%s), to(%s)) fixed' % \
172- (theme.background_start_color, theme.background_end_color)
173+ background = 'background: -webkit-gradient(linear, left top, right top, from({start}), to({end})) ' \
174+ 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color)
175 else:
176- background = 'background: -webkit-gradient(radial, %s 50%%, 100, %s 50%%, %s, from(%s), to(%s)) fixed'\
177- % (width, width, width, theme.background_start_color, theme.background_end_color)
178+ background = 'background: -webkit-gradient(radial, {width} 50%, 100, {width} 50%, {width}, ' \
179+ 'from({start}), to({end})) fixed'.format(width=width,
180+ start=theme.background_start_color,
181+ end=theme.background_end_color)
182 return background
183
184
185@@ -647,6 +650,7 @@
186
187 :param item: Service Item containing theme and location information
188 """
189+ # TODO: Verify this before converting to python3
190 style = """
191 .lyricstable {
192 z-index: 5;
193@@ -669,12 +673,13 @@
194 lyrics = ''
195 lyricsmain = ''
196 if theme_data and item.main:
197- lyricstable = 'left: %spx; top: %spx;' % (item.main.x(), item.main.y())
198+ lyricstable = 'left: {left}px; top: {top}px;'.format(left=item.main.x(), top=item.main.y())
199 lyrics = build_lyrics_format_css(theme_data, item.main.width(), item.main.height())
200 lyricsmain += build_lyrics_outline_css(theme_data)
201 if theme_data.font_main_shadow:
202- lyricsmain += ' text-shadow: %s %spx %spx;' % \
203- (theme_data.font_main_shadow_color, theme_data.font_main_shadow_size, theme_data.font_main_shadow_size)
204+ lyricsmain += ' text-shadow: {theme} {shadow}px ' \
205+ '{shadow}px;'.format(theme=theme_data.font_main_shadow_color,
206+ shadow=theme_data.font_main_shadow_size)
207 lyrics_css = style % (lyricstable, lyrics, lyricsmain)
208 return lyrics_css
209
210@@ -689,7 +694,9 @@
211 size = float(theme_data.font_main_outline_size) / 16
212 fill_color = theme_data.font_main_color
213 outline_color = theme_data.font_main_outline_color
214- return ' -webkit-text-stroke: %sem %s; -webkit-text-fill-color: %s; ' % (size, outline_color, fill_color)
215+ return ' -webkit-text-stroke: {size}em {color}; -webkit-text-fill-color: {fill}; '.format(size=size,
216+ color=outline_color,
217+ fill=fill_color)
218 return ''
219
220
221@@ -715,13 +722,21 @@
222 padding_bottom = '0.5em'
223 else:
224 padding_bottom = '0'
225- lyrics = '%s word-wrap: break-word; ' \
226- 'text-align: %s; vertical-align: %s; font-family: %s; ' \
227- 'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
228- 'padding: 0; padding-bottom: %s; padding-left: %spx; width: %spx; height: %spx; ' % \
229- (justify, align, valign, theme_data.font_main_name, theme_data.font_main_size,
230- theme_data.font_main_color, 100 + int(theme_data.font_main_line_adjustment), padding_bottom,
231- left_margin, width, height)
232+ lyrics = '{justify} word-wrap: break-word; ' \
233+ 'text-align: {align}; vertical-align: {valign}; font-family: {font}; ' \
234+ 'font-size: {size}pt; color: {color}; line-height: {line:d}%; margin: 0;' \
235+ 'padding: 0; padding-bottom: {bottom}; padding-left: {left}px; width: {width}px; ' \
236+ 'height: {height}px; '.format(justify=justify,
237+ align=align,
238+ valign=valign,
239+ font=theme_data.font_main_name,
240+ size=theme_data.font_main_size,
241+ color=theme_data.font_main_color,
242+ line=100 + int(theme_data.font_main_line_adjustment),
243+ bottom=padding_bottom,
244+ left=left_margin,
245+ width=width,
246+ height=height)
247 if theme_data.font_main_italics:
248 lyrics += 'font-style:italic; '
249 if theme_data.font_main_bold:
250@@ -737,20 +752,21 @@
251 :param height:
252 """
253 style = """
254- left: %spx;
255- bottom: %spx;
256- width: %spx;
257- font-family: %s;
258- font-size: %spt;
259- color: %s;
260+ left: {left}px;
261+ bottom: {bottom}px;
262+ width: {width}px;
263+ font-family: {family};
264+ font-size: {size}pt;
265+ color: {color};
266 text-align: left;
267- white-space: %s;
268+ white-space: {space};
269 """
270 theme = item.theme_data
271 if not theme or not item.footer:
272 return ''
273 bottom = height - int(item.footer.y()) - int(item.footer.height())
274 whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap'
275- lyrics_html = style % (item.footer.x(), bottom, item.footer.width(),
276- theme.font_footer_name, theme.font_footer_size, theme.font_footer_color, whitespace)
277+ lyrics_html = style.format(left=item.footer.x(), bottom=bottom, width=item.footer.width(),
278+ family=theme.font_footer_name, size=theme.font_footer_size,
279+ color=theme.font_footer_color, space=whitespace)
280 return lyrics_html
281
282=== modified file 'openlp/core/lib/imagemanager.py'
283--- openlp/core/lib/imagemanager.py 2015-12-31 22:46:06 +0000
284+++ openlp/core/lib/imagemanager.py 2016-05-17 13:27:53 +0000
285@@ -236,7 +236,7 @@
286 """
287 Return the ``QImage`` from the cache. If not present wait for the background thread to process it.
288 """
289- log.debug('getImage %s' % path)
290+ log.debug('getImage {path}'.format(path=path))
291 image = self._cache[(path, source, width, height)]
292 if image.image is None:
293 self._conversion_queue.modify_priority(image, Priority.High)
294@@ -256,7 +256,7 @@
295 """
296 Returns the byte string for an image. If not present wait for the background thread to process it.
297 """
298- log.debug('get_image_bytes %s' % path)
299+ log.debug('get_image_bytes {path}'.format(path=path))
300 image = self._cache[(path, source, width, height)]
301 if image.image_bytes is None:
302 self._conversion_queue.modify_priority(image, Priority.Urgent)
303@@ -271,7 +271,7 @@
304 """
305 Add image to cache if it is not already there.
306 """
307- log.debug('add_image %s' % path)
308+ log.debug('add_image {path}'.format(path=path))
309 if not (path, source, width, height) in self._cache:
310 image = Image(path, source, background, width, height)
311 self._cache[(path, source, width, height)] = image
312
313=== modified file 'openlp/core/lib/mediamanageritem.py'
314--- openlp/core/lib/mediamanageritem.py 2016-04-17 19:32:15 +0000
315+++ openlp/core/lib/mediamanageritem.py 2016-05-17 13:27:53 +0000
316@@ -186,7 +186,7 @@
317 for action in toolbar_actions:
318 if action[0] == StringContent.Preview:
319 self.toolbar.addSeparator()
320- self.toolbar.add_toolbar_action('%s%sAction' % (self.plugin.name, action[0]),
321+ self.toolbar.add_toolbar_action('{name}{action}Action'.format(name=self.plugin.name, action=action[0]),
322 text=self.plugin.get_string(action[1])['title'], icon=action[2],
323 tooltip=self.plugin.get_string(action[1])['tooltip'],
324 triggers=action[3])
325@@ -200,7 +200,7 @@
326 self.list_view.setSpacing(1)
327 self.list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
328 self.list_view.setAlternatingRowColors(True)
329- self.list_view.setObjectName('%sListView' % self.plugin.name)
330+ self.list_view.setObjectName('{name}ListView'.format(name=self.plugin.name))
331 # Add to page_layout
332 self.page_layout.addWidget(self.list_view)
333 # define and add the context menu
334@@ -212,19 +212,22 @@
335 triggers=self.on_edit_click)
336 create_widget_action(self.list_view, separator=True)
337 create_widget_action(self.list_view,
338- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
339+ 'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(),
340+ preview=StringContent.Preview.title()),
341 text=self.plugin.get_string(StringContent.Preview)['title'],
342 icon=':/general/general_preview.png',
343 can_shortcuts=True,
344 triggers=self.on_preview_click)
345 create_widget_action(self.list_view,
346- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()),
347+ 'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(),
348+ live=StringContent.Live.title()),
349 text=self.plugin.get_string(StringContent.Live)['title'],
350 icon=':/general/general_live.png',
351 can_shortcuts=True,
352 triggers=self.on_live_click)
353 create_widget_action(self.list_view,
354- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Service.title()),
355+ 'listView{plugin}{service}Item'.format(plugin=self.plugin.name.title(),
356+ service=StringContent.Service.title()),
357 can_shortcuts=True,
358 text=self.plugin.get_string(StringContent.Service)['title'],
359 icon=':/general/general_add.png',
360@@ -232,7 +235,8 @@
361 if self.has_delete_icon:
362 create_widget_action(self.list_view, separator=True)
363 create_widget_action(self.list_view,
364- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
365+ 'listView{plugin}{delete}Item'.format(plugin=self.plugin.name.title(),
366+ delete=StringContent.Delete.title()),
367 text=self.plugin.get_string(StringContent.Delete)['title'],
368 icon=':/general/general_delete.png',
369 can_shortcuts=True, triggers=self.on_delete_click)
370@@ -313,7 +317,7 @@
371 files = FileDialog.getOpenFileNames(self, self.on_new_prompt,
372 Settings().value(self.settings_section + '/last directory'),
373 self.on_new_file_masks)
374- log.info('New files(s) %s' % files)
375+ log.info('New files(s) {files}'.format(files=files))
376 if files:
377 self.application.set_busy_cursor()
378 self.validate_and_load(files)
379@@ -333,7 +337,8 @@
380 if not error_shown:
381 critical_error_message_box(translate('OpenLP.MediaManagerItem', 'Invalid File Type'),
382 translate('OpenLP.MediaManagerItem',
383- 'Invalid File %s.\nSuffix not supported') % file_name)
384+ 'Invalid File {name}.\n'
385+ 'Suffix not supported').format(name=file_name))
386 error_shown = True
387 else:
388 new_files.append(file_name)
389@@ -375,7 +380,8 @@
390 self.load_list(full_list, target_group)
391 last_dir = os.path.split(files[0])[0]
392 Settings().setValue(self.settings_section + '/last directory', last_dir)
393- Settings().setValue('%s/%s files' % (self.settings_section, self.settings_section), self.get_file_list())
394+ Settings().setValue('{section}/{section} files'.format(section=self.settings_section),
395+ self.get_file_list())
396 if duplicates_found:
397 critical_error_message_box(UiStrings().Duplicate,
398 translate('OpenLP.MediaManagerItem',
399@@ -550,7 +556,7 @@
400 # Is it possible to process multiple list items to generate
401 # multiple service items?
402 if self.single_service_item:
403- log.debug('%s Add requested', self.plugin.name)
404+ log.debug('{plugin} Add requested'.format(plugin=self.plugin.name))
405 self.add_to_service(replace=self.remote_triggered)
406 else:
407 items = self.list_view.selectedIndexes()
408@@ -591,7 +597,7 @@
409 translate('OpenLP.MediaManagerItem',
410 'You must select one or more items.'))
411 else:
412- log.debug('%s Add requested', self.plugin.name)
413+ log.debug('{plugin} Add requested'.format(plugin=self.plugin.name))
414 service_item = self.service_manager.get_service_item()
415 if not service_item:
416 QtWidgets.QMessageBox.information(self, UiStrings().NISs,
417@@ -604,7 +610,8 @@
418 # Turn off the remote edit update message indicator
419 QtWidgets.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'Invalid Service Item'),
420 translate('OpenLP.MediaManagerItem',
421- 'You must select a %s service item.') % self.title)
422+ 'You must select a {title} '
423+ 'service item.').format(title=self.title))
424
425 def build_service_item(self, item=None, xml_version=False, remote=False, context=ServiceItemContext.Live):
426 """
427
428=== modified file 'openlp/core/lib/plugin.py'
429--- openlp/core/lib/plugin.py 2016-04-04 19:53:54 +0000
430+++ openlp/core/lib/plugin.py 2016-05-17 13:27:53 +0000
431@@ -130,7 +130,7 @@
432 :param settings_tab_class: The class name of the plugin's settings tab.
433 :param version: Defaults to *None*, which means that the same version number is used as OpenLP's version number.
434 """
435- log.debug('Plugin %s initialised' % name)
436+ log.debug('Plugin {plugin} initialised'.format(plugin=name))
437 super(Plugin, self).__init__()
438 self.name = name
439 self.text_strings = {}
440@@ -154,11 +154,11 @@
441 # Append a setting for files in the mediamanager (note not all plugins
442 # which have a mediamanager need this).
443 if media_item_class is not None:
444- default_settings['%s/%s files' % (name, name)] = []
445+ default_settings['{name}/{name} files'.format(name=name)] = []
446 # Add settings to the dict of all settings.
447 Settings.extend_default_settings(default_settings)
448- Registry().register_function('%s_add_service_item' % self.name, self.process_add_service_event)
449- Registry().register_function('%s_config_updated' % self.name, self.config_update)
450+ Registry().register_function('{name}_add_service_item'.format(name=self.name), self.process_add_service_event)
451+ Registry().register_function('{name}_config_updated'.format(name=self.name), self.config_update)
452
453 def check_pre_conditions(self):
454 """
455@@ -256,7 +256,7 @@
456 """
457 Generic Drag and drop handler triggered from service_manager.
458 """
459- log.debug('process_add_service_event event called for plugin %s' % self.name)
460+ log.debug('process_add_service_event event called for plugin {name}'.format(name=self.name))
461 if replace:
462 self.media_item.on_add_edit_click()
463 else:
464
465=== modified file 'openlp/core/lib/pluginmanager.py'
466--- openlp/core/lib/pluginmanager.py 2015-12-31 22:46:06 +0000
467+++ openlp/core/lib/pluginmanager.py 2016-05-17 13:27:53 +0000
468@@ -43,7 +43,7 @@
469 super(PluginManager, self).__init__(parent)
470 self.log_info('Plugin manager Initialising')
471 self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
472- self.log_debug('Base path %s ' % self.base_path)
473+ self.log_debug('Base path {path}'.format(path=self.base_path))
474 self.plugins = []
475 self.log_info('Plugin manager Initialised')
476
477@@ -73,7 +73,7 @@
478 """
479 start_depth = len(os.path.abspath(self.base_path).split(os.sep))
480 present_plugin_dir = os.path.join(self.base_path, 'presentations')
481- self.log_debug('finding plugins in %s at depth %d' % (self.base_path, start_depth))
482+ self.log_debug('finding plugins in {path} at depth {depth:d}'.format(path=self.base_path, depth=start_depth))
483 for root, dirs, files in os.walk(self.base_path):
484 for name in files:
485 if name.endswith('.py') and not name.startswith('__'):
486@@ -84,7 +84,9 @@
487 break
488 module_name = name[:-3]
489 # import the modules
490- self.log_debug('Importing %s from %s. Depth %d' % (module_name, root, this_depth))
491+ self.log_debug('Importing {name} from {root}. Depth {depth:d}'.format(name=module_name,
492+ root=root,
493+ depth=this_depth))
494 try:
495 # Use the "imp" library to try to get around a problem with the PyUNO library which
496 # monkey-patches the __import__ function to do some magic. This causes issues with our tests.
497@@ -93,21 +95,21 @@
498 # Then load the module (do the actual import) using the details from find_module()
499 imp.load_module(module_name, fp, path_name, description)
500 except ImportError as e:
501- self.log_exception('Failed to import module %s on path %s: %s'
502- % (module_name, path, e.args[0]))
503+ self.log_exception('Failed to import module {name} on path {path}: '
504+ '{args}'.format(name=module_name, path=path, args=e.args[0]))
505 plugin_classes = Plugin.__subclasses__()
506 plugin_objects = []
507 for p in plugin_classes:
508 try:
509 plugin = p()
510- self.log_debug('Loaded plugin %s' % str(p))
511+ self.log_debug('Loaded plugin {plugin}'.format(plugin=str(p)))
512 plugin_objects.append(plugin)
513 except TypeError:
514- self.log_exception('Failed to load plugin %s' % str(p))
515+ self.log_exception('Failed to load plugin {plugin}'.format(plugin=str(p)))
516 plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight)
517 for plugin in plugins_list:
518 if plugin.check_pre_conditions():
519- self.log_debug('Plugin %s active' % str(plugin.name))
520+ self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name)))
521 plugin.set_status()
522 else:
523 plugin.status = PluginStatus.Disabled
524@@ -175,10 +177,11 @@
525 Loop through all the plugins and give them an opportunity to initialise themselves.
526 """
527 for plugin in self.plugins:
528- self.log_info('initialising plugins %s in a %s state' % (plugin.name, plugin.is_active()))
529+ self.log_info('initialising plugins {plugin} in a {state} state'.format(plugin=plugin.name,
530+ state=plugin.is_active()))
531 if plugin.is_active():
532 plugin.initialise()
533- self.log_info('Initialisation Complete for %s ' % plugin.name)
534+ self.log_info('Initialisation Complete for {plugin}'.format(plugin=plugin.name))
535
536 def finalise_plugins(self):
537 """
538@@ -187,7 +190,7 @@
539 for plugin in self.plugins:
540 if plugin.is_active():
541 plugin.finalise()
542- self.log_info('Finalisation Complete for %s ' % plugin.name)
543+ self.log_info('Finalisation Complete for {plugin}'.format(plugin=plugin.name))
544
545 def get_plugin_by_name(self, name):
546 """
547
548=== modified file 'openlp/core/lib/renderer.py'
549--- openlp/core/lib/renderer.py 2016-01-23 12:38:08 +0000
550+++ openlp/core/lib/renderer.py 2016-05-17 13:27:53 +0000
551@@ -107,7 +107,7 @@
552
553 :param theme_name: The theme name
554 """
555- self.log_debug("_set_theme with theme %s" % theme_name)
556+ self.log_debug("_set_theme with theme {theme}".format(theme=theme_name))
557 if theme_name not in self._theme_dimensions:
558 theme_data = self.theme_manager.get_theme_data(theme_name)
559 main_rect = self.get_main_rectangle(theme_data)
560@@ -183,7 +183,7 @@
561
562 :param item_theme_name: The item theme's name.
563 """
564- self.log_debug("set_item_theme with theme %s" % item_theme_name)
565+ self.log_debug("set_item_theme with theme {theme}".format(theme=item_theme_name))
566 self._set_theme(item_theme_name)
567 self.item_theme_name = item_theme_name
568
569@@ -317,7 +317,7 @@
570 self.width = screen_size.width()
571 self.height = screen_size.height()
572 self.screen_ratio = self.height / self.width
573- self.log_debug('_calculate default %s, %f' % (screen_size, self.screen_ratio))
574+ self.log_debug('_calculate default {size}, {ratio:f}'.format(size=screen_size, ratio=self.screen_ratio))
575 # 90% is start of footer
576 self.footer_start = int(self.height * 0.90)
577
578@@ -354,7 +354,7 @@
579 :param rect_main: The main text block.
580 :param rect_footer: The footer text block.
581 """
582- self.log_debug('_set_text_rectangle %s , %s' % (rect_main, rect_footer))
583+ self.log_debug('_set_text_rectangle {main} , {footer}'.format(main=rect_main, footer=rect_footer))
584 self._rect = rect_main
585 self._rect_footer = rect_footer
586 self.page_width = self._rect.width()
587@@ -370,6 +370,7 @@
588 self.web.resize(self.page_width, self.page_height)
589 self.web_frame = self.web.page().mainFrame()
590 # Adjust width and height to account for shadow. outline done in css.
591+ # TODO: Verify before converting to python3 strings
592 html = """<!DOCTYPE html><html><head><script>
593 function show_text(newtext) {
594 var main = document.getElementById('main');
595@@ -518,7 +519,8 @@
596
597 :param text: The text to check. It may contain HTML tags.
598 """
599- self.web_frame.evaluateJavaScript('show_text("%s")' % text.replace('\\', '\\\\').replace('\"', '\\\"'))
600+ self.web_frame.evaluateJavaScript('show_text'
601+ '("{text}")'.format(text=text.replace('\\', '\\\\').replace('\"', '\\\"')))
602 return self.web_frame.contentsSize().height() <= self.empty_height
603
604
605
606=== modified file 'openlp/core/lib/screen.py'
607--- openlp/core/lib/screen.py 2016-01-10 16:00:05 +0000
608+++ openlp/core/lib/screen.py 2016-05-17 13:27:53 +0000
609@@ -78,7 +78,7 @@
610 ``number``
611 The number of the screen, which size has changed.
612 """
613- log.info('screen_resolution_changed %d' % number)
614+ log.info('screen_resolution_changed {number:d}'.format(number=number))
615 for screen in self.screen_list:
616 if number == screen['number']:
617 new_screen = {
618@@ -105,7 +105,7 @@
619 """
620 # Do not log at start up.
621 if changed_screen != -1:
622- log.info('screen_count_changed %d' % self.desktop.screenCount())
623+ log.info('screen_count_changed {count:d}'.format(count=self.desktop.screenCount()))
624 # Remove unplugged screens.
625 for screen in copy.deepcopy(self.screen_list):
626 if screen['number'] == self.desktop.screenCount():
627@@ -132,9 +132,11 @@
628 """
629 screen_list = []
630 for screen in self.screen_list:
631- screen_name = '%s %d' % (translate('OpenLP.ScreenList', 'Screen'), screen['number'] + 1)
632+ screen_name = '{name} {number:d}'.format(name=translate('OpenLP.ScreenList', 'Screen'),
633+ number=screen['number'] + 1)
634 if screen['primary']:
635- screen_name = '%s (%s)' % (screen_name, translate('OpenLP.ScreenList', 'primary'))
636+ screen_name = '{name} ({primary})'.format(name=screen_name,
637+ primary=translate('OpenLP.ScreenList', 'primary'))
638 screen_list.append(screen_name)
639 return screen_list
640
641@@ -152,7 +154,7 @@
642 'size': PyQt5.QtCore.QRect(0, 0, 1024, 768)
643 }
644 """
645- log.info('Screen %d found with resolution %s' % (screen['number'], screen['size']))
646+ log.info('Screen {number:d} found with resolution {size}'.format(number=screen['number'], size=screen['size']))
647 if screen['primary']:
648 self.current = screen
649 self.override = copy.deepcopy(self.current)
650@@ -165,7 +167,7 @@
651
652 :param number: The screen number (int).
653 """
654- log.info('remove_screen %d' % number)
655+ log.info('remove_screen {number:d}'.forma(number=number))
656 for screen in self.screen_list:
657 if screen['number'] == number:
658 self.screen_list.remove(screen)
659@@ -189,7 +191,7 @@
660
661 :param number: The screen number (int).
662 """
663- log.debug('set_current_display %s' % number)
664+ log.debug('set_current_display {number}'.format(number=number))
665 if number + 1 > self.display_count:
666 self.current = self.screen_list[0]
667 else:
668
669=== modified file 'openlp/core/lib/searchedit.py'
670--- openlp/core/lib/searchedit.py 2015-12-31 22:46:06 +0000
671+++ openlp/core/lib/searchedit.py 2016-05-17 13:27:53 +0000
672@@ -62,9 +62,10 @@
673 right_padding = self.clear_button.width() + frame_width
674 if hasattr(self, 'menu_button'):
675 left_padding = self.menu_button.width()
676- stylesheet = 'QLineEdit { padding-left: %spx; padding-right: %spx; } ' % (left_padding, right_padding)
677+ stylesheet = 'QLineEdit {{ padding-left:{left}px; padding-right: {right}px; }} '.format(left=left_padding,
678+ right=right_padding)
679 else:
680- stylesheet = 'QLineEdit { padding-right: %spx; } ' % right_padding
681+ stylesheet = 'QLineEdit {{ padding-right: {right}px; }} '.format(right=right_padding)
682 self.setStyleSheet(stylesheet)
683 msz = self.minimumSizeHint()
684 self.setMinimumSize(max(msz.width(), self.clear_button.width() + (frame_width * 2) + 2),
685
686=== modified file 'openlp/core/lib/serviceitem.py'
687--- openlp/core/lib/serviceitem.py 2016-05-05 03:57:04 +0000
688+++ openlp/core/lib/serviceitem.py 2016-05-17 13:27:53 +0000
689@@ -247,7 +247,7 @@
690 self.renderer.set_item_theme(self.theme)
691 self.theme_data, self.main, self.footer = self.renderer.pre_render()
692 if self.service_item_type == ServiceItemType.Text:
693- log.debug('Formatting slides: %s' % self.title)
694+ log.debug('Formatting slides: {title}'.format(title=self.title))
695 # Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
696 # the dict instead of rendering them again.
697 previous_pages = {}
698@@ -270,7 +270,7 @@
699 elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
700 pass
701 else:
702- log.error('Invalid value renderer: %s' % self.service_item_type)
703+ log.error('Invalid value renderer: {item}'.format(item=self.service_item_type))
704 self.title = clean_tags(self.title)
705 # The footer should never be None, but to be compatible with a few
706 # nightly builds between 1.9.4 and 1.9.5, we have to correct this to
707@@ -325,7 +325,8 @@
708 self.service_item_type = ServiceItemType.Command
709 # If the item should have a display title but this frame doesn't have one, we make one up
710 if self.is_capable(ItemCapabilities.HasDisplayTitle) and not display_title:
711- display_title = translate('OpenLP.ServiceItem', '[slide %d]') % (len(self._raw_frames) + 1)
712+ display_title = translate('OpenLP.ServiceItem',
713+ '[slide {frame:d}]').format(frame=len(self._raw_frames) + 1)
714 # Update image path to match servicemanager location if file was loaded from service
715 if image and not self.has_original_files and self.name == 'presentations':
716 file_location = os.path.join(path, file_name)
717@@ -392,7 +393,7 @@
718 :param path: Defaults to *None*. This is the service manager path for things which have their files saved
719 with them or None when the saved service is lite and the original file paths need to be preserved.
720 """
721- log.debug('set_from_service called with path %s' % path)
722+ log.debug('set_from_service called with path {path}'.format(path=path))
723 header = service_item['serviceitem']['header']
724 self.title = header['title']
725 self.name = header['name']
726@@ -608,11 +609,13 @@
727 start = None
728 end = None
729 if self.start_time != 0:
730- start = translate('OpenLP.ServiceItem', '<strong>Start</strong>: %s') % \
731- str(datetime.timedelta(seconds=self.start_time))
732+ time = str(datetime.timedelta(seconds=self.start_time))
733+ start = translate('OpenLP.ServiceItem',
734+ '<strong>Start</strong>: {start}').format(start=time)
735 if self.media_length != 0:
736- end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: %s') % \
737- str(datetime.timedelta(seconds=self.media_length // 1000))
738+ length = str(datetime.timedelta(seconds=self.media_length // 1000))
739+ end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: {length}').format(length=length)
740+
741 if not start and not end:
742 return ''
743 elif start and not end:
744@@ -620,7 +623,7 @@
745 elif not start and end:
746 return end
747 else:
748- return '%s <br>%s' % (start, end)
749+ return '{start} <br>{end}'.format(start=start, end=end)
750
751 def update_theme(self, theme):
752 """
753
754=== modified file 'openlp/core/lib/theme.py'
755--- openlp/core/lib/theme.py 2016-04-30 15:40:23 +0000
756+++ openlp/core/lib/theme.py 2016-05-17 13:27:53 +0000
757@@ -427,7 +427,7 @@
758 try:
759 theme_xml = objectify.fromstring(xml)
760 except etree.XMLSyntaxError:
761- log.exception('Invalid xml %s', xml)
762+ log.exception('Invalid xml {text}'.format(text=xml))
763 return
764 xml_iter = theme_xml.getiterator()
765 for element in xml_iter:
766@@ -513,6 +513,7 @@
767 theme_strings = []
768 for key in dir(self):
769 if key[0:1] != '_':
770+ # TODO: Verify spacing format before converting to python3 string
771 theme_strings.append('%30s: %s' % (key, getattr(self, key)))
772 return '\n'.join(theme_strings)
773
774
775=== modified file 'openlp/core/lib/ui.py'
776--- openlp/core/lib/ui.py 2016-03-31 16:34:22 +0000
777+++ openlp/core/lib/ui.py 2016-05-17 13:27:53 +0000
778@@ -165,7 +165,7 @@
779 kwargs.setdefault('icon', ':/services/service_down.png')
780 kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
781 else:
782- log.warning('The role "%s" is not defined in create_push_button().', role)
783+ log.warning('The role "{role}" is not defined in create_push_button().'.format(role=role))
784 if kwargs.pop('btn_class', '') == 'toolbutton':
785 button = QtWidgets.QToolButton(parent)
786 else:
787@@ -183,7 +183,7 @@
788 button.clicked.connect(kwargs.pop('click'))
789 for key in list(kwargs.keys()):
790 if key not in ['text', 'icon', 'tooltip', 'click']:
791- log.warning('Parameter %s was not consumed in create_button().', key)
792+ log.warning('Parameter {key} was not consumed in create_button().'.format(key=key))
793 return button
794
795
796@@ -270,7 +270,7 @@
797 action.triggered.connect(kwargs.pop('triggers'))
798 for key in list(kwargs.keys()):
799 if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']:
800- log.warning('Parameter %s was not consumed in create_action().' % key)
801+ log.warning('Parameter {key} was not consumed in create_action().'.format(key=key))
802 return action
803
804
805
806=== modified file 'openlp/core/lib/webpagereader.py'
807--- openlp/core/lib/webpagereader.py 2016-04-05 18:33:50 +0000
808+++ openlp/core/lib/webpagereader.py 2016-05-17 13:27:53 +0000
809@@ -133,37 +133,37 @@
810 time.sleep(0.1)
811 try:
812 page = urllib.request.urlopen(req, timeout=CONNECTION_TIMEOUT)
813- log.debug('Downloaded page {}'.format(page.geturl()))
814+ log.debug('Downloaded page {text}'.format(text=page.geturl()))
815 break
816 except urllib.error.URLError as err:
817- log.exception('URLError on {}'.format(url))
818- log.exception('URLError: {}'.format(err.reason))
819+ log.exception('URLError on {text}'.format(text=url))
820+ log.exception('URLError: {text}'.format(text=err.reason))
821 page = None
822 if retries > CONNECTION_RETRIES:
823 raise
824 except socket.timeout:
825- log.exception('Socket timeout: {}'.format(url))
826+ log.exception('Socket timeout: {text}'.format(text=url))
827 page = None
828 if retries > CONNECTION_RETRIES:
829 raise
830 except socket.gaierror:
831- log.exception('Socket gaierror: {}'.format(url))
832+ log.exception('Socket gaierror: {text}'.format(text=url))
833 page = None
834 if retries > CONNECTION_RETRIES:
835 raise
836 except ConnectionRefusedError:
837- log.exception('ConnectionRefused: {}'.format(url))
838+ log.exception('ConnectionRefused: {text}'.format(text=url))
839 page = None
840 if retries > CONNECTION_RETRIES:
841 raise
842 break
843 except ConnectionError:
844- log.exception('Connection error: {}'.format(url))
845+ log.exception('Connection error: {text}'.format(text=url))
846 page = None
847 if retries > CONNECTION_RETRIES:
848 raise
849 except HTTPException:
850- log.exception('HTTPException error: {}'.format(url))
851+ log.exception('HTTPException error: {text}'.format(text=url))
852 page = None
853 if retries > CONNECTION_RETRIES:
854 raise
855@@ -173,7 +173,7 @@
856 if update_openlp:
857 Registry().get('application').process_events()
858 if not page:
859- log.exception('{} could not be downloaded'.format(url))
860+ log.exception('{text} could not be downloaded'.format(text=url))
861 return None
862 log.debug(page)
863 return page
864
865=== modified file 'tests/functional/openlp_core_lib/test_projector_pjlink1.py'
866--- tests/functional/openlp_core_lib/test_projector_pjlink1.py 2016-04-24 11:22:04 +0000
867+++ tests/functional/openlp_core_lib/test_projector_pjlink1.py 2016-05-17 13:27:53 +0000
868@@ -112,7 +112,7 @@
869 @patch.object(pjlink_test, 'projectorReceivedData')
870 def projector_process_lamp_test(self, mock_projectorReceivedData):
871 """
872- Test setting lamp on/off and hours
873+ Test status lamp on/off and hours
874 """
875 # GIVEN: Test object
876 pjlink = pjlink_test
877@@ -129,7 +129,7 @@
878 @patch.object(pjlink_test, 'projectorReceivedData')
879 def projector_process_multiple_lamp_test(self, mock_projectorReceivedData):
880 """
881- Test setting multiple lamp on/off and hours
882+ Test status multiple lamp on/off and hours
883 """
884 # GIVEN: Test object
885 pjlink = pjlink_test
886@@ -156,7 +156,7 @@
887 @patch.object(pjlink_test, 'projectorReceivedData')
888 def projector_process_power_on_test(self, mock_projectorReceivedData):
889 """
890- Test setting power to ON
891+ Test status power to ON
892 """
893 # GIVEN: Test object and preset
894 pjlink = pjlink_test
895@@ -171,7 +171,7 @@
896 @patch.object(pjlink_test, 'projectorReceivedData')
897 def projector_process_power_off_test(self, mock_projectorReceivedData):
898 """
899- Test setting power to STANDBY
900+ Test status power to STANDBY
901 """
902 # GIVEN: Test object and preset
903 pjlink = pjlink_test
904@@ -182,3 +182,71 @@
905
906 # THEN: Power should be set to STANDBY
907 self.assertEquals(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY')
908+
909+ @patch.object(pjlink_test, 'projectorUpdateIcons')
910+ def projector_process_avmt_closed_unmuted_test(self, mock_projectorReceivedData):
911+ """
912+ Test avmt status shutter closed and audio muted
913+ """
914+ # GIVEN: Test object
915+ pjlink = pjlink_test
916+ pjlink.shutter = False
917+ pjlink.mute = True
918+
919+ # WHEN: Called with setting shutter closed and mute off
920+ pjlink.process_avmt('11')
921+
922+ # THEN: Shutter should be True and mute should be False
923+ self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed')
924+ self.assertFalse(pjlink.mute, 'Audio should be off')
925+
926+ @patch.object(pjlink_test, 'projectorUpdateIcons')
927+ def projector_process_avmt_open_muted_test(self, mock_projectorReceivedData):
928+ """
929+ Test avmt status shutter open and mute on
930+ """
931+ # GIVEN: Test object
932+ pjlink = pjlink_test
933+ pjlink.shutter = True
934+ pjlink.mute = False
935+
936+ # WHEN: Called with setting shutter closed and mute on
937+ pjlink.process_avmt('21')
938+
939+ # THEN: Shutter should be closed and mute should be True
940+ self.assertFalse(pjlink.shutter, 'Shutter should have been set to closed')
941+ self.assertTrue(pjlink.mute, 'Audio should be off')
942+
943+ @patch.object(pjlink_test, 'projectorUpdateIcons')
944+ def projector_process_avmt_open_unmuted_test(self, mock_projectorReceivedData):
945+ """
946+ Test avmt status shutter open and mute off off
947+ """
948+ # GIVEN: Test object
949+ pjlink = pjlink_test
950+ pjlink.shutter = True
951+ pjlink.mute = True
952+
953+ # WHEN: Called with setting shutter to closed and mute on
954+ pjlink.process_avmt('30')
955+
956+ # THEN: Shutter should be closed and mute should be True
957+ self.assertFalse(pjlink.shutter, 'Shutter should have been set to open')
958+ self.assertFalse(pjlink.mute, 'Audio should be on')
959+
960+ @patch.object(pjlink_test, 'projectorUpdateIcons')
961+ def projector_process_avmt_closed_muted_test(self, mock_projectorReceivedData):
962+ """
963+ Test avmt status shutter closed and mute off
964+ """
965+ # GIVEN: Test object
966+ pjlink = pjlink_test
967+ pjlink.shutter = False
968+ pjlink.mute = False
969+
970+ # WHEN: Called with setting shutter to closed and mute on
971+ pjlink.process_avmt('31')
972+
973+ # THEN: Shutter should be closed and mute should be True
974+ self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed')
975+ self.assertTrue(pjlink.mute, 'Audio should be on')