forked from openlp/openlp
More fixes
This commit is contained in:
parent
ac841a934c
commit
7aa1acc176
@ -66,7 +66,6 @@ class Endpoint(object):
|
|||||||
if not self.template_dir:
|
if not self.template_dir:
|
||||||
raise Exception('No template directory specified')
|
raise Exception('No template directory specified')
|
||||||
path = os.path.abspath(os.path.join(self.template_dir, filename))
|
path = os.path.abspath(os.path.join(self.template_dir, filename))
|
||||||
print("path = ", path)
|
|
||||||
# if self.static_dir:
|
# if self.static_dir:
|
||||||
# kwargs['static_url'] = '/{prefix}/static'.format(prefix=self.url_prefix)
|
# kwargs['static_url'] = '/{prefix}/static'.format(prefix=self.url_prefix)
|
||||||
return Template(filename=path, input_encoding='utf-8').render(**kwargs)
|
return Template(filename=path, input_encoding='utf-8').render(**kwargs)
|
||||||
|
@ -26,15 +26,17 @@ import urllib.error
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from openlp.core.api.http.endpoint import Endpoint
|
from openlp.core.api.http.endpoint import Endpoint
|
||||||
from openlp.core.api.http import register_endpoint
|
from openlp.core.api.http import register_endpoint, requires_auth
|
||||||
from openlp.core.common import Registry, AppLocation, Settings
|
from openlp.core.common import Registry, AppLocation, Settings
|
||||||
from openlp.core.lib import ItemCapabilities, create_thumb
|
from openlp.core.lib import ItemCapabilities, create_thumb
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
controller_endpoint = Endpoint('controller')
|
controller_endpoint = Endpoint('controller')
|
||||||
|
api_controller_endpoint = Endpoint('api')
|
||||||
|
|
||||||
|
|
||||||
|
@api_controller_endpoint.route('controller/live/text')
|
||||||
@controller_endpoint.route('live/text')
|
@controller_endpoint.route('live/text')
|
||||||
def controller_text(request):
|
def controller_text(request):
|
||||||
"""
|
"""
|
||||||
@ -65,6 +67,7 @@ def controller_text(request):
|
|||||||
# Create thumbnail if it doesn't exists
|
# Create thumbnail if it doesn't exists
|
||||||
if not os.path.exists(full_thumbnail_path):
|
if not os.path.exists(full_thumbnail_path):
|
||||||
create_thumb(current_item.get_frame_path(index), full_thumbnail_path, False)
|
create_thumb(current_item.get_frame_path(index), full_thumbnail_path, False)
|
||||||
|
Registry().get('image_manager').add_image(full_thumbnail_path, frame['title'], None, 88, 88)
|
||||||
item['img'] = urllib.request.pathname2url(os.path.sep + thumbnail_path)
|
item['img'] = urllib.request.pathname2url(os.path.sep + thumbnail_path)
|
||||||
item['text'] = str(frame['title'])
|
item['text'] = str(frame['title'])
|
||||||
item['html'] = str(frame['title'])
|
item['html'] = str(frame['title'])
|
||||||
@ -81,6 +84,7 @@ def controller_text(request):
|
|||||||
data_path = AppLocation.get_data_path()
|
data_path = AppLocation.get_data_path()
|
||||||
if frame['image'][0:len(data_path)] == data_path:
|
if frame['image'][0:len(data_path)] == data_path:
|
||||||
item['img'] = urllib.request.pathname2url(frame['image'][len(data_path):])
|
item['img'] = urllib.request.pathname2url(frame['image'][len(data_path):])
|
||||||
|
Registry().get('image_manager').add_image(frame['image'], frame['title'], None, 88, 88)
|
||||||
item['text'] = str(frame['title'])
|
item['text'] = str(frame['title'])
|
||||||
item['html'] = str(frame['title'])
|
item['html'] = str(frame['title'])
|
||||||
item['selected'] = (live_controller.selected_row == index)
|
item['selected'] = (live_controller.selected_row == index)
|
||||||
@ -91,7 +95,9 @@ def controller_text(request):
|
|||||||
return json_data
|
return json_data
|
||||||
|
|
||||||
|
|
||||||
|
@api_controller_endpoint.route('controller/live/set')
|
||||||
@controller_endpoint.route('live/set')
|
@controller_endpoint.route('live/set')
|
||||||
|
@requires_auth
|
||||||
def controller_set(request):
|
def controller_set(request):
|
||||||
"""
|
"""
|
||||||
Perform an action on the slide controller.
|
Perform an action on the slide controller.
|
||||||
@ -108,3 +114,4 @@ def controller_set(request):
|
|||||||
return {'results': {'success': True}}
|
return {'results': {'success': True}}
|
||||||
|
|
||||||
register_endpoint(controller_endpoint)
|
register_endpoint(controller_endpoint)
|
||||||
|
register_endpoint(api_controller_endpoint)
|
||||||
|
@ -118,6 +118,7 @@ def toggle_display(request, display):
|
|||||||
return {'results': {'success': True}}
|
return {'results': {'success': True}}
|
||||||
|
|
||||||
|
|
||||||
|
@blank_endpoint.route('api/plugin/{search:search}')
|
||||||
@blank_endpoint.route('plugin/{search:search}')
|
@blank_endpoint.route('plugin/{search:search}')
|
||||||
def plugin_search(request, search):
|
def plugin_search(request, search):
|
||||||
"""
|
"""
|
||||||
@ -131,25 +132,25 @@ def plugin_search(request, search):
|
|||||||
searches.append([plugin.name, str(plugin.text_strings[StringContent.Name]['plural'])])
|
searches.append([plugin.name, str(plugin.text_strings[StringContent.Name]['plural'])])
|
||||||
return {'results': {'items': searches}}
|
return {'results': {'items': searches}}
|
||||||
|
|
||||||
# @stage_endpoint.route('(stage)/(.*)$')
|
|
||||||
# def bespoke_file_access(request):
|
@stage_endpoint.route('{local_path}')
|
||||||
# """
|
def bespoke_file_access(request, local_path):
|
||||||
# Allow Stage view to be delivered with custom views.
|
"""
|
||||||
#
|
Allow Stage view to be delivered with custom views.
|
||||||
# :param request: base path of the URL. Not used but passed by caller
|
|
||||||
# :return:
|
:param request: base path of the URL. Not used but passed by caller
|
||||||
# """
|
:param local_path: path within the stages config directory
|
||||||
# file_name = request.path
|
:return:
|
||||||
# config_dir = os.path.join(AppLocation.get_data_path(), 'stages')
|
"""
|
||||||
# log.debug('serve file request {name}'.format(name=file_name))
|
config_dir = os.path.join(AppLocation.get_data_path(), 'stages')
|
||||||
# parts = file_name.split('/')
|
log.debug('serve file request {name}'.format(name=local_path))
|
||||||
# if len(parts) == 1:
|
parts = local_path.split('/')
|
||||||
# file_name = os.path.join(parts[0], 'stage.mako')
|
if len(parts) == 1:
|
||||||
# elif len(parts) == 3:
|
file_name = os.path.join(parts[0], 'stage.mako')
|
||||||
# file_name = os.path.join(parts[1], parts[2])
|
elif len(parts) == 3:
|
||||||
# path = os.path.normpath(os.path.join(config_dir, file_name))
|
file_name = os.path.join(parts[1], parts[2])
|
||||||
# #return _process_file(path)
|
path = os.path.normpath(os.path.join(config_dir, file_name))
|
||||||
# pass
|
#return _process_file(path)
|
||||||
|
|
||||||
|
|
||||||
@main_endpoint.route('image')
|
@main_endpoint.route('image')
|
||||||
@ -165,17 +166,6 @@ def main_image(request):
|
|||||||
}
|
}
|
||||||
return {'results': result}
|
return {'results': result}
|
||||||
|
|
||||||
# @stage_endpoint.route(r'^/(\w+)/thumbnails([^/]+)?/(.*)$')
|
|
||||||
# def main_image(request):
|
|
||||||
# """
|
|
||||||
# Get a list of songs
|
|
||||||
# :param request: base path of the URL. Not used but passed by caller
|
|
||||||
# :return:
|
|
||||||
# """
|
|
||||||
# # songs = db.query(Song).get()
|
|
||||||
# # return {'songs': [dictify(song) for song in songs]}
|
|
||||||
# print("AAA")
|
|
||||||
|
|
||||||
|
|
||||||
def get_content_type(file_name):
|
def get_content_type(file_name):
|
||||||
"""
|
"""
|
||||||
|
@ -30,8 +30,10 @@ from openlp.core.common import Registry
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
service_endpoint = Endpoint('service')
|
service_endpoint = Endpoint('service')
|
||||||
|
api_service_endpoint = Endpoint('api/service')
|
||||||
|
|
||||||
|
|
||||||
|
@api_service_endpoint.route('list')
|
||||||
@service_endpoint.route('list')
|
@service_endpoint.route('list')
|
||||||
def list_service(request):
|
def list_service(request):
|
||||||
"""
|
"""
|
||||||
@ -42,6 +44,7 @@ def list_service(request):
|
|||||||
return {'results': {'items': get_service_items()}}
|
return {'results': {'items': get_service_items()}}
|
||||||
|
|
||||||
|
|
||||||
|
@api_service_endpoint.route('set')
|
||||||
@service_endpoint.route('set')
|
@service_endpoint.route('set')
|
||||||
@requires_auth
|
@requires_auth
|
||||||
def service_set(request):
|
def service_set(request):
|
||||||
@ -82,3 +85,4 @@ def get_service_items():
|
|||||||
return service_items
|
return service_items
|
||||||
|
|
||||||
register_endpoint(service_endpoint)
|
register_endpoint(service_endpoint)
|
||||||
|
register_endpoint(api_service_endpoint)
|
||||||
|
@ -79,6 +79,9 @@ def _make_response(view_result):
|
|||||||
body = json.dumps(body)
|
body = json.dumps(body)
|
||||||
response = Response(body=body, status=view_result[1],
|
response = Response(body=body, status=view_result[1],
|
||||||
content_type=content_type, charset='utf8')
|
content_type=content_type, charset='utf8')
|
||||||
|
response.headers.add("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
response.headers.add("Pragma", "no-cache")
|
||||||
|
response.headers.add("Expires", "0")
|
||||||
if len(view_result) >= 3:
|
if len(view_result) >= 3:
|
||||||
response.headers.update(view_result[2])
|
response.headers.update(view_result[2])
|
||||||
return response
|
return response
|
||||||
@ -134,13 +137,11 @@ class WSGIApplication(object):
|
|||||||
Find the appropriate URL and run the view function
|
Find the appropriate URL and run the view function
|
||||||
"""
|
"""
|
||||||
# We are not interested in this so discard
|
# We are not interested in this so discard
|
||||||
if '/favicon.ico' in request.path:
|
if 'favicon' in request.path:
|
||||||
return
|
return
|
||||||
# First look to see if this is a static file request
|
# First look to see if this is a static file request
|
||||||
for route, static_app in self.static_routes.items():
|
for route, static_app in self.static_routes.items():
|
||||||
print(route, request.path)
|
|
||||||
if re.match(route, request.path):
|
if re.match(route, request.path):
|
||||||
print("matched static")
|
|
||||||
# Pop the path info twice in order to get rid of the "/<plugin>/static"
|
# Pop the path info twice in order to get rid of the "/<plugin>/static"
|
||||||
# request.path_info_pop()
|
# request.path_info_pop()
|
||||||
request.path_info_pop()
|
request.path_info_pop()
|
||||||
@ -148,12 +149,7 @@ class WSGIApplication(object):
|
|||||||
# If not a static route, try the views
|
# If not a static route, try the views
|
||||||
for route, views in self.route_map.items():
|
for route, views in self.route_map.items():
|
||||||
path = request.path
|
path = request.path
|
||||||
# /api is legacy so we need to handle backwards compatibility
|
|
||||||
if path.startswith('/api'):
|
|
||||||
path = path[4:]
|
|
||||||
print("route MATCHED", route, request.path, path)
|
|
||||||
match = re.match(route, path)
|
match = re.match(route, path)
|
||||||
print(match)
|
|
||||||
if match and request.method.upper() in views:
|
if match and request.method.upper() in views:
|
||||||
kwargs = match.groupdict()
|
kwargs = match.groupdict()
|
||||||
log.debug('Found {method} {url}'.format(method=request.method, url=request.path))
|
log.debug('Found {method} {url}'.format(method=request.method, url=request.path))
|
||||||
@ -171,10 +167,16 @@ class WSGIApplication(object):
|
|||||||
response = self.dispatch(request)
|
response = self.dispatch(request)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
response = _make_response(_handle_exception(e))
|
response = _make_response(_handle_exception(e))
|
||||||
|
response.headers.add("cache-control", "no-cache, no-store, must-revalidate")
|
||||||
|
response.headers.add("pragma", "no-cache")
|
||||||
|
response.headers.add("expires", "0")
|
||||||
return response(environ, start_response)
|
return response(environ, start_response)
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
"""
|
"""
|
||||||
Shortcut for wsgi_app.
|
Shortcut for wsgi_app.
|
||||||
"""
|
"""
|
||||||
|
# We are not interested in this so discard
|
||||||
|
if 'favicon' in environ["PATH_INFO"]:
|
||||||
|
return
|
||||||
return self.wsgi_app(environ, start_response)
|
return self.wsgi_app(environ, start_response)
|
||||||
|
@ -235,8 +235,15 @@ class ImageManager(QtCore.QObject):
|
|||||||
def get_image(self, path, source, width=-1, height=-1):
|
def get_image(self, path, source, width=-1, height=-1):
|
||||||
"""
|
"""
|
||||||
Return the ``QImage`` from the cache. If not present wait for the background thread to process it.
|
Return the ``QImage`` from the cache. If not present wait for the background thread to process it.
|
||||||
|
|
||||||
|
:param: path: The image path
|
||||||
|
:param: source: The source of the image
|
||||||
|
:param: background: The image background colour
|
||||||
|
:param: width: The processed image width
|
||||||
|
:param: height: The processed image height
|
||||||
"""
|
"""
|
||||||
log.debug('getImage {path}'.format(path=path))
|
log.debug('get_image {path} {source} {width} {height}'.format(path=path, source=source,
|
||||||
|
width=width, height=height))
|
||||||
image = self._cache[(path, source, width, height)]
|
image = self._cache[(path, source, width, height)]
|
||||||
if image.image is None:
|
if image.image is None:
|
||||||
self._conversion_queue.modify_priority(image, Priority.High)
|
self._conversion_queue.modify_priority(image, Priority.High)
|
||||||
@ -255,8 +262,15 @@ class ImageManager(QtCore.QObject):
|
|||||||
def get_image_bytes(self, path, source, width=-1, height=-1):
|
def get_image_bytes(self, path, source, width=-1, height=-1):
|
||||||
"""
|
"""
|
||||||
Returns the byte string for an image. If not present wait for the background thread to process it.
|
Returns the byte string for an image. If not present wait for the background thread to process it.
|
||||||
|
|
||||||
|
:param: path: The image path
|
||||||
|
:param: source: The source of the image
|
||||||
|
:param: background: The image background colour
|
||||||
|
:param: width: The processed image width
|
||||||
|
:param: height: The processed image height
|
||||||
"""
|
"""
|
||||||
log.debug('get_image_bytes {path}'.format(path=path))
|
log.debug('get_image_bytes {path} {source} {width} {height}'.format(path=path, source=source,
|
||||||
|
width=width, height=height))
|
||||||
image = self._cache[(path, source, width, height)]
|
image = self._cache[(path, source, width, height)]
|
||||||
if image.image_bytes is None:
|
if image.image_bytes is None:
|
||||||
self._conversion_queue.modify_priority(image, Priority.Urgent)
|
self._conversion_queue.modify_priority(image, Priority.Urgent)
|
||||||
@ -270,8 +284,15 @@ class ImageManager(QtCore.QObject):
|
|||||||
def add_image(self, path, source, background, width=-1, height=-1):
|
def add_image(self, path, source, background, width=-1, height=-1):
|
||||||
"""
|
"""
|
||||||
Add image to cache if it is not already there.
|
Add image to cache if it is not already there.
|
||||||
|
|
||||||
|
:param: path: The image path
|
||||||
|
:param: source: The source of the image
|
||||||
|
:param: background: The image background colour
|
||||||
|
:param: width: The processed image width
|
||||||
|
:param: height: The processed image height
|
||||||
"""
|
"""
|
||||||
log.debug('add_image {path}'.format(path=path))
|
log.debug('add_image {path} {source} {width} {height}'.format(path=path, source=source,
|
||||||
|
width=width, height=height))
|
||||||
if not (path, source, width, height) in self._cache:
|
if not (path, source, width, height) in self._cache:
|
||||||
image = Image(path, source, background, width, height)
|
image = Image(path, source, background, width, height)
|
||||||
self._cache[(path, source, width, height)] = image
|
self._cache[(path, source, width, height)] = image
|
||||||
|
@ -1068,8 +1068,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||||||
if self.service_item is not None:
|
if self.service_item is not None:
|
||||||
if hide:
|
if hide:
|
||||||
Registry().execute('live_display_hide', HideMode.Screen)
|
Registry().execute('live_display_hide', HideMode.Screen)
|
||||||
Registry().execute('{text}_hide'.format(text=self.service_item.name.lower()),
|
# Registry().execute('{text}_hide'.format(text=self.service_item.name.lower()),
|
||||||
[self.service_item, self.is_live])
|
# [self.service_item, self.is_live])
|
||||||
else:
|
else:
|
||||||
if not self.service_item.is_command():
|
if not self.service_item.is_command():
|
||||||
Registry().execute('live_display_show')
|
Registry().execute('live_display_show')
|
||||||
|
@ -66,5 +66,43 @@ def presentations_service(request):
|
|||||||
"""
|
"""
|
||||||
return service(request, 'presentations', log)
|
return service(request, 'presentations', log)
|
||||||
|
|
||||||
|
|
||||||
|
# /presentations/thumbnails88x88/PA%20Rota.pdf/slide5.png
|
||||||
|
@api_presentations_endpoint.route('presentations/thumbnails88x88/{file_name}/{slide}')
|
||||||
|
@presentations_endpoint.route('thumbnails88x88/{file_name}/{slide}')
|
||||||
|
def presentations_thumbnails(request, file_name, slide):
|
||||||
|
"""
|
||||||
|
Handles requests for adding a song to the service
|
||||||
|
|
||||||
|
:param request: The http request object.
|
||||||
|
"""
|
||||||
|
controller_name = 'presentations'
|
||||||
|
dimensions = '88x88'
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import urllib
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from webob import Response
|
||||||
|
from openlp.core.common import Registry, AppLocation
|
||||||
|
|
||||||
|
log.debug('serve thumbnail {cname}/thumbnails{dim}/{fname}'.format(cname=controller_name,
|
||||||
|
dim=dimensions,
|
||||||
|
fname=file_name))
|
||||||
|
content = None
|
||||||
|
if controller_name and file_name:
|
||||||
|
file_name = urllib.parse.unquote(file_name)
|
||||||
|
if '..' not in file_name: # no hacking please
|
||||||
|
full_path = os.path.normpath(os.path.join(AppLocation.get_section_data_path(controller_name),
|
||||||
|
'thumbnails/', file_name, slide))
|
||||||
|
if os.path.exists(full_path):
|
||||||
|
image_manager = Registry().get("image_manager")
|
||||||
|
i = 0
|
||||||
|
while i < 4 and content is None:
|
||||||
|
content = image_manager.get_image_bytes(full_path, file_name, 88, 88)
|
||||||
|
time.sleep(0.1)
|
||||||
|
i += 1
|
||||||
|
return Response(body=content, status=200, content_type='data:image/png;base64', charset='utf8')
|
||||||
|
|
||||||
|
|
||||||
register_endpoint(presentations_endpoint)
|
register_endpoint(presentations_endpoint)
|
||||||
register_endpoint(api_presentations_endpoint)
|
register_endpoint(api_presentations_endpoint)
|
||||||
|
Loading…
Reference in New Issue
Block a user