Merge branch 'dev' into bug/backup-refresh

This commit is contained in:
Zedifus 2022-10-22 20:39:05 +01:00
commit ba968cfd71
4 changed files with 123 additions and 69 deletions

View File

@ -1,18 +1,18 @@
# Changelog # Changelog
## --- [4.0.16] - 2022/10/09 ## --- [4.0.16] - 2022/10/23
### New features ### New features
TBD - Automatically set update url for (new) server creation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/487))
### Bug fixes ### Bug fixes
- Fix conditional issue with zip imports/uploads ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/476)) - Fix conditional issue with zip imports/uploads ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/476))
- Fix API Schedule updates ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/478)) - Fix API Schedule updates ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/478))
- Add port constraint for all server creation & api ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/479)) - Add port constraint for all server creation & api ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/479))
- Clean up backup configs when deleting servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/480)) - Clean up backup configs when deleting servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/480))
- Add timeout to socket for servers with incorrect port selection ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/482)) - Add timeout to socket for servers with incorrect port selection ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/482))
- Fix server_stats db file when deleting server ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/486))
### Tweaks ### Tweaks
- Fix sidebar to not move when scrolling ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/481)) - Fix sidebar to not move when scrolling ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/481))
- Add the rest of CSS predefined colors to themes ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/477)) - Add the rest of CSS predefined colors to themes ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/477))
### Lang - Only send realtime stats when clients connected ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/488))
TBD
<br><br> <br><br>
## --- [4.0.15] - 2022/10/02 ## --- [4.0.15] - 2022/10/02

View File

