More fixes

This commit is contained in:
Tim Bentley 2016-06-27 21:55:36 +01:00
parent ac841a934c
commit 7aa1acc176
8 changed files with 106 additions and 45 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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):
""" """

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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')

View File

@ -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)