2020-01-29 06:50:09 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
|
|
# ---------------------------------------------------------------------- #
|
2022-02-06 09:10:17 +00:00
|
|
|
# Copyright (c) 2008-2022 OpenLP Developers #
|
2020-01-29 06:50:09 +00:00
|
|
|
# ---------------------------------------------------------------------- #
|
|
|
|
# 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, either version 3 of the License, or #
|
|
|
|
# (at your option) any later version. #
|
|
|
|
# #
|
|
|
|
# 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, see <https://www.gnu.org/licenses/>. #
|
|
|
|
##########################################################################
|
2020-05-02 18:53:56 +00:00
|
|
|
import logging
|
2020-01-27 22:57:58 +00:00
|
|
|
|
|
|
|
from openlp.core.api.lib import login_required
|
2020-04-01 18:26:57 +00:00
|
|
|
from openlp.core.common import ThemeLevel
|
2020-01-27 22:57:58 +00:00
|
|
|
from openlp.core.common.registry import Registry
|
2020-08-27 06:19:47 +00:00
|
|
|
from openlp.core.lib import image_to_data_uri
|
2020-01-27 22:57:58 +00:00
|
|
|
|
2020-08-01 19:30:49 +00:00
|
|
|
from flask import jsonify, request, abort, Blueprint, Response
|
2020-01-27 22:57:58 +00:00
|
|
|
|
|
|
|
controller_views = Blueprint('controller', __name__)
|
2020-05-02 18:53:56 +00:00
|
|
|
log = logging.getLogger(__name__)
|
2020-01-27 22:57:58 +00:00
|
|
|
|
|
|
|
|
2020-10-19 07:18:26 +00:00
|
|
|
@controller_views.route('/live-items')
|
|
|
|
def controller_live_items():
|
|
|
|
log.debug('controller-v2-live-items')
|
2020-01-27 22:57:58 +00:00
|
|
|
live_controller = Registry().get('live_controller')
|
|
|
|
current_item = live_controller.service_item
|
2020-07-22 06:42:40 +00:00
|
|
|
live_item = {}
|
2020-01-27 22:57:58 +00:00
|
|
|
if current_item:
|
2020-07-22 06:42:40 +00:00
|
|
|
live_item = current_item.to_dict()
|
|
|
|
live_item['slides'][live_controller.selected_row]['selected'] = True
|
|
|
|
return jsonify(live_item)
|
2020-01-27 22:57:58 +00:00
|
|
|
|
|
|
|
|
2020-10-19 07:18:26 +00:00
|
|
|
@controller_views.route('/live-item')
|
|
|
|
def controller_live_item():
|
|
|
|
log.debug('controller-v2-live-item')
|
|
|
|
live_controller = Registry().get('live_controller')
|
|
|
|
current_item = live_controller.service_item
|
|
|
|
live_item = {}
|
|
|
|
if current_item:
|
|
|
|
live_item = current_item.to_dict(True, live_controller.selected_row)
|
|
|
|
return jsonify(live_item)
|
|
|
|
|
|
|
|
|
2020-01-27 22:57:58 +00:00
|
|
|
@controller_views.route('/show', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def controller_set():
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-show-post')
|
2020-01-27 22:57:58 +00:00
|
|
|
data = request.json
|
|
|
|
if not data:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Missing request data')
|
2020-01-27 22:57:58 +00:00
|
|
|
abort(400)
|
|
|
|
num = data.get('id', -1)
|
|
|
|
Registry().get('live_controller').slidecontroller_live_set.emit([num])
|
|
|
|
return '', 204
|
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/progress', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def controller_direction():
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-progress-post')
|
2020-01-27 22:57:58 +00:00
|
|
|
ALLOWED_ACTIONS = ['next', 'previous']
|
|
|
|
data = request.json
|
|
|
|
if not data:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Missing request data')
|
2020-01-27 22:57:58 +00:00
|
|
|
abort(400)
|
|
|
|
action = data.get('action', '').lower()
|
|
|
|
if action not in ALLOWED_ACTIONS:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Invalid action passed ' + action)
|
2020-01-27 22:57:58 +00:00
|
|
|
abort(400)
|
|
|
|
getattr(Registry().get('live_controller'), 'slidecontroller_live_{action}'.
|
|
|
|
format(action=action)).emit()
|
|
|
|
return '', 204
|
2020-04-01 18:26:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/theme-level', methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
def get_theme_level():
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-theme-level-get')
|
2020-04-01 18:26:57 +00:00
|
|
|
theme_level = Registry().get('settings').value('themes/theme level')
|
|
|
|
if theme_level == ThemeLevel.Global:
|
|
|
|
theme_level = 'global'
|
|
|
|
elif theme_level == ThemeLevel.Service:
|
|
|
|
theme_level = 'service'
|
|
|
|
elif theme_level == ThemeLevel.Song:
|
|
|
|
theme_level = 'song'
|
|
|
|
return jsonify(theme_level)
|
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/theme-level', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def set_theme_level():
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-theme-level-post')
|
2020-04-01 18:26:57 +00:00
|
|
|
data = request.json
|
|
|
|
if not data:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Missing request data')
|
2020-04-01 18:26:57 +00:00
|
|
|
abort(400)
|
|
|
|
theme_level = ''
|
|
|
|
try:
|
|
|
|
theme_level = str(data.get("level"))
|
|
|
|
except ValueError:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Invalid data passed ' + theme_level)
|
2020-04-01 18:26:57 +00:00
|
|
|
abort(400)
|
|
|
|
if theme_level == 'global':
|
|
|
|
Registry().get('settings').setValue('themes/theme level', 1)
|
|
|
|
elif theme_level == 'service':
|
|
|
|
Registry().get('settings').setValue('themes/theme level', 2)
|
|
|
|
elif theme_level == 'song':
|
2020-05-20 07:40:23 +00:00
|
|
|
Registry().get('settings').setValue('themes/theme level', 3)
|
2020-04-01 18:26:57 +00:00
|
|
|
else:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Unsupported data passed ' + theme_level)
|
2020-04-01 18:26:57 +00:00
|
|
|
abort(400)
|
2022-01-16 13:15:09 +00:00
|
|
|
Registry().get('theme_manager').theme_level_updated.emit()
|
2020-04-01 18:26:57 +00:00
|
|
|
return '', 204
|
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/themes', methods=['GET'])
|
|
|
|
def get_themes():
|
2020-08-01 19:30:49 +00:00
|
|
|
"""
|
|
|
|
Gets a list of all existing themes
|
|
|
|
"""
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-themes-get')
|
2020-04-01 18:26:57 +00:00
|
|
|
theme_level = Registry().get('settings').value('themes/theme level')
|
|
|
|
theme_list = []
|
|
|
|
current_theme = ''
|
|
|
|
if theme_level == ThemeLevel.Global:
|
|
|
|
current_theme = Registry().get('theme_manager').global_theme
|
|
|
|
if theme_level == ThemeLevel.Service:
|
|
|
|
current_theme = Registry().get('service_manager').service_theme
|
|
|
|
# Gets and appends theme list
|
|
|
|
themes = Registry().execute('get_theme_names')
|
|
|
|
try:
|
|
|
|
for theme in themes[0]:
|
2020-08-27 06:19:47 +00:00
|
|
|
# Gets the background path, get the thumbnail from it, and encode it to a base64 data uri
|
|
|
|
theme_path = Registry().get('theme_manager').theme_path
|
|
|
|
encoded_thumb = image_to_data_uri(theme_path / 'thumbnails' / '{file_name}.png'.format(file_name=theme))
|
|
|
|
# Append the theme to the list
|
2020-04-01 18:26:57 +00:00
|
|
|
theme_list.append({
|
|
|
|
'name': theme,
|
2020-08-27 06:19:47 +00:00
|
|
|
'selected': False,
|
|
|
|
'thumbnail': encoded_thumb
|
2020-04-01 18:26:57 +00:00
|
|
|
})
|
|
|
|
for i in theme_list:
|
|
|
|
if i["name"] == current_theme:
|
|
|
|
i["selected"] = True
|
|
|
|
except IndexError:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Missing theme passed ' + str(themes))
|
2020-04-01 18:26:57 +00:00
|
|
|
pass
|
|
|
|
return jsonify(theme_list)
|
|
|
|
|
|
|
|
|
2020-08-01 19:30:49 +00:00
|
|
|
@controller_views.route('/themes/<theme_name>', methods=['GET'])
|
|
|
|
def get_theme_data(theme_name):
|
|
|
|
"""
|
|
|
|
Get a theme's data
|
|
|
|
"""
|
|
|
|
log.debug(f'controller-v2-theme-data-get {theme_name}')
|
|
|
|
themes = Registry().execute('get_theme_names')[0]
|
|
|
|
if theme_name not in themes:
|
|
|
|
log.error('Requested non-existent theme')
|
|
|
|
abort(404)
|
|
|
|
theme_data = Registry().get('theme_manager').get_theme_data(theme_name).export_theme_self_contained(True)
|
|
|
|
return Response(theme_data, mimetype='application/json')
|
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/live-theme', methods=['GET'])
|
|
|
|
def get_live_theme_data():
|
|
|
|
"""
|
|
|
|
Get the live theme's data
|
|
|
|
"""
|
|
|
|
log.debug('controller-v2-live-theme-data-get')
|
|
|
|
live_service_item = Registry().get('live_controller').service_item
|
|
|
|
if live_service_item:
|
|
|
|
theme_data = live_service_item.get_theme_data()
|
|
|
|
else:
|
|
|
|
theme_data = Registry().get('theme_manager').get_theme_data(None)
|
|
|
|
self_contained_theme = theme_data.export_theme_self_contained(True)
|
|
|
|
return Response(self_contained_theme, mimetype='application/json')
|
|
|
|
|
|
|
|
|
2020-05-16 05:28:21 +00:00
|
|
|
@controller_views.route('/theme', methods=['GET'])
|
|
|
|
def get_theme():
|
|
|
|
"""
|
2020-08-01 19:30:49 +00:00
|
|
|
Get the current theme name
|
2020-05-16 05:28:21 +00:00
|
|
|
"""
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-theme-get')
|
2020-05-16 05:28:21 +00:00
|
|
|
theme_level = Registry().get('settings').value('themes/theme level')
|
|
|
|
if theme_level == ThemeLevel.Service:
|
|
|
|
theme = Registry().get('settings').value('servicemanager/service theme')
|
|
|
|
else:
|
|
|
|
theme = Registry().get('settings').value('themes/global theme')
|
|
|
|
return jsonify(theme)
|
|
|
|
|
|
|
|
|
2020-04-01 18:26:57 +00:00
|
|
|
@controller_views.route('/theme', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def set_theme():
|
2020-05-20 07:40:23 +00:00
|
|
|
log.debug('controller-v2-themes-post')
|
2020-04-01 18:26:57 +00:00
|
|
|
data = request.json
|
|
|
|
theme = ''
|
|
|
|
theme_level = Registry().get('settings').value('themes/theme level')
|
|
|
|
if not data:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Missing request data')
|
2020-04-01 18:26:57 +00:00
|
|
|
abort(400)
|
|
|
|
try:
|
|
|
|
theme = str(data.get('theme'))
|
|
|
|
except ValueError:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Invalid data passed ' + theme)
|
2020-04-01 18:26:57 +00:00
|
|
|
abort(400)
|
|
|
|
if theme_level == ThemeLevel.Global:
|
|
|
|
Registry().get('settings').setValue('themes/global theme', theme)
|
2020-10-28 04:06:56 +00:00
|
|
|
Registry().get('theme_manager').theme_update_global.emit()
|
2020-04-01 18:26:57 +00:00
|
|
|
elif theme_level == ThemeLevel.Service:
|
|
|
|
Registry().get('settings').setValue('servicemanager/service theme', theme)
|
2020-10-28 04:06:56 +00:00
|
|
|
Registry().get('service_manager').theme_update_service.emit()
|
2020-04-01 18:26:57 +00:00
|
|
|
elif theme_level == ThemeLevel.Song:
|
2020-05-02 18:53:56 +00:00
|
|
|
log.error('Unimplemented method')
|
2020-04-01 18:26:57 +00:00
|
|
|
return '', 501
|
|
|
|
return '', 204
|
2020-05-20 07:40:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
@controller_views.route('/clear/<controller>', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def controller_clear(controller):
|
|
|
|
"""
|
|
|
|
Clears the slide controller display
|
|
|
|
:param controller: the Live or Preview controller
|
|
|
|
:return: HTTP return code
|
|
|
|
"""
|
|
|
|
log.debug(f'controller-v2-clear-get {controller}')
|
|
|
|
if controller in ['live', 'preview']:
|
|
|
|
getattr(Registry().get(f'{controller}_controller'), f'slidecontroller_{controller}_clear').emit()
|
|
|
|
return '', 204
|
|
|
|
else:
|
|
|
|
return '', 404
|