WIP: Remote/local saves

This commit is contained in:
Profitroll 2023-01-26 16:27:32 +01:00
parent 062a38ceec
commit d844d182f6
3 changed files with 111 additions and 24 deletions

View File

@ -22,3 +22,13 @@ class ConnectionState(Enum):
OK = "ok" OK = "ok"
BAD = "bad" BAD = "bad"
UNAUTHORIZED = "unauthorized" UNAUTHORIZED = "unauthorized"
class SaveType(Enum):
LOCAL = "local"
REMOTE = "remote"
BOTH = "both"
class SaveState(Enum):
OUTDATED = "outdated"
RECENT = "recent"
CURRENT = "current"

View File

@ -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 tkinter import LEFT, NSEW, Misc, S, W, ttk
from classes.custom.themed_frame import ThemedFrame from classes.custom.themed_frame import ThemedFrame
from classes.enums import SaveState
from modules.utils import osname from modules.utils import osname
class FrameSave(ThemedFrame): 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) super().__init__(master, style="Card.TFrame", **kwargs)
@ -17,18 +18,21 @@ class FrameSave(ThemedFrame):
self.grid_columnconfigure(1, weight=3) self.grid_columnconfigure(1, weight=3)
self.grid_columnconfigure(2, 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.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.description.grid(column=0, row=1, padx=9, pady=9, sticky=W)
self.buttons = ThemedFrame(self) self.buttons = ThemedFrame(self)
self.buttons.grid(column=0, columnspan=2, row=2, sticky=NSEW, padx=9, pady=9) self.buttons.grid(column=0, columnspan=2, row=2, sticky=NSEW, padx=9, pady=9)
self.buttons.grid_columnconfigure(0, weight=1) self.buttons.grid_columnconfigure(0, weight=1)
upload_date = datetime.utcfromtimestamp(save_dict["date"]).replace(tzinfo=timezone.utc).astimezone(tz=None) if save_dict["date"] != 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) 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.last_upload.grid(column=0, row=0, sticky=W+S)
# self.button_device_rename_action = partial(self.rename) # 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_rename.grid(column=0, row=0, padx=9, sticky=E)
#self.button_device_delete_action = partial(self.delete) #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_synchronize = 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.grid(column=1, row=0, sticky=W)
def convert_date(self, year: int, month: int, day: int) -> str: if save_dict["state"] is SaveState.CURRENT:
pass 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: def convert_playtime(self, seconds: int) -> str:
pass pass
def upload(self):
pass
def download(self):
pass

View File

@ -1,11 +1,13 @@
from os import path, walk from os import path, walk
from tkinter import E, NSEW, W, ttk from tkinter import E, NSEW, W, ttk
from traceback import print_exc
import xmltodict import xmltodict
from ttkthemes import ThemedTk from ttkthemes import ThemedTk
from classes.custom.scrollable_frame import ScrollableFrame from classes.custom.scrollable_frame import ScrollableFrame
from classes.custom.themed_frame import ThemedFrame from classes.custom.themed_frame import ThemedFrame
from classes.enums import SaveState, SaveType
from classes.frames.save import FrameSave from classes.frames.save import FrameSave
from modules.utils import configGet from modules.utils import configGet
@ -24,26 +26,75 @@ class FrameSaves(ScrollableFrame):
# self["borderwidth"] = 1 # self["borderwidth"] = 1
# self["relief"] = "solid" # 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")): for subdir, dirs, files in walk(configGet("saves_location")):
try: try:
for dir in dirs: 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()) 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"]), "id": int(save_dict["SaveGame"]["uniqueIDForThisGame"]),
"user": None, "user": None,
"device": configGet("name"), "device": configGet("name"),
"date": None, "date": save_date,
"type": save_type,
"state": SaveState.RECENT,
"data": { "data": {
"farmer": save_dict["Farmer"]["name"], "farmer": save_info_dict["Farmer"]["name"],
"money": int(save_dict["Farmer"]["money"]), "money": int(save_info_dict["Farmer"]["money"]),
"played": int(save_dict["Farmer"]["millisecondsPlayed"]), "played": int(save_info_dict["Farmer"]["millisecondsPlayed"]),
"save_time": int(save_dict["Farmer"]["saveTime"]), "save_time": int(save_info_dict["Farmer"]["saveTime"]),
"year": int(save_dict["Farmer"]["yearForSaveGame"]), "year": int(save_info_dict["Farmer"]["yearForSaveGame"]),
"season": int(save_dict["Farmer"]["seasonForSaveGame"]), "season": int(save_info_dict["Farmer"]["seasonForSaveGame"]),
"day": int(save_dict["Farmer"]["dayOfMonthForSaveGame"]), "day": int(save_info_dict["Farmer"]["dayOfMonthForSaveGame"]),
"game_version": save_dict["Farmer"]["gameVersion"] "game_version": save_info_dict["Farmer"]["gameVersion"]
}, },
"file": { "file": {
"name": None, "name": None,
@ -51,9 +102,10 @@ class FrameSaves(ScrollableFrame):
"path": None "path": None
} }
} }
) )
except: except:
pass print_exc()
# Merge local and remote saves. # Merge local and remote saves.
# Maybe add something that indicates availability of an # Maybe add something that indicates availability of an
@ -68,6 +120,8 @@ class FrameSaves(ScrollableFrame):
i = 0 i = 0
for save in self.saves: for save in self.saves:
print(save)
save_frame = FrameSave(self, save_dict=save) save_frame = FrameSave(self, save_dict=save)
save_frame.grid(column=0, row=i, pady=9, padx=9, sticky=W+E) save_frame.grid(column=0, row=i, pady=9, padx=9, sticky=W+E)