Compare commits

...

13 Commits

Author SHA1 Message Date
Tomas Groth 6fe8eea144 Merge branch 'remote-sync' into 'master'
WIP: Add new remote-sync plugin

See merge request openlp/openlp!9
2024-04-27 05:43:07 +00:00
Raoul Snyman 6bbfe00ec0 Merge branch 'translations-21042024' into 'master'
Translations 21042024

See merge request openlp/openlp!748
2024-04-27 05:42:58 +00:00
Tim Bentley cee0a9d573 Translations 21042024 2024-04-27 05:42:58 +00:00
Raoul Snyman 2ad33529e4 Merge branch 'issue-1877' into 'master'
Attempt to bubble up permissions errors to the user so that we don't run into None files or hashes

See merge request openlp/openlp!746
2024-04-20 22:26:55 +00:00
Raoul Snyman 7bb7dc35c0 Merge branch 'minor_fixes2' into 'master'
Stop Service File items from containing more than one audio file

See merge request openlp/openlp!742
2024-04-20 22:14:30 +00:00
Tim Bentley 9b9d8feafa Stop Service File items from containing more than one audio file 2024-04-20 22:14:29 +00:00
Raoul Snyman 32d132c2f0 Merge branch 'issue-1883' into 'master'
Fix build part of version number

Closes #1883

See merge request openlp/openlp!745
2024-04-20 22:13:26 +00:00
Raoul Snyman f5e0682e0d Fix build part of version number 2024-04-20 22:13:26 +00:00
Raoul Snyman 7d44795cf7 Merge branch 'issue-1878' into 'master'
Attempt to fix #1878 by checking if the service item exists first

Closes #1878

See merge request openlp/openlp!744
2024-04-20 22:13:08 +00:00
Raoul Snyman 64f1a0e52d Attempt to bubble up permissions errors to the user so that we don't run into None files or hashes 2024-04-19 23:11:01 -07:00
Raoul Snyman d2a2b94273 Merge branch 'hide-live-when-screen-setup-has-changed' into 'master'
Hide live when screen setup has changed

See merge request openlp/openlp!743
2024-04-20 05:42:23 +00:00
Chris Witterholt e93ac46f2a Hide live when screen setup has changed 2024-04-20 05:42:23 +00:00
Raoul Snyman 2639c7cd00 Attempt to fix #1878 by checking if the service item exists first 2024-04-19 21:59:07 -07:00
44 changed files with 13215 additions and 12110 deletions

View File

@ -275,6 +275,8 @@ def sha256_file_hash(filename):
"""
Returns the hashed output of sha256 on the file content using Python3 hashlib
This method allows PermissionError to bubble up, while supressing other exceptions
:param filename: Name of the file to hash
:returns: str
"""
@ -288,6 +290,8 @@ def sha256_file_hash(filename):
hash_obj.update(chunk)
return hash_obj.hexdigest()
except PermissionError:
raise
except Exception:
return None

View File

@ -427,6 +427,7 @@ class UiStrings(metaclass=Singleton):
self.OptionalShowInFooter = translate('OpenLP.Ui', 'Optional, this will be displayed in footer.')
self.OptionalHideInFooter = translate('OpenLP.Ui', 'Optional, this won\'t be displayed in footer.')
self.Other = translate('SongsPlugin.VerseType', 'Other')
self.PermissionError = translate('OpenLP.Ui', 'Permission Error')
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
self.PlaySlidesToEnd = translate('OpenLP.Ui', 'Play Slides to End')
self.PreChorus = translate('SongsPlugin.VerseType', 'Pre-Chorus')
@ -445,6 +446,11 @@ class UiStrings(metaclass=Singleton):
self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
self.SaveAndClose = translate('OpenLP.ui', translate('SongsPlugin.EditSongForm', '&Save && Close'))
self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
self.ScreenSetupHasChangedTitle = translate('OpenLP.MainWindow', 'Screen setup has changed')
self.ScreenSetupHasChanged = translate('OpenLP.MainWindow',
'The screen setup has changed. OpenLP will try to '
'automatically select a display screen, but '
'you should consider updating the screen settings.')
self.Search = translate('OpenLP.Ui', 'Search')
self.SearchThemes = translate('OpenLP.Ui', 'Search Themes...', 'Search bar place holder text ')
self.SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.')
@ -464,6 +470,9 @@ class UiStrings(metaclass=Singleton):
self.Tools = translate('OpenLP.Ui', 'Tools')
self.Top = translate('OpenLP.Ui', 'Top')
self.Transpose = translate('SongsPlugin.EditVerseForm', 'Transpose:')
self.UnableToRead = translate('OpenLP.Ui', 'Unable to read the file(s) listed below, please check that '
'your user has permission to read the file(s) or that the '
'file(s) are not using cloud storage (e.g. Dropbox, OneDrive).')
self.UnsupportedFile = translate('OpenLP.Ui', 'Unsupported File')
self.Up = translate('SongsPlugin.EditVerseForm', 'Up')
self.Verse = translate('SongsPlugin.VerseType', 'Verse')

View File

