move methods

This commit is contained in:
Tim Bentley 2016-04-03 20:44:09 +01:00
parent 6fa0f07e32
commit a0bfc7d069
16 changed files with 146 additions and 105 deletions

View File

@ -22,6 +22,7 @@
""" """
The :mod:`languagemanager` module provides all the translation settings and language file loading for OpenLP. The :mod:`languagemanager` module provides all the translation settings and language file loading for OpenLP.
""" """
import locale
import logging import logging
import re import re
@ -32,6 +33,8 @@ from openlp.core.common import AppLocation, Settings, translate, is_win, is_maco
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
DIGITS_OR_NONDIGITS = re.compile(r'\d+|\D+', re.UNICODE)
class LanguageManager(object): class LanguageManager(object):
""" """
@ -143,3 +146,60 @@ class LanguageManager(object):
if not LanguageManager.__qm_list__: if not LanguageManager.__qm_list__:
LanguageManager.init_qm_list() LanguageManager.init_qm_list()
return LanguageManager.__qm_list__ return LanguageManager.__qm_list__
def format_time(text, local_time):
"""
Workaround for Python built-in time formatting function time.strftime().
time.strftime() accepts only ascii characters. This function accepts
unicode string and passes individual % placeholders to time.strftime().
This ensures only ascii characters are passed to time.strftime().
:param text: The text to be processed.
:param local_time: The time to be used to add to the string. This is a time object
"""
def match_formatting(match):
"""
Format the match
"""
return local_time.strftime(match.group())
return re.sub('\%[a-zA-Z]', match_formatting, text)
def get_locale_key(string):
"""
Creates a key for case insensitive, locale aware string sorting.
:param string: The corresponding string.
"""
string = string.lower()
# ICU is the prefered way to handle locale sort key, we fallback to locale.strxfrm which will work in most cases.
global ICU_COLLATOR
try:
if ICU_COLLATOR is None:
import icu
language = LanguageManager.get_language()
icu_locale = icu.Locale(language)
ICU_COLLATOR = icu.Collator.createInstance(icu_locale)
return ICU_COLLATOR.getSortKey(string)
except:
return locale.strxfrm(string).encode()
def get_natural_key(string):
"""
Generate a key for locale aware natural string sorting.
:param string: string to be sorted by
Returns a list of string compare keys and integers.
"""
key = DIGITS_OR_NONDIGITS.findall(string)
key = [int(part) if part.isdigit() else get_locale_key(part) for part in key]
# Python 3 does not support comparison of different types anymore. So make sure, that we do not compare str
# and int.
if string and string[0].isdigit():
return [b''] + key
return key

View File

@ -31,7 +31,8 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate
from openlp.core.lib import ColorButton, SettingsTab, build_icon from openlp.core.lib import ColorButton, SettingsTab, build_icon
from openlp.core.utils import format_time, get_images_filter from openlp.core.common.languagemanager import format_time
from openlp.core.utils import get_images_filter
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -38,7 +38,8 @@ from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.lib import OpenLPToolbar, ServiceItem, ItemCapabilities, PluginStatus, build_icon from openlp.core.lib import OpenLPToolbar, ServiceItem, ItemCapabilities, PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.utils import delete_file, split_filename, format_time from openlp.core.utils import delete_file, split_filename
from openlp.core.common.languagemanager import format_time
class ServiceManagerList(QtWidgets.QTreeWidget): class ServiceManagerList(QtWidgets.QTreeWidget):

View File

@ -36,7 +36,8 @@ from openlp.core.lib import FileDialog, ImageSource, OpenLPToolbar, ValidationEr
from openlp.core.lib.theme import ThemeXML, BackgroundType from openlp.core.lib.theme import ThemeXML, BackgroundType
from openlp.core.lib.ui import critical_error_message_box, create_widget_action from openlp.core.lib.ui import critical_error_message_box, create_widget_action
from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import delete_file, get_locale_key, get_filesystem_encoding from openlp.core.utils import delete_file, get_filesystem_encoding
from openlp.core.common.languagemanager import get_locale_key
class Ui_ThemeManager(object): class Ui_ThemeManager(object):

View File

