Added next and previous to both service and slide controller, and added blank and unblank.

This commit is contained in:
Raoul Snyman 2011-03-16 08:39:25 +02:00
parent a1b26df5fe
commit df79ab09fa
3 changed files with 76 additions and 127 deletions

View File

@ -32,11 +32,11 @@
</ul>
</div>
<div data-role="footer" data-theme="b" class="ui-bar">
<a href="#" data-role="button" data-icon="blank">Blank</a>
<a href="#" data-role="button" data-icon="unblank">Unblank</a>
<a href="#" data-role="button" data-icon="refresh">Refresh</a>
<a href="#" data-role="button" data-icon="arrow-l">Previous</a>
<a href="#" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
<a href="#" id="service-blank" data-role="button" data-icon="blank">Blank</a>
<a href="#" id="service-unblank" data-role="button" data-icon="unblank">Unblank</a>
<a href="#" id="service-refresh" data-role="button" data-icon="refresh">Refresh</a>
<a href="#" id="service-previous" data-role="button" data-icon="arrow-l">Previous</a>
<a href="#" id="service-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
</div>
</div>
<div data-role="page" id="slide-controller">
@ -49,11 +49,11 @@
</ul>
</div>
<div data-role="footer" data-theme="b" class="ui-bar">
<a href="#" data-role="button" data-icon="blank">Blank</a>
<a href="#" data-role="button" data-icon="unblank">Unblank</a>
<a href="#" data-role="button" data-icon="refresh">Refresh</a>
<a href="#" data-role="button" data-icon="arrow-l">Previous</a>
<a href="#" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
<a href="#" id="controller-blank" data-role="button" data-icon="blank">Blank</a>
<a href="#" id="controller-unblank" data-role="button" data-icon="unblank">Unblank</a>
<a href="#" id="controller-refresh" data-role="button" data-icon="refresh">Refresh</a>
<a href="#" id="controller-previous" data-role="button" data-icon="arrow-l">Previous</a>
<a href="#" id="controller-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
</div>
</div>
<div data-role="page" id="alerts">

View File

@ -44,12 +44,12 @@ window.OpenLP = {
function (data, status) {
var ul = $("#service-manager > div[data-role=content] > ul[data-role=listview]");
ul.html("");
for (idx in data.results) {
$.each(data.results.items, function (idx, value) {
var li = $("<li data-icon=\"false\">").append(
$("<a href=\"#\">").attr("value", parseInt(idx, 10)).text(data.results[idx]["title"]));
$("<a href=\"#\">").attr("value", parseInt(idx, 10)).text(value["title"]));
li.children("a").click(OpenLP.setItem);
ul.append(li);
}
});
ul.listview("refresh");
}
);
@ -146,11 +146,40 @@ window.OpenLP = {
}
}
);
},
nextItem: function (event) {
$.getJSON("/api/service/next");
},
previousItem: function (event) {
$.getJSON("/api/service/previous");
},
nextSlide: function (event) {
$.getJSON("/api/controller/live/next");
},
previousSlide: function (event) {
$.getJSON("/api/controller/live/previous");
},
blankDisplay: function (event) {
$.getJSON("/api/display/hide");
},
unblankDisplay: function (event) {
$.getJSON("/api/display/show");
}
}
// Service Manager
$("#service-manager").live("pagebeforeshow", OpenLP.loadService);
$("#service-refresh").live("click", OpenLP.loadService);
$("#service-next").live("click", OpenLP.nextItem);
$("#service-previous").live("click", OpenLP.previousItem);
$("#service-blank").live("click", OpenLP.blankDisplay);
$("#service-unblank").live("click", OpenLP.unblankDisplay);
// Slide Controller
$("#slide-controller").live("pagebeforeshow", OpenLP.loadController);
$("#controller-refresh").live("click", OpenLP.loadController);
$("#controller-next").live("click", OpenLP.nextSlide);
$("#controller-previous").live("click", OpenLP.previousSlide);
$("#controller-blank").live("click", OpenLP.blankDisplay);
$("#controller-unblank").live("click", OpenLP.unblankDisplay);
// Poll the server twice a second to get any updates.
setInterval("OpenLP.pollServer();", 500);
OpenLP.pollServer();

View File

