openlp/openlp/core/api/http/server.py

178 lines
7.3 KiB
Python
Raw Normal View History

2016-06-04 10:50:43 +00:00
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2017-12-29 09:15:48 +00:00
# Copyright (c) 2008-2018 OpenLP Developers #
2016-06-04 10:50:43 +00:00
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
2016-06-05 21:16:13 +00:00
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.
"""
2016-06-05 16:20:39 +00:00
import logging
2017-09-26 21:18:09 +00:00
import time
2017-09-26 21:18:09 +00:00
from PyQt5 import QtCore, QtWidgets
from waitress import serve
2017-09-26 21:18:09 +00:00
from openlp.core.api.deploy import download_and_check, download_sha256
2016-08-13 05:18:46 +00:00
from openlp.core.api.endpoint.controller import controller_endpoint, api_controller_endpoint
2017-06-18 05:21:23 +00:00
from openlp.core.api.endpoint.core import chords_endpoint, stage_endpoint, blank_endpoint, main_endpoint
2017-09-26 21:04:39 +00:00
from openlp.core.api.endpoint.remote import remote_endpoint
2017-12-28 08:27:44 +00:00
from openlp.core.api.endpoint.service import service_endpoint, api_service_endpoint
2017-10-07 07:05:07 +00:00
from openlp.core.api.http import application
2017-12-28 08:27:44 +00:00
from openlp.core.api.http import register_endpoint
2017-10-07 07:05:07 +00:00
from openlp.core.api.poll import Poller
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings
from openlp.core.common.i18n import translate
2017-10-23 22:09:57 +00:00
from openlp.core.common.mixins import LogMixin, RegistryProperties
2017-10-07 07:05:07 +00:00
from openlp.core.common.path import create_paths
2017-10-23 22:09:57 +00:00
from openlp.core.common.registry import Registry, RegistryBase
2017-10-07 07:05:07 +00:00
from openlp.core.common.settings import Settings
from openlp.core.threading import ThreadWorker, run_thread
2016-06-05 16:20:39 +00:00
log = logging.getLogger(__name__)
2016-06-04 10:50:43 +00:00
class HttpWorker(ThreadWorker):
"""
2016-06-05 21:16:13 +00:00
A special Qt thread class to allow the HTTP server to run at the same time as the UI.
"""
def start(self):
2016-06-04 10:50:43 +00:00
"""
2016-06-05 21:16:13 +00:00
Run the thread.
"""
2016-07-09 11:21:25 +00:00
address = Settings().value('api/ip address')
port = Settings().value('api/port')
2017-09-27 18:56:21 +00:00
Registry().execute('get_website_version')
try:
serve(application, host=address, port=port)
except OSError:
log.exception('An error occurred when serving the application.')
self.quit.emit()
2017-10-23 22:09:57 +00:00
class HttpServer(RegistryBase, RegistryProperties, LogMixin):
"""
2016-06-05 21:16:13 +00:00
Wrapper round a server instance
"""
2016-08-13 05:18:46 +00:00
def __init__(self, parent=None):
"""
2016-06-13 19:51:46 +00:00
Initialise the http server, and start the http server
"""
2016-08-13 05:18:46 +00:00
super(HttpServer, self).__init__(parent)
2017-12-02 09:11:22 +00:00
if Registry().get_flag('no_web_server'):
worker = HttpWorker()
run_thread(worker, 'http_server')
2017-12-02 09:11:22 +00:00
Registry().register_function('download_website', self.first_time)
Registry().register_function('get_website_version', self.website_version)
2017-09-29 18:53:04 +00:00
Registry().set_flag('website_version', '0.0')
2016-08-13 05:18:46 +00:00
def bootstrap_post_set_up(self):
"""
Register the poll return service and start the servers.
"""
2017-09-26 21:18:09 +00:00
self.initialise()
2016-08-13 05:18:46 +00:00
self.poller = Poller()
Registry().register('poller', self.poller)
2016-12-17 06:58:44 +00:00
application.initialise()
2016-08-13 05:18:46 +00:00
register_endpoint(controller_endpoint)
register_endpoint(api_controller_endpoint)
2017-06-18 05:21:23 +00:00
register_endpoint(chords_endpoint)
2016-08-13 05:18:46 +00:00
register_endpoint(stage_endpoint)
register_endpoint(blank_endpoint)
register_endpoint(main_endpoint)
register_endpoint(service_endpoint)
register_endpoint(api_service_endpoint)
2017-09-26 21:04:39 +00:00
register_endpoint(remote_endpoint)
2017-09-26 21:18:09 +00:00
@staticmethod
def initialise():
"""
Create the internal file structure if it does not exist
:return:
"""
2017-10-07 07:05:07 +00:00
create_paths(AppLocation.get_section_data_path('remotes') / 'assets',
AppLocation.get_section_data_path('remotes') / 'images',
AppLocation.get_section_data_path('remotes') / 'static',
AppLocation.get_section_data_path('remotes') / 'static' / 'index',
AppLocation.get_section_data_path('remotes') / 'templates')
2017-09-26 21:18:09 +00:00
def first_time(self):
"""
Import web site code if active
"""
self.application.process_events()
2017-09-29 18:53:04 +00:00
progress = DownloadProgressDialog(self)
2017-09-26 21:18:09 +00:00
progress.forceShow()
self.application.process_events()
time.sleep(1)
download_and_check(progress)
self.application.process_events()
time.sleep(1)
progress.close()
self.application.process_events()
Settings().setValue('remotes/download version', self.version)
def website_version(self):
"""
Download and save the website version and sha256
:return: None
"""
sha256, self.version = download_sha256()
Registry().set_flag('website_sha256', sha256)
Registry().set_flag('website_version', self.version)
2017-09-29 18:53:04 +00:00
class DownloadProgressDialog(QtWidgets.QProgressDialog):
2017-09-26 21:18:09 +00:00
"""
Local class to handle download display based and supporting httputils:get_web_page
"""
def __init__(self, parent):
2017-09-29 18:53:04 +00:00
super(DownloadProgressDialog, self).__init__(parent.main_window)
2017-09-26 21:18:09 +00:00
self.parent = parent
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle(translate('RemotePlugin', 'Importing Website'))
self.setLabelText(UiStrings().StartingImport)
self.setCancelButton(None)
self.setRange(0, 1)
self.setMinimumDuration(0)
self.was_cancelled = False
self.previous_size = 0
2018-01-04 06:01:35 +00:00
def update_progress(self, count, block_size):
2017-09-26 21:18:09 +00:00
"""
Calculate and display the download progress.
"""
increment = (count * block_size) - self.previous_size
self._increment_progress_bar(None, increment)
self.previous_size = count * block_size
def _increment_progress_bar(self, status_text, increment=1):
"""
Update the wizard progress page.
:param status_text: Current status information to display.
:param increment: The value to increment the progress bar by.
"""
if status_text:
self.setText(status_text)
if increment > 0:
self.setValue(self.value() + increment)
2017-09-27 19:21:08 +00:00
self.parent.application.process_events()