from time import time
from datetime import datetime
from random import choice
+from gamiki import Session
class Game(dict):
"""Game object generated from a directory."""
desc : str = ""
total_time : int = 0
total_sessions : int = 0
- sessions : list = None # list of (YYYY-MM-DD, HH:MM, secs, opt)
+ sessions : list = None # list:Session (call read_sessions() first)
icon : Path = None # "main" icon
icons : dict = None # all found icons
intro : list = None # all found intro videos
except FileNotFoundError:
pass
- file = self.dir.joinpath("sessions.total")
- try:
- with open(file, encoding="utf-8") as data:
- ln = data.readline() # number of sessions
- sessions = int(ln.split(":", maxsplit=1)[1].strip())
- ln = data.readline() # total time in human formated time
- human = ln.split(":", maxsplit=1)[1].strip()
- tab = human.split(":")
- total = int((int)(tab[0]) * 3600
- + (int)(tab[1]) * 60
- + (int)(tab[2])
- )
-
- self.total_time = total
- self.total_sessions = sessions
-
- # TODO: read the total per option times
- except FileNotFoundError:
- pass
- except Exception as e:
- print(f"Error when querying {file.as_posix()}: {e}", file=stderr)
+ self.total, self.sessions = Session.read_total(self.dir)
+ # TODO: read the total per option times
def _read_icon(self, suffix: str = "") -> PurePath:
"""
def get_icon(self, key: str) -> PurePath:
return self.icons.get(key, self.icon)
- def _read_sessions(self) -> list:
- self.sessions = []
- file = self.dir.joinpath("sessions.txt")
- if (file.exists()):
- try:
- with open(file, "r", encoding="utf-8") as data:
- for ln in data:
- start_d = ""
- start_h = ""
- total = 0
- so = ""
- tab = ln.strip().split(" ")
- if (len(tab) >= 4):
- start_d = tab[2]
- start_h = tab[3].split("(")[1].split(")")[0]
- if (len(tab) >= 6):
- htab = tab[5].split(":")
- if (len(htab) == 3):
- total += int(htab[0]) * 3600
- total += int(htab[1]) * 60
- total += int(htab[2])
- if (len(tab) >= 8):
- so = tab[7]
- if (start_d and start_h):
- self.sessions.append((start_d, start_h, total, so))
- except Exception as e:
- print(f"Error when querying {file.as_posix()}: {e}",file=stderr)
-
- def add_session(self, when: datetime, elapsed: int, opt: str):
- def human(seconds: int) -> str:
- ss = (seconds % 60)
- mm = (seconds // 60) % 60
- hh = (seconds // 3600)
- return f"{hh:02}:{mm:02}:{ss:02}"
-
- O = ""
- if (opt):
- O = f" - {opt}"
-
- start_d = when.strftime('%Y-%m-%d')
- start_h = when.strftime('%H:%M')
- text = f"Session of {start_d} ({start_h}) lasted: {human(elapsed)}{O}"
- print(f"[{self.name}]: {text}")
-
- if (not self.sessions):
- self._read_sessions()
-
- self.sessions.append((start_d, start_h, elapsed, opt))
-
- total = 0
- for session in self.sessions:
- total += session[2]
- print(
- f"[{self.name}]: Total time: "
- f"{human(total)} (in {len(self.sessions)} session(s))"
- )
-
- try:
- file = self.dir.joinpath("sessions.txt")
- with open(file, "a", encoding="utf-8") as data:
- data.write(text)
- data.write("\n")
- except Exception as e:
- print("Cannot save session time:", e, file=stderr)
- total = None
-
- try:
- if (total):
- file = self.dir.joinpath("sessions.total")
- with open(file, "w", encoding="utf-8") as data:
- data.write(f"Sessions: {len(self.sessions)}\n")
- data.write(f"Total time: {human(total)}\n")
-
- if (len(self.opts) > 1):
- data.write("\nTotal per option:\n")
- total = 0
- for session in self.sessions:
- if (session[3] == None or session[3] == ""):
- total += session[2]
- data.write(f"* {human(total)}\n");
- for opt in self.opts:
- total = 0
- for session in self.sessions:
- if (len(session) > 3):
- if (session[3] == opt):
- total += session[2]
- data.write(f"* {human(total)} - {opt}\n");
-
- except:
- print("Cannot save total time", file=stderr)
+ def read_sessions(self) -> list:
+ self.sessions = Session.read_sessions(self.dir)
def run(self, opt: str = None):
if (not self.support):
elapsed = int(time() - begin)
if (elapsed >= 60): # Ignore very short sessions
- self.add_session(today, elapsed, opt)
+ if (self.sessions == None):
+ self.read_sessions()
+
+ new_sess = Session(today, elapsed, opt)
+ Session.write_new_session(self.dir, self.sessions, new_sess)
--- /dev/null
+from pathlib import PurePath, Path
+from sys import stderr
+from time import time
+from datetime import datetime
+
+class Session():
+ """Play session for a game."""
+
+ when : datetime = None
+ elapsed : int = None
+ opt : str = None
+
+ def __init__(self, when: datetime, elapsed: int, opt: str = None):
+ self.when = when
+ self.elapsed = elapsed
+ self.opt = opt
+
+ def from_str(ln: str):
+ dat = ""
+ hour = ""
+ total = 0
+ opt = ""
+ tab = ln.strip().split(" ")
+ if (len(tab) >= 4):
+ dat = tab[2]
+ hour = tab[3].split("(")[1].split(")")[0]
+ if (len(tab) >= 6):
+ htab = tab[5].split(":")
+ if (len(htab) == 3):
+ total += int(htab[0]) * 3600
+ total += int(htab[1]) * 60
+ total += int(htab[2])
+ if (len(tab) >= 8):
+ opt = tab[7]
+ if (dat and hour):
+ return Session(
+ datetime.strptime(f"{dat} {hour}", "%Y-%m-%d %H:%M"), total, opt
+ )
+
+ return None
+
+ def __str__(self) -> str:
+ oopt = ""
+ if (self.opt):
+ oopt = f" - {opt}"
+
+ dat = self.when.strftime('%Y-%m-%d')
+ hour = self.when.strftime('%H:%M')
+ humanf = Session._human(self.elapsed)
+ return f"Session of {dat} ({hour}) lasted: {humanf}{oopt}"
+
+ def read_total(dir: PurePath) -> (int, int):
+ """
+ Read a session.total file.
+
+ @param dir: the game directory where to find the session.total file
+
+ @return (total play time in second, number of sessions played)
+ """
+
+ ln1 = "(not read yet)"
+ ln2 = "(not read yet)"
+ file = dir.joinpath("sessions.total")
+ try:
+ with open(file, encoding="utf-8") as data:
+ ln1 = data.readline().strip() # number of sessions
+ num_sessions = int(ln1.split(":", maxsplit=1)[1].strip())
+ ln2 = data.readline().strip() # total time, human formated
+ humanf = ln2.split(":", maxsplit=1)[1].strip()
+ tab = humanf.split(":")
+ total = int((int)(tab[0]) * 3600
+ + (int)(tab[1]) * 60
+ + (int)(tab[2])
+ )
+
+ # TODO: read the total per option times?
+ return (total, num_sessions)
+ except FileNotFoundError:
+ pass
+ except Exception as e:
+ #raise ValueError(f"Error when querying {file.as_posix()}: {e}"
+ # + "\n" + "First 2 lines:\n" + ln1 + "\n" + ln2 + "\n.\n"
+ #)
+ print(f"Error when reading total from {file.as_posix()}: {e}"
+ + "\n" + "First 2 lines:\n" + ln1 + "\n" + ln2 + "\n.\n"
+ + "We will try to re-read the whole session file...",
+ file=stderr
+ )
+
+ total = 0
+ num_sessions = 0
+ sessions = Session.read_sessions(dir)
+ for sess in sessions:
+ num_sessions += 1
+ total += sess.elapsed
+
+ return (total, num_sessions)
+
+ def read_sessions(dir: PurePath) -> list['Session']:
+ sessions = []
+ file = dir.joinpath("sessions.txt")
+ if (file.exists()):
+ try:
+ with open(file, "r", encoding="utf-8") as data:
+ for ln in data:
+ sess = Session.from_str(ln)
+ if (sess):
+ sessions.append(sess)
+ except Exception as e:
+ raise ValueError(f"Error when reading {file.as_posix()}: {e}")
+
+ return sessions
+
+ def write_total(dir: PurePath, sessions: list):
+ total = 0
+ opts = []
+ for sess in sessions:
+ total += sess.elapsed
+ if not sess.opt in opts:
+ opts.append(sess.opt)
+
+ file = dir.joinpath("sessions.total")
+ with open(file, "w", encoding="utf-8") as data:
+ data.write(f"Sessions: {len(sessions)}\n")
+ data.write(f"Total time: {Session._human(total)}\n")
+
+ if (len(opts) > 1):
+ data.write("\nTotal per option:\n")
+ total = 0
+ for session in sessions:
+ if (session[3] == None or session[3] == ""):
+ total += session[2]
+ data.write(f"* {_human(total)}\n");
+ for opt in opts:
+ total = 0
+ for session in sessions:
+ if (len(session) > 3):
+ if (session[3] == opt):
+ total += session[2]
+ data.write(f"* {Session._human(total)} - {opt}\n");
+
+ def write_new_session(dir: PurePath, sessions: list, new_sess: 'Session'):
+ """
+ Write a new session on the given game directory -- will also update the
+ sessions.total file or create it if needed.
+
+ @param dir: the game directory where to find the session.total file
+ @param sessions: the previous play sessions (will be used to overwrite
+ the previous information, be careful!) -- note that the
+ new play session will also be appended on this one
+ @param new_sess: the new play session to add
+
+ """
+
+ # Can throw:
+ file = dir.joinpath("sessions.txt")
+ with open(file, "a", encoding="utf-8") as data:
+ data.write(str(new_sess))
+ data.write("\n")
+
+ sessions.append(new_sess)
+
+ # We catch the exceptions, as this file can be recomputed if needed
+ try:
+ Session.write_total(dir, sessions)
+ except Exception as e:
+ print(f"Cannot save total time: {e}", file=stderr)
+
+ def _human(seconds: int) -> str:
+ ss = (seconds % 60)
+ mm = (seconds // 60) % 60
+ hh = (seconds // 3600)
+ return f"{hh:02}:{mm:02}:{ss:02}"