2022-04-27 19:07:34 +00:00
|
|
|
import os
|
|
|
|
import logging
|
|
|
|
import datetime
|
2022-05-24 22:48:27 +00:00
|
|
|
import typing as t
|
|
|
|
|
|
|
|
from playhouse.shortcuts import model_to_dict
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
from app.classes.models.servers import Servers, HelperServers
|
|
|
|
from app.classes.shared.helpers import Helpers
|
|
|
|
from app.classes.shared.migration import MigrationManager
|
|
|
|
|
|
|
|
try:
|
|
|
|
from peewee import (
|
|
|
|
SqliteDatabase,
|
|
|
|
Model,
|
|
|
|
ForeignKeyField,
|
|
|
|
CharField,
|
|
|
|
AutoField,
|
|
|
|
DateTimeField,
|
|
|
|
BooleanField,
|
|
|
|
IntegerField,
|
|
|
|
FloatField,
|
2022-05-25 11:16:14 +00:00
|
|
|
DoesNotExist,
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
except ModuleNotFoundError as e:
|
|
|
|
Helpers.auto_installer_fix(e)
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
peewee_logger = logging.getLogger("peewee")
|
|
|
|
peewee_logger.setLevel(logging.INFO)
|
|
|
|
|
|
|
|
|
|
|
|
# **********************************************************************************
|
|
|
|
# Servers Stats Class
|
|
|
|
# **********************************************************************************
|
|
|
|
class ServerStats(Model):
|
|
|
|
stats_id = AutoField()
|
|
|
|
created = DateTimeField(default=datetime.datetime.now)
|
|
|
|
server_id = ForeignKeyField(Servers, backref="server", index=True)
|
|
|
|
started = CharField(default="")
|
|
|
|
running = BooleanField(default=False)
|
|
|
|
cpu = FloatField(default=0)
|
|
|
|
mem = FloatField(default=0)
|
|
|
|
mem_percent = FloatField(default=0)
|
|
|
|
world_name = CharField(default="")
|
|
|
|
world_size = CharField(default="")
|
|
|
|
server_port = IntegerField(default=25565)
|
|
|
|
int_ping_results = CharField(default="")
|
|
|
|
online = IntegerField(default=0)
|
|
|
|
max = IntegerField(default=0)
|
|
|
|
players = CharField(default="")
|
|
|
|
desc = CharField(default="Unable to Connect")
|
|
|
|
version = CharField(default="")
|
|
|
|
updating = BooleanField(default=False)
|
|
|
|
waiting_start = BooleanField(default=False)
|
|
|
|
first_run = BooleanField(default=True)
|
|
|
|
crashed = BooleanField(default=False)
|
|
|
|
downloading = BooleanField(default=False)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
table_name = "server_stats"
|
|
|
|
|
|
|
|
|
|
|
|
# **********************************************************************************
|
|
|
|
# Servers_Stats Methods
|
|
|
|
# **********************************************************************************
|
|
|
|
class HelperServerStats:
|
|
|
|
def __init__(self, database):
|
|
|
|
self.database = database
|
|
|
|
|
|
|
|
@staticmethod
|
2022-05-24 22:48:27 +00:00
|
|
|
def init_database(server_id) -> t.Optional[SqliteDatabase]:
|
2022-04-27 19:07:34 +00:00
|
|
|
try:
|
|
|
|
server = HelperServers.get_server_data_by_id(server_id)
|
|
|
|
db_folder = os.path.join(f"{server['path']}", "db_stats")
|
|
|
|
db_file = os.path.join(
|
|
|
|
db_folder,
|
2022-05-19 16:14:30 +00:00
|
|
|
"crafty_server_stats.sqlite",
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
database = SqliteDatabase(
|
|
|
|
db_file, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
|
|
|
|
)
|
|
|
|
if not os.path.exists(db_file):
|
|
|
|
try:
|
|
|
|
os.mkdir(db_folder)
|
|
|
|
except Exception as ex:
|
|
|
|
logger.warning(
|
|
|
|
f"Error try to create the db_stats folder for server : {ex}"
|
|
|
|
)
|
|
|
|
helper_stats = Helpers()
|
|
|
|
helper_stats.migration_dir = os.path.join(
|
|
|
|
f"{helper_stats.migration_dir}", "stats"
|
|
|
|
)
|
|
|
|
helper_stats.db_path = db_file
|
|
|
|
migration_manager = MigrationManager(database, helper_stats)
|
|
|
|
migration_manager.up() # Automatically runs migrations
|
2022-05-24 22:48:27 +00:00
|
|
|
return database
|
2022-04-27 19:07:34 +00:00
|
|
|
except Exception as ex:
|
|
|
|
logger.warning(
|
|
|
|
f"Error try to look for the db_stats files for server : {ex}"
|
|
|
|
)
|
2022-05-24 22:48:27 +00:00
|
|
|
return None
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
2022-05-24 22:48:27 +00:00
|
|
|
def select_database(server_id) -> t.Optional[SqliteDatabase]:
|
2022-04-27 19:07:34 +00:00
|
|
|
try:
|
|
|
|
server = HelperServers.get_server_data_by_id(server_id)
|
|
|
|
db_file = os.path.join(
|
|
|
|
f"{server['path']}",
|
|
|
|
"db_stats",
|
2022-05-19 16:14:30 +00:00
|
|
|
"crafty_server_stats.sqlite",
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
database = SqliteDatabase(
|
|
|
|
db_file, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
|
|
|
|
)
|
2022-05-24 22:48:27 +00:00
|
|
|
return database
|
2022-04-27 19:07:34 +00:00
|
|
|
except Exception as ex:
|
|
|
|
logger.warning(
|
|
|
|
f"Error try to look for the db_stats files for server : {ex}"
|
|
|
|
)
|
2022-05-24 22:48:27 +00:00
|
|
|
return None
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_all_servers_stats():
|
|
|
|
servers = HelperServers.get_all_defined_servers()
|
|
|
|
server_data = []
|
|
|
|
try:
|
2022-05-24 22:48:27 +00:00
|
|
|
for server in servers:
|
|
|
|
stats = HelperServerStats.get_server_stats_by_id(server["server_id"])
|
|
|
|
|
2022-04-27 19:07:34 +00:00
|
|
|
server_data.append(
|
|
|
|
{
|
2022-05-24 22:48:27 +00:00
|
|
|
"server_data": server,
|
|
|
|
"stats": stats,
|
2022-04-27 19:07:34 +00:00
|
|
|
"user_command_permission": True,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
except IndexError as ex:
|
|
|
|
logger.error(
|
|
|
|
f"Stats collection failed with error: {ex}. Was a server just created?"
|
|
|
|
)
|
|
|
|
return server_data
|
|
|
|
|
|
|
|
@staticmethod
|
2022-05-25 13:15:51 +00:00
|
|
|
def insert_server_stats(server_stats):
|
|
|
|
server_id = server_stats.get("id", 0)
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
if server_id == 0:
|
|
|
|
logger.warning("Stats saving failed with error: Server unknown (id = 0)")
|
|
|
|
return
|
|
|
|
|
|
|
|
ServerStats.insert(
|
|
|
|
{
|
2022-05-25 13:15:51 +00:00
|
|
|
ServerStats.server_id: server_stats.get("id", 0),
|
|
|
|
ServerStats.started: server_stats.get("started", ""),
|
|
|
|
ServerStats.running: server_stats.get("running", False),
|
|
|
|
ServerStats.cpu: server_stats.get("cpu", 0),
|
|
|
|
ServerStats.mem: server_stats.get("mem", 0),
|
|
|
|
ServerStats.mem_percent: server_stats.get("mem_percent", 0),
|
|
|
|
ServerStats.world_name: server_stats.get("world_name", ""),
|
|
|
|
ServerStats.world_size: server_stats.get("world_size", ""),
|
2022-06-01 19:35:11 +00:00
|
|
|
ServerStats.server_port: server_stats.get("server_port", 0),
|
2022-05-25 13:15:51 +00:00
|
|
|
ServerStats.int_ping_results: server_stats.get(
|
|
|
|
"int_ping_results", False
|
|
|
|
),
|
|
|
|
ServerStats.online: server_stats.get("online", False),
|
|
|
|
ServerStats.max: server_stats.get("max", False),
|
|
|
|
ServerStats.players: server_stats.get("players", False),
|
|
|
|
ServerStats.desc: server_stats.get("desc", False),
|
|
|
|
ServerStats.version: server_stats.get("version", False),
|
2022-04-27 19:07:34 +00:00
|
|
|
}
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
2022-05-25 11:49:17 +00:00
|
|
|
def remove_old_stats(server_id, minimum_to_exist):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-06-01 19:35:11 +00:00
|
|
|
ServerStats.delete().where(ServerStats.created < minimum_to_exist).execute(
|
|
|
|
database
|
|
|
|
)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_latest_server_stats(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
return (
|
|
|
|
ServerStats.select()
|
|
|
|
.where(ServerStats.server_id == server_id)
|
|
|
|
.order_by(ServerStats.created.desc())
|
|
|
|
.limit(1)
|
2022-05-24 22:48:27 +00:00
|
|
|
.execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_server_stats_by_id(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
stats = (
|
|
|
|
ServerStats.select()
|
|
|
|
.where(ServerStats.server_id == server_id)
|
|
|
|
.order_by(ServerStats.created.desc())
|
|
|
|
.limit(1)
|
2022-05-24 22:48:27 +00:00
|
|
|
.first(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
2022-05-24 22:48:27 +00:00
|
|
|
return model_to_dict(stats)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def server_id_exists(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
|
|
|
# We can't use .exists because it doesn't seem to use the database parameter
|
|
|
|
return (
|
|
|
|
ServerStats.select()
|
|
|
|
.where(ServerStats.server_id == server_id)
|
|
|
|
.count(database)
|
|
|
|
!= 0
|
|
|
|
)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def sever_crashed(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(crashed=True).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def set_download(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(downloading=True).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def finish_download(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(downloading=False).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_download_status(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
download_status = (
|
2022-05-24 22:48:27 +00:00
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
return download_status.downloading
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def server_crash_reset(server_id):
|
|
|
|
if server_id is None:
|
|
|
|
return
|
|
|
|
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(crashed=False).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def is_crashed(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
|
|
|
svr = (
|
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
|
|
|
|
)
|
|
|
|
return svr.crashed
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def set_update(server_id, value):
|
|
|
|
if server_id is None:
|
|
|
|
return
|
|
|
|
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
try:
|
|
|
|
# Checks if server even exists
|
2022-05-24 22:48:27 +00:00
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).execute(
|
|
|
|
database
|
|
|
|
)
|
|
|
|
except DoesNotExist as ex:
|
2022-04-27 19:07:34 +00:00
|
|
|
logger.error(f"Database entry not found! {ex}")
|
2022-05-24 22:48:27 +00:00
|
|
|
return
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(updating=value).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_update_status(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
update_status = (
|
2022-05-24 22:48:27 +00:00
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
return update_status.updating
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def set_first_run(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
# Sets first run to false
|
|
|
|
try:
|
|
|
|
# Checks if server even exists
|
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id)
|
2022-05-24 22:48:27 +00:00
|
|
|
except DoesNotExist as ex:
|
2022-04-27 19:07:34 +00:00
|
|
|
logger.error(f"Database entry not found! {ex}")
|
|
|
|
return
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(first_run=False).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_first_run(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
|
|
|
first_run = (
|
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
|
|
|
|
)
|
2022-04-27 19:07:34 +00:00
|
|
|
return first_run.first_run
|
|
|
|
|
|
|
|
@staticmethod
|
2022-04-28 20:24:34 +00:00
|
|
|
def get_ttl_without_player(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
last_stat = (
|
|
|
|
ServerStats.select()
|
|
|
|
.where(ServerStats.server_id == server_id)
|
|
|
|
.order_by(ServerStats.created.desc())
|
2022-05-24 22:48:27 +00:00
|
|
|
.first(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
last_stat_with_player = (
|
|
|
|
ServerStats.select()
|
|
|
|
.where(ServerStats.server_id == server_id)
|
|
|
|
.where(ServerStats.online > 0)
|
|
|
|
.order_by(ServerStats.created.desc())
|
2022-05-24 22:48:27 +00:00
|
|
|
.first(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
return last_stat.created - last_stat_with_player.created
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def can_stop_no_players(server_id, time_limit):
|
2022-04-28 20:25:59 +00:00
|
|
|
ttl_no_players = HelperServerStats.get_ttl_without_player(server_id)
|
2022-05-24 22:48:27 +00:00
|
|
|
return (time_limit == -1) or (ttl_no_players > time_limit)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def set_waiting_start(server_id, value):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
try:
|
|
|
|
# Checks if server even exists
|
2022-05-24 22:48:27 +00:00
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).execute(
|
|
|
|
database
|
|
|
|
)
|
|
|
|
except DoesNotExist as ex:
|
2022-04-27 19:07:34 +00:00
|
|
|
logger.error(f"Database entry not found! {ex}")
|
2022-05-24 22:48:27 +00:00
|
|
|
return
|
2022-05-21 18:26:58 +00:00
|
|
|
ServerStats.update(waiting_start=value).where(
|
|
|
|
ServerStats.server_id == server_id
|
2022-05-24 22:48:27 +00:00
|
|
|
).execute(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_waiting_start(server_id):
|
2022-05-24 22:48:27 +00:00
|
|
|
database = HelperServerStats.select_database(server_id)
|
2022-04-27 19:07:34 +00:00
|
|
|
waiting_start = (
|
2022-05-24 22:48:27 +00:00
|
|
|
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
|
2022-04-27 19:07:34 +00:00
|
|
|
)
|
|
|
|
return waiting_start.waiting_start
|