@ -1035,11 +1035,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
and (datetime.now() - self.screen_change_timestamp).seconds < 5
should_show_messagebox = self.settings_form.isHidden() and not has_shown_messagebox_recently
if should_show_messagebox:
QtWidgets.QMessageBox.information(self, translate('OpenLP.MainWindow', 'Screen setup has changed'),
translate('OpenLP.MainWindow',
'The screen setup has changed. OpenLP will try to '
'automatically select a display screen, but '
'you should consider updating the screen settings.'),
self.live_controller.toggle_display('desktop')
QtWidgets.QMessageBox.information(self,
UiStrings().ScreenSetupHasChangedTitle,
UiStrings().ScreenSetupHasChanged,
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
self.screen_change_timestamp = datetime.now()
self.application.set_busy_cursor()

View File

@ -668,7 +668,12 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
missing_list = []
if not self._save_lite:
write_list, missing_list = self.get_write_file_list()
try:
write_list, missing_list = self.get_write_file_list()
except PermissionError as pe:
self.main_window.error_message(UiStrings.PermissionError,
UiStrings.UnableToRead + '\n\n' + pe.filename)
return False
if missing_list:
self.application.set_normal_cursor()
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')

View File

@ -1265,8 +1265,8 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
fallback_to_windowed = display_above_horizontal or display_above_vertical \
or display_beyond_horizontal or display_beyond_vertical
if fallback_to_windowed:
if self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or self.service_item.is_media() or \
self.service_item.is_command():
if self.service_item and (self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
self.service_item.is_media() or self.service_item.is_command()):
if self.service_item.is_command():
# Attempting to get screenshot from command handler
service_item_name = self.service_item.name.lower()

View File

@ -162,11 +162,23 @@ def get_version():
except OSError:
log.exception('Error in version file.')
full_version = '0.0.0'
bits = full_version.split('.dev')
if '.dev' in full_version:
# Old way of doing build numbers, but also how hatch does them
version_number, build_number = full_version.split('.dev', 1)
build_number = build_number.split('+', 1)[1]
elif '+' in full_version:
# Current way of doing build numbers, may be replaced by hatch later
version_number, build_number = full_version.split('+', 1)
else:
# If this is a release, there is no build number
version_number = full_version
build_number = None
APPLICATION_VERSION = {
'full': full_version,
'version': bits[0],
'build': full_version.split('+')[1] if '+' in full_version else None
'version': version_number,
'build': build_number
}
if APPLICATION_VERSION['build']:
log.info('OpenLP version {version} build {build}'.format(version=APPLICATION_VERSION['version'],

View File

@ -628,9 +628,11 @@ class SongMediaItem(MediaManagerItem):
if State().check_preconditions('media'):
service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
total_length = 0
# We could have stored multiple files but only the first one will be played.
for m in song.media_files:
total_length += self.media_controller.media_length(m.file_path)
service_item.background_audio = [(m.file_path, m.file_hash) for m in song.media_files]
service_item.background_audio = [(m.file_path, m.file_hash)]
break
service_item.set_media_length(total_length)
service_item.metadata.append('<em>{label}:</em> {media}'.
format(label=translate('SongsPlugin.MediaItem', 'Media'),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -428,12 +428,26 @@ def test_sha256_file_hash_no_exist():
def test_sha256_file_hash_permission_error():
"""
Test SHA256 file hash when there is a permission error
Test that SHA256 file hash re-raises a permission error
"""
# GIVEN: A mocked Path object
mocked_path = MagicMock()
mocked_path.open.side_effect = PermissionError
# WHEN: Generating a hash for the file
# THEN: The PermissionError should be bubbled up
with pytest.raises(PermissionError):
sha256_file_hash(mocked_path)
def test_sha256_file_hash_other_error():
"""
Test SHA256 file hash when there is an error other than permission error
"""
# GIVEN: A mocked Path object
mocked_path = MagicMock()
mocked_path.open.side_effect = NotADirectoryError
# WHEN: Generating a hash for the file
result = sha256_file_hash(mocked_path)

View File

@ -21,10 +21,10 @@
"""
Package to test the openlp.core.version package.
"""
import sys
from datetime import date
from unittest.mock import MagicMock, patch
import pytest
from requests.exceptions import ConnectionError
from openlp.core.version import VersionWorker, check_for_update, get_version, update_check_date
@ -251,15 +251,25 @@ def test_check_for_update_skipped(mocked_run_thread, mock_settings):
assert mocked_run_thread.call_count == 0
def test_get_version_dev_version():
@pytest.mark.parametrize('in_version, out_version', [
('3.1.1', {'full': '3.1.1', 'version': '3.1.1', 'build': None}),
('3.0.2+git.cb1db9f43', {'full': '3.0.2+git.cb1db9f43', 'version': '3.0.2', 'build': 'git.cb1db9f43'}),
('3.1.2.dev15+gff6b05ed3', {'full': '3.1.2.dev15+gff6b05ed3', 'version': '3.1.2', 'build': 'gff6b05ed3'})
])
@patch('openlp.core.version.AppLocation.get_directory')
def test_get_version(mocked_get_directory: MagicMock, in_version: str, out_version: dict):
"""
Test the get_version() function
"""
# GIVEN: We're in dev mode
with patch.object(sys, 'argv', ['--dev-version']), \
patch('openlp.core.version.APPLICATION_VERSION', None):
# WHEN: get_version() is run
# GIVEN: Some mocks and predefined versions
mocked_path = MagicMock()
mocked_path.__truediv__.return_value = mocked_path
mocked_path.read_text.return_value = in_version
mocked_get_directory.return_value = mocked_path
# WHEN: get_version() is run
with patch('openlp.core.version.APPLICATION_VERSION', None):
version = get_version()
# THEN: version is something
assert version
assert version == out_version