Implement custom slide sync

This commit is contained in:
Tomas Groth 2024-02-20 06:44:03 +01:00
parent e65ca1453f
commit 3573fc7dd6
5 changed files with 87 additions and 16 deletions

View File

@ -119,6 +119,7 @@ class EditCustomForm(QtWidgets.QDialog, Ui_CustomEditDialog):
self.custom_slide.theme_name = self.theme_combo_box.currentText()
success = self.manager.save_object(self.custom_slide)
self.media_item.auto_select_id = self.custom_slide.id
Registry().execute('custom_changed', self.custom_slide.id)
return success
def on_up_button_clicked(self):

View File

@ -112,7 +112,7 @@ class CustomMediaItem(MediaManagerItem):
self.load_list(self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
self.config_update()
def load_list(self, custom_slides, target_group=None):
def load_list(self, custom_slides=None, target_group=None):
# Sort out what custom we want to select after loading the list.
"""
@ -121,6 +121,8 @@ class CustomMediaItem(MediaManagerItem):
"""
self.save_auto_select_id()
self.list_view.clear()
if not custom_slides:
custom_slides = self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title)
custom_slides.sort()
for custom_slide in custom_slides:
custom_name = QtWidgets.QListWidgetItem(custom_slide.title)
@ -201,6 +203,7 @@ class CustomMediaItem(MediaManagerItem):
id_list = [(item.data(QtCore.Qt.UserRole)) for item in self.list_view.selectedIndexes()]
for id in id_list:
self.plugin.db_manager.delete_object(CustomSlide, id)
Registry().execute('custom_deleted', id)
self.on_search_text_button_clicked()
def on_focus(self):
@ -257,6 +260,7 @@ class CustomMediaItem(MediaManagerItem):
credits=old_custom_slide.credits,
theme_name=old_custom_slide.theme_name)
self.plugin.db_manager.save_object(new_custom_slide)
Registry().execute('custom_changed', new_custom_slide.id)
self.on_search_text_button_clicked()
def on_search_text_button_clicked(self):

View File

@ -24,6 +24,7 @@ import shutil
import logging
from pathlib import Path
from openlp.plugins.custom.lib.customxmlhandler import CustomXML
from openlp.plugins.remotesync.lib.backends.synchronizer import Synchronizer, SyncItemType, ConflictException, \
LockException, ConflictReason
from openlp.plugins.remotesync.lib.db import RemoteSyncItem
@ -83,7 +84,9 @@ class FolderSynchronizer(Synchronizer):
def initialize_remote(self):
self.song_history_folder_path.mkdir(parents=True, exist_ok=True)
self.custom_folder_path.mkdir(parents=True, exist_ok=True)
self.song_deleted_folder_path.mkdir(parents=True, exist_ok=True)
self.custom_history_folder_path.mkdir(parents=True, exist_ok=True)
self.custom_deleted_folder_path.mkdir(parents=True, exist_ok=True)
self.service_folder_path.mkdir(parents=True, exist_ok=True)
def _get_file_list(self, path, mask):
@ -222,14 +225,66 @@ class FolderSynchronizer(Synchronizer):
updated = self._get_remote_changes(SyncItemType.Custom)
return updated
def send_custom(self, custom):
pass
def send_custom(self, custom, custom_uuid, last_known_version, first_sync_attempt, prev_lock_id):
"""
Sends a custom slide to the shared folder.
:param custom: The sutom object to synchronize
:param custom_uuid: The uuid of the custom slide
:param last_known_version: The last known version of the custom slide
:param first_sync_attempt: If the custom slide has been attempted synchronized before,
this is the timestamp of the first sync attempt.
:param prev_lock_id: If the custom slide has been attempted synchronized before, this is the id of the lock
that prevented the synchronization.
:return: The new version.
"""
if last_known_version:
counter = int(last_known_version.split('=')[0]) + 1
else:
counter = 0
version = '{counter}={computer_id}'.format(counter=counter, computer_id=self.pc_id)
custom_xml = CustomXML(custom.text)
#custom_xml.set_version(version)
content = str(custom_xml.extract_xml(True), 'utf-8')
self._send_item(SyncItemType.Custom, content, custom_uuid, version, last_known_version, first_sync_attempt,
prev_lock_id)
return version
def fetch_custom(self):
pass
def fetch_custom(self, custom_uuid, custom_id):
"""
Fetch a specific custom slide from the shared folder
:param custom_uuid: uuid of the custom slide
:param custom_id: custom db id, None if the custom slide does not yet exists in the custom db
:return: The custom object
"""
version, item_content = self._fetch_item(SyncItemType.Custom, custom_uuid)
if not version:
return None
custom = CustomXML(item_content)
sync_item = self.manager.get_object_filtered(RemoteSyncItem, RemoteSyncItem.uuid == custom_uuid)
if not sync_item:
sync_item = RemoteSyncItem()
sync_item.type = SyncItemType.Custom
sync_item.item_id = custom.id
sync_item.uuid = custom_uuid
sync_item.version = version
self.manager.save_object(sync_item, True)
return custom
def delete_custom(self):
pass
def delete_custom(self, custom_uuid, first_del_attempt, prev_lock_id):
"""
Delete custom slide from the remote location. Does the following:
1. Check for an existing lock, raise LockException if one found.
2. Create a lock file and move the existing file to the history folder.
3. Place a file in the deleted folder, named after the custom slide uuid.
4. Delete lock file.
:param custom_uuid:
:type str:
:param first_del_attempt:
:type DateTime:
:param prev_lock_id:
:type str:
"""
self._delete_item(SyncItemType.Custom, custom_uuid, first_del_attempt, prev_lock_id)
def send_service(self, service):
pass

