mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'download-status' into 'dev'
Add server download status indicator See merge request crafty-controller/crafty-commander!181
This commit is contained in:
commit
3373d6035c
@ -50,6 +50,18 @@ class Servers_Controller:
|
||||
def update_server(server_obj):
|
||||
return servers_helper.update_server(server_obj)
|
||||
|
||||
@staticmethod
|
||||
def set_download(server_id):
|
||||
return servers_helper.set_download(server_id)
|
||||
|
||||
@staticmethod
|
||||
def finish_download(server_id):
|
||||
return servers_helper.finish_download(server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_download_status(server_id):
|
||||
return servers_helper.get_download_status(server_id)
|
||||
|
||||
@staticmethod
|
||||
def remove_server(server_id):
|
||||
roles_list = server_permissions.get_roles_from_server(server_id)
|
||||
|
@ -8,6 +8,9 @@ from datetime import datetime
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.controllers.servers_controller import Servers_Controller
|
||||
from app.classes.web.websocket_helper import websocket_helper
|
||||
from app.classes.models.server_permissions import server_permissions
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -170,21 +173,51 @@ class ServerJars:
|
||||
response = self._get_api_result(url)
|
||||
return response
|
||||
|
||||
def download_jar(self, server, version, path):
|
||||
update_thread = threading.Thread(target=self.a_download_jar, daemon=True, args=(server, version, path))
|
||||
def download_jar(self, server, version, path, server_id):
|
||||
update_thread = threading.Thread(target=self.a_download_jar, daemon=True, args=(server, version, path, server_id))
|
||||
update_thread.start()
|
||||
|
||||
def a_download_jar(self, server, version, path):
|
||||
def a_download_jar(self, server, version, path, server_id):
|
||||
#delaying download for server register to finish
|
||||
time.sleep(3)
|
||||
fetch_url = f"{self.base_url}/api/fetchJar/{server}/{version}"
|
||||
server_users = server_permissions.get_server_user_list(server_id)
|
||||
|
||||
|
||||
#We need to make sure the server is registered before we submit a db update for it's stats.
|
||||
while True:
|
||||
try:
|
||||
Servers_Controller.set_download(server_id)
|
||||
for user in server_users:
|
||||
websocket_helper.broadcast_user(user, 'send_start_reload', {
|
||||
})
|
||||
|
||||
break
|
||||
except:
|
||||
logger.debug("server not registered yet. Delaying download.")
|
||||
|
||||
# open a file stream
|
||||
with requests.get(fetch_url, timeout=2, stream=True) as r:
|
||||
try:
|
||||
with open(path, 'wb') as output:
|
||||
shutil.copyfileobj(r.raw, output)
|
||||
Servers_Controller.finish_download(server_id)
|
||||
|
||||
for user in server_users:
|
||||
websocket_helper.broadcast_user(user, 'notification', "Executable download finished")
|
||||
time.sleep(3)
|
||||
websocket_helper.broadcast_user(user, 'send_start_reload', {
|
||||
})
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to save jar to {path} due to error:{e}")
|
||||
Servers_Controller.finish_download(server_id)
|
||||
server_users = server_permissions.get_server_user_list(server_id)
|
||||
for user in server_users:
|
||||
websocket_helper.broadcast_user(user, 'notification', "Executable download finished")
|
||||
time.sleep(3)
|
||||
websocket_helper.broadcast_user(user, 'send_start_reload', {
|
||||
})
|
||||
|
||||
return False
|
||||
|
||||
|
@ -75,6 +75,7 @@ class Server_Stats(Model):
|
||||
waiting_start = BooleanField(default=False)
|
||||
first_run = BooleanField(default=True)
|
||||
crashed = BooleanField(default=False)
|
||||
downloading = BooleanField(default=False)
|
||||
|
||||
|
||||
class Meta:
|
||||
@ -194,6 +195,22 @@ class helper_servers:
|
||||
with database.atomic():
|
||||
Server_Stats.update(crashed=True).where(Server_Stats.server_id == server_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def set_download(server_id):
|
||||
with database.atomic():
|
||||
Server_Stats.update(downloading=True).where(Server_Stats.server_id == server_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def finish_download(server_id):
|
||||
with database.atomic():
|
||||
Server_Stats.update(downloading=False).where(Server_Stats.server_id == server_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_download_status(server_id):
|
||||
download_status = Server_Stats.select().where(Server_Stats.server_id == server_id).get()
|
||||
return download_status.downloading
|
||||
|
||||
|
||||
@staticmethod
|
||||
def server_crash_reset(server_id):
|
||||
with database.atomic():
|
||||
|
@ -292,11 +292,12 @@ class Controller:
|
||||
server_log_file = f"{server_dir}/logs/latest.log"
|
||||
server_stop = "stop"
|
||||
|
||||
# download the jar
|
||||
server_jar_obj.download_jar(server, version, full_jar_path)
|
||||
|
||||
new_id = self.register_server(name, server_id, server_dir, backup_path, server_command, server_file, server_log_file, server_stop,
|
||||
port, server_type='minecraft-java')
|
||||
|
||||
# download the jar
|
||||
server_jar_obj.download_jar(server, version, full_jar_path, new_id)
|
||||
|
||||
return new_id
|
||||
|
||||
@staticmethod
|
||||
|
@ -188,6 +188,13 @@ class Server:
|
||||
else:
|
||||
user_lang = users_helper.get_user_lang_by_id(user_id)
|
||||
|
||||
if servers_helper.get_download_status(self.server_id):
|
||||
if user_id:
|
||||
websocket_helper.broadcast_user(user_id, 'send_start_error',{
|
||||
'error': translation.translate('error', 'not-downloaded', user_lang)
|
||||
})
|
||||
return False
|
||||
|
||||
logger.info(f"Start command detected. Reloading settings from DB for server {self.name}")
|
||||
self.setup_server_run_command()
|
||||
# fail safe in case we try to start something already running
|
||||
|
@ -150,7 +150,7 @@ class PanelHandler(BaseHandler):
|
||||
else:
|
||||
if not self.controller.servers.server_id_authorized(server_id, exec_user["user_id"]):
|
||||
print(f'User {exec_user["user_id"]} does not have permission')
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
self.redirect("/pandel/error?error=Invalid Server ID")
|
||||
return None
|
||||
return server_id
|
||||
|
||||
@ -209,14 +209,17 @@ class PanelHandler(BaseHandler):
|
||||
user_order = user_order['server_order'].split(',')
|
||||
page_servers = []
|
||||
server_ids = []
|
||||
un_used_servers = defined_servers
|
||||
|
||||
for server_id in user_order:
|
||||
for server in defined_servers:
|
||||
for server in un_used_servers:
|
||||
if str(server['server_id']) == str(server_id):
|
||||
page_servers.append(server)
|
||||
un_used_servers.remove(server)
|
||||
user_order.remove(server_id)
|
||||
|
||||
|
||||
for server in defined_servers:
|
||||
for server in un_used_servers:
|
||||
server_ids.append(str(server['server_id']))
|
||||
if server not in page_servers:
|
||||
page_servers.append(server)
|
||||
@ -335,14 +338,33 @@ class PanelHandler(BaseHandler):
|
||||
user_order = user_order['server_order'].split(',')
|
||||
page_servers = []
|
||||
server_ids = []
|
||||
un_used_servers = page_data['servers']
|
||||
flag = 0
|
||||
|
||||
for server_id in user_order:
|
||||
for server in page_data['servers']:
|
||||
for server in un_used_servers:
|
||||
if flag == 0:
|
||||
server['stats']['downloading'] = self.controller.servers.get_download_status(
|
||||
str(server['stats']['server_id']['server_id']))
|
||||
server['stats']['crashed'] = self.controller.servers.is_crashed(
|
||||
str(server['stats']['server_id']['server_id']))
|
||||
try:
|
||||
server['stats']['waiting_start'] = self.controller.servers.get_waiting_start(
|
||||
str(server['stats']['server_id']['server_id']))
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get server waiting to start: {e}")
|
||||
server['stats']['waiting_start'] = False
|
||||
|
||||
if str(server['server_data']['server_id']) == str(server_id):
|
||||
page_servers.append(server)
|
||||
un_used_servers.remove(server)
|
||||
user_order.remove(server_id)
|
||||
#we only want to set these server stats values once. We need to update the flag so it only hits that if once.
|
||||
flag += 1
|
||||
|
||||
|
||||
for server in page_data['servers']:
|
||||
|
||||
for server in un_used_servers:
|
||||
server_ids.append(str(server['server_data']['server_id']))
|
||||
if server not in page_servers:
|
||||
page_servers.append(server)
|
||||
@ -352,17 +374,6 @@ class PanelHandler(BaseHandler):
|
||||
user_order.remove(server_id)
|
||||
page_data['servers'] = page_servers
|
||||
|
||||
|
||||
for data in page_data['servers']:
|
||||
data['stats']['crashed'] = self.controller.servers.is_crashed(
|
||||
str(data['stats']['server_id']['server_id']))
|
||||
try:
|
||||
data['stats']['waiting_start'] = self.controller.servers.get_waiting_start(
|
||||
str(data['stats']['server_id']['server_id']))
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get server waiting to start: {e}")
|
||||
data['stats']['waiting_start'] = False
|
||||
|
||||
try:
|
||||
self.fetch_server_data(page_data)
|
||||
except:
|
||||
@ -390,6 +401,8 @@ class PanelHandler(BaseHandler):
|
||||
# server_data isn't needed since the server_stats also pulls server data
|
||||
page_data['server_data'] = self.controller.servers.get_server_data_by_id(server_id)
|
||||
page_data['server_stats'] = self.controller.servers.get_server_stats_by_id(server_id)
|
||||
page_data['downloading'] = self.controller.servers.get_download_status(
|
||||
server_id)
|
||||
try:
|
||||
page_data['waiting_start'] = self.controller.servers.get_waiting_start(server_id)
|
||||
except Exception as e:
|
||||
|
@ -158,6 +158,9 @@
|
||||
<a data-id="{{server['server_data']['server_id']}}" class="" title={{
|
||||
translate('dashboard', 'delay-explained' , data['lang'])}}>{{ translate('dashboard', 'starting',
|
||||
data['lang']) }}</i></a>
|
||||
{% elif server['stats']['downloading']%}
|
||||
<a data-id="{{server['server_data']['server_id']}}" class=""><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'downloading',
|
||||
data['lang']) }}</a>
|
||||
{% else %}
|
||||
<a data-id="{{server['server_data']['server_id']}}" class="play_button"
|
||||
data-toggle="tooltip" title="{{ translate('dashboard', 'start' , data['lang']) }}">
|
||||
|
@ -59,6 +59,13 @@
|
||||
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
||||
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
||||
</div>
|
||||
{% elif data['downloading'] %}
|
||||
<div id="control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
||||
<button onclick="" id="start-btn" style="max-width: 12rem; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled"><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'downloading',
|
||||
data['lang']) }}</button>
|
||||
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
||||
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
||||
<button onclick="send_command(serverId, 'start_server');" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ translate('serverTerm', 'start', data['lang']) }}</button>
|
||||
@ -153,6 +160,12 @@
|
||||
restartBtn.setAttribute('disabled', 'disabled');
|
||||
stopBtn.setAttribute('disabled', 'disabled');
|
||||
}
|
||||
|
||||
if (webSocket) {
|
||||
webSocket.on('send_start_reload', function () {
|
||||
location.reload()
|
||||
});
|
||||
}
|
||||
//{% end %}
|
||||
|
||||
function get_server_log() {
|
||||
|
16
app/migrations/20220303_downloading.py
Normal file
16
app/migrations/20220303_downloading.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns('server_stats', downloading=peewee.BooleanField(default=False))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns('server_stats', ['downloading'])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
@ -165,7 +165,8 @@
|
||||
"stop": "Stop",
|
||||
"updating": "Updating...",
|
||||
"starting": "Delayed-Start",
|
||||
"delay-explained": "The service/agent has recently started and is delaying the start of the minecraft server instance"
|
||||
"delay-explained": "The service/agent has recently started and is delaying the start of the minecraft server instance",
|
||||
"downloading": "Downloading..."
|
||||
},
|
||||
"serverPlayerManagement": {
|
||||
"players": "Players",
|
||||
|
Loading…
Reference in New Issue
Block a user