forked from openlp/openlp
move files
This commit is contained in:
parent
5a0f2f1781
commit
dc4d7fcfb1
@ -20,10 +20,8 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from .errors import NotFound, ServerError
|
from .errors import NotFound, ServerError, HttpError
|
||||||
from .httprouter import WSGIApplication
|
from .http import WSGIApplication, application
|
||||||
|
|
||||||
application = WSGIApplication('api')
|
|
||||||
|
|
||||||
|
|
||||||
def _route_from_url(url_prefix, url):
|
def _route_from_url(url_prefix, url):
|
||||||
@ -49,9 +47,8 @@ def register_endpoint(end_point):
|
|||||||
|
|
||||||
from .endpoint import Endpoint
|
from .endpoint import Endpoint
|
||||||
from .apitab import ApiTab
|
from .apitab import ApiTab
|
||||||
from .poll import Poll
|
from .websockets import WsServer, Poll
|
||||||
from .wsserver import WsServer
|
from .http import HttpServer
|
||||||
from .httpserver import HttpServer
|
|
||||||
from .apicontroller import ApiController
|
from .apicontroller import ApiController
|
||||||
|
|
||||||
__all__ = ['Poll', 'ApiController', 'HttpServer', 'application']
|
__all__ = ['Poll', 'ApiController', 'HttpServer', 'application']
|
||||||
|
@ -19,20 +19,64 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
"""
|
"""
|
||||||
App stuff
|
The :mod:`http` module contains the API web server. This is a lightweight web server used by remotes to interact
|
||||||
|
with OpenLP. It uses JSON to communicate with the remotes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from PyQt5 import QtCore
|
||||||
|
from waitress import serve
|
||||||
from webob import Request, Response
|
from webob import Request, Response
|
||||||
|
|
||||||
from .errors import HttpError, NotFound, ServerError
|
from openlp.core.api import NotFound, ServerError, HttpError
|
||||||
|
from openlp.core.common import RegistryProperties, OpenLPMixin
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class HttpThread(QtCore.QObject):
|
||||||
|
"""
|
||||||
|
A special Qt thread class to allow the HTTP server to run at the same time as the UI.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Constructor for the thread class.
|
||||||
|
|
||||||
|
:param server: The http server class.
|
||||||
|
"""
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Run the thread.
|
||||||
|
"""
|
||||||
|
serve(application, host='0.0.0.0', port=4318)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class HttpServer(RegistryProperties, OpenLPMixin):
|
||||||
|
"""
|
||||||
|
Wrapper round a server instance
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Initialise the http server, and start the http server
|
||||||
|
"""
|
||||||
|
super(HttpServer, self).__init__()
|
||||||
|
self.thread = QtCore.QThread()
|
||||||
|
self.worker = HttpThread()
|
||||||
|
self.worker.moveToThread(self.thread)
|
||||||
|
self.thread.started.connect(self.worker.start)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
|
||||||
def _make_response(view_result):
|
def _make_response(view_result):
|
||||||
"""
|
"""
|
||||||
Create a Response object from response
|
Create a Response object from response
|
||||||
@ -123,3 +167,5 @@ class WSGIApplication(object):
|
|||||||
"""
|
"""
|
||||||
return self.wsgi_app(environ, start_response)
|
return self.wsgi_app(environ, start_response)
|
||||||
|
|
||||||
|
|
||||||
|
application = WSGIApplication('api')
|
@ -1,74 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# OpenLP - Open Source Lyrics Projection #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# 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; version 2 of the License. #
|
|
||||||
# #
|
|
||||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
"""
|
|
||||||
The :mod:`http` module contains the API web server. This is a lightweight web server used by remotes to interact
|
|
||||||
with OpenLP. It uses JSON to communicate with the remotes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from PyQt5 import QtCore
|
|
||||||
from waitress import serve
|
|
||||||
|
|
||||||
from openlp.core.api import application
|
|
||||||
from openlp.core.common import RegistryProperties, OpenLPMixin
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class HttpThread(QtCore.QObject):
|
|
||||||
"""
|
|
||||||
A special Qt thread class to allow the HTTP server to run at the same time as the UI.
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Constructor for the thread class.
|
|
||||||
|
|
||||||
:param server: The http server class.
|
|
||||||
"""
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""
|
|
||||||
Run the thread.
|
|
||||||
"""
|
|
||||||
serve(application, host='0.0.0.0', port=4318)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class HttpServer(RegistryProperties, OpenLPMixin):
|
|
||||||
"""
|
|
||||||
Wrapper round a server instance
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Initialise the http server, and start the http server
|
|
||||||
"""
|
|
||||||
super(HttpServer, self).__init__()
|
|
||||||
self.thread = QtCore.QThread()
|
|
||||||
self.worker = HttpThread()
|
|
||||||
self.worker.moveToThread(self.thread)
|
|
||||||
self.thread.started.connect(self.worker.start)
|
|
||||||
self.thread.start()
|
|
@ -29,6 +29,7 @@ import asyncio
|
|||||||
import websockets
|
import websockets
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
|
|
||||||
@ -149,3 +150,39 @@ class WsServer(RegistryProperties, OpenLPMixin):
|
|||||||
self.http_thread.stop()
|
self.http_thread.stop()
|
||||||
self.httpd = None
|
self.httpd = None
|
||||||
log.debug('Stopped the server.')
|
log.debug('Stopped the server.')
|
||||||
|
class Poll(RegistryProperties):
|
||||||
|
"""
|
||||||
|
Access by the web layer to get status type information from the application
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Constructor for the poll builder class.
|
||||||
|
"""
|
||||||
|
super(Poll, self).__init__()
|
||||||
|
|
||||||
|
def poll(self):
|
||||||
|
"""
|
||||||
|
Poll OpenLP to determine the current slide number and item name.
|
||||||
|
"""
|
||||||
|
result = {
|
||||||
|
'service': self.service_manager.service_id,
|
||||||
|
'slide': self.live_controller.selected_row or 0,
|
||||||
|
'item': self.live_controller.service_item.unique_identifier if self.live_controller.service_item else '',
|
||||||
|
'twelve': Settings().value('remotes/twelve hour'),
|
||||||
|
'blank': self.live_controller.blank_screen.isChecked(),
|
||||||
|
'theme': self.live_controller.theme_screen.isChecked(),
|
||||||
|
'display': self.live_controller.desktop_screen.isChecked(),
|
||||||
|
'version': 2,
|
||||||
|
'isSecure': Settings().value('remotes/authentication enabled'),
|
||||||
|
'isAuthorised': False
|
||||||
|
}
|
||||||
|
return json.dumps({'results': result}).encode()
|
||||||
|
|
||||||
|
def main_poll(self):
|
||||||
|
"""
|
||||||
|
Poll OpenLP to determine the current slide count.
|
||||||
|
"""
|
||||||
|
result = {
|
||||||
|
'slide_count': self.live_controller.slide_count
|
||||||
|
}
|
||||||
|
return json.dumps({'results': result}).encode()
|
@ -143,7 +143,7 @@ class HttpRouter(RegistryProperties, OpenLPMixin):
|
|||||||
"""
|
"""
|
||||||
auth_code = "{user}:{password}".format(user=Settings().value('remotes/user id'),
|
auth_code = "{user}:{password}".format(user=Settings().value('remotes/user id'),
|
||||||
password=Settings().value('remotes/password'))
|
password=Settings().value('remotes/password'))
|
||||||
self.openlppoll = Registry().get('OpenLPPoll')
|
self.openlppoll = Registry().get('api_poll')
|
||||||
try:
|
try:
|
||||||
self.auth = base64.b64encode(auth_code)
|
self.auth = base64.b64encode(auth_code)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -34,8 +34,8 @@ class TestHttpServer(TestCase):
|
|||||||
"""
|
"""
|
||||||
A test suite to test starting the http server
|
A test suite to test starting the http server
|
||||||
"""
|
"""
|
||||||
@patch('openlp.core.api.httpserver.HttpThread')
|
@patch('openlp.core.api.http.HttpThread')
|
||||||
@patch('openlp.core.api.httpserver.QtCore.QThread')
|
@patch('openlp.core.api.http.QtCore.QThread')
|
||||||
def test_serverstart(self, mock_qthread, mock_thread):
|
def test_serverstart(self, mock_qthread, mock_thread):
|
||||||
"""
|
"""
|
||||||
Test the starting of the Waitress Server
|
Test the starting of the Waitress Server
|
@ -20,14 +20,14 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
This module contains tests for the lib submodule of the Remotes plugin.
|
Functional tests to test the Http Server Class.
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from openlp.core.common import Registry, Settings
|
from openlp.core.common import Registry, Settings
|
||||||
from openlp.core.api.poll import Poll
|
from openlp.core.api import Poll, WsServer
|
||||||
from tests.functional import MagicMock
|
from tests.functional import MagicMock, patch
|
||||||
from tests.helpers.testmixin import TestMixin
|
from tests.helpers.testmixin import TestMixin
|
||||||
|
|
||||||
__default_settings__ = {
|
__default_settings__ = {
|
||||||
@ -41,9 +41,9 @@ __default_settings__ = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestOpenLPPoll(TestCase, TestMixin):
|
class TestWSServer(TestCase, TestMixin):
|
||||||
"""
|
"""
|
||||||
Test the functions in the :mod:`lib` module.
|
A test suite to test starting the websocket server
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""
|
"""
|
||||||
@ -60,6 +60,21 @@ class TestOpenLPPoll(TestCase, TestMixin):
|
|||||||
"""
|
"""
|
||||||
self.destroy_settings()
|
self.destroy_settings()
|
||||||
|
|
||||||
|
|
||||||
|
@patch('openlp.core.api.websockets.WSThread')
|
||||||
|
@patch('openlp.core.api.websockets.QtCore.QThread')
|
||||||
|
def test_serverstart(self, mock_qthread, mock_thread):
|
||||||
|
"""
|
||||||
|
Test the starting of the WebSockets Server
|
||||||
|
"""
|
||||||
|
# GIVEN: A new httpserver
|
||||||
|
# WHEN: I start the server
|
||||||
|
server = WsServer()
|
||||||
|
|
||||||
|
# THEN: the api environment should have been created
|
||||||
|
self.assertEquals(1, mock_qthread.call_count, 'The qthread should have been called once')
|
||||||
|
self.assertEquals(1, mock_thread.call_count, 'The http thread should have been called once')
|
||||||
|
|
||||||
def test_main_poll(self):
|
def test_main_poll(self):
|
||||||
"""
|
"""
|
||||||
Test the main_poll function returns the correct JSON
|
Test the main_poll function returns the correct JSON
|
@ -1,49 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# OpenLP - Open Source Lyrics Projection #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# 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; version 2 of the License. #
|
|
||||||
# #
|
|
||||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
|
||||||
###############################################################################
|
|
||||||
"""
|
|
||||||
Functional tests to test the Http Server Class.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
from openlp.core.api import WsServer
|
|
||||||
|
|
||||||
from tests.functional import patch
|
|
||||||
|
|
||||||
|
|
||||||
class TestWSServer(TestCase):
|
|
||||||
"""
|
|
||||||
A test suite to test starting the websocket server
|
|
||||||
"""
|
|
||||||
@patch('openlp.core.api.wsserver.WSThread')
|
|
||||||
@patch('openlp.core.api.wsserver.QtCore.QThread')
|
|
||||||
def test_serverstart(self, mock_qthread, mock_thread):
|
|
||||||
"""
|
|
||||||
Test the starting of the WebSockets Server
|
|
||||||
"""
|
|
||||||
# GIVEN: A new httpserver
|
|
||||||
# WHEN: I start the server
|
|
||||||
server = WsServer()
|
|
||||||
|
|
||||||
# THEN: the api environment should have been created
|
|
||||||
self.assertEquals(1, mock_qthread.call_count, 'The qthread should have been called once')
|
|
||||||
self.assertEquals(1, mock_thread.call_count, 'The http thread should have been called once')
|
|
Loading…
Reference in New Issue
Block a user