diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 330c36f5c..219cae9a6 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -36,6 +36,7 @@ from openlp.core.ui import HideMode log = logging.getLogger(__name__) + class Controller(object): """ This is the Presentation listener who acts on events from the slide controller and passes the messages on the the diff --git a/openlp/plugins/remotes/html/live.html b/openlp/plugins/remotes/html/live.html index 2f505f98e..33a14fd52 100644 --- a/openlp/plugins/remotes/html/live.html +++ b/openlp/plugins/remotes/html/live.html @@ -29,14 +29,22 @@ --> - ${live_title} + ${live_title}A + - -
A
+ \ No newline at end of file diff --git a/openlp/plugins/remotes/html/live.js b/openlp/plugins/remotes/html/live.js index a44ce02ca..d55072c16 100644 --- a/openlp/plugins/remotes/html/live.js +++ b/openlp/plugins/remotes/html/live.js @@ -28,49 +28,9 @@ window.OpenLP = { $.getJSON( "/live/image", function (data, status) { - OpenLP.currentSlides = data.results.slides; - OpenLP.currentSlide = 0; - OpenLP.currentTags = Array(); - var div = $("#verseorder"); - div.html(""); - var tag = ""; - var tags = 0; - var lastChange = 0; - $.each(data.results.slides, function(idx, slide) { - var prevtag = tag; - tag = slide["tag"]; - if (tag != prevtag) { - // If the tag has changed, add new one to the list - lastChange = idx; - tags = tags + 1; - div.append(" "); - $("#verseorder span").last().attr("id", "tag" + tags).text(tag); - } - else { - if ((slide["text"] == data.results.slides[lastChange]["text"]) && - (data.results.slides.length > idx + (idx - lastChange))) { - // If the tag hasn't changed, check to see if the same verse - // has been repeated consecutively. Note the verse may have been - // split over several slides, so search through. If so, repeat the tag. - var match = true; - for (var idx2 = 0; idx2 < idx - lastChange; idx2++) { - if(data.results.slides[lastChange + idx2]["text"] != data.results.slides[idx + idx2]["text"]) { - match = false; - break; - } - } - if (match) { - lastChange = idx; - tags = tags + 1; - div.append(" "); - $("#verseorder span").last().attr("id", "tag" + tags).text(tag); - } - } - } - OpenLP.currentTags[idx] = tags; - if (slide["selected"]) - OpenLP.currentSlide = idx; - }) + var img = document.getElementById('image'); + img.src = data.results.slide_image; + img.style.display = 'block'; } ); }, diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 7a7acab2b..8d4872cfc 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -124,7 +124,7 @@ import cherrypy from mako.template import Template from PyQt4 import QtCore -from openlp.core.lib import Registry, Settings, PluginStatus, StringContent +from openlp.core.lib import Registry, Settings, PluginStatus, StringContent, image_to_byte from openlp.core.utils import AppLocation, translate from cherrypy._cpcompat import sha, ntob @@ -175,9 +175,11 @@ class HttpServer(object): self.root = self.Public() self.root.files = self.Files() self.root.stage = self.Stage() + self.root.live = self.Live() self.root.router = self.router self.root.files.router = self.router self.root.stage.router = self.router + self.root.live.router = self.router cherrypy.tree.mount(self.root, '/', config=self.define_config()) # Turn off the flood of access messages cause by poll cherrypy.log.access_log.propagate = False @@ -212,6 +214,9 @@ class HttpServer(object): u'tools.staticdir.dir': self.router.html_dir, u'tools.basic_auth.on': False}, u'/stage': {u'tools.staticdir.on': True, + u'tools.staticdir.dir': self.router.html_dir, + u'tools.basic_auth.on': False}, + u'/live': {u'tools.staticdir.on': True, u'tools.staticdir.dir': self.router.html_dir, u'tools.basic_auth.on': False}} return directory_config @@ -239,7 +244,16 @@ class HttpServer(object): class Stage(object): """ - Stageview is read only so security is not relevant and would reduce it's usability + Stage view is read only so security is not relevant and would reduce it's usability + """ + @cherrypy.expose + def default(self, *args, **kwargs): + url = urlparse.urlparse(cherrypy.url()) + return self.router.process_http_request(url.path, *args) + + class Live(object): + """ + Live view is read only so security is not relevant and would reduce it's usability """ @cherrypy.expose def default(self, *args, **kwargs): @@ -270,6 +284,7 @@ class HttpRouter(object): (r'^/api/poll$', self.poll), (r'^/stage/poll$', self.poll), (r'^/live/poll$', self.live_poll), + (r'^/live/image$', self.live_image), (r'^/api/controller/(live|preview)/(.*)$', self.controller), (r'^/stage/controller/(live|preview)/(.*)$', self.controller), (r'^/api/service/(.*)$', self.service), @@ -363,12 +378,11 @@ class HttpRouter(object): def serve_file(self, filename=None): """ - Send a file to the socket. For now, just a subset of file types - and must be top level inside the html folder. + Send a file to the socket. For now, just a subset of file types and must be top level inside the html folder. If subfolders requested return 404, easier for security for the present. - Ultimately for i18n, this could first look for xx/file.html before - falling back to file.html... where xx is the language, e.g. 'en' + Ultimately for i18n, this could first look for xx/file.html before falling back to file.html. + where xx is the language, e.g. 'en' """ log.debug(u'serve file request %s' % filename) if not filename: @@ -433,7 +447,7 @@ class HttpRouter(object): def live_poll(self): """ - Poll OpenLP to determine the current display value. + Poll OpenLP to determine the current slide count. """ result = { u'slide_count': self.live_controller.slide_count @@ -441,6 +455,16 @@ class HttpRouter(object): cherrypy.response.headers['Content-Type'] = u'application/json' return json.dumps({u'results': result}) + def live_image(self): + """ + Return the latest display image as a byte stream. + """ + result = { + u'slide_image': str(image_to_byte(self.live_controller.slide_image)) + } + cherrypy.response.headers['Content-Type'] = u'application/json' + return json.dumps({u'results': result}) + def display(self, action): """ Hide or show the display screen.