Skip to content

Commit

Permalink
[script.logviewer] 2.1.7+matrix.1 (#2649)
Browse files Browse the repository at this point in the history
  • Loading branch information
i96751414 authored Oct 5, 2024
1 parent 401cff8 commit 7008f31
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 219 deletions.
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

0 comments on commit 7008f31

Please sign in to comment.