Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[script.logviewer@matrix] 2.1.7+matrix.1 #2649

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions script.logviewer/addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="script.logviewer" name="Log Viewer for Kodi" provider-name="i96751414" version="2.1.6+matrix.1">
<addon id="script.logviewer" name="Log Viewer for Kodi" provider-name="i96751414" version="2.1.7+matrix.1">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
</requires>
Expand All @@ -19,8 +19,8 @@
<description lang="pt_PT">Ferramenta para verificar e ler facilmente o log do Kodi.</description>
<platform>all</platform>
<news>
- Update log level regular expressions for v20.
- Small code improvements on webtail.
- Make text window skin independent
- Improve HTTP server
</news>
<assets>
<icon>icon.png</icon>
Expand Down
62 changes: 22 additions & 40 deletions script.logviewer/resources/lib/httpserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import logging
import os
import shutil
import threading

from resources.lib.logreader import LogReader
from resources.lib.logviewer import log_location
Expand All @@ -20,46 +19,47 @@


def base_handler(ctx):
with open(os.path.join(ADDON_PATH, "resources", "templates", "webtail.html"), "rb") as f:
html = f.read()

html_path = os.path.join(ADDON_PATH, "resources", "templates", "webtail.html")
ctx.send_response(200)
ctx.send_header("Content-Type", "text/html")
ctx.send_header('Content-Length', len(html))
ctx.send_header('Connection', 'keep-alive')
ctx.send_header("Content-Length", str(os.path.getsize(html_path)))
ctx.send_header("Connection", "keep-alive")
ctx.end_headers()
ctx.wfile.write(html)
with open(html_path, "rb") as f:
shutil.copyfileobj(f, ctx.wfile)


def tail_handler(ctx):
if ctx.log_path is None:
logging.error("Unable to find log path")
ctx.send_response(500)
ctx.end_headers()
ctx.send_response_and_end(500)
return

offset = int(ctx.request.get('offset', 0))
offset = int(ctx.request.get("offset", 0))
reader = LogReader(ctx.log_path)
reader.set_offset(offset)
content = encode(reader.tail())

ctx.send_response(200)
ctx.send_header("Content-Type", "text/plain")
ctx.send_header('Content-Length', len(content))
ctx.send_header('X-Seek-Offset', str(reader.get_offset()))
ctx.send_header("Content-Length", len(content))
ctx.send_header("X-Seek-Offset", str(reader.get_offset()))
ctx.end_headers()
ctx.wfile.write(content)


def favicon_handler(ctx):
favicon_path = os.path.join(ADDON_PATH, "resources", "images", "favicon.ico")
ctx.send_response(200)
ctx.send_header("Content-Type", "image/x-icon")
ctx.send_header("Content-length", str(os.path.getsize(favicon_path)))
ctx.end_headers()
with open(os.path.join(ADDON_PATH, "resources", "images", "favicon.ico"), "rb") as f:
with open(favicon_path, "rb") as f:
shutil.copyfileobj(f, ctx.wfile)


