2021-08-17 02:51:42 +00:00
|
|
|
import json
|
|
|
|
from datetime import datetime
|
|
|
|
from json.encoder import JSONEncoder
|
|
|
|
from pathlib import Path
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
DATA_DIR = Path.home().joinpath(".tracker_api/trackers")
|
2021-08-17 02:51:42 +00:00
|
|
|
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
def object_hook(dct):
|
|
|
|
if "date_str" in dct:
|
|
|
|
return TrackerPoint(dct["date_str"], dct["value"])
|
|
|
|
if "name" in dct:
|
|
|
|
return Tracker(dct["name"], dct["points"])
|
|
|
|
|
|
|
|
|
|
|
|
class TrackerEncoder(JSONEncoder):
|
2021-08-17 02:51:42 +00:00
|
|
|
def default(self, o):
|
2021-08-23 06:14:40 +00:00
|
|
|
if isinstance(o, Tracker):
|
|
|
|
return dict(name=o.name, points=o.points)
|
|
|
|
elif isinstance(o, TrackerPoint):
|
|
|
|
return dict(date_str=o.datetime.isoformat(), value=o.value)
|
2021-08-17 02:51:42 +00:00
|
|
|
else:
|
2021-08-23 06:14:40 +00:00
|
|
|
return json.JSONEncoder.default(self, o)
|
2021-08-17 02:51:42 +00:00
|
|
|
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
class TrackerPoint:
|
|
|
|
def __init__(self, date_str: str, value: int) -> None:
|
|
|
|
self.datetime = datetime.fromisoformat(date_str)
|
2021-08-17 02:51:42 +00:00
|
|
|
self.value = value
|
|
|
|
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
class Tracker:
|
|
|
|
def __init__(self, name: str, points: list[TrackerPoint]):
|
2021-08-17 02:51:42 +00:00
|
|
|
self.name = name
|
|
|
|
self.points = points
|
|
|
|
|
|
|
|
def rename(self, name):
|
2021-08-23 06:14:40 +00:00
|
|
|
"""Rename the Tracker."""
|
2021-08-17 02:51:42 +00:00
|
|
|
DATA_DIR.joinpath(f"{self.name}.json").rename(
|
|
|
|
DATA_DIR.joinpath(f"{name}.json"))
|
|
|
|
self.name = name
|
|
|
|
self.save()
|
|
|
|
|
|
|
|
def delete(self):
|
2021-08-23 06:14:40 +00:00
|
|
|
"""Delete the Tracker."""
|
2021-08-17 02:51:42 +00:00
|
|
|
filepath = DATA_DIR.joinpath(f"{self.name}.json")
|
|
|
|
filepath.unlink()
|
|
|
|
|
|
|
|
def to_json(self):
|
2021-08-23 06:14:40 +00:00
|
|
|
"""Convert Tracker object to JSON."""
|
|
|
|
return json.dumps(self, indent=4, cls=TrackerEncoder)
|
2021-08-17 02:51:42 +00:00
|
|
|
|
|
|
|
def save(self):
|
|
|
|
"""Save the tracker to JSON."""
|
|
|
|
DATA_DIR.mkdir(exist_ok=True)
|
|
|
|
filepath = DATA_DIR.joinpath(f"{self.name}.json")
|
|
|
|
filepath.touch(exist_ok=True)
|
|
|
|
filepath.write_text(self.to_json())
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
def modify_point(self, date_str: str, value: int):
|
2021-08-17 02:51:42 +00:00
|
|
|
"""Modify a point. Change its assigned value to the one given."""
|
2021-08-23 06:14:40 +00:00
|
|
|
date_time = datetime.fromisoformat(date_str)
|
2021-08-17 02:51:42 +00:00
|
|
|
for point in self.points:
|
|
|
|
if point.datetime == date_time:
|
|
|
|
point.value = value
|
|
|
|
break
|
|
|
|
self.save()
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
def add_point(self, date_str: str, value: int):
|
2021-08-17 02:51:42 +00:00
|
|
|
"""Add a point to the tracker."""
|
2021-08-23 06:14:40 +00:00
|
|
|
point = TrackerPoint(date_str, value)
|
2021-08-17 02:51:42 +00:00
|
|
|
self.points.append(point)
|
|
|
|
self.save()
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
def delete_point(self, date_str: str):
|
2021-08-17 02:51:42 +00:00
|
|
|
"""Remove a point from the tracker."""
|
2021-08-23 06:14:40 +00:00
|
|
|
date_time = datetime.fromisoformat(date_str)
|
2021-08-17 02:51:42 +00:00
|
|
|
for point in self.points:
|
|
|
|
if point.datetime == date_time:
|
|
|
|
self.points.remove(point)
|
|
|
|
break
|
|
|
|
self.save()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def from_data(cls, name):
|
2021-08-23 06:14:40 +00:00
|
|
|
"""Load a tracker from the DATA_DIR."""
|
2021-08-17 02:51:42 +00:00
|
|
|
filepath = DATA_DIR.joinpath(f"{name}.json")
|
|
|
|
return cls.from_json(filepath.read_text())
|
|
|
|
|
2021-08-23 06:14:40 +00:00
|
|
|
@staticmethod
|
|
|
|
def from_json(json_str):
|
|
|
|
"""Load a tracker from a JSON string."""
|
|
|
|
return json.loads(json_str, object_hook=object_hook)
|