diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index db135ef10..6f6addbbd 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -222,10 +222,11 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): QtWidgets.QMessageBox.warning(None, translate('OpenLP', 'Backup'), translate('OpenLP', 'Backup of the data folder failed!')) return - QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), - translate('OpenLP', - 'A backup of the data folder has been created at %s') - % data_folder_backup_path) + message = translate('OpenLP', + 'A backup of the data folder has been created' + 'at {text}').format(text=data_folder_backup_path) + QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message) + # Update the version in the settings Settings().setValue('core/application version', openlp_version) @@ -257,7 +258,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): """ if event.type() == QtCore.QEvent.FileOpen: file_name = event.file() - log.debug('Got open file event for %s!', file_name) + log.debug('Got open file event for {name}!'.format(name=file_name)) self.args.insert(0, file_name) return True # Mac OS X should restore app window when user clicked on the OpenLP icon @@ -311,7 +312,7 @@ def set_up_logging(log_path): logfile.setFormatter(logging.Formatter('%(asctime)s %(name)-55s %(levelname)-8s %(message)s')) log.addHandler(logfile) if log.isEnabledFor(logging.DEBUG): - print('Logging to: %s' % filename) + print('Logging to: {name}'.format(name=filename)) def main(args=None): @@ -351,12 +352,12 @@ def main(args=None): log.info('Running portable') portable_settings_file = os.path.abspath(os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini')) # Make this our settings file - log.info('INI file: %s', portable_settings_file) + log.info('INI file: {name}'.format(name=portable_settings_file)) Settings.set_filename(portable_settings_file) portable_settings = Settings() # Set our data path data_path = os.path.abspath(os.path.join(application_path, '..', '..', 'Data',)) - log.info('Data path: %s', data_path) + log.info('Data path: {name}'.format(name=data_path)) # Point to our data path portable_settings.setValue('advanced/data path', data_path) portable_settings.setValue('advanced/is portable', True) diff --git a/openlp/core/common/__init__.py b/openlp/core/common/__init__.py index f3076a86f..f1abd8fe6 100644 --- a/openlp/core/common/__init__.py +++ b/openlp/core/common/__init__.py @@ -55,7 +55,9 @@ def trace_error_handler(logger): """ log_string = "OpenLP Error trace" for tb in traceback.extract_stack(): - log_string = '%s\n File %s at line %d \n\t called %s' % (log_string, tb[0], tb[1], tb[3]) + log_string += '\n File {file} at line {line} \n\t called {data}'.format(file=tb[0], + line=tb[1], + data=tb[3]) logger.error(log_string) @@ -67,7 +69,7 @@ def check_directory_exists(directory, do_not_log=False): :param do_not_log: To not log anything. This is need for the start up, when the log isn't ready. """ if not do_not_log: - log.debug('check_directory_exists %s' % directory) + log.debug('check_directory_exists {text}'.format(text=directory)) try: if not os.path.exists(directory): os.makedirs(directory) @@ -202,13 +204,13 @@ def md5_hash(salt, data=None): :param data: OPTIONAL Data to hash :returns: str """ - log.debug('md5_hash(salt="%s")' % salt) + log.debug('md5_hash(salt="{text}")'.format(text=salt)) hash_obj = hashlib.new('md5') hash_obj.update(salt) if data: hash_obj.update(data) hash_value = hash_obj.hexdigest() - log.debug('md5_hash() returning "%s"' % hash_value) + log.debug('md5_hash() returning "{text}"'.format(text=hash_value)) return hash_value @@ -221,12 +223,12 @@ def qmd5_hash(salt, data=None): :param data: OPTIONAL Data to hash :returns: str """ - log.debug('qmd5_hash(salt="%s"' % salt) + log.debug('qmd5_hash(salt="{text}"'.format(text=salt)) hash_obj = QHash(QHash.Md5) hash_obj.addData(salt) hash_obj.addData(data) hash_value = hash_obj.result().toHex() - log.debug('qmd5_hash() returning "%s"' % hash_value) + log.debug('qmd5_hash() returning "{text}"'.format(text=hash_value)) return hash_value.data() @@ -283,7 +285,7 @@ def get_uno_command(connection_type='pipe'): CONNECTION = '"--accept=pipe,name=openlp_pipe;urp;"' else: CONNECTION = '"--accept=socket,host=localhost,port=2002;urp;"' - return '%s %s %s' % (command, OPTIONS, CONNECTION) + return '{cmd} {opt} {conn}'.format(cmd=command, opt=OPTIONS, conn=CONNECTION) def get_uno_instance(resolver, connection_type='pipe'): @@ -333,7 +335,7 @@ def delete_file(file_path_name): os.remove(file_path_name) return True except (IOError, OSError): - log.exception("Unable to delete file %s" % file_path_name) + log.exception("Unable to delete file {text}".format(text=file_path_name)) return False @@ -345,9 +347,11 @@ def get_images_filter(): if not IMAGES_FILTER: log.debug('Generating images filter.') formats = list(map(bytes.decode, list(map(bytes, QtGui.QImageReader.supportedImageFormats())))) - visible_formats = '(*.%s)' % '; *.'.join(formats) - actual_formats = '(*.%s)' % ' *.'.join(formats) - IMAGES_FILTER = '%s %s %s' % (translate('OpenLP', 'Image Files'), visible_formats, actual_formats) + visible_formats = '(*.{text})'.format(text='; *.'.join(formats)) + actual_formats = '(*.{text})'.format(text=' *.'.join(formats)) + IMAGES_FILTER = '{text} {visible} {actual}'.format(text=translate('OpenLP', 'Image Files'), + visible=visible_formats, + actual=actual_formats) return IMAGES_FILTER @@ -385,7 +389,7 @@ def check_binary_exists(program_path): :param program_path:The full path to the binary to check. :return: program output to be parsed """ - log.debug('testing program_path: %s', program_path) + log.debug('testing program_path: {text}'.format(text=program_path)) try: # Setup startupinfo options for check_output to avoid console popping up on windows if is_win(): @@ -399,5 +403,5 @@ def check_binary_exists(program_path): except Exception: trace_error_handler(log) runlog = '' - log.debug('check_output returned: %s' % runlog) + log.debug('check_output returned: {text}'.format(text=runlog)) return runlog diff --git a/openlp/core/common/actions.py b/openlp/core/common/actions.py index cb5b9ccaf..d22ef8fd1 100644 --- a/openlp/core/common/actions.py +++ b/openlp/core/common/actions.py @@ -114,7 +114,7 @@ class CategoryActionList(object): if item[1] == action: self.actions.remove(item) return - raise ValueError('Action "%s" does not exist.' % action) + raise ValueError('Action "{action}" does not exist.'.format(action=action)) class CategoryList(object): @@ -138,7 +138,7 @@ class CategoryList(object): for category in self.categories: if category.name == key: return category - raise KeyError('Category "%s" does not exist.' % key) + raise KeyError('Category "{keY}" does not exist.'.format(key=key)) def __len__(self): """ @@ -203,7 +203,7 @@ class CategoryList(object): if category.name == name: self.categories.remove(category) return - raise ValueError('Category "%s" does not exist.' % name) + raise ValueError('Category "{name}" does not exist.'.format(name=name)) class ActionList(object): @@ -272,8 +272,9 @@ class ActionList(object): actions.append(action) ActionList.shortcut_map[shortcuts[1]] = actions else: - log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % - (shortcuts[1], action.objectName())) + log.warning('Shortcut "{shortcut}" is removed from "{action}" because another ' + 'action already uses this shortcut.'.format(shortcut=shortcuts[1], + action=action.objectName())) shortcuts.remove(shortcuts[1]) # Check the primary shortcut. existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) @@ -283,8 +284,9 @@ class ActionList(object): actions.append(action) ActionList.shortcut_map[shortcuts[0]] = actions else: - log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % - (shortcuts[0], action.objectName())) + log.warning('Shortcut "{shortcut}" is removed from "{action}" ' + 'because another action already uses this shortcut.'.format(shortcut=shortcuts[0], + action=action.objectName())) shortcuts.remove(shortcuts[0]) action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) diff --git a/openlp/core/common/languagemanager.py b/openlp/core/common/languagemanager.py index 52e9e9f13..58262ffb5 100644 --- a/openlp/core/common/languagemanager.py +++ b/openlp/core/common/languagemanager.py @@ -68,7 +68,7 @@ class LanguageManager(object): """ Find all available language files in this OpenLP install """ - log.debug('Translation files: %s', AppLocation.get_directory(AppLocation.LanguageDir)) + log.debug('Translation files: {files}'.format(files=AppLocation.get_directory(AppLocation.LanguageDir))) trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir)) file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name) # Remove qm files from the list which start with "qt_". @@ -93,7 +93,7 @@ class LanguageManager(object): """ language = Settings().value('core/language') language = str(language) - log.info('Language file: \'%s\' Loaded from conf file' % language) + log.info("Language file: '{language}' Loaded from conf file".format(language=language)) if re.match(r'[[].*[]]', language): LanguageManager.auto_language = True language = re.sub(r'[\[\]]', '', language) @@ -117,9 +117,9 @@ class LanguageManager(object): qm_list = LanguageManager.get_qm_list() language = str(qm_list[action_name]) if LanguageManager.auto_language: - language = '[%s]' % language + language = '[{language}]'.format(language=language) Settings().setValue('core/language', language) - log.info('Language file: \'%s\' written to conf file' % language) + log.info("Language file: '{language}' written to conf file".format(language=language)) if message: QtWidgets.QMessageBox.information(None, translate('OpenLP.LanguageManager', 'Language'), @@ -136,7 +136,8 @@ class LanguageManager(object): for counter, qmf in enumerate(qm_files): reg_ex = QtCore.QRegExp("^.*i18n/(.*).qm") if reg_ex.exactMatch(qmf): - name = '%s' % reg_ex.cap(1) + name = '{regex}'.format(regex=reg_ex.cap(1)) + # TODO: Test before converting to python3 string format LanguageManager.__qm_list__['%#2i %s' % (counter + 1, LanguageManager.language_name(qmf))] = name @staticmethod diff --git a/openlp/core/common/openlpmixin.py b/openlp/core/common/openlpmixin.py index d17f36bd6..94505b86b 100644 --- a/openlp/core/common/openlpmixin.py +++ b/openlp/core/common/openlpmixin.py @@ -49,12 +49,13 @@ class OpenLPMixin(object): Code to added debug wrapper to work on called functions within a decorated class. """ def wrapped(*args, **kwargs): - parent.logger.debug("Entering %s" % func.__name__) + parent.logger.debug("Entering {function}".format(function=func.__name__)) try: return func(*args, **kwargs) except Exception as e: if parent.logger.getEffectiveLevel() <= logging.ERROR: - parent.logger.error('Exception in %s : %s' % (func.__name__, e)) + parent.logger.error('Exception in {function} : {error}'.format(function=func.__name__, + error=e)) raise e return wrapped diff --git a/openlp/core/common/registry.py b/openlp/core/common/registry.py index adf495a36..b904d627c 100644 --- a/openlp/core/common/registry.py +++ b/openlp/core/common/registry.py @@ -71,8 +71,8 @@ class Registry(object): else: if not self.initialising: trace_error_handler(log) - log.error('Service %s not found in list' % key) - raise KeyError('Service %s not found in list' % key) + log.error('Service {key} not found in list'.format(key=key)) + raise KeyError('Service {key} not found in list'.format(key=key)) def register(self, key, reference): """ @@ -83,8 +83,8 @@ class Registry(object): """ if key in self.service_list: trace_error_handler(log) - log.error('Duplicate service exception %s' % key) - raise KeyError('Duplicate service exception %s' % key) + log.error('Duplicate service exception {key}'.format(key=key)) + raise KeyError('Duplicate service exception {key}'.format(key=key)) else: self.service_list[key] = reference @@ -140,8 +140,8 @@ class Registry(object): except TypeError: # Who has called me can help in debugging trace_error_handler(log) - log.exception('Exception for function %s', function) + log.exception('Exception for function {function}'.format(function=function)) else: trace_error_handler(log) - log.error("Event %s called but not registered" % event) + log.error("Event {event} called but not registered".format(event=event)) return results diff --git a/openlp/core/common/settings.py b/openlp/core/common/settings.py index 84fc6db96..7bbd4349d 100644 --- a/openlp/core/common/settings.py +++ b/openlp/core/common/settings.py @@ -487,16 +487,16 @@ class Settings(QtCore.QSettings): # Do NOT do this anywhere else! settings = QtCore.QSettings(self.fileName(), Settings.IniFormat) settings.beginGroup(plugin.settings_section) - if settings.contains('%s count' % plugin.name): + if settings.contains('{name} count'.format(name=plugin.name)): # Get the count. - list_count = int(settings.value('%s count' % plugin.name, 0)) + list_count = int(settings.value('{name} count'.format(name=plugin.name), 0)) if list_count: for counter in range(list_count): # The keys were named e. g.: "image 0" - item = settings.value('%s %d' % (plugin.name, counter), '') + item = settings.value('{name} {counter:d}'.format(name=plugin.name, counter=counter), '') if item: files_list.append(item) - settings.remove('%s %d' % (plugin.name, counter)) - settings.remove('%s count' % plugin.name) + settings.remove('{name} {counter:d}'.format(name=plugin.name, counter=counter)) + settings.remove('{name} count'.format(name=plugin.name)) settings.endGroup() return files_list diff --git a/openlp/core/common/uistrings.py b/openlp/core/common/uistrings.py index fa01a44d2..b313059ae 100644 --- a/openlp/core/common/uistrings.py +++ b/openlp/core/common/uistrings.py @@ -81,6 +81,7 @@ class UiStrings(object): self.Export = translate('OpenLP.Ui', 'Export') self.File = translate('OpenLP.Ui', 'File') self.FileNotFound = translate('OpenLP.Ui', 'File Not Found') + # TODO: Check before converting to python3 string self.FileNotFoundMessage = translate('OpenLP.Ui', 'File %s not found.\nPlease try selecting it individually.') self.FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') self.Help = translate('OpenLP.Ui', 'Help') @@ -111,8 +112,8 @@ class UiStrings(object): self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural') self.OLP = translate('OpenLP.Ui', 'OpenLP') - self.OLPV2 = "%s %s" % (self.OLP, "2") - self.OLPV2x = "%s %s" % (self.OLP, "2.4") + self.OLPV2 = "{name} {version}".format(name=self.OLP, version="2") + self.OLPV2x = "{name} {version}".format(name=self.OLP, version="2.4") self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?') self.OpenService = translate('OpenLP.Ui', 'Open service.') self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop') @@ -140,6 +141,7 @@ class UiStrings(object): self.Split = translate('OpenLP.Ui', 'Optional &Split') self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two only if it does not fit on the screen as one slide.') + # TODO: Check before converting to python3 string self.StartTimeCode = translate('OpenLP.Ui', 'Start %s') self.StopPlaySlidesInLoop = translate('OpenLP.Ui', 'Stop Play Slides in Loop') self.StopPlaySlidesToEnd = translate('OpenLP.Ui', 'Stop Play Slides to End') @@ -153,3 +155,4 @@ class UiStrings(object): self.Version = translate('OpenLP.Ui', 'Version') self.View = translate('OpenLP.Ui', 'View') self.ViewMode = translate('OpenLP.Ui', 'View Mode') + self.Video = translate('OpenLP.Ui', 'Video') diff --git a/openlp/core/common/versionchecker.py b/openlp/core/common/versionchecker.py index 136405607..fb706968b 100644 --- a/openlp/core/common/versionchecker.py +++ b/openlp/core/common/versionchecker.py @@ -44,9 +44,10 @@ class VersionThread(QtCore.QThread): log.debug('Version thread - run') app_version = get_application_version() version = check_latest_version(app_version) - log.debug("Versions %s and %s " % (LooseVersion(str(version)), LooseVersion(str(app_version['full'])))) + log.debug("Versions {version1} and {version2} ".format(version1=LooseVersion(str(version)), + version2=LooseVersion(str(app_version['full'])))) if LooseVersion(str(version)) > LooseVersion(str(app_version['full'])): - self.main_window.openlp_version_check.emit('%s' % version) + self.main_window.openlp_version_check.emit('{version}'.format(version=version)) def get_application_version(): @@ -91,7 +92,7 @@ def get_application_version(): if tree_revision == tag_revision: full_version = tag_version.strip() else: - full_version = '%s-bzr%s' % (tag_version.strip(), tree_revision.strip()) + full_version = '{tag}-bzr{tree}'.format(tag=tag_version.strip(), tree=tree_revision.strip()) else: # We're not running the development version, let's use the file. file_path = AppLocation.get_directory(AppLocation.VersionDir) @@ -113,9 +114,10 @@ def get_application_version(): 'build': bits[1] if len(bits) > 1 else None } if APPLICATION_VERSION['build']: - log.info('Openlp version %s build %s', APPLICATION_VERSION['version'], APPLICATION_VERSION['build']) + log.info('Openlp version {version} build {build}'.format(version=APPLICATION_VERSION['version'], + build=APPLICATION_VERSION['build'])) else: - log.info('Openlp version %s' % APPLICATION_VERSION['version']) + log.info('Openlp version {version}'.format(version=APPLICATION_VERSION['version'])) return APPLICATION_VERSION @@ -149,8 +151,9 @@ def check_latest_version(current_version): req = urllib.request.Request('http://www.openlp.org/files/dev_version.txt') else: req = urllib.request.Request('http://www.openlp.org/files/version.txt') - req.add_header('User-Agent', 'OpenLP/%s %s/%s; ' % (current_version['full'], platform.system(), - platform.release())) + req.add_header('User-Agent', 'OpenLP/{version} {system}/{release}; '.format(version=current_version['full'], + system=platform.system(), + release=platform.release())) remote_version = None retries = 0 while True: diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index e56cb0d61..59053e283 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -55,9 +55,13 @@ class ImageSource(object): ``Theme`` This says, that the image is used by a theme. + + ``CommandPlugins`` + This states that an image is being used by a command plugin. """ ImagePlugin = 1 Theme = 2 + CommandPlugins = 3 class MediaType(object): @@ -97,7 +101,7 @@ def get_text_file_string(text_file): file_handle.seek(0) content = file_handle.read() except (IOError, UnicodeError): - log.exception('Failed to open text file %s' % text_file) + log.exception('Failed to open text file {text}'.format(text=text_file)) finally: if file_handle: file_handle.close() @@ -174,10 +178,30 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None): ext = os.path.splitext(thumb_path)[1].lower() reader = QtGui.QImageReader(image_path) if size is None: - ratio = reader.size().width() / reader.size().height() + # No size given; use default height of 88 + if reader.size().isEmpty(): + ratio = 1 + else: + ratio = reader.size().width() / reader.size().height() reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88)) - else: + elif size.isValid(): + # Complete size given reader.setScaledSize(size) + else: + # Invalid size given + if reader.size().isEmpty(): + ratio = 1 + else: + ratio = reader.size().width() / reader.size().height() + if size.width() >= 0: + # Valid width; scale height + reader.setScaledSize(QtCore.QSize(size.width(), int(size.width() / ratio))) + elif size.height() >= 0: + # Valid height; scale width + reader.setScaledSize(QtCore.QSize(int(ratio * size.height()), size.height())) + else: + # Invalid; use default height of 88 + reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88)) thumb = reader.read() thumb.save(thumb_path, ext[1:]) if not return_icon: @@ -300,6 +324,8 @@ def create_separated_list(string_list): return '' elif len(string_list) == 1: return string_list[0] + # TODO: + # Cannot convert these strings to python3 yet until I can figure out how to mock translate() with the new format elif len(string_list) == 2: return translate('OpenLP.core.lib', '%s and %s', 'Locale list separator: 2 items') % (string_list[0], string_list[1]) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 7ae3cdc6f..3decb0a3b 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -68,9 +68,11 @@ def get_db_path(plugin_name, db_file_name=None): :return: The path to the database as type str """ if db_file_name is None: - return 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name) + return 'sqlite:///{path}/{plugin}.sqlite'.format(path=AppLocation.get_section_data_path(plugin_name), + plugin=plugin_name) else: - return 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name) + return 'sqlite:///{path}/{name}'.format(path=AppLocation.get_section_data_path(plugin_name), + name=db_file_name) def handle_db_error(plugin_name, db_file_name): @@ -82,10 +84,10 @@ def handle_db_error(plugin_name, db_file_name): :return: None """ db_path = get_db_path(plugin_name, db_file_name) - log.exception('Error loading database: %s', db_path) + log.exception('Error loading database: {db}'.format(db=db_path)) critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), - translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s') - % db_path) + translate('OpenLP.Manager', + 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) def init_url(plugin_name, db_file_name=None): @@ -101,10 +103,11 @@ def init_url(plugin_name, db_file_name=None): if db_type == 'sqlite': db_url = get_db_path(plugin_name, db_file_name) else: - db_url = '%s://%s:%s@%s/%s' % (db_type, urlquote(settings.value('db username')), - urlquote(settings.value('db password')), - urlquote(settings.value('db hostname')), - urlquote(settings.value('db database'))) + db_url = '{type}://{user}:{password}@{host}/{db}'.format(type=db_type, + user=urlquote(settings.value('db username')), + password=urlquote(settings.value('db password')), + host=urlquote(settings.value('db hostname')), + db=urlquote(settings.value('db database'))) settings.endGroup() return db_url @@ -157,10 +160,10 @@ def upgrade_db(url, upgrade): return version, upgrade.__version__ version += 1 try: - while hasattr(upgrade, 'upgrade_%d' % version): - log.debug('Running upgrade_%d', version) + while hasattr(upgrade, 'upgrade_{version:d}'.format(version=version)): + log.debug('Running upgrade_{version:d}'.format(version=version)) try: - upgrade_func = getattr(upgrade, 'upgrade_%d' % version) + upgrade_func = getattr(upgrade, 'upgrade_{version:d}'.format(version=version)) upgrade_func(session, metadata) session.commit() # Update the version number AFTER a commit so that we are sure the previous transaction happened @@ -168,8 +171,8 @@ def upgrade_db(url, upgrade): session.commit() version += 1 except (SQLAlchemyError, DBAPIError): - log.exception('Could not run database upgrade script "upgrade_%s", upgrade process has been halted.', - version) + log.exception('Could not run database upgrade script ' + '"upgrade_{version:d}", upgrade process has been halted.'.format(version=version)) break except (SQLAlchemyError, DBAPIError): version_meta = Metadata.populate(key='version', value=int(upgrade.__version__)) @@ -242,9 +245,10 @@ class Manager(object): critical_error_message_box( translate('OpenLP.Manager', 'Database Error'), translate('OpenLP.Manager', 'The database being loaded was created in a more recent version of ' - 'OpenLP. The database is version %d, while OpenLP expects version %d. The database will ' - 'not be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url) - ) + 'OpenLP. The database is version {db_ver}, while OpenLP expects version {db_up}. ' + 'The database will not be loaded.\n\nDatabase: {db_name}').format(db_ver=db_ver, + db_up=up_ver, + db_name=self.db_url)) return if not session: try: @@ -460,7 +464,7 @@ class Manager(object): raise except InvalidRequestError: self.session.rollback() - log.exception('Failed to delete %s records', object_class.__name__) + log.exception('Failed to delete {name} records'.format(name=object_class.__name__)) return False except: self.session.rollback() diff --git a/openlp/core/lib/filedialog.py b/openlp/core/lib/filedialog.py index 823567a37..249f7959d 100644 --- a/openlp/core/lib/filedialog.py +++ b/openlp/core/lib/filedialog.py @@ -50,7 +50,8 @@ class FileDialog(QtWidgets.QFileDialog): log.info('File not found. Attempting to unquote.') file = parse.unquote(file) if not os.path.exists(file): - log.error('File %s not found.' % file) + log.error('File {text} not found.'.format(text=file)) + # TODO: Test with UiStrings() before converting to python3 strings QtWidgets.QMessageBox.information(parent, UiStrings().FileNotFound, UiStrings().FileNotFoundMessage % file) continue diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 812680027..f0d8ddef2 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -396,6 +396,7 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic log = logging.getLogger(__name__) +# TODO: Verify where this is used before converting to python3 HTMLSRC = """ @@ -564,13 +565,13 @@ def build_html(item, screen, is_live, background, image=None, plugins=None): theme_data = item.theme_data # Image generated and poked in if background: - bgimage_src = 'src="data:image/png;base64,%s"' % background + bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=background) elif item.bg_image_bytes: - bgimage_src = 'src="data:image/png;base64,%s"' % item.bg_image_bytes + bgimage_src = 'src="data:image/png;base64,{image}"'.format(image=item.bg_image_bytes) else: bgimage_src = 'style="display:none;"' if image: - image_src = 'src="data:image/png;base64,%s"' % image + image_src = 'src="data:image/png;base64,{image}"'.format(image=image) else: image_src = 'style="display:none;"' css_additions = '' @@ -601,7 +602,7 @@ def webkit_version(): """ try: webkit_ver = float(QtWebKit.qWebKitVersion()) - log.debug('Webkit version = %s' % webkit_ver) + log.debug('Webkit version = {version}'.format(version=webkit_ver)) except AttributeError: webkit_ver = 0 return webkit_ver @@ -621,23 +622,25 @@ def build_background_css(item, width): if theme.background_type == BackgroundType.to_string(BackgroundType.Transparent): background = '' elif theme.background_type == BackgroundType.to_string(BackgroundType.Solid): - background = 'background-color: %s' % theme.background_color + background = 'background-color: {theme}'.format(theme=theme.background_color) else: if theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Horizontal): - background = 'background: -webkit-gradient(linear, left top, left bottom, from(%s), to(%s)) fixed' \ - % (theme.background_start_color, theme.background_end_color) + background = 'background: -webkit-gradient(linear, left top, left bottom, from({start}), to({end})) ' \ + 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color) elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftTop): - background = 'background: -webkit-gradient(linear, left top, right bottom, from(%s), to(%s)) fixed' \ - % (theme.background_start_color, theme.background_end_color) + background = 'background: -webkit-gradient(linear, left top, right bottom, from({start}), to({end})) ' \ + 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color) elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftBottom): - background = 'background: -webkit-gradient(linear, left bottom, right top, from(%s), to(%s)) fixed' \ - % (theme.background_start_color, theme.background_end_color) + background = 'background: -webkit-gradient(linear, left bottom, right top, from({start}), to({end})) ' \ + 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color) elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Vertical): - background = 'background: -webkit-gradient(linear, left top, right top, from(%s), to(%s)) fixed' % \ - (theme.background_start_color, theme.background_end_color) + background = 'background: -webkit-gradient(linear, left top, right top, from({start}), to({end})) ' \ + 'fixed'.format(start=theme.background_start_color, end=theme.background_end_color) else: - background = 'background: -webkit-gradient(radial, %s 50%%, 100, %s 50%%, %s, from(%s), to(%s)) fixed'\ - % (width, width, width, theme.background_start_color, theme.background_end_color) + background = 'background: -webkit-gradient(radial, {width} 50%, 100, {width} 50%, {width}, ' \ + 'from({start}), to({end})) fixed'.format(width=width, + start=theme.background_start_color, + end=theme.background_end_color) return background @@ -647,6 +650,7 @@ def build_lyrics_css(item): :param item: Service Item containing theme and location information """ + # TODO: Verify this before converting to python3 style = """ .lyricstable { z-index: 5; @@ -669,12 +673,13 @@ def build_lyrics_css(item): lyrics = '' lyricsmain = '' if theme_data and item.main: - lyricstable = 'left: %spx; top: %spx;' % (item.main.x(), item.main.y()) + lyricstable = 'left: {left}px; top: {top}px;'.format(left=item.main.x(), top=item.main.y()) lyrics = build_lyrics_format_css(theme_data, item.main.width(), item.main.height()) lyricsmain += build_lyrics_outline_css(theme_data) if theme_data.font_main_shadow: - lyricsmain += ' text-shadow: %s %spx %spx;' % \ - (theme_data.font_main_shadow_color, theme_data.font_main_shadow_size, theme_data.font_main_shadow_size) + lyricsmain += ' text-shadow: {theme} {shadow}px ' \ + '{shadow}px;'.format(theme=theme_data.font_main_shadow_color, + shadow=theme_data.font_main_shadow_size) lyrics_css = style % (lyricstable, lyrics, lyricsmain) return lyrics_css @@ -689,7 +694,9 @@ def build_lyrics_outline_css(theme_data): size = float(theme_data.font_main_outline_size) / 16 fill_color = theme_data.font_main_color outline_color = theme_data.font_main_outline_color - return ' -webkit-text-stroke: %sem %s; -webkit-text-fill-color: %s; ' % (size, outline_color, fill_color) + return ' -webkit-text-stroke: {size}em {color}; -webkit-text-fill-color: {fill}; '.format(size=size, + color=outline_color, + fill=fill_color) return '' @@ -715,13 +722,21 @@ def build_lyrics_format_css(theme_data, width, height): padding_bottom = '0.5em' else: padding_bottom = '0' - lyrics = '%s word-wrap: break-word; ' \ - 'text-align: %s; vertical-align: %s; font-family: %s; ' \ - 'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \ - 'padding: 0; padding-bottom: %s; padding-left: %spx; width: %spx; height: %spx; ' % \ - (justify, align, valign, theme_data.font_main_name, theme_data.font_main_size, - theme_data.font_main_color, 100 + int(theme_data.font_main_line_adjustment), padding_bottom, - left_margin, width, height) + lyrics = '{justify} word-wrap: break-word; ' \ + 'text-align: {align}; vertical-align: {valign}; font-family: {font}; ' \ + 'font-size: {size}pt; color: {color}; line-height: {line:d}%; margin: 0;' \ + 'padding: 0; padding-bottom: {bottom}; padding-left: {left}px; width: {width}px; ' \ + 'height: {height}px; '.format(justify=justify, + align=align, + valign=valign, + font=theme_data.font_main_name, + size=theme_data.font_main_size, + color=theme_data.font_main_color, + line=100 + int(theme_data.font_main_line_adjustment), + bottom=padding_bottom, + left=left_margin, + width=width, + height=height) if theme_data.font_main_italics: lyrics += 'font-style:italic; ' if theme_data.font_main_bold: @@ -737,20 +752,21 @@ def build_footer_css(item, height): :param height: """ style = """ - left: %spx; - bottom: %spx; - width: %spx; - font-family: %s; - font-size: %spt; - color: %s; + left: {left}px; + bottom: {bottom}px; + width: {width}px; + font-family: {family}; + font-size: {size}pt; + color: {color}; text-align: left; - white-space: %s; + white-space: {space}; """ theme = item.theme_data if not theme or not item.footer: return '' bottom = height - int(item.footer.y()) - int(item.footer.height()) whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap' - lyrics_html = style % (item.footer.x(), bottom, item.footer.width(), - theme.font_footer_name, theme.font_footer_size, theme.font_footer_color, whitespace) + lyrics_html = style.format(left=item.footer.x(), bottom=bottom, width=item.footer.width(), + family=theme.font_footer_name, size=theme.font_footer_size, + color=theme.font_footer_color, space=whitespace) return lyrics_html diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 0d0903a3b..1c25fca25 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -236,7 +236,7 @@ class ImageManager(QtCore.QObject): """ Return the ``QImage`` from the cache. If not present wait for the background thread to process it. """ - log.debug('getImage %s' % path) + log.debug('getImage {path}'.format(path=path)) image = self._cache[(path, source, width, height)] if image.image is None: self._conversion_queue.modify_priority(image, Priority.High) @@ -256,7 +256,7 @@ class ImageManager(QtCore.QObject): """ Returns the byte string for an image. If not present wait for the background thread to process it. """ - log.debug('get_image_bytes %s' % path) + log.debug('get_image_bytes {path}'.format(path=path)) image = self._cache[(path, source, width, height)] if image.image_bytes is None: self._conversion_queue.modify_priority(image, Priority.Urgent) @@ -271,7 +271,7 @@ class ImageManager(QtCore.QObject): """ Add image to cache if it is not already there. """ - log.debug('add_image %s' % path) + log.debug('add_image {path}'.format(path=path)) if not (path, source, width, height) in self._cache: image = Image(path, source, background, width, height) self._cache[(path, source, width, height)] = image diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 5af90c1b7..358c82543 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -186,7 +186,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): for action in toolbar_actions: if action[0] == StringContent.Preview: self.toolbar.addSeparator() - self.toolbar.add_toolbar_action('%s%sAction' % (self.plugin.name, action[0]), + self.toolbar.add_toolbar_action('{name}{action}Action'.format(name=self.plugin.name, action=action[0]), text=self.plugin.get_string(action[1])['title'], icon=action[2], tooltip=self.plugin.get_string(action[1])['tooltip'], triggers=action[3]) @@ -200,7 +200,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): self.list_view.setSpacing(1) self.list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.list_view.setAlternatingRowColors(True) - self.list_view.setObjectName('%sListView' % self.plugin.name) + self.list_view.setObjectName('{name}ListView'.format(name=self.plugin.name)) # Add to page_layout self.page_layout.addWidget(self.list_view) # define and add the context menu @@ -212,19 +212,22 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): triggers=self.on_edit_click) create_widget_action(self.list_view, separator=True) create_widget_action(self.list_view, - 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()), + 'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(), + preview=StringContent.Preview.title()), text=self.plugin.get_string(StringContent.Preview)['title'], icon=':/general/general_preview.png', can_shortcuts=True, triggers=self.on_preview_click) create_widget_action(self.list_view, - 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()), + 'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(), + live=StringContent.Live.title()), text=self.plugin.get_string(StringContent.Live)['title'], icon=':/general/general_live.png', can_shortcuts=True, triggers=self.on_live_click) create_widget_action(self.list_view, - 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Service.title()), + 'listView{plugin}{service}Item'.format(plugin=self.plugin.name.title(), + service=StringContent.Service.title()), can_shortcuts=True, text=self.plugin.get_string(StringContent.Service)['title'], icon=':/general/general_add.png', @@ -232,7 +235,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): if self.has_delete_icon: create_widget_action(self.list_view, separator=True) create_widget_action(self.list_view, - 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()), + 'listView{plugin}{delete}Item'.format(plugin=self.plugin.name.title(), + delete=StringContent.Delete.title()), text=self.plugin.get_string(StringContent.Delete)['title'], icon=':/general/general_delete.png', can_shortcuts=True, triggers=self.on_delete_click) @@ -313,7 +317,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): files = FileDialog.getOpenFileNames(self, self.on_new_prompt, Settings().value(self.settings_section + '/last directory'), self.on_new_file_masks) - log.info('New files(s) %s' % files) + log.info('New files(s) {files}'.format(files=files)) if files: self.application.set_busy_cursor() self.validate_and_load(files) @@ -333,7 +337,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): if not error_shown: critical_error_message_box(translate('OpenLP.MediaManagerItem', 'Invalid File Type'), translate('OpenLP.MediaManagerItem', - 'Invalid File %s.\nSuffix not supported') % file_name) + 'Invalid File {name}.\n' + 'Suffix not supported').format(name=file_name)) error_shown = True else: new_files.append(file_name) @@ -375,7 +380,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): self.load_list(full_list, target_group) last_dir = os.path.split(files[0])[0] Settings().setValue(self.settings_section + '/last directory', last_dir) - Settings().setValue('%s/%s files' % (self.settings_section, self.settings_section), self.get_file_list()) + Settings().setValue('{section}/{section} files'.format(section=self.settings_section), + self.get_file_list()) if duplicates_found: critical_error_message_box(UiStrings().Duplicate, translate('OpenLP.MediaManagerItem', @@ -550,7 +556,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): # Is it possible to process multiple list items to generate # multiple service items? if self.single_service_item: - log.debug('%s Add requested', self.plugin.name) + log.debug('{plugin} Add requested'.format(plugin=self.plugin.name)) self.add_to_service(replace=self.remote_triggered) else: items = self.list_view.selectedIndexes() @@ -591,7 +597,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): translate('OpenLP.MediaManagerItem', 'You must select one or more items.')) else: - log.debug('%s Add requested', self.plugin.name) + log.debug('{plugin} Add requested'.format(plugin=self.plugin.name)) service_item = self.service_manager.get_service_item() if not service_item: QtWidgets.QMessageBox.information(self, UiStrings().NISs, @@ -604,7 +610,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): # Turn off the remote edit update message indicator QtWidgets.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'Invalid Service Item'), translate('OpenLP.MediaManagerItem', - 'You must select a %s service item.') % self.title) + 'You must select a {title} ' + 'service item.').format(title=self.title)) def build_service_item(self, item=None, xml_version=False, remote=False, context=ServiceItemContext.Live): """ diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index b9c8ca5f0..9df77760b 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -130,7 +130,7 @@ class Plugin(QtCore.QObject, RegistryProperties): :param settings_tab_class: The class name of the plugin's settings tab. :param version: Defaults to *None*, which means that the same version number is used as OpenLP's version number. """ - log.debug('Plugin %s initialised' % name) + log.debug('Plugin {plugin} initialised'.format(plugin=name)) super(Plugin, self).__init__() self.name = name self.text_strings = {} @@ -154,11 +154,11 @@ class Plugin(QtCore.QObject, RegistryProperties): # Append a setting for files in the mediamanager (note not all plugins # which have a mediamanager need this). if media_item_class is not None: - default_settings['%s/%s files' % (name, name)] = [] + default_settings['{name}/{name} files'.format(name=name)] = [] # Add settings to the dict of all settings. Settings.extend_default_settings(default_settings) - Registry().register_function('%s_add_service_item' % self.name, self.process_add_service_event) - Registry().register_function('%s_config_updated' % self.name, self.config_update) + Registry().register_function('{name}_add_service_item'.format(name=self.name), self.process_add_service_event) + Registry().register_function('{name}_config_updated'.format(name=self.name), self.config_update) def check_pre_conditions(self): """ @@ -256,7 +256,7 @@ class Plugin(QtCore.QObject, RegistryProperties): """ Generic Drag and drop handler triggered from service_manager. """ - log.debug('process_add_service_event event called for plugin %s' % self.name) + log.debug('process_add_service_event event called for plugin {name}'.format(name=self.name)) if replace: self.media_item.on_add_edit_click() else: diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 598c7c5d1..4eb4c2f01 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -43,7 +43,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): super(PluginManager, self).__init__(parent) self.log_info('Plugin manager Initialising') self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir)) - self.log_debug('Base path %s ' % self.base_path) + self.log_debug('Base path {path}'.format(path=self.base_path)) self.plugins = [] self.log_info('Plugin manager Initialised') @@ -73,7 +73,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): """ start_depth = len(os.path.abspath(self.base_path).split(os.sep)) present_plugin_dir = os.path.join(self.base_path, 'presentations') - self.log_debug('finding plugins in %s at depth %d' % (self.base_path, start_depth)) + self.log_debug('finding plugins in {path} at depth {depth:d}'.format(path=self.base_path, depth=start_depth)) for root, dirs, files in os.walk(self.base_path): for name in files: if name.endswith('.py') and not name.startswith('__'): @@ -84,7 +84,9 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): break module_name = name[:-3] # import the modules - self.log_debug('Importing %s from %s. Depth %d' % (module_name, root, this_depth)) + self.log_debug('Importing {name} from {root}. Depth {depth:d}'.format(name=module_name, + root=root, + depth=this_depth)) try: # Use the "imp" library to try to get around a problem with the PyUNO library which # monkey-patches the __import__ function to do some magic. This causes issues with our tests. @@ -93,21 +95,21 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): # Then load the module (do the actual import) using the details from find_module() imp.load_module(module_name, fp, path_name, description) except ImportError as e: - self.log_exception('Failed to import module %s on path %s: %s' - % (module_name, path, e.args[0])) + self.log_exception('Failed to import module {name} on path {path}: ' + '{args}'.format(name=module_name, path=path, args=e.args[0])) plugin_classes = Plugin.__subclasses__() plugin_objects = [] for p in plugin_classes: try: plugin = p() - self.log_debug('Loaded plugin %s' % str(p)) + self.log_debug('Loaded plugin {plugin}'.format(plugin=str(p))) plugin_objects.append(plugin) except TypeError: - self.log_exception('Failed to load plugin %s' % str(p)) + self.log_exception('Failed to load plugin {plugin}'.format(plugin=str(p))) plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight) for plugin in plugins_list: if plugin.check_pre_conditions(): - self.log_debug('Plugin %s active' % str(plugin.name)) + self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name))) plugin.set_status() else: plugin.status = PluginStatus.Disabled @@ -175,10 +177,11 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): Loop through all the plugins and give them an opportunity to initialise themselves. """ for plugin in self.plugins: - self.log_info('initialising plugins %s in a %s state' % (plugin.name, plugin.is_active())) + self.log_info('initialising plugins {plugin} in a {state} state'.format(plugin=plugin.name, + state=plugin.is_active())) if plugin.is_active(): plugin.initialise() - self.log_info('Initialisation Complete for %s ' % plugin.name) + self.log_info('Initialisation Complete for {plugin}'.format(plugin=plugin.name)) def finalise_plugins(self): """ @@ -187,7 +190,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): for plugin in self.plugins: if plugin.is_active(): plugin.finalise() - self.log_info('Finalisation Complete for %s ' % plugin.name) + self.log_info('Finalisation Complete for {plugin}'.format(plugin=plugin.name)) def get_plugin_by_name(self, name): """ diff --git a/openlp/core/lib/projector/constants.py b/openlp/core/lib/projector/constants.py index 6bfc88a6f..5c0d6c6c2 100644 --- a/openlp/core/lib/projector/constants.py +++ b/openlp/core/lib/projector/constants.py @@ -297,7 +297,11 @@ PJLINK_ERST_STATUS = {'0': ERROR_STRING[E_OK], PJLINK_POWR_STATUS = {'0': S_STANDBY, '1': S_ON, '2': S_COOLDOWN, - '3': S_WARMUP} + '3': S_WARMUP, + S_STANDBY: '0', + S_ON: '1', + S_COOLDOWN: '2', + S_WARMUP: '3'} PJLINK_DEFAULT_SOURCES = {'1': translate('OpenLP.DB', 'RGB'), '2': translate('OpenLP.DB', 'Video'), diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index f76d28853..0d233a9c4 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -107,7 +107,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties): :param theme_name: The theme name """ - self.log_debug("_set_theme with theme %s" % theme_name) + self.log_debug("_set_theme with theme {theme}".format(theme=theme_name)) if theme_name not in self._theme_dimensions: theme_data = self.theme_manager.get_theme_data(theme_name) main_rect = self.get_main_rectangle(theme_data) @@ -183,7 +183,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties): :param item_theme_name: The item theme's name. """ - self.log_debug("set_item_theme with theme %s" % item_theme_name) + self.log_debug("set_item_theme with theme {theme}".format(theme=item_theme_name)) self._set_theme(item_theme_name) self.item_theme_name = item_theme_name @@ -317,7 +317,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties): self.width = screen_size.width() self.height = screen_size.height() self.screen_ratio = self.height / self.width - self.log_debug('_calculate default %s, %f' % (screen_size, self.screen_ratio)) + self.log_debug('_calculate default {size}, {ratio:f}'.format(size=screen_size, ratio=self.screen_ratio)) # 90% is start of footer self.footer_start = int(self.height * 0.90) @@ -354,7 +354,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties): :param rect_main: The main text block. :param rect_footer: The footer text block. """ - self.log_debug('_set_text_rectangle %s , %s' % (rect_main, rect_footer)) + self.log_debug('_set_text_rectangle {main} , {footer}'.format(main=rect_main, footer=rect_footer)) self._rect = rect_main self._rect_footer = rect_footer self.page_width = self._rect.width() @@ -370,6 +370,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties): self.web.resize(self.page_width, self.page_height) self.web_frame = self.web.page().mainFrame() # Adjust width and height to account for shadow. outline done in css. + # TODO: Verify before converting to python3 strings html = """