View File

@ -124,7 +124,7 @@ class RemoteSyncPlugin(Plugin):
self.synchronizer.initialize_remote()
# TODO: register delete functions
Registry().register_function('song_changed', self.queue_song_for_sync)
Registry().register_function('custom_changed', self.queue_custom_for_sync) # TODO: implement executing
Registry().register_function('custom_changed', self.queue_custom_for_sync)
Registry().register_function('service_changed', self.save_service)
Registry().register_function('synchronize_to_remote', self.push_to_remote)
Registry().register_function('synchronize_from_remote', self.pull_from_remote)
@ -182,18 +182,28 @@ class RemoteSyncPlugin(Plugin):
RemoteSyncItem.item_id == song.id))
if not synced_songs:
self.queue_song_for_sync(song.id)
# TODO: Also check custom slides
custom_manager = Registry().get('custom_manager')
all_custom_slides = custom_manager.get_all_objects(CustomSlide)
for custom in all_custom_slides:
# TODO: Check that custom slide actually exists remotely - should we delete if not?
synced_custom = self.manager.get_object_filtered(RemoteSyncItem,
and_(RemoteSyncItem.type == SyncItemType.Song,
RemoteSyncItem.item_id == custom.id))
if not synced_custom:
self.queue_custom_for_sync(custom.id)
def synchronize(self):
"""
Synchronize by first pulling data from remote and then pushing local changes to the remote
"""
self.synchronizer.connect()
self.pull_from_remote()
self.push_to_remote()
self.synchronizer.disconnect()
# Set a timer to start the synchronization again in 10 minutes.
self.sync_timer.start(60000)
if self.synchronizer:
self.synchronizer.connect()
self.pull_from_remote()
self.push_to_remote()
self.synchronizer.disconnect()
# Set a timer to start the synchronization again in 10 minutes.
self.sync_timer.start(60000)
def push_to_remote(self):
"""

View File

@ -546,6 +546,7 @@ class SongMediaItem(MediaManagerItem):
new_song.media_files.append(new_media_file)
self.plugin.manager.save_object(new_song)
new_song.init_on_load()
Registry().execute('song_changed', new_song.id)
self.on_song_list_load()
def generate_slide_data(self, service_item, *, item=None, context=ServiceItemContext.Service, **kwargs):