mirror of
https://github.com/fHDHR/fHDHR_NextPVR.git
synced 2025-12-06 16:46:58 -05:00
Add Restart Button to Web Interface
This commit is contained in:
parent
d87ef97494
commit
602e74f565
@ -21,6 +21,8 @@ class fHDHR_INT_OBJ():
|
||||
|
||||
self.api = fHDHR_API_URLs(settings, self.web)
|
||||
|
||||
self.threads = {}
|
||||
|
||||
|
||||
class fHDHR_OBJ():
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
import threading
|
||||
|
||||
from fHDHR import fHDHR_VERSION, fHDHR_OBJ
|
||||
import fHDHR.exceptions
|
||||
@ -38,28 +36,24 @@ def run(settings, logger, db, script_dir, fHDHR_web, origin, alternative_epg):
|
||||
|
||||
try:
|
||||
|
||||
fhdhr.logger.info("HTTP Server Starting")
|
||||
fhdhr_web = threading.Thread(target=fhdhrweb.run)
|
||||
fhdhr_web.start()
|
||||
# Start Flask Thread
|
||||
fhdhrweb.start()
|
||||
|
||||
# Start SSDP Thread
|
||||
if settings.dict["fhdhr"]["discovery_address"]:
|
||||
fhdhr.logger.info("SSDP Server Starting")
|
||||
fhdhr_ssdp = threading.Thread(target=fhdhr.device.ssdp.run)
|
||||
fhdhr_ssdp.start()
|
||||
fhdhr.device.ssdp.start()
|
||||
|
||||
# Start EPG Thread
|
||||
if settings.dict["epg"]["method"]:
|
||||
fhdhr.logger.info("EPG Update Thread Starting")
|
||||
fhdhr_epg = threading.Thread(target=fhdhr.device.epg.run)
|
||||
fhdhr_epg.start()
|
||||
fhdhr.device.epg.start()
|
||||
|
||||
# Perform some actions now that HTTP Server is running
|
||||
fhdhr.logger.info("Waiting 3 seconds to send startup tasks trigger.")
|
||||
time.sleep(3)
|
||||
fhdhr.api.get("/api/startup_tasks")
|
||||
|
||||
# wait forever
|
||||
while True:
|
||||
time.sleep(3600)
|
||||
while fhdhr.threads["flask"].is_alive():
|
||||
restart_code = "restart"
|
||||
return restart_code
|
||||
|
||||
except KeyboardInterrupt:
|
||||
return ERR_CODE_NO_RESTART
|
||||
@ -92,7 +86,10 @@ def main(script_dir, fHDHR_web, origin, alternative_epg):
|
||||
|
||||
try:
|
||||
args = build_args_parser()
|
||||
return start(args, script_dir, fHDHR_web, origin, alternative_epg)
|
||||
while True:
|
||||
returned_code = start(args, script_dir, fHDHR_web, origin, alternative_epg)
|
||||
if returned_code not in ["restart"]:
|
||||
return returned_code
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nInterrupted")
|
||||
return ERR_CODE
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import threading
|
||||
|
||||
from fHDHR.tools import channel_sort
|
||||
|
||||
@ -39,6 +40,8 @@ class EPG():
|
||||
|
||||
self.epg_update_url = "/api/epg?method=update"
|
||||
|
||||
self.fhdhr.threads["epg"] = threading.Thread(target=self.run)
|
||||
|
||||
def clear_epg_cache(self, method=None):
|
||||
|
||||
if not method:
|
||||
@ -294,19 +297,25 @@ class EPG():
|
||||
self.fhdhr.db.set_fhdhr_value("update_time", method, time.time())
|
||||
self.fhdhr.logger.info("Wrote %s EPG cache. %s Programs for %s Channels" % (epgtypename, total_programs, total_channels))
|
||||
|
||||
def start(self):
|
||||
self.fhdhr.logger.info("EPG Update Thread Starting")
|
||||
self.fhdhr.threads["epg"].start()
|
||||
|
||||
def stop(self):
|
||||
self.fhdhr.logger.info("EPG Update Thread Stopping")
|
||||
|
||||
def run(self):
|
||||
time.sleep(1800)
|
||||
try:
|
||||
while True:
|
||||
for epg_method in self.epg_methods:
|
||||
last_update_time = self.fhdhr.db.get_fhdhr_value("update_time", epg_method)
|
||||
updatetheepg = False
|
||||
if not last_update_time:
|
||||
updatetheepg = True
|
||||
elif time.time() >= (last_update_time + self.sleeptime[epg_method]):
|
||||
updatetheepg = True
|
||||
if updatetheepg:
|
||||
self.fhdhr.api.get("%s&source=%s" % (self.epg_update_url, epg_method))
|
||||
time.sleep(1800)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
while True:
|
||||
for epg_method in self.epg_methods:
|
||||
last_update_time = self.fhdhr.db.get_fhdhr_value("update_time", epg_method)
|
||||
updatetheepg = False
|
||||
if not last_update_time:
|
||||
updatetheepg = True
|
||||
elif time.time() >= (last_update_time + self.sleeptime[epg_method]):
|
||||
updatetheepg = True
|
||||
if updatetheepg:
|
||||
self.fhdhr.api.get("%s&source=%s" % (self.epg_update_url, epg_method))
|
||||
time.sleep(1800)
|
||||
|
||||
self.stop()
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import socket
|
||||
import struct
|
||||
import time
|
||||
import threading
|
||||
|
||||
from .ssdp_detect import fHDHR_Detect
|
||||
from .rmg_ssdp import RMG_SSDP
|
||||
@ -15,6 +16,8 @@ class SSDPServer():
|
||||
|
||||
self.detect_method = fHDHR_Detect(fhdhr)
|
||||
|
||||
self.fhdhr.threads["ssdp"] = threading.Thread(target=self.run)
|
||||
|
||||
if (self.fhdhr.config.dict["fhdhr"]["discovery_address"] and
|
||||
self.fhdhr.config.dict["ssdp"]["enabled"]):
|
||||
self.setup_ssdp()
|
||||
@ -32,6 +35,21 @@ class SSDPServer():
|
||||
self.do_alive()
|
||||
self.m_search()
|
||||
|
||||
def start(self):
|
||||
self.fhdhr.logger.info("SSDP Server Starting")
|
||||
self.fhdhr.threads["ssdp"].start()
|
||||
|
||||
def stop(self):
|
||||
self.fhdhr.logger.info("SSDP Server Stopping")
|
||||
self.sock.close()
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
data, address = self.sock.recvfrom(1024)
|
||||
self.on_recv(data, address)
|
||||
self.do_alive()
|
||||
self.stop()
|
||||
|
||||
def do_alive(self, forcealive=False):
|
||||
|
||||
send_alive = False
|
||||
@ -132,15 +150,6 @@ class SSDPServer():
|
||||
|
||||
return data.encode("utf-8")
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
while True:
|
||||
data, address = self.sock.recvfrom(1024)
|
||||
self.on_recv(data, address)
|
||||
self.do_alive()
|
||||
except KeyboardInterrupt:
|
||||
self.sock.close()
|
||||
|
||||
def setup_ssdp(self):
|
||||
self.sock = None
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
from gevent.pywsgi import WSGIServer
|
||||
from flask import Flask, request, session
|
||||
import threading
|
||||
import uuid
|
||||
|
||||
from .pages import fHDHR_Pages
|
||||
from .files import fHDHR_Files
|
||||
@ -23,6 +25,7 @@ class fHDHR_HTTP_Server():
|
||||
self.fhdhr.logger.info("Loading Flask.")
|
||||
|
||||
self.fhdhr.app = Flask("fHDHR", template_folder=self.template_folder)
|
||||
self.instance_id = str(uuid.uuid4())
|
||||
|
||||
# Allow Internal API Usage
|
||||
self.fhdhr.app.testing = True
|
||||
@ -63,11 +66,24 @@ class fHDHR_HTTP_Server():
|
||||
self.fhdhr.app.after_request(self.after_request)
|
||||
self.fhdhr.app.before_first_request(self.before_first_request)
|
||||
|
||||
self.fhdhr.threads["flask"] = threading.Thread(target=self.run)
|
||||
|
||||
def start(self):
|
||||
self.fhdhr.logger.info("Flask HTTP Thread Starting")
|
||||
self.fhdhr.threads["flask"].start()
|
||||
|
||||
def stop(self):
|
||||
self.fhdhr.logger.info("Flask HTTP Thread Stopping")
|
||||
self.http.stop()
|
||||
|
||||
def before_first_request(self):
|
||||
self.fhdhr.logger.info("HTTP Server Online.")
|
||||
|
||||
def before_request(self):
|
||||
|
||||
session["session_id"] = str(uuid.uuid4())
|
||||
session["instance_id"] = self.instance_id
|
||||
|
||||
session["is_internal_api"] = self.detect_internal_api(request)
|
||||
if session["is_internal_api"]:
|
||||
self.fhdhr.logger.debug("Client is using internal API call.")
|
||||
@ -84,6 +100,8 @@ class fHDHR_HTTP_Server():
|
||||
|
||||
session["tuner_used"] = None
|
||||
|
||||
session["restart"] = False
|
||||
|
||||
self.fhdhr.logger.debug("Client %s requested %s Opening" % (request.method, request.path))
|
||||
|
||||
def after_request(self, response):
|
||||
@ -96,7 +114,10 @@ class fHDHR_HTTP_Server():
|
||||
# tuner.close()
|
||||
|
||||
self.fhdhr.logger.debug("Client %s requested %s Closing" % (request.method, request.path))
|
||||
return response
|
||||
if not session["restart"]:
|
||||
return response
|
||||
else:
|
||||
return self.stop()
|
||||
|
||||
def detect_internal_api(self, request):
|
||||
user_agent = request.headers.get('User-Agent')
|
||||
@ -165,8 +186,8 @@ class fHDHR_HTTP_Server():
|
||||
self.http = WSGIServer(self.fhdhr.api.address_tuple,
|
||||
self.fhdhr.app.wsgi_app,
|
||||
log=self.fhdhr.logger)
|
||||
|
||||
try:
|
||||
self.http.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
self.http.stop()
|
||||
self.stop()
|
||||
except AttributeError:
|
||||
self.fhdhr.logger.info("HTTP Server Offline")
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from flask import request, redirect
|
||||
from flask import request, redirect, session
|
||||
import urllib.parse
|
||||
|
||||
|
||||
@ -34,6 +34,11 @@ class Settings():
|
||||
|
||||
self.fhdhr.config.write(config_section, config_name, config_value)
|
||||
|
||||
elif method == "restart":
|
||||
instance_id = request.args.get('instance_id', default=None, type=str)
|
||||
if instance_id == session["instance_id"]:
|
||||
session["restart"] = True
|
||||
|
||||
if redirect_url:
|
||||
return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Success" % method))
|
||||
else:
|
||||
|
||||
@ -2,67 +2,72 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h4 style="text-align: center;">fHDHR Settings</h4>
|
||||
<h4 style="text-align: center;">fHDHR Settings</h4>
|
||||
|
||||
<h4 style="text-align: center;">Settings will require a manual restart.</h4>
|
||||
<h4 style="text-align: center;">Some Settings will require a manual restart.</h4>
|
||||
|
||||
{% for config_section in list(web_settings_dict.keys()) %}
|
||||
<div style="text-align: center;">
|
||||
<button onclick="OpenLink('/api/settings?method=restart&instance_id={{ session["instance_id"] }}&redirect=%2Fsettings')">Restart fHDHR</a></button><p> Note: This may take some time, and you will have to refresh your page.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
{% if config_section == "origin" %}
|
||||
<h4 style="text-align: center;">{{ fhdhr.config.dict["main"]["dictpopname"] }}</h4>
|
||||
{% else %}
|
||||
<h4 style="text-align: center;">{{ config_section }}</h4>
|
||||
{% endif %}
|
||||
{% for config_section in list(web_settings_dict.keys()) %}
|
||||
|
||||
{% if config_section == "origin" %}
|
||||
<h4 style="text-align: center;">{{ fhdhr.config.dict["main"]["dictpopname"] }}</h4>
|
||||
{% else %}
|
||||
<h4 style="text-align: center;">{{ config_section }}</h4>
|
||||
{% endif %}
|
||||
|
||||
<div class="container">
|
||||
<table class="table-settings center action-col text-edit-cols">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Config Name</th>
|
||||
<th>Config Default Value</th>
|
||||
<th>Config Value</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<table class="table-settings center action-col text-edit-cols">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Config Name</th>
|
||||
<th>Config Default Value</th>
|
||||
<th>Config Value</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for config_item in list(web_settings_dict[config_section].keys()) %}
|
||||
|
||||
<tr>
|
||||
<td>{{ config_item }}</td>
|
||||
<tr>
|
||||
<td>{{ config_item }}</td>
|
||||
|
||||
<td>{{ web_settings_dict[config_section][config_item]["value_default"] }}</td>
|
||||
<td>{{ web_settings_dict[config_section][config_item]["value_default"] }}</td>
|
||||
|
||||
<td>
|
||||
<form method="post" action="/api/settings?method=update&redirect=%2Fsettings">
|
||||
<input type="hidden" name="config_section" value="{{ config_section }}">
|
||||
<input type="hidden" name="config_name" value="{{ config_item }}">
|
||||
<input type="hidden" name="config_default" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
{% if web_settings_dict[config_section][config_item]["hide"] %}
|
||||
<input type="text" size="25" name="config_value" value="**************">
|
||||
{% else %}
|
||||
<input type="text" size="25" name="config_value" value="{{ web_settings_dict[config_section][config_item]["value"] }}">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="display:flex;">
|
||||
<span style="margin:auto">
|
||||
<input type="submit" value="Update">
|
||||
</form>
|
||||
</span>
|
||||
<form style="margin:auto">
|
||||
<input type="hidden" name="config_section" value="{{ config_section }}">
|
||||
<input type="hidden" name="config_name" value="{{ config_item }}">
|
||||
<input type="hidden" name="config_value" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
<input type="hidden" name="config_default" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
<input type="submit" value="Reset">
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" action="/api/settings?method=update&redirect=%2Fsettings">
|
||||
<input type="hidden" name="config_section" value="{{ config_section }}">
|
||||
<input type="hidden" name="config_name" value="{{ config_item }}">
|
||||
<input type="hidden" name="config_default" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
{% if web_settings_dict[config_section][config_item]["hide"] %}
|
||||
<input type="text" size="25" name="config_value" value="**************">
|
||||
{% else %}
|
||||
<input type="text" size="25" name="config_value" value="{{ web_settings_dict[config_section][config_item]["value"] }}">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="display:flex;">
|
||||
<span style="margin:auto">
|
||||
<input type="submit" value="Update">
|
||||
</form>
|
||||
</span>
|
||||
<form style="margin:auto">
|
||||
<input type="hidden" name="config_section" value="{{ config_section }}">
|
||||
<input type="hidden" name="config_name" value="{{ config_item }}">
|
||||
<input type="hidden" name="config_value" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
<input type="hidden" name="config_default" value="{{ web_settings_dict[config_section][config_item]["value_default"] }}">
|
||||
<input type="submit" value="Reset">
|
||||
</form>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user