@ -22,7 +22,6 @@
""" """
The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP. The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
""" """
import locale
import logging import logging
import os import os
import platform import platform
@ -463,62 +462,6 @@ def get_uno_instance(resolver, connection_type='pipe'):
else: else:
return resolver.resolve('uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext') return resolver.resolve('uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
def format_time(text, local_time):
"""
Workaround for Python built-in time formatting function time.strftime().
time.strftime() accepts only ascii characters. This function accepts
unicode string and passes individual % placeholders to time.strftime().
This ensures only ascii characters are passed to time.strftime().
:param text: The text to be processed.
:param local_time: The time to be used to add to the string. This is a time object
"""
def match_formatting(match):
"""
Format the match
"""
return local_time.strftime(match.group())
return re.sub('\%[a-zA-Z]', match_formatting, text)
def get_locale_key(string):
"""
Creates a key for case insensitive, locale aware string sorting.
:param string: The corresponding string.
"""
string = string.lower()
# ICU is the prefered way to handle locale sort key, we fallback to locale.strxfrm which will work in most cases.
global ICU_COLLATOR
try:
if ICU_COLLATOR is None:
import icu
from openlp.core.common.languagemanager import LanguageManager
language = LanguageManager.get_language()
icu_locale = icu.Locale(language)
ICU_COLLATOR = icu.Collator.createInstance(icu_locale)
return ICU_COLLATOR.getSortKey(string)
except:
return locale.strxfrm(string).encode()
def get_natural_key(string):
"""
Generate a key for locale aware natural string sorting.
:param string: string to be sorted by
Returns a list of string compare keys and integers.
"""
key = DIGITS_OR_NONDIGITS.findall(string)
key = [int(part) if part.isdigit() else get_locale_key(part) for part in key]
# Python 3 does not support comparison of different types anymore. So make sure, that we do not compare str
# and int.
if string and string[0].isdigit():
return [b''] + key
return key
__all__ = ['get_application_version', 'check_latest_version', __all__ = ['get_application_version', 'check_latest_version',
'get_filesystem_encoding', 'get_web_page', 'get_uno_command', 'get_uno_instance', 'get_filesystem_encoding', 'get_web_page', 'get_uno_command', 'get_uno_instance',
'delete_file', 'clean_filename', 'format_time', 'get_locale_key', 'get_natural_key'] 'delete_file', 'clean_filename']

View File

@ -32,7 +32,7 @@ from openlp.core.common import AppLocation, Settings, UiStrings, translate
from openlp.core.lib.db import delete_database from openlp.core.lib.db import delete_database
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.core.utils import get_locale_key from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.bibles.lib.manager import BibleFormat from openlp.plugins.bibles.lib.manager import BibleFormat
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
from openlp.plugins.bibles.lib.http import CWExtract, BGExtract, BSExtract from openlp.plugins.bibles.lib.http import CWExtract, BGExtract, BSExtract

View File

@ -29,7 +29,7 @@ from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemConte
from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \ from openlp.core.lib.ui import set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \
critical_error_message_box, find_and_set_in_combo_box, build_icon critical_error_message_box, find_and_set_in_combo_box, build_icon
from openlp.core.utils import get_locale_key from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm
from openlp.plugins.bibles.forms.editbibleform import EditBibleForm from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \ from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \

View File

@ -28,7 +28,7 @@ from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper from sqlalchemy.orm import mapper
from openlp.core.lib.db import BaseModel, init_db from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import get_locale_key from openlp.core.common.languagemanager import get_locale_key
class CustomSlide(BaseModel): class CustomSlide(BaseModel):

View File

@ -29,7 +29,8 @@ from openlp.core.common import Registry, AppLocation, Settings, UiStrings, check
from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, TreeWidgetWithDnD,\ from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, TreeWidgetWithDnD,\
build_icon, check_item_selected, create_thumb, validate_thumb build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import create_widget_action, critical_error_message_box from openlp.core.lib.ui import create_widget_action, critical_error_message_box
from openlp.core.utils import delete_file, get_locale_key, get_images_filter from openlp.core.utils import delete_file, get_images_filter
from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.images.forms import AddGroupForm, ChooseGroupForm from openlp.plugins.images.forms import AddGroupForm, ChooseGroupForm
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups

View File

@ -32,7 +32,7 @@ from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, Servi
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.ui import DisplayController, Display, DisplayControllerType from openlp.core.ui import DisplayController, Display, DisplayControllerType
from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds
from openlp.core.utils import get_locale_key from openlp.core.common.languagemanager import get_locale_key
from openlp.core.ui.media.vlcplayer import get_vlc from openlp.core.ui.media.vlcplayer import get_vlc
if get_vlc() is not None: if get_vlc() is not None:

View File

@ -29,7 +29,7 @@ from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext,\ from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext,\
build_icon, check_item_selected, create_thumb, validate_thumb build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.utils import get_locale_key from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES

View File

@ -29,7 +29,7 @@ from sqlalchemy.orm import mapper, relation, reconstructor
from sqlalchemy.sql.expression import func, text from sqlalchemy.sql.expression import func, text
from openlp.core.lib.db import BaseModel, init_db from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import get_natural_key from openlp.core.common.languagemanager import get_natural_key
from openlp.core.lib import translate from openlp.core.lib import translate

View File

@ -32,7 +32,7 @@ from openlp.core.common import Registry, AppLocation, Settings, check_directory_
from openlp.core.lib import MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \ from openlp.core.lib import MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \
check_item_selected, create_separated_list check_item_selected, create_separated_list
from openlp.core.lib.ui import create_widget_action from openlp.core.lib.ui import create_widget_action
from openlp.core.utils import get_natural_key from openlp.core.common.languagemanager import get_natural_key
from openlp.plugins.songs.forms.editsongform import EditSongForm from openlp.plugins.songs.forms.editsongform import EditSongForm
from openlp.plugins.songs.forms.songmaintenanceform import SongMaintenanceForm from openlp.plugins.songs.forms.songmaintenanceform import SongMaintenanceForm
from openlp.plugins.songs.forms.songimportform import SongImportForm from openlp.plugins.songs.forms.songimportform import SongImportForm

View File

@ -22,11 +22,10 @@
""" """
Functional tests to test the AppLocation class and related methods. Functional tests to test the AppLocation class and related methods.
""" """
import os
from unittest import TestCase from unittest import TestCase
from openlp.core.common import add_actions from openlp.core.common import add_actions
from tests.functional import MagicMock, patch from tests.functional import MagicMock
class TestInit(TestCase): class TestInit(TestCase):

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2016 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Functional tests to test the AppLocation class and related methods.
"""
from unittest import TestCase
from tests.functional import patch
from openlp.core.common.languagemanager import get_locale_key, get_natural_key
class TestLanguageManager(TestCase):
"""
A test suite to test out various methods around the common __init__ class.
"""
def get_locale_key_test(self):
"""
Test the get_locale_key(string) function
"""
with patch('openlp.core.common.languagemanager.LanguageManager.get_language') as mocked_get_language:
# GIVEN: The language is German
# 0x00C3 (A with diaresis) should be sorted as "A". 0x00DF (sharp s) should be sorted as "ss".
mocked_get_language.return_value = 'de'
unsorted_list = ['Auszug', 'Aushang', '\u00C4u\u00DFerung']
# WHEN: We sort the list and use get_locale_key() to generate the sorting keys
sorted_list = sorted(unsorted_list, key=get_locale_key)
# THEN: We get a properly sorted list
self.assertEqual(['Aushang', '\u00C4u\u00DFerung', 'Auszug'], sorted_list,
'Strings should be sorted properly')
def get_natural_key_test(self):
"""
Test the get_natural_key(string) function
"""
with patch('openlp.core.common.languagemanager.LanguageManager.get_language') as mocked_get_language:
# GIVEN: The language is English (a language, which sorts digits before letters)
mocked_get_language.return_value = 'en'
unsorted_list = ['item 10a', 'item 3b', '1st item']
# WHEN: We sort the list and use get_natural_key() to generate the sorting keys
sorted_list = sorted(unsorted_list, key=get_natural_key)
# THEN: We get a properly sorted list
self.assertEqual(['1st item', 'item 3b', 'item 10a'], sorted_list, 'Numbers should be sorted naturally')

View File

@ -25,8 +25,9 @@ Functional tests to test the AppLocation class and related methods.
import os import os
from unittest import TestCase from unittest import TestCase
from openlp.core.utils import clean_filename, delete_file, get_filesystem_encoding, get_locale_key, \ from openlp.core.utils import clean_filename, delete_file, get_filesystem_encoding, \
get_natural_key, split_filename, _get_user_agent, get_web_page, get_uno_instance split_filename, _get_user_agent, get_web_page, get_uno_instance
from openlp.core.common.languagemanager import get_locale_key, get_natural_key
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
@ -179,38 +180,6 @@ class TestUtils(TestCase):
self.assertEqual(mocked_log.exception.call_count, 1) self.assertEqual(mocked_log.exception.call_count, 1)
self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError') self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError')
def get_locale_key_test(self):
"""
Test the get_locale_key(string) function
"""
with patch('openlp.core.common.languagemanager.LanguageManager.get_language') as mocked_get_language:
# GIVEN: The language is German
# 0x00C3 (A with diaresis) should be sorted as "A". 0x00DF (sharp s) should be sorted as "ss".
mocked_get_language.return_value = 'de'
unsorted_list = ['Auszug', 'Aushang', '\u00C4u\u00DFerung']
# WHEN: We sort the list and use get_locale_key() to generate the sorting keys
sorted_list = sorted(unsorted_list, key=get_locale_key)
# THEN: We get a properly sorted list
self.assertEqual(['Aushang', '\u00C4u\u00DFerung', 'Auszug'], sorted_list,
'Strings should be sorted properly')
def get_natural_key_test(self):
"""
Test the get_natural_key(string) function
"""
with patch('openlp.core.common.languagemanager.LanguageManager.get_language') as mocked_get_language:
# GIVEN: The language is English (a language, which sorts digits before letters)
mocked_get_language.return_value = 'en'
unsorted_list = ['item 10a', 'item 3b', '1st item']
# WHEN: We sort the list and use get_natural_key() to generate the sorting keys
sorted_list = sorted(unsorted_list, key=get_natural_key)
# THEN: We get a properly sorted list
self.assertEqual(['1st item', 'item 3b', 'item 10a'], sorted_list, 'Numbers should be sorted naturally')
def get_uno_instance_pipe_test(self): def get_uno_instance_pipe_test(self):
""" """
Test that when the UNO connection type is "pipe" the resolver is given the "pipe" URI Test that when the UNO connection type is "pipe" the resolver is given the "pipe" URI