mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
One monster truck commit for rework and backups
This commit is contained in:
parent
12cc971c64
commit
81c60d6dac
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@ venv.bak/
|
||||
|
||||
.idea/
|
||||
servers/
|
||||
backups/
|
||||
session.lock
|
||||
.header
|
||||
default.json
|
||||
|
@ -9,7 +9,6 @@ from datetime import datetime
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.models import Servers
|
||||
# from app.classes.shared.controller import controller
|
||||
from app.classes.minecraft.server_props import ServerProps
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -8,7 +8,6 @@ import datetime
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.minecraft.mc_ping import ping
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.shared.models import db_helper
|
||||
from app.classes.shared.models import Host_Stats, Server_Stats
|
||||
|
||||
@ -17,6 +16,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Stats:
|
||||
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
|
||||
def get_node_stats(self):
|
||||
boot_time = datetime.datetime.fromtimestamp(psutil.boot_time())
|
||||
data = {}
|
||||
@ -184,7 +186,7 @@ class Stats:
|
||||
server_stats_list = []
|
||||
server_stats = {}
|
||||
|
||||
servers = controller.servers_list
|
||||
servers = self.controller.servers_list
|
||||
|
||||
logger.info("Getting Stats for all servers...")
|
||||
|
||||
@ -210,7 +212,7 @@ class Stats:
|
||||
internal_ip = server_data.get('server_ip', "127.0.0.1")
|
||||
server_port = server_settings.get('server_port', "25565")
|
||||
|
||||
logger.debug("Pinging {} on port {}".format(internal_ip, server_port))
|
||||
logger.debug("Pinging server '{}' on {}:{}".format(s.get('server_name', "ID#{}".format(server_id)), internal_ip, server_port))
|
||||
int_mc_ping = ping(internal_ip, int(server_port))
|
||||
|
||||
int_data = False
|
||||
@ -288,5 +290,3 @@ class Stats:
|
||||
|
||||
Host_Stats.delete().where(Host_Stats.time < last_week).execute()
|
||||
Server_Stats.delete().where(Server_Stats.created < last_week).execute()
|
||||
|
||||
stats = Stats()
|
||||
|
@ -9,7 +9,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.tasks import tasks_manager
|
||||
from app.classes.web.websocket_helper import websocket_helper
|
||||
|
||||
try:
|
||||
@ -21,7 +20,11 @@ except ModuleNotFoundError as e:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class MainPrompt(cmd.Cmd):
|
||||
class MainPrompt(cmd.Cmd, object):
|
||||
|
||||
def __init__(self, tasks_manager):
|
||||
super().__init__()
|
||||
self.tasks_manager = tasks_manager
|
||||
|
||||
# overrides the default Prompt
|
||||
prompt = "Crafty Controller v{} > ".format(helper.get_version_string())
|
||||
@ -48,7 +51,7 @@ class MainPrompt(cmd.Cmd):
|
||||
self._clean_shutdown()
|
||||
console.info('Waiting for main thread to stop')
|
||||
while True:
|
||||
if tasks_manager.get_main_thread_run_status():
|
||||
if self.tasks_manager.get_main_thread_run_status():
|
||||
sys.exit(0)
|
||||
time.sleep(1)
|
||||
|
||||
|
@ -15,6 +15,7 @@ from app.classes.shared.models import db_helper, Servers
|
||||
from app.classes.shared.server import Server
|
||||
from app.classes.minecraft.server_props import ServerProps
|
||||
from app.classes.minecraft.serverjars import server_jar_obj
|
||||
from app.classes.minecraft.stats import Stats
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -23,6 +24,7 @@ class Controller:
|
||||
|
||||
def __init__(self):
|
||||
self.servers_list = []
|
||||
self.stats = Stats(self)
|
||||
|
||||
def check_server_loaded(self, server_id_to_check: int):
|
||||
|
||||
@ -72,7 +74,7 @@ class Controller:
|
||||
temp_server_dict = {
|
||||
'server_id': s.get('server_id'),
|
||||
'server_data_obj': s,
|
||||
'server_obj': Server(),
|
||||
'server_obj': Server(self.stats),
|
||||
'server_settings': settings.props
|
||||
}
|
||||
|
||||
@ -94,7 +96,6 @@ class Controller:
|
||||
server_obj.reload_server_settings()
|
||||
|
||||
def get_server_obj(self, server_id):
|
||||
|
||||
for s in self.servers_list:
|
||||
if int(s['server_id']) == int(server_id):
|
||||
return s['server_obj']
|
||||
@ -190,12 +191,14 @@ class Controller:
|
||||
def create_jar_server(self, server: str, version: str, name: str, min_mem: int, max_mem: int, port: int):
|
||||
server_id = helper.create_uuid()
|
||||
server_dir = os.path.join(helper.servers_dir, server_id)
|
||||
backup_path = os.path.join(helper.backup_path, server_id)
|
||||
|
||||
server_file = "{server}-{version}.jar".format(server=server, version=version)
|
||||
full_jar_path = os.path.join(server_dir, server_file)
|
||||
|
||||
# make the dir - perhaps a UUID?
|
||||
helper.ensure_dir_exists(server_dir)
|
||||
helper.ensure_dir_exists(backup_path)
|
||||
|
||||
try:
|
||||
# do a eula.txt
|
||||
@ -221,7 +224,7 @@ class Controller:
|
||||
# download the jar
|
||||
server_jar_obj.download_jar(server, version, full_jar_path)
|
||||
|
||||
new_id = self.register_server(name, server_id, server_dir, server_command, server_file, server_log_file, server_stop)
|
||||
new_id = self.register_server(name, server_id, server_dir, backup_path, server_command, server_file, server_log_file, server_stop)
|
||||
return new_id
|
||||
|
||||
@staticmethod
|
||||
@ -242,8 +245,10 @@ class Controller:
|
||||
def import_jar_server(self, server_name: str, server_path: str, server_jar: str, min_mem: int, max_mem: int, port: int):
|
||||
server_id = helper.create_uuid()
|
||||
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
||||
backup_path = os.path.join(helper.backup_path, server_id)
|
||||
|
||||
helper.ensure_dir_exists(new_server_dir)
|
||||
helper.ensure_dir_exists(backup_path)
|
||||
dir_util.copy_tree(server_path, new_server_dir)
|
||||
|
||||
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||
@ -253,15 +258,18 @@ class Controller:
|
||||
server_log_file = "{}/logs/latest.log".format(new_server_dir)
|
||||
server_stop = "stop"
|
||||
|
||||
new_id = self.register_server(server_name, server_id, new_server_dir, server_command, server_jar,
|
||||
new_id = self.register_server(server_name, server_id, new_server_dir, backup_path, server_command, server_jar,
|
||||
server_log_file, server_stop, port)
|
||||
return new_id
|
||||
|
||||
def import_zip_server(self, server_name: str, zip_path: str, server_jar: str, min_mem: int, max_mem: int, port: int):
|
||||
server_id = helper.create_uuid()
|
||||
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
||||
backup_path = os.path.join(helper.backup_path, server_id)
|
||||
|
||||
if helper.check_file_perms(zip_path):
|
||||
helper.ensure_dir_exists(new_server_dir)
|
||||
helper.ensure_dir_exists(backup_path)
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(new_server_dir)
|
||||
else:
|
||||
@ -275,11 +283,11 @@ class Controller:
|
||||
server_log_file = "{}/logs/latest.log".format(new_server_dir)
|
||||
server_stop = "stop"
|
||||
|
||||
new_id = self.register_server(server_name, server_id, new_server_dir, server_command, server_jar,
|
||||
new_id = self.register_server(server_name, server_id, new_server_dir, backup_path, server_command, server_jar,
|
||||
server_log_file, server_stop, port)
|
||||
return new_id
|
||||
|
||||
def register_server(self, name: str, server_id: str, server_dir: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565):
|
||||
def register_server(self, name: str, server_id: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565):
|
||||
# put data in the db
|
||||
new_id = Servers.insert({
|
||||
Servers.server_name: name,
|
||||
@ -292,7 +300,8 @@ class Controller:
|
||||
Servers.crash_detection: False,
|
||||
Servers.log_path: server_log_file,
|
||||
Servers.server_port: server_port,
|
||||
Servers.stop_command: server_stop
|
||||
Servers.stop_command: server_stop,
|
||||
Servers.backup_path: backup_path
|
||||
}).execute()
|
||||
|
||||
try:
|
||||
@ -336,6 +345,3 @@ class Controller:
|
||||
self.servers_list.pop(counter)
|
||||
|
||||
counter += 1
|
||||
|
||||
|
||||
controller = Controller()
|
||||
|
8
app/classes/shared/exceptions.py
Normal file
8
app/classes/shared/exceptions.py
Normal file
@ -0,0 +1,8 @@
|
||||
class CraftyException(Exception):
|
||||
pass
|
||||
|
||||
class DatabaseException(CraftyException):
|
||||
pass
|
||||
|
||||
class SchemaError(DatabaseException):
|
||||
pass
|
@ -10,6 +10,8 @@ import socket
|
||||
import random
|
||||
import logging
|
||||
import html
|
||||
import zipfile
|
||||
import pathlib
|
||||
|
||||
from datetime import datetime
|
||||
from socket import gethostname
|
||||
@ -36,6 +38,7 @@ class Helpers:
|
||||
self.config_dir = os.path.join(self.root_dir, 'app', 'config')
|
||||
self.webroot = os.path.join(self.root_dir, 'app', 'frontend')
|
||||
self.servers_dir = os.path.join(self.root_dir, 'servers')
|
||||
self.backup_path = os.path.join(self.root_dir, 'backups')
|
||||
|
||||
self.session_file = os.path.join(self.root_dir, 'app', 'config', 'session.lock')
|
||||
self.settings_file = os.path.join(self.root_dir, 'app', 'config', 'config.json')
|
||||
@ -306,6 +309,8 @@ class Helpers:
|
||||
|
||||
@staticmethod
|
||||
def check_path_exists(path: str):
|
||||
if not path:
|
||||
return False
|
||||
logger.debug('Looking for path: {}'.format(path))
|
||||
|
||||
if os.path.exists(path):
|
||||
@ -372,6 +377,19 @@ class Helpers:
|
||||
total += entry.stat(follow_symlinks=False).st_size
|
||||
return total
|
||||
|
||||
@staticmethod
|
||||
def list_dir_by_date(path: str, reverse=False):
|
||||
return [str(p) for p in sorted(pathlib.Path(path).iterdir(), key=os.path.getmtime, reverse=reverse)]
|
||||
|
||||
def get_human_readable_files_sizes(self, paths: list):
|
||||
sizes = []
|
||||
for p in paths:
|
||||
sizes.append({
|
||||
"path": p,
|
||||
"size": self.human_readable_file_size(os.stat(p).st_size)
|
||||
})
|
||||
return sizes
|
||||
|
||||
@staticmethod
|
||||
def base64_encode_string(string: str):
|
||||
s_bytes = str(string).encode('utf-8')
|
||||
@ -521,7 +539,7 @@ class Helpers:
|
||||
@staticmethod
|
||||
def get_banned_players(server_id, db_helper):
|
||||
stats = db_helper.get_server_stats_by_id(server_id)
|
||||
server_path = stats[0]['server_id']['path']
|
||||
server_path = stats['server_id']['path']
|
||||
path = os.path.join(server_path, 'banned-players.json')
|
||||
|
||||
try:
|
||||
@ -534,5 +552,13 @@ class Helpers:
|
||||
|
||||
return json.loads(content)
|
||||
|
||||
@staticmethod
|
||||
def zip_directory(file, path, compression=zipfile.ZIP_LZMA):
|
||||
with zipfile.ZipFile(file, 'w', compression) as zf:
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
zf.write(os.path.join(root, file),
|
||||
os.path.relpath(os.path.join(root, file),
|
||||
os.path.join(path, '..')))
|
||||
|
||||
helper = Helpers()
|
||||
|
@ -9,6 +9,8 @@ from app.classes.minecraft.server_props import ServerProps
|
||||
from app.classes.web.websocket_helper import websocket_helper
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
peewee_logger = logging.getLogger('peewee')
|
||||
peewee_logger.setLevel(logging.INFO)
|
||||
|
||||
try:
|
||||
from peewee import *
|
||||
@ -20,15 +22,30 @@ except ModuleNotFoundError as e:
|
||||
console.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
sys.exit(1)
|
||||
|
||||
schema_version = (0, 1, 0) # major, minor, patch semver
|
||||
|
||||
database = SqliteDatabase(helper.db_path, pragmas={
|
||||
'journal_mode': 'wal',
|
||||
'cache_size': -1024 * 10})
|
||||
|
||||
|
||||
class BaseModel(Model):
|
||||
class Meta:
|
||||
database = database
|
||||
|
||||
class SchemaVersion(BaseModel):
|
||||
# DO NOT EVER CHANGE THE SCHEMA OF THIS TABLE
|
||||
# (unless we have a REALLY good reason to)
|
||||
# There will only ever be one row, and it allows the database loader to detect
|
||||
# what it needs to do on major version upgrades so you don't have to wipe the DB
|
||||
# every time you upgrade
|
||||
schema_major = IntegerField()
|
||||
schema_minor = IntegerField()
|
||||
schema_patch = IntegerField()
|
||||
|
||||
class Meta:
|
||||
table_name = 'schema_version'
|
||||
primary_key = CompositeKey('schema_major', 'schema_minor', 'schema_patch')
|
||||
|
||||
|
||||
class Users(BaseModel):
|
||||
user_id = AutoField()
|
||||
@ -97,6 +114,7 @@ class Servers(BaseModel):
|
||||
server_uuid = CharField(default="", index=True)
|
||||
server_name = CharField(default="Server", index=True)
|
||||
path = CharField(default="")
|
||||
backup_path = CharField(default="")
|
||||
executable = CharField(default="")
|
||||
log_path = CharField(default="")
|
||||
execution_command = CharField(default="")
|
||||
@ -111,16 +129,6 @@ class Servers(BaseModel):
|
||||
class Meta:
|
||||
table_name = "servers"
|
||||
|
||||
|
||||
class User_Servers(BaseModel):
|
||||
user_id = ForeignKeyField(Users, backref='user_server')
|
||||
server_id = ForeignKeyField(Servers, backref='user_server')
|
||||
|
||||
class Meta:
|
||||
table_name = 'user_servers'
|
||||
primary_key = CompositeKey('user_id', 'server_id')
|
||||
|
||||
|
||||
class Role_Servers(BaseModel):
|
||||
role_id = ForeignKeyField(Roles, backref='role_server')
|
||||
server_id = ForeignKeyField(Servers, backref='role_server')
|
||||
@ -178,12 +186,25 @@ class Webhooks(BaseModel):
|
||||
class Meta:
|
||||
table_name = "webhooks"
|
||||
|
||||
class Schedules(BaseModel):
|
||||
schedule_id = IntegerField(unique=True, primary_key=True)
|
||||
server_id = ForeignKeyField(Servers, backref='schedule_server')
|
||||
enabled = BooleanField()
|
||||
action = CharField()
|
||||
interval = IntegerField()
|
||||
interval_type = CharField()
|
||||
start_time = CharField(null=True)
|
||||
command = CharField(null=True)
|
||||
comment = CharField()
|
||||
|
||||
class Meta:
|
||||
table_name = 'schedules'
|
||||
|
||||
class Backups(BaseModel):
|
||||
directories = CharField()
|
||||
storage_location = CharField()
|
||||
directories = CharField(null=True)
|
||||
max_backups = IntegerField()
|
||||
server_id = IntegerField(index=True)
|
||||
server_id = ForeignKeyField(Servers, backref='backups_server')
|
||||
schedule_id = ForeignKeyField(Schedules, backref='backups_schedule')
|
||||
|
||||
class Meta:
|
||||
table_name = 'backups'
|
||||
@ -202,17 +223,23 @@ class db_builder:
|
||||
Host_Stats,
|
||||
Webhooks,
|
||||
Servers,
|
||||
User_Servers,
|
||||
Role_Servers,
|
||||
Server_Stats,
|
||||
Commands,
|
||||
Audit_Log
|
||||
Audit_Log,
|
||||
SchemaVersion,
|
||||
Schedules
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def default_settings():
|
||||
logger.info("Fresh Install Detected - Creating Default Settings")
|
||||
console.info("Fresh Install Detected - Creating Default Settings")
|
||||
SchemaVersion.insert({
|
||||
SchemaVersion.schema_major: schema_version[0],
|
||||
SchemaVersion.schema_minor: schema_version[1],
|
||||
SchemaVersion.schema_patch: schema_version[2]
|
||||
}).execute()
|
||||
default_data = helper.find_default_password()
|
||||
|
||||
username = default_data.get("username", 'admin')
|
||||
@ -239,9 +266,39 @@ class db_builder:
|
||||
return True
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def check_schema_version():
|
||||
svs = SchemaVersion.select().execute()
|
||||
if len(svs) != 1:
|
||||
raise exceptions.SchemaError("Multiple or no schema versions detected - potentially a failed upgrade?")
|
||||
sv = svs[0]
|
||||
svt = (sv.schema_major, sv.schema_minor, sv.schema_patch)
|
||||
logger.debug("Schema: found {}, expected {}".format(svt, schema_version))
|
||||
console.debug("Schema: found {}, expected {}".format(svt, schema_version))
|
||||
if sv.schema_major > schema_version[0]:
|
||||
raise exceptions.SchemaError("Major version mismatch - possible code reversion")
|
||||
elif sv.schema_major < schema_version[0]:
|
||||
db_shortcuts.upgrade_schema()
|
||||
|
||||
if sv.schema_minor > schema_version[1]:
|
||||
logger.warning("Schema minor mismatch detected: found {}, expected {}. Proceed with caution".format(svt, schema_version))
|
||||
console.warning("Schema minor mismatch detected: found {}, expected {}. Proceed with caution".format(svt, schema_version))
|
||||
elif sv.schema_minor < schema_version[1]:
|
||||
db_shortcuts.upgrade_schema()
|
||||
|
||||
if sv.schema_patch > schema_version[2]:
|
||||
logger.info("Schema patch mismatch detected: found {}, expected {}. Proceed with caution".format(svt, schema_version))
|
||||
console.info("Schema patch mismatch detected: found {}, expected {}. Proceed with caution".format(svt, schema_version))
|
||||
elif sv.schema_patch < schema_version[2]:
|
||||
db_shortcuts.upgrade_schema()
|
||||
logger.info("Schema validation successful! {}".format(schema_version))
|
||||
|
||||
class db_shortcuts:
|
||||
|
||||
@staticmethod
|
||||
def upgrade_schema():
|
||||
raise NotImplemented("I don't know who you are or how you reached this code, but this should NOT have happened. Please report it to the developer with due haste.")
|
||||
|
||||
@staticmethod
|
||||
def return_rows(query):
|
||||
rows = []
|
||||
@ -258,13 +315,12 @@ class db_shortcuts:
|
||||
|
||||
@staticmethod
|
||||
def get_server_data_by_id(server_id):
|
||||
query = Servers.select().where(Servers.server_id == server_id).limit(1)
|
||||
try:
|
||||
query = Servers.get_by_id(server_id)
|
||||
except DoesNotExist:
|
||||
return db_helper.return_rows(query)[0]
|
||||
except IndexError:
|
||||
return {}
|
||||
|
||||
return model_to_dict(query)
|
||||
|
||||
@staticmethod
|
||||
def get_all_defined_servers():
|
||||
query = Servers.select()
|
||||
@ -277,13 +333,13 @@ class db_shortcuts:
|
||||
|
||||
for s in servers:
|
||||
latest = Server_Stats.select().where(Server_Stats.server_id == s.get('server_id')).order_by(Server_Stats.created.desc()).limit(1)
|
||||
server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)})
|
||||
server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0]})
|
||||
return server_data
|
||||
|
||||
@staticmethod
|
||||
def get_server_stats_by_id(server_id):
|
||||
stats = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).limit(1)
|
||||
return db_helper.return_rows(stats)
|
||||
return db_helper.return_rows(stats)[0]
|
||||
|
||||
@staticmethod
|
||||
def server_id_exists(server_id):
|
||||
@ -316,6 +372,8 @@ class db_shortcuts:
|
||||
|
||||
@staticmethod
|
||||
def get_userid_by_name(username):
|
||||
if username == "SYSTEM":
|
||||
return 0
|
||||
try:
|
||||
return (Users.get(Users.username == username)).user_id
|
||||
except DoesNotExist:
|
||||
@ -323,6 +381,21 @@ class db_shortcuts:
|
||||
|
||||
@staticmethod
|
||||
def get_user(user_id):
|
||||
if user_id == 0:
|
||||
return {
|
||||
user_id: 0,
|
||||
created: None,
|
||||
last_login: None,
|
||||
last_update: None,
|
||||
last_ip: "127.27.23.89",
|
||||
username: "SYSTEM",
|
||||
password: None,
|
||||
enabled: True,
|
||||
superuser: False,
|
||||
api_token: None,
|
||||
roles: [],
|
||||
servers: []
|
||||
}
|
||||
user = model_to_dict(Users.get(Users.user_id == user_id))
|
||||
|
||||
if user:
|
||||
@ -331,13 +404,13 @@ class db_shortcuts:
|
||||
roles = set()
|
||||
for r in roles_query:
|
||||
roles.add(r.role_id.role_id)
|
||||
servers_query = User_Servers.select().join(Servers, JOIN.INNER).where(User_Servers.user_id == user_id)
|
||||
# TODO: this query needs to be narrower
|
||||
#servers_query = User_Servers.select().join(Servers, JOIN.INNER).where(User_Servers.user_id == user_id)
|
||||
## TODO: this query needs to be narrower
|
||||
servers = set()
|
||||
for s in servers_query:
|
||||
servers.add(s.server_id.server_id)
|
||||
#for s in servers_query:
|
||||
# servers.add(s.server_id.server_id)
|
||||
user['roles'] = roles
|
||||
user['servers'] = servers
|
||||
#user['servers'] = servers
|
||||
logger.debug("user: ({}) {}".format(user_id, user))
|
||||
return user
|
||||
else:
|
||||
@ -377,10 +450,10 @@ class db_shortcuts:
|
||||
# TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point
|
||||
User_Roles.delete().where(User_Roles.user_id == user_id).where(User_Roles.role_id.in_(removed_roles)).execute()
|
||||
|
||||
for server in added_servers:
|
||||
User_Servers.get_or_create(user_id=user_id, server_id=server)
|
||||
# TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point
|
||||
User_Servers.delete().where(User_Servers.user_id == user_id).where(User_Servers.server_id.in_(removed_servers)).execute()
|
||||
#for server in added_servers:
|
||||
# User_Servers.get_or_create(user_id=user_id, server_id=server)
|
||||
# # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point
|
||||
#User_Servers.delete().where(User_Servers.user_id == user_id).where(User_Servers.server_id.in_(removed_servers)).execute()
|
||||
if up_data:
|
||||
Users.update(up_data).where(Users.user_id == user_id).execute()
|
||||
|
||||
@ -555,8 +628,111 @@ class db_shortcuts:
|
||||
Audit_Log.source_ip: source_ip
|
||||
}).execute()
|
||||
|
||||
@staticmethod
|
||||
def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True):
|
||||
sch_id = Schedules.insert({
|
||||
Schedules.server_id: server_id,
|
||||
Schedules.action: action,
|
||||
Schedules.enabled: enabled,
|
||||
Schedules.interval: interval,
|
||||
Schedules.interval_type: interval_type,
|
||||
Schedules.start_time: start_time,
|
||||
Schedules.command: command,
|
||||
Schedules.comment: comment
|
||||
}).execute()
|
||||
return sch_id
|
||||
|
||||
@staticmethod
|
||||
def delete_scheduled_task(schedule_id):
|
||||
sch = Schedules.get(Schedules.schedule_id == schedule_id)
|
||||
return Schedules.delete_instance(sch)
|
||||
|
||||
@staticmethod
|
||||
def update_scheduled_task(schedule_id, updates):
|
||||
Schedules.update(updates).where(Schedules.schedule_id == schedule_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_scheduled_task(schedule_id):
|
||||
return model_to_dict(Schedules.get(Schedules.schedule_id == schedule_id)).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_schedules_by_server(server_id):
|
||||
return Schedules.select().where(Schedules.server_id == server_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_schedules_all():
|
||||
return Schedules.select().execute()
|
||||
|
||||
@staticmethod
|
||||
def get_schedules_enabled():
|
||||
return Schedules.select().where(Schedules.enabled == True).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_backup_config(server_id):
|
||||
try:
|
||||
row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0]
|
||||
conf = {
|
||||
"backup_path": row.server_id.backup_path,
|
||||
"directories": row.directories,
|
||||
"max_backups": row.max_backups,
|
||||
"auto_enabled": row.schedule_id.enabled,
|
||||
"server_id": row.server_id.server_id
|
||||
}
|
||||
except IndexError:
|
||||
conf = {
|
||||
"backup_path": None,
|
||||
"directories": None,
|
||||
"max_backups": 0,
|
||||
"auto_enabled": True,
|
||||
"server_id": server_id
|
||||
}
|
||||
return conf
|
||||
|
||||
@staticmethod
|
||||
def set_backup_config(server_id: int, backup_path: str = None, max_backups: int = None, auto_enabled: bool = True):
|
||||
logger.debug("Updating server {} backup config with {}".format(server_id, locals()))
|
||||
try:
|
||||
row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0]
|
||||
new_row = False
|
||||
conf = {}
|
||||
schd = {}
|
||||
except IndexError:
|
||||
conf = {
|
||||
"directories": None,
|
||||
"max_backups": 0,
|
||||
"server_id": server_id
|
||||
}
|
||||
schd = {
|
||||
"enabled": True,
|
||||
"action": "backup_server",
|
||||
"interval_type": "days",
|
||||
"interval": 1,
|
||||
"start_time": "00:00",
|
||||
"server_id": server_id,
|
||||
"comment": "Default backup job"
|
||||
}
|
||||
new_row = True
|
||||
if max_backups is not None:
|
||||
conf['max_backups'] = max_backups
|
||||
schd['enabled'] = bool(auto_enabled)
|
||||
if not new_row:
|
||||
with database.atomic():
|
||||
if backup_path is not None:
|
||||
u1 = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id).execute()
|
||||
else:
|
||||
u1 = 0
|
||||
u2 = Backups.update(conf).where(Backups.server_id == server_id).execute()
|
||||
u3 = Schedules.update(schd).where(Schedules.schedule_id == row.schedule_id).execute()
|
||||
logger.debug("Updating existing backup record. {}+{}+{} rows affected".format(u1, u2, u3))
|
||||
else:
|
||||
with database.atomic():
|
||||
conf["server_id"] = server_id
|
||||
if backup_path is not None:
|
||||
u = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id)
|
||||
s = Schedules.create(**schd)
|
||||
conf['schedule_id'] = s.schedule_id
|
||||
b = Backups.create(**conf)
|
||||
logger.debug("Creating new backup record.")
|
||||
|
||||
installer = db_builder()
|
||||
db_helper = db_shortcuts()
|
@ -9,6 +9,7 @@ import datetime
|
||||
import threading
|
||||
import schedule
|
||||
import logging.config
|
||||
import zipfile
|
||||
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
@ -29,7 +30,7 @@ except ModuleNotFoundError as e:
|
||||
|
||||
class Server:
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, stats):
|
||||
# holders for our process
|
||||
self.process = None
|
||||
self.line = False
|
||||
@ -45,6 +46,7 @@ class Server:
|
||||
self.is_crashed = False
|
||||
self.restart_count = 0
|
||||
self.crash_watcher_schedule = None
|
||||
self.stats = stats
|
||||
|
||||
def reload_server_settings(self):
|
||||
server_data = db_helper.get_server_data_by_id(self.server_id)
|
||||
@ -108,7 +110,6 @@ class Server:
|
||||
helper.do_exit()
|
||||
|
||||
def start_server(self):
|
||||
from app.classes.minecraft.stats import stats
|
||||
|
||||
# fail safe in case we try to start something already running
|
||||
if self.check_running():
|
||||
@ -160,7 +161,7 @@ class Server:
|
||||
logger.info("Server {} running with PID {}".format(self.name, self.PID))
|
||||
console.info("Server {} running with PID {}".format(self.name, self.PID))
|
||||
self.is_crashed = False
|
||||
stats.record_stats()
|
||||
self.stats.record_stats()
|
||||
else:
|
||||
logger.warning("Server PID {} died right after starting - is this a server config issue?".format(self.PID))
|
||||
console.warning("Server PID {} died right after starting - is this a server config issue?".format(self.PID))
|
||||
@ -178,7 +179,6 @@ class Server:
|
||||
self.server_thread.join()
|
||||
|
||||
def stop_server(self):
|
||||
from app.classes.minecraft.stats import stats
|
||||
if self.settings['stop_command']:
|
||||
self.send_command(self.settings['stop_command'])
|
||||
|
||||
@ -212,7 +212,7 @@ class Server:
|
||||
# massive resetting of variables
|
||||
self.cleanup_server_object()
|
||||
|
||||
stats.record_stats()
|
||||
self.stats.record_stats()
|
||||
|
||||
def restart_threaded_server(self):
|
||||
|
||||
@ -337,3 +337,26 @@ class Server:
|
||||
logger.info("Removing old crash detection watcher thread")
|
||||
console.info("Removing old crash detection watcher thread")
|
||||
schedule.clear(self.name)
|
||||
|
||||
def backup_server(self):
|
||||
logger.info("Starting server {} (ID {}) backup".format(self.name, self.server_id))
|
||||
conf = db_helper.get_backup_config(self.server_id)
|
||||
try:
|
||||
backup_filename = "{}/{}.zip".format(conf['backup_path'], datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
|
||||
logger.info("Creating backup of server '{}' (ID#{}) at '{}'".format(self.settings['server_name'], self.server_id, backup_filename))
|
||||
helper.zip_directory(backup_filename, self.server_path)
|
||||
backup_list = self.list_backups()
|
||||
if len(self.list_backups()) > conf["max_backups"]:
|
||||
oldfile = backup_list[0]
|
||||
logger.info("Removing old backup '{}'".format(oldfile))
|
||||
os.remove(oldfile)
|
||||
except:
|
||||
logger.exception("Failed to create backup of server {} (ID {})".format(self.name, self.server_id))
|
||||
|
||||
def list_backups(self):
|
||||
conf = db_helper.get_backup_config(self.server_id)
|
||||
if helper.check_path_exists(self.settings['backup_path']):
|
||||
files = helper.get_human_readable_files_sizes(helper.list_dir_by_date(self.settings['backup_path']))
|
||||
return [{"path": os.path.relpath(f['path'], start=conf['backup_path']), "size": f["size"]} for f in files]
|
||||
else:
|
||||
return []
|
||||
|
@ -8,11 +8,9 @@ import asyncio
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.web.tornado import webserver
|
||||
from app.classes.web.tornado import Webserver
|
||||
from app.classes.web.websocket_helper import websocket_helper
|
||||
|
||||
from app.classes.minecraft.stats import stats
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.minecraft.serverjars import server_jar_obj
|
||||
from app.classes.shared.models import db_helper
|
||||
|
||||
@ -26,11 +24,26 @@ except ModuleNotFoundError as e:
|
||||
console.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
sys.exit(1)
|
||||
|
||||
scheduler_intervals = { 'seconds',
|
||||
'minutes',
|
||||
'hours',
|
||||
'days',
|
||||
'weeks',
|
||||
'monday',
|
||||
'tuesday',
|
||||
'wednesday',
|
||||
'thursday',
|
||||
'friday',
|
||||
'saturday',
|
||||
'sunday'
|
||||
}
|
||||
|
||||
class TasksManager:
|
||||
|
||||
def __init__(self):
|
||||
self.tornado = webserver()
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
self.tornado = Webserver(controller, self)
|
||||
|
||||
self.webserver_thread = threading.Thread(target=self.tornado.run_tornado, daemon=True, name='tornado_thread')
|
||||
|
||||
self.main_kill_switch_thread = threading.Thread(target=self.main_kill_switch, daemon=True, name="main_loop")
|
||||
@ -39,13 +52,13 @@ class TasksManager:
|
||||
self.schedule_thread = threading.Thread(target=self.scheduler_thread, daemon=True, name="scheduler")
|
||||
|
||||
self.log_watcher_thread = threading.Thread(target=self.log_watcher, daemon=True, name="log_watcher")
|
||||
self.log_watcher_thread.start()
|
||||
|
||||
self.command_thread = threading.Thread(target=self.command_watcher, daemon=True, name="command_watcher")
|
||||
self.command_thread.start()
|
||||
|
||||
self.realtime_thread = threading.Thread(target=self.realtime, daemon=True, name="realtime")
|
||||
self.realtime_thread.start()
|
||||
|
||||
self.reload_schedule_from_db()
|
||||
|
||||
|
||||
def get_main_thread_run_status(self):
|
||||
return self.main_thread_exiting
|
||||
@ -60,14 +73,29 @@ class TasksManager:
|
||||
self._main_graceful_exit()
|
||||
time.sleep(5)
|
||||
|
||||
@staticmethod
|
||||
def command_watcher():
|
||||
def reload_schedule_from_db(self):
|
||||
jobs = db_helper.get_schedules_enabled()
|
||||
schedule.clear(tag='backup')
|
||||
schedule.clear(tag='db')
|
||||
for j in jobs:
|
||||
if j.interval_type in scheduler_intervals:
|
||||
logger.info("Loading schedule ID#{i}: '{a}' every {n} {t} at {s}".format(
|
||||
i=j.schedule_id, a=j.action, n=j.interval, t=j.interval_type, s=j.start_time))
|
||||
try:
|
||||
getattr(schedule.every(j.interval), j.interval_type).at(j.start_time).do(
|
||||
db_helper.send_command, 0, j.server_id, "127.27.23.89", j.action)
|
||||
except schedule.ScheduleValueError as e:
|
||||
logger.critical("Scheduler value error occurred: {} on ID#{}".format(e, j.schedule_id))
|
||||
else:
|
||||
logger.critical("Unknown schedule job type '{}' at id {}, skipping".format(j.interval_type, j.schedule_id))
|
||||
|
||||
def command_watcher(self):
|
||||
while True:
|
||||
# select any commands waiting to be processed
|
||||
commands = db_helper.get_unactioned_commands()
|
||||
for c in commands:
|
||||
|
||||
svr = controller.get_server_obj(c['server_id']['server_id'])
|
||||
svr = self.controller.get_server_obj(c['server_id']['server_id'])
|
||||
command = c.get('command', None)
|
||||
|
||||
if command == 'start_server':
|
||||
@ -79,6 +107,9 @@ class TasksManager:
|
||||
elif command == "restart_server":
|
||||
svr.restart_threaded_server()
|
||||
|
||||
elif command == "backup_server":
|
||||
svr.backup_server()
|
||||
|
||||
db_helper.mark_command_complete(c.get('command_id', None))
|
||||
|
||||
time.sleep(1)
|
||||
@ -88,7 +119,7 @@ class TasksManager:
|
||||
os.remove(helper.session_file)
|
||||
os.remove(os.path.join(helper.root_dir, 'exit.txt'))
|
||||
os.remove(os.path.join(helper.root_dir, '.header'))
|
||||
controller.stop_all_servers()
|
||||
self.controller.stop_all_servers()
|
||||
except:
|
||||
logger.info("Caught error during shutdown", exc_info=True)
|
||||
|
||||
@ -113,6 +144,15 @@ class TasksManager:
|
||||
logger.info("Launching Scheduler Thread...")
|
||||
console.info("Launching Scheduler Thread...")
|
||||
self.schedule_thread.start()
|
||||
logger.info("Launching command thread...")
|
||||
console.info("Launching command thread...")
|
||||
self.command_thread.start()
|
||||
logger.info("Launching log watcher...")
|
||||
console.info("Launching log watcher...")
|
||||
self.log_watcher_thread.start()
|
||||
logger.info("Launching realtime thread...")
|
||||
console.info("Launching realtime thread...")
|
||||
self.realtime_thread.start()
|
||||
|
||||
@staticmethod
|
||||
def scheduler_thread():
|
||||
@ -120,17 +160,16 @@ class TasksManager:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
|
||||
@staticmethod
|
||||
def start_stats_recording():
|
||||
def start_stats_recording(self):
|
||||
stats_update_frequency = helper.get_setting('stats_update_frequency')
|
||||
logger.info("Stats collection frequency set to {stats} seconds".format(stats=stats_update_frequency))
|
||||
console.info("Stats collection frequency set to {stats} seconds".format(stats=stats_update_frequency))
|
||||
|
||||
# one for now,
|
||||
stats.record_stats()
|
||||
self.controller.stats.record_stats()
|
||||
|
||||
# one for later
|
||||
schedule.every(stats_update_frequency).seconds.do(stats.record_stats)
|
||||
schedule.every(stats_update_frequency).seconds.do(self.controller.stats.record_stats).tag('stats-recording')
|
||||
|
||||
@staticmethod
|
||||
def serverjar_cache_refresher():
|
||||
@ -138,7 +177,7 @@ class TasksManager:
|
||||
server_jar_obj.refresh_cache()
|
||||
|
||||
logger.info("Scheduling Serverjars.com cache refresh service every 12 hours")
|
||||
schedule.every(12).hours.do(server_jar_obj.refresh_cache)
|
||||
schedule.every(12).hours.do(server_jar_obj.refresh_cache).tag('serverjars')
|
||||
|
||||
@staticmethod
|
||||
def realtime():
|
||||
@ -174,9 +213,4 @@ class TasksManager:
|
||||
def log_watcher(self):
|
||||
console.debug('in log_watcher')
|
||||
helper.check_for_old_logs(db_helper)
|
||||
schedule.every(6).hours.do(lambda: helper.check_for_old_logs(db_helper))
|
||||
|
||||
|
||||
|
||||
|
||||
tasks_manager = TasksManager()
|
||||
schedule.every(6).hours.do(lambda: helper.check_for_old_logs(db_helper)).tag('log-mgmt')
|
@ -9,7 +9,6 @@ import shutil
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.models import Users, installer
|
||||
from app.classes.web.base_handler import BaseHandler
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.shared.models import db_helper
|
||||
from app.classes.shared.helpers import helper
|
||||
|
||||
@ -56,8 +55,8 @@ class AjaxHandler(BaseHandler):
|
||||
logger.warning("Server Data not found in server_log ajax call")
|
||||
self.redirect("/panel/error?error=Server ID Not Found")
|
||||
|
||||
if server_data['log_path']:
|
||||
logger.warning("Server ID not found in server_log ajax call ({})".format(server_id))
|
||||
if not server_data['log_path']:
|
||||
logger.warning("Log path not found in server_log ajax call ({})".format(server_id))
|
||||
|
||||
if full_log:
|
||||
log_lines = helper.get_setting('max_log_lines')
|
||||
@ -149,7 +148,7 @@ class AjaxHandler(BaseHandler):
|
||||
logger.warning("Server ID not found in send_command ajax call")
|
||||
console.warning("Server ID not found in send_command ajax call")
|
||||
|
||||
srv_obj = controller.get_server_obj(server_id)
|
||||
srv_obj = self.controller.get_server_obj(server_id)
|
||||
|
||||
if command:
|
||||
if srv_obj.check_running():
|
||||
@ -219,7 +218,6 @@ class AjaxHandler(BaseHandler):
|
||||
if page == "del_file":
|
||||
file_path = self.get_body_argument('file_path', default=None, strip=True)
|
||||
server_id = self.get_argument('id', None)
|
||||
print(server_id)
|
||||
|
||||
if server_id is None:
|
||||
logger.warning("Server ID not found in del_file ajax call")
|
||||
@ -234,7 +232,9 @@ class AjaxHandler(BaseHandler):
|
||||
console.warning("Server ID not found in del_file ajax call ({})".format(server_id))
|
||||
return False
|
||||
|
||||
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path) \
|
||||
server_info = db_helper.get_server_data_by_id(server_id)
|
||||
if not helper.in_path(server_info['path'], file_path) \
|
||||
or not helper.in_path(server_info['backup_path'], file_path) \
|
||||
or not helper.check_file_exists(os.path.abspath(file_path)):
|
||||
logger.warning("Invalid path in del_file ajax call ({})".format(file_path))
|
||||
console.warning("Invalid path in del_file ajax call ({})".format(file_path))
|
||||
@ -261,7 +261,9 @@ class AjaxHandler(BaseHandler):
|
||||
console.warning("Server ID not found in del_file ajax call ({})".format(server_id))
|
||||
return False
|
||||
|
||||
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], dir_path) \
|
||||
server_info = db_helper.get_server_data_by_id(server_id)
|
||||
if not helper.in_path(server_info['path'], dir_path) \
|
||||
or not helper.in_path(server_info['backup_path'], dir_path) \
|
||||
or not helper.check_path_exists(os.path.abspath(dir_path)):
|
||||
logger.warning("Invalid path in del_file ajax call ({})".format(dir_path))
|
||||
console.warning("Invalid path in del_file ajax call ({})".format(dir_path))
|
||||
|
@ -5,13 +5,13 @@ import tornado.web
|
||||
import tornado.escape
|
||||
import logging
|
||||
|
||||
from app.classes.web.base_handler import BaseHandler
|
||||
from app.classes.shared.models import Users
|
||||
from app.classes.minecraft.stats import stats
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BaseHandler(tornado.web.RequestHandler):
|
||||
class ApiHandler(BaseHandler):
|
||||
|
||||
def return_response(self, data: dict):
|
||||
# Define a standardized response
|
||||
@ -25,6 +25,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
def authenticate_user(self):
|
||||
try:
|
||||
log.debug("Searching for specified token")
|
||||
# TODO: YEET THIS
|
||||
user_data = Users.get(api_token=self.get_argument('token'))
|
||||
log.debug("Checking results")
|
||||
if user_data:
|
||||
@ -40,19 +41,19 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
pass
|
||||
|
||||
|
||||
class ServersStats(BaseHandler):
|
||||
class ServersStats(ApiHandler):
|
||||
def get(self):
|
||||
"""Get details about all servers"""
|
||||
self.authenticate_user()
|
||||
# Get server stats
|
||||
self.finish(self.write({"servers": stats.get_servers_stats()}))
|
||||
self.finish(self.write({"servers": self.controller.stats.get_servers_stats()}))
|
||||
|
||||
|
||||
class NodeStats(BaseHandler):
|
||||
class NodeStats(ApiHandler):
|
||||
def get(self):
|
||||
"""Get stats for particular node"""
|
||||
self.authenticate_user()
|
||||
# Get node stats
|
||||
node_stats = stats.get_node_stats()
|
||||
node_stats = self.controller.stats.get_node_stats()
|
||||
node_stats.pop("servers")
|
||||
self.finish(self.write(node_stats))
|
||||
|
@ -1,11 +1,21 @@
|
||||
import logging
|
||||
import tornado.web
|
||||
import bleach
|
||||
from typing import (
|
||||
Union,
|
||||
List,
|
||||
Optional
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BaseHandler(tornado.web.RequestHandler):
|
||||
|
||||
def initialize(self, controller=None, tasks_manager=None):
|
||||
self.controller = controller
|
||||
self.tasks_manager = tasks_manager
|
||||
|
||||
def get_remote_ip(self):
|
||||
remote_ip = self.request.headers.get("X-Real-IP") or \
|
||||
self.request.headers.get("X-Forwarded-For") or \
|
||||
@ -14,3 +24,28 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
|
||||
def get_current_user(self):
|
||||
return self.get_secure_cookie("user", max_age_days=1)
|
||||
|
||||
def autobleach(self, text):
|
||||
if type(text) is bool:
|
||||
return text
|
||||
else:
|
||||
return text
|
||||
|
||||
def get_argument(
|
||||
self,
|
||||
name: str,
|
||||
default: Union[None, str, tornado.web._ArgDefaultMarker] = tornado.web._ARG_DEFAULT,
|
||||
strip: bool = True,
|
||||
) -> Optional[str]:
|
||||
arg = self._get_argument(name, default, self.request.arguments, strip)
|
||||
logger.debug("Bleaching {}: {}".format(name, arg))
|
||||
return bleach.clean(arg)
|
||||
|
||||
def get_arguments(self, name: str, strip: bool = True) -> List[str]:
|
||||
assert isinstance(strip, bool)
|
||||
args = self._get_arguments(name, self.request.arguments, strip)
|
||||
args_ret = []
|
||||
for arg in args:
|
||||
logger.debug("Bleaching {}: {}".format(name, arg))
|
||||
args_ret += bleach.clean(arg)
|
||||
return args_ret
|
||||
|
@ -5,14 +5,13 @@ import tornado.escape
|
||||
import bleach
|
||||
import time
|
||||
import datetime
|
||||
import os
|
||||
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.models import Users, installer
|
||||
from app.classes.web.base_handler import BaseHandler
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.shared.models import db_helper, Servers
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.minecraft.stats import stats
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -29,7 +28,7 @@ class PanelHandler(BaseHandler):
|
||||
now = time.time()
|
||||
formatted_time = str(datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S'))
|
||||
|
||||
defined_servers = controller.list_defined_servers()
|
||||
defined_servers = self.controller.list_defined_servers()
|
||||
|
||||
page_data = {
|
||||
# todo: make this actually pull and compare version data
|
||||
@ -38,8 +37,8 @@ class PanelHandler(BaseHandler):
|
||||
'user_data': user_data,
|
||||
'server_stats': {
|
||||
'total': len(defined_servers),
|
||||
'running': len(controller.list_running_servers()),
|
||||
'stopped': (len(controller.list_defined_servers()) - len(controller.list_running_servers()))
|
||||
'running': len(self.controller.list_running_servers()),
|
||||
'stopped': (len(self.controller.list_defined_servers()) - len(self.controller.list_running_servers()))
|
||||
},
|
||||
'menu_servers': defined_servers,
|
||||
'hosts_data': db_helper.get_latest_hosts_stats(),
|
||||
@ -52,7 +51,7 @@ class PanelHandler(BaseHandler):
|
||||
if page_data['server_stats']['total'] == 0 and page != "error":
|
||||
self.set_status(301)
|
||||
self.redirect("/server/step1")
|
||||
return False
|
||||
return
|
||||
|
||||
if page == 'unauthorized':
|
||||
template = "panel/denied.html"
|
||||
@ -81,13 +80,12 @@ class PanelHandler(BaseHandler):
|
||||
server_id,
|
||||
self.get_remote_ip())
|
||||
|
||||
controller.remove_server(server_id)
|
||||
self.controller.remove_server(server_id)
|
||||
self.redirect("/panel/dashboard")
|
||||
return
|
||||
|
||||
elif page == 'dashboard':
|
||||
page_data['servers'] = db_helper.get_all_servers_stats()
|
||||
|
||||
for s in page_data['servers']:
|
||||
try:
|
||||
data = json.loads(s['int_ping_results'])
|
||||
@ -103,26 +101,30 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
server_id = bleach.clean(server_id)
|
||||
|
||||
# does this server id exist?
|
||||
if not db_helper.server_id_exists(server_id):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return False
|
||||
return
|
||||
|
||||
valid_subpages = ['term', 'logs', 'config', 'files', 'admin_controls']
|
||||
valid_subpages = ['term', 'logs', 'backup', 'config', 'files', 'admin_controls']
|
||||
|
||||
if subpage not in valid_subpages:
|
||||
logger.debug('not a valid subpage')
|
||||
subpage = 'term'
|
||||
logger.debug('Subpage: "{}"'.format(subpage))
|
||||
|
||||
server = self.controller.get_server_obj(server_id)
|
||||
# server_data isn't needed since the server_stats also pulls server data
|
||||
# page_data['server_data'] = db_helper.get_server_data_by_id(server_id)
|
||||
page_data['server_data'] = db_helper.get_server_data_by_id(server_id)
|
||||
page_data['server_stats'] = db_helper.get_server_stats_by_id(server_id)
|
||||
page_data['get_players'] = lambda: stats.get_server_players(server_id)
|
||||
page_data['get_players'] = lambda: self.controller.stats.get_server_players(server_id)
|
||||
if subpage == "backup":
|
||||
page_data['backup_config'] = db_helper.get_backup_config(server_id)
|
||||
page_data['backup_list'] = server.list_backups()
|
||||
|
||||
def get_banned_players_html():
|
||||
banned_players = helper.get_banned_players(server_id, db_helper)
|
||||
@ -149,6 +151,79 @@ class PanelHandler(BaseHandler):
|
||||
# template = "panel/server_details.html"
|
||||
template = "panel/server_{subpage}.html".format(subpage=subpage)
|
||||
|
||||
elif page == 'download_backup':
|
||||
server_id = self.get_argument('id', None)
|
||||
file = self.get_argument('file', "")
|
||||
|
||||
if server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
else:
|
||||
server_id = bleach.clean(server_id)
|
||||
|
||||
# does this server id exist?
|
||||
if not db_helper.server_id_exists(server_id):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return
|
||||
|
||||
server_info = db_helper.get_server_data_by_id(server_id)
|
||||
backup_file = os.path.abspath(os.path.join(server_info["backup_path"], file))
|
||||
if not helper.in_path(server_info["backup_path"], backup_file) \
|
||||
or not os.path.isfile(backup_file):
|
||||
self.redirect("/panel/error?error=Invalid path detected")
|
||||
return
|
||||
|
||||
self.set_header('Content-Type', 'application/octet-stream')
|
||||
self.set_header('Content-Disposition', 'attachment; filename=' + file)
|
||||
chunk_size = 1024 * 1024 * 4 # 4 MiB
|
||||
|
||||
with open(backup_file, 'rb') as f:
|
||||
while True:
|
||||
chunk = f.read(chunk_size)
|
||||
if not chunk:
|
||||
break
|
||||
try:
|
||||
self.write(chunk) # write the chunk to response
|
||||
self.flush() # send the chunk to client
|
||||
except iostream.StreamClosedError:
|
||||
# this means the client has closed the connection
|
||||
# so break the loop
|
||||
break
|
||||
finally:
|
||||
# deleting the chunk is very important because
|
||||
# if many clients are downloading files at the
|
||||
# same time, the chunks in memory will keep
|
||||
# increasing and will eat up the RAM
|
||||
del chunk
|
||||
self.redirect("/panel/server_detail?id={}&subpage=backup".format(server_id))
|
||||
|
||||
elif page == 'backup_now':
|
||||
server_id = self.get_argument('id', None)
|
||||
|
||||
if server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
else:
|
||||
# does this server id exist?
|
||||
if not db_helper.server_id_exists(server_id):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return
|
||||
|
||||
server = self.controller.get_server_obj(server_id).backup_server()
|
||||
self.redirect("/panel/server_detail?id={}&subpage=backup".format(server_id))
|
||||
|
||||
elif page == 'panel_config':
|
||||
page_data['users'] = db_helper.get_all_users()
|
||||
page_data['roles'] = db_helper.get_all_roles()
|
||||
@ -177,10 +252,10 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
|
||||
page_data['roles_all'] = db_helper.get_all_roles()
|
||||
page_data['servers_all'] = controller.list_defined_servers()
|
||||
page_data['servers_all'] = self.controller.list_defined_servers()
|
||||
template = "panel/panel_edit_user.html"
|
||||
|
||||
elif page == "edit_user":
|
||||
@ -188,16 +263,16 @@ class PanelHandler(BaseHandler):
|
||||
user_id = self.get_argument('id', None)
|
||||
page_data['user'] = db_helper.get_user(user_id)
|
||||
page_data['roles_all'] = db_helper.get_all_roles()
|
||||
page_data['servers_all'] = controller.list_defined_servers()
|
||||
page_data['servers_all'] = self.controller.list_defined_servers()
|
||||
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif user_id is None:
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
return False
|
||||
return
|
||||
|
||||
if exec_user['user_id'] != page_data['user']['user_id']:
|
||||
page_data['user']['api_token'] = "********"
|
||||
@ -211,19 +286,19 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif user_id is None:
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
target_user = db_helper.get_user(user_id)
|
||||
if not target_user:
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
return False
|
||||
return
|
||||
elif target_user['superuser']:
|
||||
self.redirect("/panel/error?error=Cannot remove a superuser")
|
||||
return False
|
||||
return
|
||||
|
||||
db_helper.remove_user(user_id)
|
||||
|
||||
@ -246,25 +321,25 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
|
||||
page_data['servers_all'] = controller.list_defined_servers()
|
||||
page_data['servers_all'] = self.controller.list_defined_servers()
|
||||
template = "panel/panel_edit_role.html"
|
||||
|
||||
elif page == "edit_role":
|
||||
page_data['new_role'] = False
|
||||
role_id = self.get_argument('id', None)
|
||||
page_data['role'] = db_helper.get_role(role_id)
|
||||
page_data['servers_all'] = controller.list_defined_servers()
|
||||
page_data['servers_all'] = self.controller.list_defined_servers()
|
||||
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif role_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return False
|
||||
return
|
||||
|
||||
template = "panel/panel_edit_role.html"
|
||||
|
||||
@ -276,16 +351,16 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif role_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
target_role = db_helper.get_user(role_id)
|
||||
if not target_role:
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return False
|
||||
return
|
||||
|
||||
db_helper.remove_role(role_id)
|
||||
|
||||
@ -331,17 +406,15 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
server_id = bleach.clean(server_id)
|
||||
|
||||
# does this server id exist?
|
||||
if not db_helper.server_id_exists(server_id):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return False
|
||||
return
|
||||
|
||||
Servers.update({
|
||||
Servers.server_name: server_name,
|
||||
@ -358,7 +431,7 @@ class PanelHandler(BaseHandler):
|
||||
Servers.logs_delete_after: logs_delete_after,
|
||||
}).where(Servers.server_id == server_id).execute()
|
||||
|
||||
controller.refresh_server_settings(server_id)
|
||||
self.controller.refresh_server_settings(server_id)
|
||||
|
||||
db_helper.add_to_audit_log(user_data['user_id'],
|
||||
"Edited server {} named {}".format(server_id, server_name),
|
||||
@ -367,6 +440,41 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
self.redirect("/panel/server_detail?id={}&subpage=config".format(server_id))
|
||||
|
||||
if page == "server_backup":
|
||||
logger.debug(self.request.arguments)
|
||||
server_id = self.get_argument('id', None)
|
||||
backup_path = bleach.clean(self.get_argument('backup_path', None))
|
||||
max_backups = bleach.clean(self.get_argument('max_backups', None))
|
||||
enabled = int(float(bleach.clean(self.get_argument('auto_enabled'), '0')))
|
||||
|
||||
user_data = json.loads(self.get_secure_cookie("user_data"))
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return
|
||||
elif server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
else:
|
||||
# does this server id exist?
|
||||
if not db_helper.server_id_exists(server_id):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return
|
||||
|
||||
if backup_path is not None:
|
||||
Servers.update({
|
||||
Servers.backup_path: backup_path
|
||||
}).where(Servers.server_id == server_id).execute()
|
||||
db_helper.set_backup_config(server_id, max_backups=max_backups)
|
||||
|
||||
db_helper.add_to_audit_log(user_data['user_id'],
|
||||
"Edited server {}: updated backups".format(server_id),
|
||||
server_id,
|
||||
self.get_remote_ip())
|
||||
self.tasks_manager.reload_schedule_from_db()
|
||||
self.redirect("/panel/server_detail?id={}&subpage=backup".format(server_id))
|
||||
|
||||
elif page == "edit_user":
|
||||
user_id = bleach.clean(self.get_argument('id', None))
|
||||
username = bleach.clean(self.get_argument('username', None))
|
||||
@ -380,22 +488,22 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif username is None or username == "":
|
||||
self.redirect("/panel/error?error=Invalid username")
|
||||
return False
|
||||
return
|
||||
elif user_id is None:
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
if not db_helper.user_id_exists(user_id):
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
return False
|
||||
return
|
||||
|
||||
if password0 != password1:
|
||||
self.redirect("/panel/error?error=Passwords must match")
|
||||
return False
|
||||
return
|
||||
|
||||
roles = set()
|
||||
for role in db_helper.get_all_roles():
|
||||
@ -408,7 +516,7 @@ class PanelHandler(BaseHandler):
|
||||
roles.add(role.role_id)
|
||||
|
||||
servers = set()
|
||||
for server in controller.list_defined_servers():
|
||||
for server in self.controller.list_defined_servers():
|
||||
argument = int(float(
|
||||
bleach.clean(
|
||||
self.get_argument('server_{}_access'.format(server['server_id']), '0')
|
||||
@ -444,19 +552,19 @@ class PanelHandler(BaseHandler):
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif username is None or username == "":
|
||||
self.redirect("/panel/error?error=Invalid username")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
if db_helper.get_userid_by_name(username) is not None:
|
||||
self.redirect("/panel/error?error=User exists")
|
||||
return False
|
||||
return
|
||||
|
||||
if password0 != password1:
|
||||
self.redirect("/panel/error?error=Passwords must match")
|
||||
return False
|
||||
return
|
||||
|
||||
roles = set()
|
||||
for role in db_helper.get_all_roles():
|
||||
@ -469,7 +577,7 @@ class PanelHandler(BaseHandler):
|
||||
roles.add(role['role_id'])
|
||||
|
||||
servers = set()
|
||||
for server in controller.list_defined_servers():
|
||||
for server in self.controller.list_defined_servers():
|
||||
argument = int(float(
|
||||
bleach.clean(
|
||||
self.get_argument('server_{}_access'.format(server['server_id']), '0')
|
||||
@ -500,21 +608,21 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif role_name is None or role_name == "":
|
||||
self.redirect("/panel/error?error=Invalid username")
|
||||
return False
|
||||
return
|
||||
elif role_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
if not db_helper.role_id_exists(role_id):
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return False
|
||||
return
|
||||
|
||||
servers = set()
|
||||
for server in controller.list_defined_servers():
|
||||
for server in self.controller.list_defined_servers():
|
||||
argument = int(float(
|
||||
bleach.clean(
|
||||
self.get_argument('server_{}_access'.format(server['server_id']), '0')
|
||||
@ -543,18 +651,18 @@ class PanelHandler(BaseHandler):
|
||||
exec_user = db_helper.get_user(user_data['user_id'])
|
||||
if not exec_user['superuser']:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
return False
|
||||
return
|
||||
elif role_name is None or role_name == "":
|
||||
self.redirect("/panel/error?error=Invalid role name")
|
||||
return False
|
||||
return
|
||||
else:
|
||||
# does this user id exist?
|
||||
if db_helper.get_roleid_by_name(role_name) is not None:
|
||||
self.redirect("/panel/error?error=Role exists")
|
||||
return False
|
||||
return
|
||||
|
||||
servers = set()
|
||||
for server in controller.list_defined_servers():
|
||||
for server in self.controller.list_defined_servers():
|
||||
argument = int(float(
|
||||
bleach.clean(
|
||||
self.get_argument('server_{}_access'.format(server['server_id']), '0')
|
||||
@ -575,3 +683,7 @@ class PanelHandler(BaseHandler):
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip())
|
||||
self.redirect("/panel/panel_config")
|
||||
|
||||
else:
|
||||
self.set_status(404)
|
||||
self.render("public/404.html")
|
@ -6,10 +6,8 @@ import shutil
|
||||
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.web.base_handler import BaseHandler
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.shared.models import db_helper, Servers
|
||||
from app.classes.minecraft.serverjars import server_jar_obj
|
||||
from app.classes.minecraft.stats import stats
|
||||
from app.classes.shared.helpers import helper
|
||||
|
||||
|
||||
@ -35,15 +33,15 @@ class ServerHandler(BaseHandler):
|
||||
|
||||
template = "public/404.html"
|
||||
|
||||
defined_servers = controller.list_defined_servers()
|
||||
defined_servers = self.controller.list_defined_servers()
|
||||
|
||||
page_data = {
|
||||
'version_data': helper.get_version_string(),
|
||||
'user_data': user_data,
|
||||
'server_stats': {
|
||||
'total': len(controller.list_defined_servers()),
|
||||
'running': len(controller.list_running_servers()),
|
||||
'stopped': (len(controller.list_defined_servers()) - len(controller.list_running_servers()))
|
||||
'total': len(self.controller.list_defined_servers()),
|
||||
'running': len(self.controller.list_running_servers()),
|
||||
'stopped': (len(self.controller.list_defined_servers()) - len(self.controller.list_running_servers()))
|
||||
},
|
||||
'hosts_data': db_helper.get_latest_hosts_stats(),
|
||||
'menu_servers': defined_servers,
|
||||
@ -130,7 +128,7 @@ class ServerHandler(BaseHandler):
|
||||
Servers.stop_command: stop_command
|
||||
}).execute()
|
||||
|
||||
controller.init_all_servers()
|
||||
self.controller.init_all_servers()
|
||||
console.debug('initted all servers')
|
||||
|
||||
return
|
||||
@ -150,26 +148,26 @@ class ServerHandler(BaseHandler):
|
||||
server_parts = server.split("|")
|
||||
|
||||
if import_type == 'import_jar':
|
||||
good_path = controller.verify_jar_server(import_server_path, import_server_jar)
|
||||
good_path = self.controller.verify_jar_server(import_server_path, import_server_jar)
|
||||
|
||||
if not good_path:
|
||||
self.redirect("/panel/error?error=Server path or Server Jar not found!")
|
||||
return False
|
||||
|
||||
new_server_id = controller.import_jar_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port)
|
||||
new_server_id = self.controller.import_jar_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port)
|
||||
elif import_type == 'import_zip':
|
||||
good_path = controller.verify_zip_server(import_server_path)
|
||||
good_path = self.controller.verify_zip_server(import_server_path)
|
||||
if not good_path:
|
||||
self.redirect("/panel/error?error=Zip file not found!")
|
||||
return False
|
||||
|
||||
new_server_id = controller.import_zip_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port)
|
||||
new_server_id = self.controller.import_zip_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port)
|
||||
if new_server_id == "false":
|
||||
self.redirect("/panel/error?error=ZIP file not accessible! You can fix this permissions issue with sudo chown -R crafty:crafty {} And sudo chmod 2775 -R {}".format(import_server_path, import_server_path))
|
||||
return False
|
||||
else:
|
||||
# todo: add server type check here and call the correct server add functions if not a jar
|
||||
new_server_id = controller.create_jar_server(server_parts[0], server_parts[1], server_name, min_mem, max_mem, port)
|
||||
new_server_id = self.controller.create_jar_server(server_parts[0], server_parts[1], server_name, min_mem, max_mem, port)
|
||||
|
||||
if new_server_id:
|
||||
db_helper.add_to_audit_log(user_data['user_id'],
|
||||
@ -180,7 +178,7 @@ class ServerHandler(BaseHandler):
|
||||
logger.error("Unable to create server")
|
||||
console.error("Unable to create server")
|
||||
|
||||
stats.record_stats()
|
||||
self.controller.stats.record_stats()
|
||||
self.redirect("/panel/dashboard")
|
||||
|
||||
self.render(
|
||||
|
@ -33,12 +33,14 @@ except ModuleNotFoundError as e:
|
||||
|
||||
|
||||
|
||||
class webserver:
|
||||
class Webserver:
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, controller, tasks_manager):
|
||||
self.ioloop = None
|
||||
self.HTTP_Server = None
|
||||
self.HTTPS_Server = None
|
||||
self.controller = controller
|
||||
self.tasks_manager = tasks_manager
|
||||
self._asyncio_patch()
|
||||
|
||||
|
||||
@ -118,15 +120,16 @@ class webserver:
|
||||
|
||||
tornado.locale.set_default_locale(lang)
|
||||
|
||||
handler_args = {"controller": self.controller, "tasks_manager": self.tasks_manager}
|
||||
handlers = [
|
||||
(r'/', DefaultHandler),
|
||||
(r'/public/(.*)', PublicHandler),
|
||||
(r'/panel/(.*)', PanelHandler),
|
||||
(r'/server/(.*)', ServerHandler),
|
||||
(r'/ajax/(.*)', AjaxHandler),
|
||||
(r'/api/stats/servers', ServersStats),
|
||||
(r'/api/stats/node', NodeStats),
|
||||
(r'/ws', SocketHandler),
|
||||
(r'/', DefaultHandler, handler_args),
|
||||
(r'/public/(.*)', PublicHandler, handler_args),
|
||||
(r'/panel/(.*)', PanelHandler, handler_args),
|
||||
(r'/server/(.*)', ServerHandler, handler_args),
|
||||
(r'/ajax/(.*)', AjaxHandler, handler_args),
|
||||
(r'/api/stats/servers', ServersStats, handler_args),
|
||||
(r'/api/stats/node', NodeStats, handler_args),
|
||||
(r'/ws', SocketHandler, handler_args),
|
||||
]
|
||||
|
||||
app = tornado.web.Application(
|
||||
|
@ -8,6 +8,10 @@ from app.classes.web.websocket_helper import websocket_helper
|
||||
|
||||
class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
def initialize(self, controller=None, tasks_manager=None):
|
||||
self.controller = controller
|
||||
self.tasks_manager = tasks_manager
|
||||
|
||||
def get_remote_ip(self):
|
||||
remote_ip = self.request.headers.get("X-Real-IP") or \
|
||||
self.request.headers.get("X-Forwarded-For") or \
|
||||
|
@ -50,8 +50,10 @@
|
||||
</div>
|
||||
|
||||
<div class="wrapper d-flex align-items-center font-weight-medium text-muted">
|
||||
{% if person['loc'] %}
|
||||
<i class="mdi mdi-map-marker-outline mr-2"></i>
|
||||
<p class="mb-0 text-muted">{{ person['loc'] }}</p>
|
||||
{% end %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -113,8 +115,10 @@
|
||||
</div>
|
||||
|
||||
<div class="wrapper d-flex align-items-center font-weight-medium text-muted">
|
||||
{% if person['loc'] %}
|
||||
<i class="mdi mdi-map-marker-outline mr-2"></i>
|
||||
<p class="mb-0 text-muted">{{ person['loc'] }}</p>
|
||||
{% end %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -177,8 +181,10 @@
|
||||
</div>
|
||||
|
||||
<div class="wrapper d-flex align-items-center font-weight-medium text-muted">
|
||||
{% if person['loc'] %}
|
||||
<i class="mdi mdi-map-marker-outline mr-2"></i>
|
||||
<p class="mb-0 text-muted">{{ person['loc'] }}</p>
|
||||
{% end %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -125,7 +125,7 @@
|
||||
|
||||
<td class="actions_serverlist">
|
||||
|
||||
{% if server['stats'][0]['running'] %}
|
||||
{% if server['stats']['running'] %}
|
||||
<a class="stop_button" data-id="{{server['server_data']['server_id']}}"> <i class="fas fa-stop"></i></a>
|
||||
<a class="restart_button" data-id="{{server['server_data']['server_id']}}"> <i class="fas fa-sync"></i></a>
|
||||
{% else %}
|
||||
@ -136,59 +136,59 @@
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats'][0]['cpu']}}">
|
||||
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats']['cpu']}}">
|
||||
<div class="progress-bar
|
||||
{% if server['stats'][0]['cpu'] <= 33 %}
|
||||
{% if server['stats']['cpu'] <= 33 %}
|
||||
bg-success
|
||||
{% elif 34 <= server['stats'][0]['cpu'] <= 66 %}
|
||||
{% elif 34 <= server['stats']['cpu'] <= 66 %}
|
||||
bg-warning
|
||||
{% else %}
|
||||
bg-danger
|
||||
{% end %}
|
||||
" role="progressbar" style="width: {{server['stats'][0]['cpu']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
" role="progressbar" style="width: {{server['stats']['cpu']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
{{server['stats'][0]['cpu']}}%
|
||||
{{server['stats']['cpu']}}%
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats'][0]['mem']}}">
|
||||
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats']['mem']}}">
|
||||
<div class="progress-bar
|
||||
{% if server['stats'][0]['mem_percent'] <= 33 %}
|
||||
{% if server['stats']['mem_percent'] <= 33 %}
|
||||
bg-success
|
||||
{% elif 34 <= server['stats'][0]['mem_percent'] <= 66 %}
|
||||
{% elif 34 <= server['stats']['mem_percent'] <= 66 %}
|
||||
bg-warning
|
||||
{% else %}
|
||||
bg-danger
|
||||
{% end %}
|
||||
" role="progressbar" style="width: {{server['stats'][0]['mem_percent']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
" role="progressbar" style="width: {{server['stats']['mem_percent']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
{{server['stats'][0]['mem_percent']}}% -
|
||||
{{server['stats']['mem_percent']}}% -
|
||||
|
||||
{% if server['stats'][0]['mem'] == 0 %}
|
||||
{% if server['stats']['mem'] == 0 %}
|
||||
0 MB
|
||||
{% else %}
|
||||
{{server['stats'][0]['mem']}}
|
||||
{{server['stats']['mem']}}
|
||||
{% end %}
|
||||
</td>
|
||||
<td>
|
||||
{{ server['stats'][0]['world_name'] }} : {{ server['stats'][0]['world_size'] }}
|
||||
{{ server['stats']['world_name'] }} : {{ server['stats']['world_size'] }}
|
||||
</td>
|
||||
<td>
|
||||
{% if server['stats'][0]['int_ping_results'] %}
|
||||
{{ server['stats'][0]['online'] }} / {{ server['stats'][0]['max'] }} Max<br />
|
||||
{% if server['stats']['int_ping_results'] %}
|
||||
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} Max<br />
|
||||
|
||||
{% if server['stats'][0]['desc'] != 'False' %}
|
||||
{{ server['stats'][0]['desc'] }} <br />
|
||||
{% if server['stats']['desc'] != 'False' %}
|
||||
{{ server['stats']['desc'] }} <br />
|
||||
{% end %}
|
||||
|
||||
{% if server['stats'][0]['version'] != 'False' %}
|
||||
{{ server['stats'][0]['version'] }}
|
||||
{% if server['stats']['version'] != 'False' %}
|
||||
{{ server['stats']['version'] }}
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
{% if server['stats'][0]['running'] %}
|
||||
{% if server['stats']['running'] %}
|
||||
<i class="fas fa-thumbs-up"></i> <span class="text-success">Online</span>
|
||||
{% else %}
|
||||
<i class="fas fa-thumbs-down"></i> <span class="text-danger">Offline</span>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<div class="card-body pt-3 pb-3">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 mr-2">
|
||||
{% if data['server_stats'][0]['running'] %}
|
||||
{% if data['server_stats']['running'] %}
|
||||
<b>Server Status:</b> <span class="text-success">Online</span><br />
|
||||
<b>Server Started:</b> <span id="started">{{ data['server_stats'][0]['started'] }} (Server Time)</span><br />
|
||||
<b>Server Started:</b> <span id="started">{{ data['server_stats']['started'] }} (Server Time)</span><br />
|
||||
<b>Server Uptime:</b> <span id="uptime">Error Calculating</span>
|
||||
{% else %}
|
||||
<b>Server Status:</b> <span class="text-danger">Offline</span><br />
|
||||
@ -16,19 +16,19 @@
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 mr-2">
|
||||
<b>CPU:</b> {{ data['server_stats'][0]['cpu'] }}% <br />
|
||||
<b>Mem:</b> {{ data['server_stats'][0]['mem'] }} <br />
|
||||
{% if data['server_stats'][0]['int_ping_results'] %}
|
||||
<b>Players:</b> {{ data['server_stats'][0]['online'] }} / {{ data['server_stats'][0]['max'] }}<br />
|
||||
<b>CPU:</b> {{ data['server_stats']['cpu'] }}% <br />
|
||||
<b>Mem:</b> {{ data['server_stats']['mem'] }} <br />
|
||||
{% if data['server_stats']['int_ping_results'] %}
|
||||
<b>Players:</b> {{ data['server_stats']['online'] }} / {{ data['server_stats']['max'] }}<br />
|
||||
{% else %}
|
||||
<b>Players:</b> 0/0<br />
|
||||
{% end %}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 mr-2">
|
||||
{% if data['server_stats'][0]['version'] != 'False' %}
|
||||
<b>Server:</b> {{ data['server_stats'][0]['version'] }} <br />
|
||||
<b>Desc:</b> {{ data['server_stats'][0]['desc'] }} <br />
|
||||
{% if data['server_stats']['version'] != 'False' %}
|
||||
<b>Server:</b> {{ data['server_stats']['version'] }} <br />
|
||||
<b>Desc:</b> {{ data['server_stats']['desc'] }} <br />
|
||||
{% else %}
|
||||
<b>Server:</b> Unable To Connect <br />
|
||||
<b>Desc:</b> Unable To Connect <br />
|
||||
@ -86,9 +86,9 @@
|
||||
let startedLocal;
|
||||
|
||||
if (started != null) {
|
||||
console.log('88', '{{ data['server_stats'][0]['started'] }}');
|
||||
{% if data['server_stats'][0]['started'] != 'False' %}
|
||||
startedUTC = '{{ (datetime.datetime.strptime(data['server_stats'][0]['started'], '%Y-%m-%d %H:%M:%S') - datetime.timedelta(seconds=-time.timezone)).strftime('%Y-%m-%d %H:%M:%S') }}';
|
||||
console.log('88', '{{ data['server_stats']['started'] }}');
|
||||
{% if data['server_stats']['started'] != 'False' %}
|
||||
startedUTC = '{{ (datetime.datetime.strptime(data['server_stats']['started'], '%Y-%m-%d %H:%M:%S') - datetime.timedelta(seconds=-time.timezone)).strftime('%Y-%m-%d %H:%M:%S') }}';
|
||||
{% end %}
|
||||
console.log('utc', startedUTC);
|
||||
startedUTC = moment.utc(startedUTC, 'YYYY-MM-DD HH:mm:ss');
|
||||
@ -105,7 +105,7 @@
|
||||
}
|
||||
|
||||
let nowServerTime = '{{ data['time'] }}';
|
||||
let startedServerTime = '{{ data['server_stats'][0]['started'] }}';
|
||||
let startedServerTime = '{{ data['server_stats']['started'] }}';
|
||||
|
||||
if (uptime != null && started != null) {
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats'][0]['server_id']['server_name'] }}
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats'][0]['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,31 +34,31 @@
|
||||
<div class="card-body pt-0">
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
|
||||
|
247
app/frontend/templates/panel/server_backup.html
Normal file
247
app/frontend/templates/panel/server_backup.html
Normal file
@ -0,0 +1,247 @@
|
||||
{% extends ../base.html %}
|
||||
|
||||
{% block meta %}
|
||||
<!-- <meta http-equiv="refresh" content="60">-->
|
||||
{% end %}
|
||||
|
||||
{% block title %}Crafty Controller - Server Details{% end %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Page Title Header Starts-->
|
||||
<div class="row page-title-header">
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Page Title Header Ends-->
|
||||
|
||||
{% include "parts/details_stats.html %}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12 grid-margin">
|
||||
<div class="card">
|
||||
<div class="card-body pt-0">
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="true">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="false">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="false">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<form class="forms-sample" method="post" action="/panel/server_backup">
|
||||
{% raw xsrf_form_html() %}
|
||||
<input type="hidden" name="id" value="{{ data['server_stats']['server_id']['server_id'] }}">
|
||||
<input type="hidden" name="subpage" value="backup">
|
||||
|
||||
<div class="form-group">
|
||||
<a href="/panel/backup_now?id={{ data['server_stats']['server_id']['server_id'] }}" class="btn btn-primary" onclick="backup_started()">Backup Now!</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="server_name">Storage Location <small class="text-muted ml-1"> - Where do you want to store backups?</small> </label>
|
||||
<input type="text" class="form-control" name="backup_path" id="backup_path" value="{{ data['server_stats']['server_id']['backup_path'] }}" placeholder="Backup Path" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="server_path">Max Backups <small class="text-muted ml-1"> - Crafty will not store more than n backups, deleting the oldest (enter 0 to keep all)</small> </label>
|
||||
<input type="text" class="form-control" name="max_backups" id="max_backups" value="{{ data['backup_config']['max_backups'] }}" placeholder="Max Backups" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="superuser" class="form-check-label ml-4 mb-4">
|
||||
{% if data['backup_config']['auto_enabled'] %}
|
||||
<input type="checkbox" class="form-check-input" id="auto_enabled" name="auto_enabled" checked="" value="1" >Auto-backup at 12:00 AM?
|
||||
{% else %}
|
||||
<input type="checkbox" class="form-check-input" id="auto_enabled" name="auto_enabled" value="1" >Auto-backup at 12:00 AM?
|
||||
{% end %}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-success mr-2">Save</button>
|
||||
<button type="reset" class="btn btn-light">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Current Backups</h4>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
|
||||
<table class="table table-responsive dataTable" id="backup_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="10%">Download</th>
|
||||
<th>Path</th>
|
||||
<th width="20%">Size</th>
|
||||
<th width="10%">Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for backup in data['backup_list'] %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/panel/download_backup?file={{ backup['path'] }}&id={{ data['server_stats']['server_id']['server_id'] }}" class="btn btn-primary">
|
||||
<i class="fas fa-download" aria-hidden="true"></i>
|
||||
Download
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ backup['path'] }}</td>
|
||||
<td>{{ backup['size'] }}</td>
|
||||
<td>
|
||||
<button data-file="{{ backup['path'] }}" class="btn btn-danger del_button">
|
||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||
Delete
|
||||
</button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% end %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<!-- content-wrapper ends -->
|
||||
|
||||
{% end %}
|
||||
|
||||
{% block js %}
|
||||
<script>
|
||||
|
||||
|
||||
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
|
||||
function getCookie(name) {
|
||||
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
|
||||
return r ? r[1] : undefined;
|
||||
}
|
||||
|
||||
function backup_started(time='5-10') {
|
||||
bootbox.alert({
|
||||
message: "A backup task has been started.",
|
||||
backdrop: true
|
||||
});
|
||||
}
|
||||
|
||||
function del_backup(filename, id){
|
||||
var token = getCookie("_xsrf")
|
||||
|
||||
data_to_send = { file_name :filename}
|
||||
|
||||
console.log('Sending Command to delete file: ' + filename)
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/del_file?server_id='+id,
|
||||
data: data_to_send,
|
||||
success: function(data){
|
||||
location.reload();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
console.log( "ready!" );
|
||||
$("#backup_config_box").hide();
|
||||
$("#backup_save_note").hide();
|
||||
|
||||
$("#show_config").click(function () {
|
||||
$("#backup_config_box").toggle();
|
||||
$('#backup_button').hide();
|
||||
$('#backup_save_note').show();
|
||||
$('#backup_data').hide();
|
||||
});
|
||||
|
||||
$('#backup_table').DataTable({
|
||||
"order": [[ 1, "desc" ]],
|
||||
"paging":true,
|
||||
"lengthChange": false,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
"autoWidth": false,
|
||||
"responsive": true,
|
||||
});
|
||||
|
||||
$( ".del_button" ).click(function() {
|
||||
var file_to_del = $(this).data("file");
|
||||
|
||||
console.log("file to delete is" + file_to_del);
|
||||
|
||||
bootbox.confirm({
|
||||
title: "Destroy backup " + file_to_del + "?",
|
||||
message: "Do you want to delete this file? This cannot be undone.",
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: '<i class="fas fa-times"></i> Cancel'
|
||||
},
|
||||
confirm: {
|
||||
label: '<i class="fas fa-check"></i> Confirm'
|
||||
}
|
||||
},
|
||||
callback: function (result) {
|
||||
console.log(result);
|
||||
if (result == true) {
|
||||
del_backup(file_to_del, {{ data['server_stats']['server_id']['server_id'] }} );
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{% end %}
|
@ -15,9 +15,9 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats'][0]['server_id']['server_name'] }}
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats'][0]['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,31 +34,31 @@
|
||||
<div class="card-body pt-0">
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
|
||||
@ -68,62 +68,62 @@
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<form class="forms-sample" method="post" action="/panel/server_detail">
|
||||
{% raw xsrf_form_html() %}
|
||||
<input type="hidden" name="id" value="{{ data['server_stats'][0]['server_id']['server_id'] }}">
|
||||
<input type="hidden" name="id" value="{{ data['server_stats']['server_id']['server_id'] }}">
|
||||
<input type="hidden" name="subpage" value="config">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="server_name">Server Name <small class="text-muted ml-1"> - What you wish to call this server</small> </label>
|
||||
<input type="text" class="form-control" name="server_name" id="server_name" value="{{ data['server_stats'][0]['server_id']['server_name'] }}" placeholder="Server Name" >
|
||||
<input type="text" class="form-control" name="server_name" id="server_name" value="{{ data['server_stats']['server_id']['server_name'] }}" placeholder="Server Name" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="server_path">Server Path <small class="text-muted ml-1"> - Absolute full path (not including executable)</small> </label>
|
||||
<input type="text" class="form-control" name="server_path" id="server_path" value="{{ data['server_stats'][0]['server_id']['path'] }}" placeholder="Server Path" >
|
||||
<input type="text" class="form-control" name="server_path" id="server_path" value="{{ data['server_stats']['server_id']['path'] }}" placeholder="Server Path" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="log_path">Server Log Location <small class="text-muted ml-1"> - Absolute full path to the log file</small> </label>
|
||||
<input type="text" class="form-control" name="log_path" id="log_path" value="{{ data['server_stats'][0]['server_id']['log_path'] }}" placeholder="Server Log" >
|
||||
<input type="text" class="form-control" name="log_path" id="log_path" value="{{ data['server_stats']['server_id']['log_path'] }}" placeholder="Server Log" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="executable">Server Executable <small class="text-muted ml-1"> - Just the executable file</small> </label>
|
||||
<input type="text" class="form-control" name="executable" id="executable" value="{{ data['server_stats'][0]['server_id']['executable'] }}" placeholder="Server Executable" >
|
||||
<input type="text" class="form-control" name="executable" id="executable" value="{{ data['server_stats']['server_id']['executable'] }}" placeholder="Server Executable" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="execution_command">Server Execution Command <small class="text-muted ml-1"> - What will be launched in a hidden terminal</small> </label>
|
||||
<input type="text" class="form-control" name="execution_command" id="execution_command" value="{{ data['server_stats'][0]['server_id']['execution_command'] }}" placeholder="Server Execution Command" >
|
||||
<input type="text" class="form-control" name="execution_command" id="execution_command" value="{{ data['server_stats']['server_id']['execution_command'] }}" placeholder="Server Execution Command" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stop_command">Server Stop Command <small class="text-muted ml-1"> - Command to send the program to stop it</small> </label>
|
||||
<input type="text" class="form-control" name="stop_command" id="stop_command" value="{{ data['server_stats'][0]['server_id']['stop_command'] }}" placeholder="Server Stop Command" >
|
||||
<input type="text" class="form-control" name="stop_command" id="stop_command" value="{{ data['server_stats']['server_id']['stop_command'] }}" placeholder="Server Stop Command" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="auto_start_delay">Server Autostart Delay <small class="text-muted ml-1"> - Delay before auto starting (if enabled below)</small> </label>
|
||||
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats'][0]['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" >
|
||||
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="server_ip">Server IP <small class="text-muted ml-1"> - IP Crafty should connect to for stats (Try a real ip instead of 127.0.0.1 if you have issues)</small> </label>
|
||||
<input type="text" class="form-control" name="server_ip" id="server_ip" value="{{ data['server_stats'][0]['server_id']['server_ip'] }}">
|
||||
<input type="text" class="form-control" name="server_ip" id="server_ip" value="{{ data['server_stats']['server_id']['server_ip'] }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="server_port">Server Port <small class="text-muted ml-1"> - Port Crafty should connect to for stats</small> </label>
|
||||
<input type="number" class="form-control" name="server_port" id="server_port" value="{{ data['server_stats'][0]['server_id']['server_port'] }}" step="1" max="65566" min="1" >
|
||||
<input type="number" class="form-control" name="server_port" id="server_port" value="{{ data['server_stats']['server_id']['server_port'] }}" step="1" max="65566" min="1" >
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="logs_delete_after">Remove Old Logs After <small class="text-muted ml-1"> - How many days will a log file has to be old to get deleted (0 is off)</small> </label>
|
||||
<input type="number" class="form-control" name="logs_delete_after" id="logs_delete_after" value="{{ data['server_stats'][0]['server_id']['logs_delete_after'] }}" step="1" max="365" min="0" >
|
||||
<input type="number" class="form-control" name="logs_delete_after" id="logs_delete_after" value="{{ data['server_stats']['server_id']['logs_delete_after'] }}" step="1" max="365" min="0" >
|
||||
</div>
|
||||
|
||||
<div class="form-check-flat">
|
||||
<label for="auto_start" class="form-check-label ml-4 mb-4">
|
||||
{% if data['server_stats'][0]['server_id']['auto_start'] %}
|
||||
{% if data['server_stats']['server_id']['auto_start'] %}
|
||||
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" checked="" value="1">Server Auto Start
|
||||
{% else %}
|
||||
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" value="1">Server Auto Start
|
||||
@ -131,7 +131,7 @@
|
||||
</label>
|
||||
|
||||
<label for="crash_detection" class="form-check-label ml-4 mb-4">
|
||||
{% if data['server_stats'][0]['server_id']['crash_detection'] %}
|
||||
{% if data['server_stats']['server_id']['crash_detection'] %}
|
||||
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection" checked="" value="1">Server Crash Detection
|
||||
{% else %}
|
||||
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection" value="1" >Server Crash Detection
|
||||
@ -170,11 +170,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
{% if data['server_stats'][0]['running'] %}
|
||||
{% if data['server_stats']['running'] %}
|
||||
<a class="btn btn-sm btn-danger disabled">Delete Server</a><br />
|
||||
<small>Please stop the server before deleting it</small>
|
||||
{% else %}
|
||||
<a href="/panel/remove_server?id={{ data['server_stats'][0]['server_id']['server_id'] }}" class="btn btn-sm btn-danger">Delete Server</a>
|
||||
<a href="/panel/remove_server?id={{ data['server_stats']['server_id']['server_id'] }}" class="btn btn-sm btn-danger">Delete Server</a>
|
||||
{% end %}
|
||||
|
||||
</div>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats'][0]['server_id']['server_name'] }}
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats'][0]['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,31 +34,31 @@
|
||||
<div class="card-body pt-0">
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="true">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
|
||||
@ -329,7 +329,7 @@
|
||||
setFileName(event.target.innerText);
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/ajax/get_file?id={{ data['server_stats'][0]['server_id']['server_id'] }}&file_path=' + encodeURIComponent(filePath),
|
||||
url: '/ajax/get_file?id={{ data['server_stats']['server_id']['server_id'] }}&file_path=' + encodeURIComponent(filePath),
|
||||
dataType: 'text',
|
||||
success: function (data) {
|
||||
console.log('Got File Contents From Server');
|
||||
@ -393,7 +393,7 @@
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/save_file?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/save_file?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
file_contents: text,
|
||||
file_path: filePath
|
||||
@ -410,7 +410,7 @@
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/create_file?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/create_file?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
file_parent: parent,
|
||||
file_name: name
|
||||
@ -428,7 +428,7 @@
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/create_dir?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/create_dir?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
dir_parent: parent,
|
||||
dir_name: name
|
||||
@ -446,7 +446,7 @@
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/rename_item?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/rename_item?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
item_path: path,
|
||||
new_item_name: name
|
||||
@ -465,7 +465,7 @@
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/del_file?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/del_file?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
file_path: path
|
||||
},
|
||||
@ -482,7 +482,7 @@
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/del_dir?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/del_dir?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: {
|
||||
dir_path: path
|
||||
},
|
||||
@ -497,7 +497,7 @@
|
||||
function getTreeView() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: '/ajax/get_tree?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/get_tree?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
dataType: 'text',
|
||||
success: function(data){
|
||||
console.log("got response:");
|
||||
|
@ -15,9 +15,9 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats'][0]['server_id']['server_name'] }}
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats'][0]['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -35,31 +35,31 @@
|
||||
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="false">
|
||||
<i class="fas fa-terminal"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="true">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="true">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="false">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
|
||||
@ -91,7 +91,7 @@
|
||||
if( !$("#stop_scroll").is(':checked')){
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/ajax/server_log?id={{ data['server_stats'][0]['server_id']['server_id'] }}&full=1',
|
||||
url: '/ajax/server_log?id={{ data['server_stats']['server_id']['server_id'] }}&full=1',
|
||||
dataType: 'text',
|
||||
success: function (data) {
|
||||
console.log('Got Log From Server')
|
||||
|
@ -15,9 +15,9 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
Server Details - {{ data['server_stats'][0]['server_id']['server_name'] }}
|
||||
Server Details - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats'][0]['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -35,31 +35,31 @@
|
||||
|
||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="true">
|
||||
<a class="nav-link active" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=term" role="tab" aria-selected="true">
|
||||
<i class="fas fa-file-signature"></i>Terminal</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=logs" role="tab" aria-selected="false">
|
||||
<i class="fas fa-file-signature"></i>Logs</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=tasks" role="tab" aria-selected="false">
|
||||
<i class="fas fa-clock"></i>Schedule</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=backup" role="tab" aria-selected="false">
|
||||
<i class="fas fa-save"></i>Backup</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=files" role="tab" aria-selected="false">
|
||||
<i class="fas fa-folder-tree"></i>Files</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="false">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=config" role="tab" aria-selected="false">
|
||||
<i class="fas fa-cogs"></i>Config</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats'][0]['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<a class="nav-link" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true">
|
||||
<i class="fas fa-users"></i>Player Controls</a>
|
||||
</li>
|
||||
<li class="nav-item term-nav-item">
|
||||
@ -128,7 +128,7 @@
|
||||
|
||||
// Convert running to lower case (example: 'True' converts to 'true') and
|
||||
// then to boolean via JSON.parse()
|
||||
let online = JSON.parse('{{ data['server_stats'][0]['running'] }}'.toLowerCase());
|
||||
let online = JSON.parse('{{ data['server_stats']['running'] }}'.toLowerCase());
|
||||
|
||||
let startBtn = document.querySelector('#start-btn');
|
||||
let restartBtn = document.querySelector('#restart-btn');
|
||||
@ -144,13 +144,13 @@
|
||||
stopBtn.setAttribute('disabled', 'disabled');
|
||||
}
|
||||
|
||||
let server_id = '{{ data['server_stats'][0]['server_id']['server_id'] }}';
|
||||
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
|
||||
|
||||
function get_server_log(){
|
||||
if( !$("#stop_scroll").is(':checked')){
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/ajax/server_log?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/server_log?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
dataType: 'text',
|
||||
success: function (data) {
|
||||
console.log('Got Log From Server')
|
||||
@ -216,7 +216,7 @@
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {'X-XSRFToken': token},
|
||||
url: '/ajax/send_command?id={{ data['server_stats'][0]['server_id']['server_id'] }}',
|
||||
url: '/ajax/send_command?id={{ data['server_stats']['server_id']['server_id'] }}',
|
||||
data: data_to_send,
|
||||
success: function(data){
|
||||
console.log("got response:");
|
||||
|
22
main.py
22
main.py
@ -9,8 +9,8 @@ import logging.config
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.models import installer
|
||||
|
||||
from app.classes.shared.controller import controller
|
||||
from app.classes.shared.tasks import TasksManager
|
||||
from app.classes.shared.controller import Controller
|
||||
from app.classes.shared.cmd import MainPrompt
|
||||
|
||||
|
||||
@ -55,7 +55,6 @@ def setup_logging(debug=False):
|
||||
|
||||
""" Our Main Starter """
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser("Crafty Controller - A Server Management System")
|
||||
|
||||
parser.add_argument('-i', '--ignore',
|
||||
@ -88,14 +87,17 @@ if __name__ == '__main__':
|
||||
fresh_install = installer.is_fresh_install()
|
||||
|
||||
if fresh_install:
|
||||
console.debug("Fresh install detected")
|
||||
installer.create_tables()
|
||||
installer.default_settings()
|
||||
else:
|
||||
console.debug("Existing install detected")
|
||||
installer.check_schema_version()
|
||||
|
||||
# now the tables are created, we can load the tasks_manger
|
||||
from app.classes.shared.tasks import tasks_manager
|
||||
|
||||
# now the tables are created, we can load the tasks_manger and server controller
|
||||
controller = Controller()
|
||||
tasks_manager = TasksManager(controller)
|
||||
tasks_manager.start_webserver()
|
||||
tasks_manager.start_scheduler()
|
||||
|
||||
# slowing down reporting just for a 1/2 second so messages look cleaner
|
||||
time.sleep(.5)
|
||||
@ -103,20 +105,22 @@ if __name__ == '__main__':
|
||||
# init servers
|
||||
logger.info("Initializing all servers defined")
|
||||
console.info("Initializing all servers defined")
|
||||
|
||||
controller.init_all_servers()
|
||||
servers = controller.list_defined_servers()
|
||||
|
||||
# start stats logging
|
||||
tasks_manager.start_stats_recording()
|
||||
|
||||
# once the controller is up and stats are logging, we can kick off the scheduler officially
|
||||
tasks_manager.start_scheduler()
|
||||
|
||||
# refresh our cache and schedule for every 12 hoursour cache refresh for serverjars.com
|
||||
tasks_manager.serverjar_cache_refresher()
|
||||
|
||||
# this should always be last
|
||||
tasks_manager.start_main_kill_switch_watcher()
|
||||
|
||||
Crafty = MainPrompt()
|
||||
Crafty = MainPrompt(tasks_manager)
|
||||
Crafty.cmdloop()
|
||||
|
||||
# our main loop - eventually a shell
|
||||
|
Loading…
Reference in New Issue
Block a user