Don't create unnecessary additional context, settings and Addon instances in service

This commit is contained in:
MoojMidge 2024-05-19 14:28:04 +10:00
parent 1d92d46054
commit 936a23b167
7 changed files with 82 additions and 84 deletions

View file

@ -12,24 +12,23 @@ from __future__ import absolute_import, division, unicode_literals
import json
import threading
from ..compatibility import xbmc, xbmcaddon, xbmcgui
from ..compatibility import xbmc, xbmcgui
from ..constants import ADDON_ID, CHECK_SETTINGS, REFRESH_CONTAINER, WAKEUP
from ..logger import log_debug
from ..network import get_connect_address, get_http_server, httpd_status
from ..settings import XbmcPluginSettings
class ServiceMonitor(xbmc.Monitor):
_settings = XbmcPluginSettings(xbmcaddon.Addon(ADDON_ID))
_settings_changes = 0
_settings_state = None
def __init__(self):
settings = self._settings
def __init__(self, context):
self._context = context
settings = context.get_settings()
self._use_httpd = (settings.use_isa()
or settings.api_config_page()
or settings.support_alternative_player())
address, port = get_connect_address()
address, port = get_connect_address(self._context)
self._old_httpd_address = self._httpd_address = address
self._old_httpd_port = self._httpd_port = port
self._whitelist = settings.httpd_whitelist()
@ -90,8 +89,7 @@ class ServiceMonitor(xbmc.Monitor):
log_debug('onSettingsChanged: {0} change(s)'.format(changes))
self._settings_changes = 0
settings = self._settings
settings.flush(xbmcaddon.Addon(ADDON_ID))
settings = self._context.get_settings(refresh=True)
xbmcgui.Window(10000).setProperty(
'-'.join((ADDON_ID, CHECK_SETTINGS)), 'true'
@ -103,7 +101,7 @@ class ServiceMonitor(xbmc.Monitor):
use_httpd = (settings.use_isa()
or settings.api_config_page()
or settings.support_alternative_player())
address, port = get_connect_address()
address, port = get_connect_address(self._context)
whitelist = settings.httpd_whitelist()
whitelist_changed = whitelist != self._whitelist
@ -147,7 +145,8 @@ class ServiceMonitor(xbmc.Monitor):
.format(ip=self._httpd_address, port=self._httpd_port))
self.httpd_address_sync()
self.httpd = get_http_server(address=self._httpd_address,
port=self._httpd_port)
port=self._httpd_port,
context=self._context)
if not self.httpd:
return
@ -180,10 +179,7 @@ class ServiceMonitor(xbmc.Monitor):
self.start_httpd()
def ping_httpd(self):
return self.httpd and httpd_status()
return self.httpd and httpd_status(self._context)
def httpd_required(self):
return self._use_httpd
def tear_down(self):
self._settings.flush()

View file

