uds actor advance

This commit is contained in:
Adolfo Gómez García 2019-12-05 09:40:06 +01:00
parent 6402106d85
commit b78a41f0d3
8 changed files with 128 additions and 20 deletions

View File

@ -37,7 +37,7 @@ import PyQt5 # pylint: disable=unused-import
from PyQt5.QtWidgets import QApplication
from udsactor.log import logger, DEBUG
from udsactor.client import UDSActorClient
if __name__ == "__main__":
logger.setLevel(DEBUG)
@ -49,6 +49,12 @@ if __name__ == "__main__":
QApplication.setQuitOnLastWindowClosed(False)
app = QApplication(sys.argv)
qApp = QApplication(sys.argv)
# Execute backgroup thread for actions
app = UDSActorClient(qApp)
app.start()
qApp.exec_()
app.join()

View File

@ -35,4 +35,4 @@ from . import platform
__title__ = 'udsactor'
__author__ = 'Adolfo Gómez <dkmaster@dkmon.com>'
__license__ = "BSD 3-clause"
__copyright__ = "Copyright 2014-2019 VirtualCable S.L.U."
__copyright__ = "Copyright 2014-2020 VirtualCable S.L.U."

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import threading
import time
import typing
from PyQt5.QtWidgets import QApplication, QMessageBox
from . import rest
from . import tools
from . import platform
from .log import logger
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from . import types
class UDSActorClient(threading.Thread):
_running: bool
_forceLogoff: bool
_qApp: QApplication
_api: rest.UDSClientApi
def __init__(self, qApp: QApplication):
super().__init__()
self._api = rest.UDSClientApi() # Self initialized
self._qApp = qApp
self._running = False
self._forceLogoff = False
def run(self):
self._running = True
# Notify loging and mark it
self._api.login(platform.operations.getCurrentUser())
while self._running:
time.sleep(1.1) # Sleep between loop iteration
self._api.logout(platform.operations.getCurrentUser())
# Notify Qapllication to exit
QApplication.quit()
if self._forceLogoff:
platform.operations.loggoff()
def _showMessage(self, message: str) -> None:
QMessageBox.information(None, 'Message', message)
def stop(self) -> None:
logger.debug('Stopping client Service')
self._running = False
def logout(self) -> typing.Any:
self._forceLogoff = True
self._running = False
return 'ok'
def message(self, msg: str) -> typing.Any:
threading.Thread(target=self._showMessage, args=(msg,)).start()
return 'ok'
def screenshot(self) -> typing.Any:
pass
def script(self, script: str) -> typing.Any:
tools.ScriptExecutorThread(script).start()
return 'ok'

View File

@ -38,7 +38,7 @@ from ..log import logger
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
UDSActorClient = typing.Any
from ..client import UDSActorClient
class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.0'
@ -101,6 +101,9 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
def method_screenshot(self, params: typing.MutableMapping[str, str]) -> typing.Any:
return self._app.screenshot()
def method_script(self, params: typing.MutableMapping[str, str]) -> typing.Any:
return self._app.script(params['script'])
def do_GET(self) -> None:
self.sendJsonResponse(error='Forbidden', code=403)

View File

@ -37,6 +37,7 @@ import typing
from ..log import logger
from .. import certs
from .. import rest
from .public import PublicProvider
from .local import LocalProvider
@ -151,12 +152,12 @@ class HTTPServerThread(threading.Thread):
self._certFile, password = certs.saveCertificate(self._service._certificate) # pylint: disable=protected-access
self._server = http.server.HTTPServer(('0.0.0.0', rest.LISTEN_PORT), HTTPServerHandler)
# self._server.socket = ssl.wrap_socket(self._server.socket, certfile=self.certFile, server_side=True)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.options = ssl.CERT_NONE
context.load_cert_chain(self._certFile, password=password)
self._server = http.server.HTTPServer(('0.0.0.0', self._service._cfg.port), HTTPServerHandler) # pylint: disable=protected-access
# self._server.socket = ssl.wrap_socket(self._server.socket, certfile=self.certFile, server_side=True)
self._server.socket = context.wrap_socket(self._server.socket, server_side=True)
self._server.serve_forever()

View File

@ -39,6 +39,9 @@ import requests
from . import types
from .info import VERSION
# Default public listen port
LISTEN_PORT = 43910
class RESTError(Exception):
ERRCODE = 0
@ -59,9 +62,9 @@ class RESTOsManagerError(RESTError):
ERRCODE = 4
#
# Basic UDS Api
#
#
class UDSApi:
class UDSApi: # pylint: disable=too-few-public-methods
"""
Base for remote api accesses
"""
@ -258,6 +261,9 @@ class UDSServerApi(UDSApi):
class UDSClientApi(UDSApi):
def __init__(self) -> None:
super().__init__('127.0.0.1:{}'.format(LISTEN_PORT), False)
def register(self, callbackUrl: str) -> None:
payLoad = {
'callback_url': callbackUrl

View File

@ -1,8 +1,5 @@
import typing
# Default public listen port
LISTEN_PORT = 43910
class InterfaceInfoType(typing.NamedTuple):
name: str
mac: str
@ -41,8 +38,6 @@ class ActorConfigurationType(typing.NamedTuple):
log_level: int = 0
port: int = LISTEN_PORT
config: typing.Optional[ActorDataConfigurationType] = None
data: typing.Optional[typing.Dict[str, typing.Any]] = None

View File

@ -208,12 +208,10 @@ def getIdleDuration() -> float:
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo) # pylint: disable=attribute-defined-outside-init
if ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lastInputInfo)) == 0:
return 0
# if lastInputInfo.dwTime > 1000000000: # Value toooo high, nonsense...
# return 0
current = ctypes.c_uint(ctypes.windll.kernel32.GetTickCount())
millis = current.value - lastInputInfo.dwTime # @UndefinedVariable
if millis < 0:
return 0
current = ctypes.c_uint(ctypes.windll.kernel32.GetTickCount()).value
if current < lastInputInfo.dwTime:
current += 4294967296 # If current has "rolled" to zero, adjust it so it is greater than lastInputInfo
millis = current - lastInputInfo.dwTime # @UndefinedVariable
return millis / 1000.0
except Exception as e:
logger.error('Getting idle duration: {}'.format(e))