@ -120,6 +120,7 @@ class HelperServerStats:
return None return None
def get_all_servers_stats(self): def get_all_servers_stats(self):
self.database.connect(reuse_if_open=True)
servers = HelperServers.get_all_defined_servers() servers = HelperServers.get_all_defined_servers()
server_data = [] server_data = []
try: try:
@ -136,18 +137,23 @@ class HelperServerStats:
logger.error( logger.error(
f"Stats collection failed with error: {ex}. Was a server just created?" f"Stats collection failed with error: {ex}. Was a server just created?"
) )
self.database.close()
return server_data return server_data
def get_history_stats(self, server_id, num_days): def get_history_stats(self, server_id, num_days):
self.database.connect(reuse_if_open=True)
max_age = datetime.datetime.now() - timedelta(days=num_days) max_age = datetime.datetime.now() - timedelta(days=num_days)
return ( server_stats = (
ServerStats.select() ServerStats.select()
.where(ServerStats.created > max_age) .where(ServerStats.created > max_age)
.where(ServerStats.server_id == server_id) .where(ServerStats.server_id == server_id)
.execute(self.database) .execute(self.database)
) )
self.database.connect(reuse_if_open=True)
return server_stats
def insert_server_stats(self, server_stats): def insert_server_stats(self, server_stats):
self.database.connect(reuse_if_open=True)
server_id = server_stats.get("id", 0) server_id = server_stats.get("id", 0)
if server_id == 0: if server_id == 0:
@ -176,13 +182,18 @@ class HelperServerStats:
} }
).execute(self.database) ).execute(self.database)
self.database.close()
def remove_old_stats(self, last_week): def remove_old_stats(self, last_week):
self.database.connect(reuse_if_open=True)
# self.select_database(self.server_id) # self.select_database(self.server_id)
ServerStats.delete().where(ServerStats.created < last_week).execute( ServerStats.delete().where(ServerStats.created < last_week).execute(
self.database self.database
) )
self.database.close()
def get_latest_server_stats(self): def get_latest_server_stats(self):
self.database.connect(reuse_if_open=True)
latest = ( latest = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
@ -190,12 +201,15 @@ class HelperServerStats:
.limit(1) .limit(1)
.get(self.database) .get(self.database)
) )
self.database.close()
try: try:
return DatabaseShortcuts.get_data_obj(latest) return DatabaseShortcuts.get_data_obj(latest)
except IndexError: except IndexError:
return {} return {}
def get_server_stats(self): def get_server_stats(self):
self.database.connect(reuse_if_open=True)
stats = ( stats = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
@ -203,63 +217,70 @@ class HelperServerStats:
.limit(1) .limit(1)
.first(self.database) .first(self.database)
) )
self.database.close()
return DatabaseShortcuts.get_data_obj(stats) return DatabaseShortcuts.get_data_obj(stats)
def server_id_exists(self): def server_id_exists(self):
# self.select_database(self.server_id)
if not HelperServers.get_server_data_by_id(self.server_id): if not HelperServers.get_server_data_by_id(self.server_id):
return False return False
return True return True
def sever_crashed(self): def sever_crashed(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
ServerStats.update(crashed=True).where( ServerStats.update(crashed=True).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def set_import(self): def set_import(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
ServerStats.update(importing=True).where( ServerStats.update(importing=True).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def finish_import(self): def finish_import(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
ServerStats.update(importing=False).where( ServerStats.update(importing=False).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def get_import_status(self): def get_import_status(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
import_status = ( import_status = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
.get(self.database) .get(self.database)
) )
self.database.close()
return import_status.importing return import_status.importing
def server_crash_reset(self): def server_crash_reset(self):
if self.server_id is None: if self.server_id is None:
return return
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
ServerStats.update(crashed=False).where( ServerStats.update(crashed=False).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def is_crashed(self): def is_crashed(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
svr: ServerStats = ( svr: ServerStats = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
.get(self.database) .get(self.database)
) )
self.database.close()
return svr.crashed return svr.crashed
def set_update(self, value): def set_update(self, value):
if self.server_id is None: if self.server_id is None:
return return
# self.select_database(self.server_id)
self.database.connect(reuse_if_open=True)
try: try:
# Checks if server even exists # Checks if server even exists
ServerStats.select().where(ServerStats.server_id == self.server_id).execute( ServerStats.select().where(ServerStats.server_id == self.server_id).execute(
@ -267,22 +288,26 @@ class HelperServerStats:
) )
except DoesNotExist as ex: except DoesNotExist as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
self.database.close()
return return
ServerStats.update(updating=value).where( ServerStats.update(updating=value).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def get_update_status(self): def get_update_status(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
update_status = ( update_status = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
.get(self.database) .get(self.database)
) )
self.database.close()
return update_status.updating return update_status.updating
def set_first_run(self): def set_first_run(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
# Sets first run to false # Sets first run to false
try: try:
# Checks if server even exists # Checks if server even exists
@ -291,22 +316,25 @@ class HelperServerStats:
) )
except Exception as ex: except Exception as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
self.database.close()
return return
ServerStats.update(first_run=False).where( ServerStats.update(first_run=False).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def get_first_run(self): def get_first_run(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
first_run = ( first_run = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
.get(self.database) .get(self.database)
) )
self.database.close()
return first_run.first_run return first_run.first_run
def get_ttl_without_player(self): def get_ttl_without_player(self):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
last_stat = ( last_stat = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
@ -320,6 +348,7 @@ class HelperServerStats:
.order_by(ServerStats.created.desc()) .order_by(ServerStats.created.desc())
.first(self.database) .first(self.database)
) )
self.database.close()
return last_stat.created - last_stat_with_player.created return last_stat.created - last_stat_with_player.created
def can_stop_no_players(self, time_limit): def can_stop_no_players(self, time_limit):
@ -327,7 +356,7 @@ class HelperServerStats:
return (time_limit == -1) or (ttl_no_players > time_limit) return (time_limit == -1) or (ttl_no_players > time_limit)
def set_waiting_start(self, value): def set_waiting_start(self, value):
# self.select_database(self.server_id) self.database.connect(reuse_if_open=True)
try: try:
# Checks if server even exists # Checks if server even exists
ServerStats.select().where(ServerStats.server_id == self.server_id).execute( ServerStats.select().where(ServerStats.server_id == self.server_id).execute(
@ -335,15 +364,19 @@ class HelperServerStats:
) )
except DoesNotExist as ex: except DoesNotExist as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
self.database.close()
return return
ServerStats.update(waiting_start=value).where( ServerStats.update(waiting_start=value).where(
ServerStats.server_id == self.server_id ServerStats.server_id == self.server_id
).execute(self.database) ).execute(self.database)
self.database.close()
def get_waiting_start(self): def get_waiting_start(self):
self.database.connect(reuse_if_open=True)
waiting_start = ( waiting_start = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == self.server_id) .where(ServerStats.server_id == self.server_id)
.get(self.database) .get(self.database)
) )
self.database.close()
return waiting_start.waiting_start return waiting_start.waiting_start

View File

@ -419,6 +419,15 @@ class Controller:
data["create_type"] == "minecraft_java" data["create_type"] == "minecraft_java"
and root_create_data["create_type"] == "download_jar" and root_create_data["create_type"] == "download_jar"
): ):
# modded update urls from server jars will only update the installer
if create_data["category"] != "modded":
server_obj = self.servers.get_server_obj(new_server_id)
url = (
f"https://serverjars.com/api/fetchJar/{create_data['category']}"
f"/{create_data['type']}/{create_data['version']}"
)
server_obj.executable_update_url = url
self.servers.update_server(server_obj)
self.server_jars.download_jar( self.server_jars.download_jar(
create_data["category"], create_data["category"],
create_data["type"], create_data["type"],
@ -502,7 +511,12 @@ class Controller:
user_id, user_id,
server_type="minecraft-java", server_type="minecraft-java",
) )
# modded update urls from server jars will only update the installer
if jar != "modded":
server_obj = self.servers.get_server_obj(new_id)
url = f"https://serverjars.com/api/fetchJar/{jar}/{server}/{version}"
server_obj.executable_update_url = url
self.servers.update_server(server_obj)
# download the jar # download the jar
self.server_jars.download_jar( self.server_jars.download_jar(
jar, server, version, os.path.join(server_dir, server_file), new_id jar, server, version, os.path.join(server_dir, server_file), new_id

View File

@ -1223,41 +1223,19 @@ class ServerInstance:
# ********************************************************************************** # **********************************************************************************
def realtime_stats(self): def realtime_stats(self):
total_players = 0 # only get stats if clients are connected.
max_players = 0 # no point in burning cpu
servers_ping = []
raw_ping_result = []
raw_ping_result = self.get_raw_server_stats(self.server_id)
if f"{raw_ping_result.get('icon')}" == "b''":
raw_ping_result["icon"] = False
servers_ping.append(
{
"id": raw_ping_result.get("id"),
"started": raw_ping_result.get("started"),
"running": raw_ping_result.get("running"),
"cpu": raw_ping_result.get("cpu"),
"mem": raw_ping_result.get("mem"),
"mem_percent": raw_ping_result.get("mem_percent"),
"world_name": raw_ping_result.get("world_name"),
"world_size": raw_ping_result.get("world_size"),
"server_port": raw_ping_result.get("server_port"),
"int_ping_results": raw_ping_result.get("int_ping_results"),
"online": raw_ping_result.get("online"),
"max": raw_ping_result.get("max"),
"players": raw_ping_result.get("players"),
"desc": raw_ping_result.get("desc"),
"version": raw_ping_result.get("version"),
"icon": raw_ping_result.get("icon"),
"crashed": self.is_crashed,
}
)
if len(self.helper.websocket_helper.clients) > 0: if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params( total_players = 0
"/panel/server_detail", max_players = 0
{"id": str(self.server_id)}, servers_ping = []
"update_server_details", raw_ping_result = []
raw_ping_result = self.get_raw_server_stats(self.server_id)
if f"{raw_ping_result.get('icon')}" == "b''":
raw_ping_result["icon"] = False
servers_ping.append(
{ {
"id": raw_ping_result.get("id"), "id": raw_ping_result.get("id"),
"started": raw_ping_result.get("started"), "started": raw_ping_result.get("started"),
@ -1276,24 +1254,53 @@ class ServerInstance:
"version": raw_ping_result.get("version"), "version": raw_ping_result.get("version"),
"icon": raw_ping_result.get("icon"), "icon": raw_ping_result.get("icon"),
"crashed": self.is_crashed, "crashed": self.is_crashed,
"created": datetime.datetime.now().strftime("%Y/%m/%d, %H:%M:%S"), }
},
) )
total_players += int(raw_ping_result.get("online")) if len(self.helper.websocket_helper.clients) > 0:
max_players += int(raw_ping_result.get("max")) self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
self.record_server_stats() {"id": str(self.server_id)},
"update_server_details",
if (len(servers_ping) > 0) & (len(self.helper.websocket_helper.clients) > 0): {
try: "id": raw_ping_result.get("id"),
self.helper.websocket_helper.broadcast_page( "started": raw_ping_result.get("started"),
"/panel/dashboard", "update_server_status", servers_ping "running": raw_ping_result.get("running"),
"cpu": raw_ping_result.get("cpu"),
"mem": raw_ping_result.get("mem"),
"mem_percent": raw_ping_result.get("mem_percent"),
"world_name": raw_ping_result.get("world_name"),
"world_size": raw_ping_result.get("world_size"),
"server_port": raw_ping_result.get("server_port"),
"int_ping_results": raw_ping_result.get("int_ping_results"),
"online": raw_ping_result.get("online"),
"max": raw_ping_result.get("max"),
"players": raw_ping_result.get("players"),
"desc": raw_ping_result.get("desc"),
"version": raw_ping_result.get("version"),
"icon": raw_ping_result.get("icon"),
"crashed": self.is_crashed,
"created": datetime.datetime.now().strftime(
"%Y/%m/%d, %H:%M:%S"
),
},
) )
self.helper.websocket_helper.broadcast_page( total_players += int(raw_ping_result.get("online"))
"/status", "update_server_status", servers_ping max_players += int(raw_ping_result.get("max"))
)
except: self.record_server_stats()
Console.critical("Can't broadcast server status to websocket")
if (len(servers_ping) > 0) & (
len(self.helper.websocket_helper.clients) > 0
):
try:
self.helper.websocket_helper.broadcast_page(
"/panel/dashboard", "update_server_status", servers_ping
)
self.helper.websocket_helper.broadcast_page(
"/status", "update_server_status", servers_ping
)
except:
Console.critical("Can't broadcast server status to websocket")
def get_servers_stats(self): def get_servers_stats(self):