@ -23,27 +23,17 @@ from ..compatibility import (
parse_qs,
urlsplit,
xbmc,
xbmcaddon,
xbmcgui,
xbmcvfs,
)
from ..constants import ADDON_ID, TEMP_PATH, paths
from ..logger import log_debug, log_error
from ..settings import XbmcPluginSettings
from ..utils import validate_ip_address, wait
_addon = xbmcaddon.Addon(ADDON_ID)
_settings = XbmcPluginSettings(_addon)
_i18n = _addon.getLocalizedString
_addon_name = _addon.getAddonInfo('name')
_addon_icon = _addon.getAddonInfo('icon')
del _addon
_server_requests = BaseRequestsClass()
class RequestHandler(BaseHTTPRequestHandler, object):
_context = None
requests = BaseRequestsClass()
BASE_PATH = xbmcvfs.translatePath(TEMP_PATH)
chunk_size = 1024 * 64
local_ranges = (
@ -56,7 +46,7 @@ class RequestHandler(BaseHTTPRequestHandler, object):
)
def __init__(self, *args, **kwargs):
self.whitelist_ips = _settings.httpd_whitelist()
self.whitelist_ips = self._context.get_settings().httpd_whitelist()
super(RequestHandler, self).__init__(*args, **kwargs)
def connection_allowed(self):
@ -85,7 +75,9 @@ class RequestHandler(BaseHTTPRequestHandler, object):
# noinspection PyPep8Naming
def do_GET(self):
api_config_enabled = _settings.api_config_page()
settings = self._context.get_settings()
localize = self._context.localize
api_config_enabled = settings.api_config_page()
# Strip trailing slash if present
stripped_path = self.path.rstrip('/')
@ -146,7 +138,10 @@ class RequestHandler(BaseHTTPRequestHandler, object):
api_id = params.get('api_id', [None])[0]
api_secret = params.get('api_secret', [None])[0]
# Bookmark this page
footer = _i18n(30638) if api_key and api_id and api_secret else ''
if api_key and api_id and api_secret:
footer = localize(30638)
else:
footer = ''
if re.search(r'api_key=(?:&|$)', query):
api_key = ''
@ -155,29 +150,29 @@ class RequestHandler(BaseHTTPRequestHandler, object):
if re.search(r'api_secret=(?:&|$)', query):
api_secret = ''
if api_key is not None and api_key != _settings.api_key():
_settings.api_key(new_key=api_key)
updated.append(_i18n(30201)) # API Key
if api_key is not None and api_key != settings.api_key():
settings.api_key(new_key=api_key)
updated.append(localize(30201)) # API Key
if api_id is not None and api_id != _settings.api_id():
_settings.api_id(new_id=api_id)
updated.append(_i18n(30202)) # API ID
if api_id is not None and api_id != settings.api_id():
settings.api_id(new_id=api_id)
updated.append(localize(30202)) # API ID
if api_secret is not None and api_secret != _settings.api_secret():
_settings.api_secret(new_secret=api_secret)
updated.append(_i18n(30203)) # API Secret
if api_secret is not None and api_secret != settings.api_secret():
settings.api_secret(new_secret=api_secret)
updated.append(localize(30203)) # API Secret
if api_key and api_id and api_secret:
enabled = _i18n(30636) # Personal keys enabled
enabled = localize(30636) # Personal keys enabled
else:
enabled = _i18n(30637) # Personal keys disabled
enabled = localize(30637) # Personal keys disabled
if updated:
# Successfully updated
updated = _i18n(30631) % ', '.join(updated)
updated = localize(30631) % ', '.join(updated)
else:
# No changes, not updated
updated = _i18n(30635)
updated = localize(30635)
html = self.api_submit_page(updated, enabled, footer)
html = html.encode('utf-8')
@ -262,11 +257,11 @@ class RequestHandler(BaseHTTPRequestHandler, object):
'Authorization': 'Bearer %s' % lic_token
}
response = _server_requests.request(lic_url,
method='POST',
headers=li_headers,
data=post_data,
stream=True)
response = self.requests.request(lic_url,
method='POST',
headers=li_headers,
data=post_data,
stream=True)
if not response or not response.ok:
self.send_error(response and response.status_code or 500)
return
@ -328,38 +323,41 @@ class RequestHandler(BaseHTTPRequestHandler, object):
for i in range(0, len(data), self.chunk_size):
yield data[i:i + self.chunk_size]
@staticmethod
def api_config_page():
api_key = _settings.api_key()
api_id = _settings.api_id()
api_secret = _settings.api_secret()
@classmethod
def api_config_page(cls):
settings = cls._context.get_settings()
localize = cls._context.localize
api_key = settings.api_key()
api_id = settings.api_id()
api_secret = settings.api_secret()
html = Pages.api_configuration.get('html')
css = Pages.api_configuration.get('css')
html = html.format(
css=css,
title=_i18n(30634), # YouTube Add-on API Configuration
api_key_head=_i18n(30201), # API Key
api_id_head=_i18n(30202), # API ID
api_secret_head=_i18n(30203), # API Secret
title=localize(30634), # YouTube Add-on API Configuration
api_key_head=localize(30201), # API Key
api_id_head=localize(30202), # API ID
api_secret_head=localize(30203), # API Secret
api_id_value=api_id,
api_key_value=api_key,
api_secret_value=api_secret,
submit=_i18n(30630), # Save
header=_i18n(30634), # YouTube Add-on API Configuration
submit=localize(30630), # Save
header=localize(30634), # YouTube Add-on API Configuration
)
return html
@staticmethod
def api_submit_page(updated_keys, enabled, footer):
@classmethod
def api_submit_page(cls, updated_keys, enabled, footer):
localize = cls._context.localize
html = Pages.api_submit.get('html')
css = Pages.api_submit.get('css')
html = html.format(
css=css,
title=_i18n(30634), # YouTube Add-on API Configuration
title=localize(30634), # YouTube Add-on API Configuration
updated=updated_keys,
enabled=enabled,
footer=footer,
header=_i18n(30634), # YouTube Add-on API Configuration
header=localize(30634), # YouTube Add-on API Configuration
)
return html
@ -547,7 +545,8 @@ class Pages(object):
}
def get_http_server(address, port):
def get_http_server(address, port, context):
RequestHandler._context = context
try:
server = TCPServer((address, port), RequestHandler, False)
server.allow_reuse_address = True
@ -558,20 +557,20 @@ def get_http_server(address, port):
except socket.error as exc:
log_error('HTTPServer: Failed to start |{address}:{port}| |{response}|'
.format(address=address, port=port, response=exc))
xbmcgui.Dialog().notification(_addon_name,
xbmcgui.Dialog().notification(context.get_name(),
str(exc),
_addon_icon,
context.get_icon(),
time=5000,
sound=False)
return None
def httpd_status():
address, port = get_connect_address()
def httpd_status(context):
address, port = get_connect_address(context)
url = 'http://{address}:{port}{path}'.format(address=address,
port=port,
path=paths.PING)
response = _server_requests.request(url)
response = RequestHandler.requests.request(url)
result = response and response.status_code
if result == 204:
return True
@ -583,13 +582,13 @@ def httpd_status():
return False
def get_client_ip_address():
def get_client_ip_address(context):
ip_address = None
address, port = get_connect_address()
address, port = get_connect_address(context)
url = 'http://{address}:{port}{path}'.format(address=address,
port=port,
path=paths.IP)
response = _server_requests.request(url)
response = RequestHandler.requests.request(url)
if response and response.status_code == 200:
response_json = response.json()
if response_json:
@ -597,9 +596,10 @@ def get_client_ip_address():
return ip_address
def get_connect_address(as_netloc=False):
address = _settings.httpd_listen()
port = _settings.httpd_port()
def get_connect_address(context, as_netloc=False):
settings = context.get_settings()
address = settings.httpd_listen()
port = settings.httpd_port()
if address == '0.0.0.0':
address = '127.0.0.1'

View file

@ -111,8 +111,8 @@ def _config_actions(context, action, *_args):
settings.httpd_listen(addresses[selected_address])
elif action == 'show_client_ip':
if httpd_status():
client_ip = get_client_ip_address()
if httpd_status(context):
client_ip = get_client_ip_address(context)
if client_ip:
ui.on_ok(context.get_name(),
context.localize('client.ip') % client_ip)

View file

@ -32,6 +32,8 @@ def run():
context = XbmcContext()
context.log_debug('YouTube service initialization...')
provider = Provider()
get_infobool = context.get_infobool
get_infolabel = context.get_infolabel
get_listitem_detail = context.get_listitem_detail
@ -44,8 +46,8 @@ def run():
clear_property(ABORT_FLAG)
monitor = ServiceMonitor()
player = PlayerMonitor(provider=Provider(),
monitor = ServiceMonitor(context=context)
player = PlayerMonitor(provider=provider,
context=context,
monitor=monitor)
@ -124,5 +126,5 @@ def run():
if monitor.httpd:
monitor.shutdown_httpd() # shutdown http server
monitor.tear_down()
provider.tear_down()
context.tear_down()

View file

@ -1369,7 +1369,7 @@ class VideoInfo(YouTubeRequestClient):
}
use_mpd_vod = _settings.use_mpd_videos()
httpd_running = _settings.use_isa() and httpd_status()
httpd_running = _settings.use_isa() and httpd_status(self._context)
pa_li_info = streaming_data.get('licenseInfos', [])
if any(pa_li_info) and not httpd_running:
@ -1382,7 +1382,7 @@ class VideoInfo(YouTubeRequestClient):
continue
self._context.log_debug('Found widevine license url: {0}'
.format(url))
address, port = get_connect_address()
address, port = get_connect_address(self._context)
license_info = {
'url': url,
'proxy': 'http://{address}:{port}{path}||R{{SSM}}|'.format(
@ -2129,7 +2129,7 @@ class VideoInfo(YouTubeRequestClient):
.format(file=filepath))
success = False
if success:
address, port = get_connect_address()
address, port = get_connect_address(self._context)
return 'http://{address}:{port}{path}{file}'.format(
address=address,
port=port,

View file

@ -102,7 +102,7 @@ def play_video(provider, context):
if is_external:
url = urlunsplit((
'http',
get_connect_address(as_netloc=True),
get_connect_address(context=context, as_netloc=True),
paths.REDIRECT,
urlencode({'url': video_stream['url']}),
'',

View file

@ -329,7 +329,7 @@ def process_default_settings(_provider, context, step, steps):
settings.default_player_web_urls(False)
if settings.cache_size() < 20:
settings.cache_size(20)
if settings.use_isa() and not httpd_status():
if settings.use_isa() and not httpd_status(context):
settings.httpd_listen('0.0.0.0')
return step