diff --git a/classes/enums.py b/classes/enums.py index 4c257b0..6a7a54a 100644 --- a/classes/enums.py +++ b/classes/enums.py @@ -21,4 +21,14 @@ class ThemeButton(Enum): class ConnectionState(Enum): OK = "ok" BAD = "bad" - UNAUTHORIZED = "unauthorized" \ No newline at end of file + UNAUTHORIZED = "unauthorized" + +class SaveType(Enum): + LOCAL = "local" + REMOTE = "remote" + BOTH = "both" + +class SaveState(Enum): + OUTDATED = "outdated" + RECENT = "recent" + CURRENT = "current" \ No newline at end of file diff --git a/classes/frames/save.py b/classes/frames/save.py index 3cf9a79..a8c1b88 100644 --- a/classes/frames/save.py +++ b/classes/frames/save.py @@ -1,13 +1,14 @@ -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone from tkinter import LEFT, NSEW, Misc, S, W, ttk from classes.custom.themed_frame import ThemedFrame +from classes.enums import SaveState from modules.utils import osname class FrameSave(ThemedFrame): - def __init__(self, master: Misc, save_dict: str, **kwargs) -> None: + def __init__(self, master: Misc, save_dict: dict, **kwargs) -> None: super().__init__(master, style="Card.TFrame", **kwargs) @@ -17,18 +18,21 @@ class FrameSave(ThemedFrame): self.grid_columnconfigure(1, weight=3) self.grid_columnconfigure(2, weight=3) - self.title = ttk.Label(self, text=save_dict["data"]["farmer"], font=("SunValleyBodyStrongFont", 12, "bold"), justify=LEFT, width=self.widget_width) + self.title = ttk.Label(self, text=f'{save_dict["data"]["farmer"]} ({save_dict["type"].value.upper()}, {save_dict["state"].value.upper()})', font=("SunValleyBodyStrongFont", 12, "bold"), justify=LEFT, width=self.widget_width) self.title.grid(column=0, row=0, padx=9, pady=9, sticky=W) - self.description = ttk.Label(self, text=f'Money: {save_dict["data"]["money"]}\nGame version: {save_dict["data"]["game_version"]}\nID: {save_dict["id"]}', width=self.widget_width) + self.description = ttk.Label(self, text=f'{self.convert_date(year=save_dict["data"]["year"], season=save_dict["data"]["season"], day=save_dict["data"]["day"])}\n{save_dict["data"]["money"]} Gold, {int((save_dict["data"]["played"]/(1000*60*60))%24)} hours played\nGame version: {save_dict["data"]["game_version"]}', width=self.widget_width) self.description.grid(column=0, row=1, padx=9, pady=9, sticky=W) self.buttons = ThemedFrame(self) self.buttons.grid(column=0, columnspan=2, row=2, sticky=NSEW, padx=9, pady=9) self.buttons.grid_columnconfigure(0, weight=1) - upload_date = datetime.utcfromtimestamp(save_dict["date"]).replace(tzinfo=timezone.utc).astimezone(tz=None) - self.last_upload = ttk.Label(self.buttons, text=f'{upload_date.strftime("%A, %d %b %Y")}\nUploaded at {upload_date.strftime("%H:%M")} by {save_dict["device"]}', font=("SunValleyBodyFont", 8), justify=LEFT, width=self.widget_width) + if save_dict["date"] != None: + upload_date = datetime.utcfromtimestamp(save_dict["date"]).replace(tzinfo=timezone.utc).astimezone(tz=None) + self.last_upload = ttk.Label(self.buttons, text=f'{upload_date.strftime("%A, %d %b %Y")}\nUploaded at {upload_date.strftime("%H:%M")} by {save_dict["device"]}', font=("SunValleyBodyFont", 8), justify=LEFT, width=self.widget_width) + else: + self.last_upload = ttk.Label(self.buttons, text=f'Exists only locally', font=("SunValleyBodyFont", 8), justify=LEFT, width=self.widget_width) self.last_upload.grid(column=0, row=0, sticky=W+S) # self.button_device_rename_action = partial(self.rename) @@ -36,11 +40,30 @@ class FrameSave(ThemedFrame): # self.button_device_rename.grid(column=0, row=0, padx=9, sticky=E) #self.button_device_delete_action = partial(self.delete) - self.button_device_delete = ttk.Button(self.buttons, text="Synchronize", style="Accent.TButton", width=11) #, command=self.button_device_delete_action) - self.button_device_delete.grid(column=1, row=0, sticky=W) + self.button_synchronize = ttk.Button(self.buttons, text="Synchronize", style="Accent.TButton", width=11) #, command=self.button_device_delete_action) + self.button_synchronize.grid(column=1, row=0, sticky=W) - def convert_date(self, year: int, month: int, day: int) -> str: - pass + if save_dict["state"] is SaveState.CURRENT: + self.button_synchronize.state(["disabled"]) + + def convert_date(self, year: int, season: int, day: int) -> str: + + if season == 0: + season = "Spring" + elif season == 1: + season = "Summer" + elif season == 2: + season = "Fall" + else: + season = "Winter" + + return "Day {0} of {1}, Year {2}".format(day, season, year) def convert_playtime(self, seconds: int) -> str: + pass + + def upload(self): + pass + + def download(self): pass \ No newline at end of file diff --git a/classes/frames/saves.py b/classes/frames/saves.py index 4076343..f50d1ff 100644 --- a/classes/frames/saves.py +++ b/classes/frames/saves.py @@ -1,11 +1,13 @@ from os import path, walk from tkinter import E, NSEW, W, ttk +from traceback import print_exc import xmltodict from ttkthemes import ThemedTk from classes.custom.scrollable_frame import ScrollableFrame from classes.custom.themed_frame import ThemedFrame +from classes.enums import SaveState, SaveType from classes.frames.save import FrameSave from modules.utils import configGet @@ -24,26 +26,75 @@ class FrameSaves(ScrollableFrame): # self["borderwidth"] = 1 # self["relief"] = "solid" + for index, entry in enumerate(self.saves): + + self.saves[index]["state"] = SaveState.RECENT + self.saves[index]["type"] = SaveType.REMOTE + for subdir, dirs, files in walk(configGet("saves_location")): + try: + for dir in dirs: - with open(path.join(dir, "SaveGameInfo"), "r", encoding="utf-8") as file: + + print("Processing", dir) + + with open(path.join(configGet("saves_location"), dir, "SaveGameInfo"), "r", encoding="utf-8") as file: + save_info_dict = xmltodict.parse(file.read()) + + with open(path.join(configGet("saves_location"), dir, dir), "r", encoding="utf-8") as file: save_dict = xmltodict.parse(file.read()) - self.saves_local.append( + + save_date = None + save_type = SaveType.LOCAL + save_state = SaveState.RECENT + + use_remote = False + + for index, entry in enumerate(self.saves): + + if entry["id"] == int(save_dict["SaveGame"]["uniqueIDForThisGame"]): + print(f'Remote: {entry["data"]["save_time"]}; Local: {int(save_info_dict["Farmer"]["saveTime"])}') + if int(save_info_dict["Farmer"]["saveTime"]) > entry["data"]["save_time"]: + self.saves[index]["type"] = SaveType.BOTH + save_type = SaveType.BOTH + save_state = SaveState.RECENT + save_date = entry["date"] + elif int(save_info_dict["Farmer"]["saveTime"]) < entry["data"]["save_time"]: + self.saves[index]["type"] = SaveType.BOTH + use_remote = True + else: + self.saves[index]["type"] = SaveType.BOTH + self.saves[index]["state"] = SaveState.CURRENT + use_remote = True + + if use_remote is True: + continue + + if save_state == SaveState.RECENT: + + for index, entry in enumerate(self.saves): + if entry["id"] == int(save_dict["SaveGame"]["uniqueIDForThisGame"]): + del self.saves[index] + break + + self.saves.append( { "id": int(save_dict["SaveGame"]["uniqueIDForThisGame"]), "user": None, "device": configGet("name"), - "date": None, + "date": save_date, + "type": save_type, + "state": SaveState.RECENT, "data": { - "farmer": save_dict["Farmer"]["name"], - "money": int(save_dict["Farmer"]["money"]), - "played": int(save_dict["Farmer"]["millisecondsPlayed"]), - "save_time": int(save_dict["Farmer"]["saveTime"]), - "year": int(save_dict["Farmer"]["yearForSaveGame"]), - "season": int(save_dict["Farmer"]["seasonForSaveGame"]), - "day": int(save_dict["Farmer"]["dayOfMonthForSaveGame"]), - "game_version": save_dict["Farmer"]["gameVersion"] + "farmer": save_info_dict["Farmer"]["name"], + "money": int(save_info_dict["Farmer"]["money"]), + "played": int(save_info_dict["Farmer"]["millisecondsPlayed"]), + "save_time": int(save_info_dict["Farmer"]["saveTime"]), + "year": int(save_info_dict["Farmer"]["yearForSaveGame"]), + "season": int(save_info_dict["Farmer"]["seasonForSaveGame"]), + "day": int(save_info_dict["Farmer"]["dayOfMonthForSaveGame"]), + "game_version": save_info_dict["Farmer"]["gameVersion"] }, "file": { "name": None, @@ -51,9 +102,10 @@ class FrameSaves(ScrollableFrame): "path": None } } - ) + ) + except: - pass + print_exc() # Merge local and remote saves. # Maybe add something that indicates availability of an @@ -68,6 +120,8 @@ class FrameSaves(ScrollableFrame): i = 0 for save in self.saves: + print(save) + save_frame = FrameSave(self, save_dict=save) save_frame.grid(column=0, row=i, pady=9, padx=9, sticky=W+E)