@ -47,6 +47,9 @@ the remotes.
{"results": False}
``/api/display/{hide|show}``
Blank or unblank the screen.
``/api/controller/{live|preview}/{action}``
Perform ``{action}`` on the live or preview controller. Valid actions
are:
@ -57,9 +60,9 @@ the remotes.
``previous``
Load the previous slide.
``jump``
Jump to a specific slide. Requires an id return in a JSON-encoded
dict like so::
``set``
Set a specific slide. Requires an id return in a JSON-encoded dict like
this::
{"request": {"id": 1}}
@ -82,9 +85,9 @@ the remotes.
``previous``
Load the previews item in the service.
``jump``
Jump to a specific item in the service. Requires an id returned in
a JSON-encoded dict like so::
``set``
Set a specific item in the service. Requires an id returned in a
JSON-encoded dict like this::
{"request": {"id": 1}}
@ -106,6 +109,7 @@ except ImportError:
from PyQt4 import QtCore, QtNetwork
from openlp.core.lib import Receiver
from openlp.core.ui import HideMode
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
@ -239,7 +243,8 @@ class HttpConnection(object):
(r'^/files/(.*)$', self.serve_file),
(r'^/api/poll$', self.poll),
(r'^/api/controller/(live|preview)/(.*)$', self.controller),
(r'^/api/service/(.*)$', self.service)
(r'^/api/service/(.*)$', self.service),
(r'^/api/display/(hide|show)$', self.display)
]
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'),
self.ready_read)
@ -356,7 +361,19 @@ class HttpConnection(object):
if self.parent.current_item else u''
}
return HttpResponse(json.dumps({u'results': result}),
{'Content-Type': 'application/json'})
{u'Content-Type': u'application/json'})
def display(self, action):
"""
Hide or show the display screen.
``action``
This is the action, either ``hide`` or ``show``.
"""
event = u'maindisplay_%s' % action
Receiver.send_message(event, HideMode.Blank)
return HttpResponse(json.dumps({u'results': {u'success': True}}),
{u'Content-Type': u'application/json'})
def controller(self, type, action):
"""
@ -398,14 +415,14 @@ class HttpConnection(object):
#if action == u'text':
# json_data = {u'results': }
return HttpResponse(json.dumps(json_data),
{'Content-Type': 'application/json'})
{u'Content-Type': u'application/json'})
def service(self, action):
event = u'servicemanager_%s' % action
if action == u'list':
return HttpResponse(
json.dumps({'results': self._get_service_items()}),
{'Content-Type': 'application/json'})
json.dumps({u'results': {u'items': self._get_service_items()}}),
{u'Content-Type': u'application/json'})
else:
event += u'_item'
if self.url_params and self.url_params.get(u'data'):
@ -413,114 +430,17 @@ class HttpConnection(object):
Receiver.send_message(event, data[u'request'][u'id'])
else:
Receiver.send_message(event)
return HttpResponse(json.dumps({'results': {u'success': True}}),
{'Content-Type': 'application/json'})
def process_event(self, **kwargs):
"""
Send a signal to openlp to perform an action.
Currently lets anything through. Later we should restrict and perform
basic parameter checking, otherwise rogue clients could crash openlp
"""
event = kwargs.get(u'event')
log.debug(u'Processing event %s' % event)
if self.url_params:
Receiver.send_message(event, self.url_params)
else:
Receiver.send_message(event)
return json.dumps([u'OK'])
def process_request(self, **kwargs):
"""
Client has requested data. Send the signal and parameters for openlp
to handle, then listen out for a corresponding ``_request`` signal
which will have the data to return.
For most events, timeout after 10 seconds (i.e. in case the signal
recipient isn't listening). ``remotes_poll_request`` is a special case
however, this is a ajax long poll which is just waiting for slide
change/song change activity. This can wait longer (one minute).
``event``
The event from the web page.
``params``
Parameters sent with the event.
"""
event = kwargs.get(u'event')
log.debug(u'Processing request %s' % event)
if not event.endswith(u'_request'):
return None
self.event = event
response = event.replace(u'_request', u'_response')
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(response), self.process_response)
self.timer = QtCore.QTimer()
self.timer.setSingleShot(True)
QtCore.QObject.connect(self.timer,
QtCore.SIGNAL(u'timeout()'), self.timeout)
if event == 'remotes_poll_request':
self.timer.start(60000)
else:
self.timer.start(10000)
if self.url_params:
Receiver.send_message(event, self.url_params)
else:
Receiver.send_message(event)
return None
def process_response(self, data):
"""
The recipient of a _request signal has sent data. Convert this to
json and return it to client
"""
log.debug(u'Processing response for %s' % self.event)
if not self.socket:
return
self.timer.stop()
json_data = json.dumps(data)
self.send_200_ok()
self.socket.write(json_data)
self.close()
return HttpResponse(json.dumps({u'results': {u'success': True}}),
{u'Content-Type': u'application/json'})
def send_response(self, response):
http = u'HTTP/1.1 %s\r\n' % response.code
for header in response.headers.iteritems():
http += '%s: %s\r\n' % header
for header, value in response.headers.iteritems():
http += '%s: %s\r\n' % (header, value)
http += '\r\n'
self.socket.write(http)
self.socket.write(response.content)
def send_200_ok(self, mimetype='text/html; charset="utf-8"'):
"""
Successful request. Send OK headers. Assume html for now.
"""
self.socket.write(u'HTTP/1.1 200 OK\r\n' + \
u'Content-Type: %s\r\n\r\n' % mimetype)
def send_404_not_found(self):
"""
Invalid url. Say so
"""
self.socket.write(u'HTTP/1.1 404 Not Found\r\n'+ \
u'Content-Type: text/html; charset="utf-8"\r\n' + \
u'\r\n')
def send_408_timeout(self):
"""
A _request hasn't returned anything in the timeout period.
Return timeout
"""
self.socket.write(u'HTTP/1.1 408 Request Timeout\r\n')
def timeout(self):
"""
Listener for timeout signal
"""
if not self.socket:
return
self.send_408_timeout()
self.close()
def disconnected(self):
"""
The client has disconnected. Tidy up