diff --git a/.gitignore b/.gitignore index 36b13f1..9d78727 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,6 @@ cython_debug/ # PyPI configuration file .pypirc +# paths for testing +content/ +cfg/ diff --git a/ac-server-scripts-api.py b/ac-server-scripts-api.py new file mode 100644 index 0000000..1d22e73 --- /dev/null +++ b/ac-server-scripts-api.py @@ -0,0 +1,132 @@ +from http.server import HTTPServer, BaseHTTPRequestHandler +import os +import json +from urllib.parse import parse_qs +from change_track import change_track, get_all_tracks, get_configs, get_preview_image, get_outline_image + +class Handler(BaseHTTPRequestHandler): + def do_GET(self): + if (self.handle_GET_path()): + return + + self.send_error(404) + + def do_POST(self): + if (self.handle_POST_path()): + return + + self.send_error(404) + + def handle_GET_path(self) -> bool: + """ + handles the path entered in the GET request. + + Returns: true if the calling function should return, false otherwise + """ + # Serve preview images + if self.path.startswith("/img/"): + parts = self.path.split("/") + parts = [p for p in parts if p] # remove empty + + img_type = parts[1] if len(parts) > 1 else "" + + track, config = self.extract_track_and_config(parts) + + img_path = "" + if (img_type == "preview"): + img_path = get_preview_image(track, config) + elif (img_type == "outline"): + img_path = get_outline_image(track, config) + else: + self.send_error(404) + return True + + + self.send_image(img_path) + + return True + + # JSON track info + if self.path.startswith("/track/"): + track = self.path.replace("/track/", "").strip("/") + configs = get_configs(track) + + data = { + "track": track, + "configs": configs, + "image": f"/img/preview/{track}", + "outline": f"/img/outline/{track}" + } + + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + self.wfile.write(json.dumps(data).encode()) + return True + + if self.path == "/" or self.path == "/index.html": + with open("index.html", "r") as f: + html = f.read() + + tracks = get_all_tracks() + track_options = "".join([f'' for t in tracks]) + + html = html.replace("{{tracks}}", track_options) + html = html.replace("{{configs}}", "") # empty at load + + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + self.wfile.write(html.encode()) + return True + + return False + + def handle_POST_path(self): + if (self.path.startswith("/changetrack/")): + parts = self.path.split("/") + parts = [p for p in parts if p] # remove empty + track, config = self.extract_track_and_config(parts, 1) + print(f"Changing track to '{track}' with config '{config}'") + + success, message = change_track(track, config) + print(message) + if success: + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + response = {"status": "success", "message": message} + self.wfile.write(json.dumps(response).encode()) + return True + else: + self.send_response(400) + self.send_header("Content-type", "application/json") + self.end_headers() + response = {"status": "error", "message": message} + self.wfile.write(json.dumps(response).encode()) + return True + return False + + def send_image(self, img_path: str): + if os.path.exists(img_path): + self.send_response(200) + self.send_header("Content-type", "image/png") + self.end_headers() + with open(img_path, "rb") as f: + self.wfile.write(f.read()) + else: + self.send_error(404) + + def extract_track_and_config(self, parts: list, track_index: int = 2) -> tuple[str, str]: + print(parts) + track = parts[track_index] if len(parts) > track_index else "" + config = parts[track_index + 1] if len(parts) > track_index + 1 else "" + + return track, config + + + + +server = HTTPServer(("0.0.0.0", 10303), Handler) +print("Server running on port 10303") +server.serve_forever() diff --git a/change_track.py b/change_track.py new file mode 100644 index 0000000..1b8e8b9 --- /dev/null +++ b/change_track.py @@ -0,0 +1,71 @@ +import os + +# CONTENT_FOLDER = "/home/sem/assetto-corsa/content" +CONFIG_FILE = "server_cfg.ini" +# CONFIG_PATH = "/home/sem/assetto-corsa/cfg" +CONTENT_FOLDER = "./content" +CONFIG_PATH = "./cfg" + +TRACKS_FOLDER = os.path.join(CONTENT_FOLDER, "tracks") + +def get_all_tracks(): + return sorted([x.name for x in os.scandir(TRACKS_FOLDER) if x.is_dir()]) + +def get_preview_image(track: str, config: str = ""): + img_path = os.path.join(TRACKS_FOLDER, track, "ui", config, "preview.png") + if os.path.exists(img_path): + return img_path + return "" + +def get_outline_image(track: str, config: str = ""): + img_path = os.path.join(TRACKS_FOLDER, track, "ui", config, "outline.png") + if os.path.exists(img_path): + return img_path + return "" + + + +def get_configs(track) -> list[str]: + track_path = os.path.join(TRACKS_FOLDER, track); + configdirs = [x.path.replace(track_path + "/","") for x in os.scandir(track_path) if x.is_dir()] + configdirs.sort() + standard_folders = {'ai', 'ui', 'extension', 'data', 'skins','texture', 'sfx'} + for s in standard_folders: + if s in configdirs: + configdirs.remove(s) + if (len(configdirs) == 0): + print("===== The map you entered does not have a config! =====") + config = "" + return configdirs + +def change_track(newname, config=""): + + print(f"handling track change for {newname} with config {config}") + + if newname not in get_all_tracks(): + return False, f"Track '{newname}' does not exist!" + + new_content = "" + + config_file = os.path.join(CONFIG_PATH, CONFIG_FILE) + with open(config_file,'r') as file: + for line in file: + line = line.strip() + if line.startswith("TRACK="): + new_content += "TRACK=" + str(newname) + print("changing line " + line + " to " + "TRACK=" + str(newname)) + elif line.startswith("CONFIG_TRACK="): + if (len(config) > 1): + new_content +="CONFIG_TRACK=" + str(config) + print("changing line " + line + " to " + "CONFIG_TRACK=" + str(config)) + else: + new_content += "CONFIG_TRACK=" + print("no config entered, setting config line to CONFIG_TRACK=") + else: + new_content += line + new_content += "\n" + + with open(config_file,'w') as newfile: + newfile.write(new_content) + + return True, f"Changed track to: {newname}" diff --git a/change-track.py b/change_track_old.py similarity index 99% rename from change-track.py rename to change_track_old.py index 1067ad7..78e8b8f 100644 --- a/change-track.py +++ b/change_track_old.py @@ -31,7 +31,7 @@ if str(newname) not in dirs: if resetname == False and len(config) > 0: configdirs = [x.path.replace("/home/sem/assetto-corsa/content/tracks/" + newname + "/","") for x in os.scandir('/home/sem/assetto-corsa/content/tracks/' + newname + '/') if x.is_dir()] configdirs.sort() - standard_folders = {'ai', 'ui', 'extension', 'data', 'skins','texture'} + standard_folders = {'ai', 'ui', 'extension', 'data', 'skins','texture', 'sfx'} for s in standard_folders: if s in configdirs: configdirs.remove(s) diff --git a/index.html b/index.html new file mode 100644 index 0000000..735838a --- /dev/null +++ b/index.html @@ -0,0 +1,76 @@ + + +
+