class ServerHandler(BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
log_path = log_location(False)

get_routes = {
Expand All @@ -79,40 +79,22 @@ def do_GET(self):
else:
self.send_response(404)
self.end_headers()
except BrokenPipeError as e:
raise e
except Exception as e:
logging.error(e)
self.send_response(500)
self.end_headers()

def send_response_and_end(self, code, message=None):
self.send_response(code, message=message)
self.send_header("Content-Length", "0")
self.end_headers()

def log_message(self, fmt, *args):
logging.debug(fmt % args)
logging.debug(fmt, *args)


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""

def __init__(self, *args, **kwargs):
self.__shutdown_request = threading.Event()
self.__is_shut_down = threading.Event()
self.__is_shut_down.set()
HTTPServer.__init__(self, *args, **kwargs)

def shutdown_server(self):
self.__shutdown_request.set()
self.__is_shut_down.wait()

def serve_until_shutdown(self, should_stop=None, timeout=1):
if should_stop is None:
def should_stop():
return False

if timeout is not None:
self.timeout = timeout

self.__is_shut_down.clear()
self.__shutdown_request.clear()

while not self.__shutdown_request.is_set() and not should_stop():
self.handle_request()

self.__is_shut_down.set()
pass
61 changes: 35 additions & 26 deletions script.logviewer/resources/lib/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
class Monitor(xbmc.Monitor):
def __init__(self):
super(Monitor, self).__init__()
self._running = False
self._port = utils.get_int_setting("port")
self._error_popup_runner = None
self._http_server_runner = None
self._lock = threading.Lock()

def start(self):
self._running = True
self.onSettingsChanged()

def stop(self):
self._running = False
self._stop_error_popup_runner()
self._stop_http_server_runner()
with self._lock:
self._stop_error_popup_runner()
self._stop_http_server_runner()

def _start_error_popup_runner(self):
if self._error_popup_runner is None:
Expand All @@ -37,49 +37,61 @@ def _stop_error_popup_runner(self):
if self._error_popup_runner is not None:
logging.debug("Stopping error popup runner")
self._error_popup_runner.stop()
self._error_popup_runner.join()
self._error_popup_runner = None

def _start_http_server_runner(self):
if self._http_server_runner is None:
logging.debug("Starting http server runner")
self._http_server_runner = HTTPServerRunner(self, utils.get_int_setting("port"))
self._http_server_runner = HTTPServerRunner(self._port)
self._http_server_runner.start()

def _stop_http_server_runner(self):
if self._http_server_runner is not None:
logging.debug("Stopping http server runner")
self._http_server_runner.stop()
self._http_server_runner.join()
self._http_server_runner = None

def onSettingsChanged(self):
if self._running:
self._start_error_popup_runner() if utils.get_boolean_setting(
"error_popup") else self._stop_error_popup_runner()
with self._lock:
http_port = utils.get_int_setting("port")
run_http_server = utils.get_boolean_setting("http_server")
run_error_popup = utils.get_boolean_setting("error_popup")

if run_http_server:
if http_port != self._port:
self._port = http_port
self._stop_http_server_runner()
self._start_http_server_runner()
else:
self._stop_http_server_runner()

self._start_http_server_runner() if utils.get_boolean_setting(
"http_server") else self._stop_http_server_runner()
if run_error_popup:
self._start_error_popup_runner()
else:
self._stop_error_popup_runner()


class HTTPServerRunner(threading.Thread):
def __init__(self, monitor, port):
self._monitor = monitor
def __init__(self, port):
self._port = port
self._server = None
super(HTTPServerRunner, self).__init__()

def run(self):
self._server = ThreadedHTTPServer(("", self._port), ServerHandler)
self._server.daemon_threads = True

logging.debug("Server started at port {}".format(self._port))
logging.debug("Local IP: {}".format(xbmc.getIPAddress()))

self._server.serve_until_shutdown(self._monitor.abortRequested)
self._server.server_close()
self._server = server = ThreadedHTTPServer(("", self._port), ServerHandler)
logging.debug("Server started at port %d", self._port)
logging.debug("Local IP is %s", xbmc.getIPAddress())
server.serve_forever()
logging.debug("Closing server")
server.server_close()
logging.debug("Server terminated")

def stop(self):
if self._server is not None:
self._server.shutdown_server()
self._server.shutdown()
self._server = None


class ErrorPopupRunner(threading.Thread):
Expand All @@ -106,17 +118,14 @@ def run(self):
# Ignore initial errors
reader.tail()

while not self._monitor.abortRequested() and self._running:
while not self._monitor.waitForAbort(1) and self._running:
content = reader.tail()
parsed_errors = logviewer.parse_errors(content, set_style=True, exceptions_only=exceptions)
if parsed_errors:
logviewer.window(utils.ADDON_NAME, parsed_errors, default=utils.is_default_window())
self._monitor.waitForAbort(1)

def stop(self):
self._running = False
# Wait for thread to stop
self.join()


def run(start_delay=20):
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
<!-- 1280 x 720 -->
<include>Animation_DialogPopupOpenClose</include>
<depth>DepthOSD</depth>
<animation type="WindowOpen" reversible="false">
<effect type="zoom" start="80" end="100" center="50%,50%" delay="160" tween="back" time="240"/>
<effect type="fade" delay="160" end="100" time="240"/>
</animation>
<animation type="WindowClose" reversible="false">
<effect type="zoom" start="100" end="80" center="50%,50%" easing="in" tween="back" time="240"/>
<effect type="fade" start="100" end="0" time="240"/>
</animation>
<depth>0.40</depth>
<defaultcontrol always="true">32500</defaultcontrol>
<controls>
<control type="group">
Expand All @@ -21,7 +28,7 @@
<top>30</top>
<width>32</width>
<height>32</height>
<texturefocus colordiffuse="button_focus">Button/close.png</texturefocus>
<texturefocus colordiffuse="FF12A0C7">Button/close.png</texturefocus>
<texturenofocus colordiffuse="EEFFFFFF">Button/close.png</texturenofocus>
<ondown>32502</ondown>
</control>
Expand All @@ -46,6 +53,11 @@
<top>100</top>
<width>10</width>
<height>580</height>
<texturesliderbackground colordiffuse="29FFFFFF">AddonWindow/white.png</texturesliderbackground>
<texturesliderbar colordiffuse="FFAAAAAA">AddonWindow/white.png</texturesliderbar>
<texturesliderbarfocus colordiffuse="FF12A0C7">AddonWindow/white.png</texturesliderbarfocus>
<textureslidernib/>
<textureslidernibfocus/>
<onup>32500</onup>
<showonepage>false</showonepage>
<orientation>vertical</orientation>
Expand Down
Loading
Loading