commit 13075f7fa37c09009ea3853ad3f6e75e70b88e94 Author: InValidFire Date: Mon Aug 16 22:51:42 2021 -0400 Initial Commit diff --git a/api.py b/api.py new file mode 100644 index 0000000..3078438 --- /dev/null +++ b/api.py @@ -0,0 +1,70 @@ +import sys + +from target import Target +from fastapi import FastAPI, status +from response import Response + +api = FastAPI() + +api_data = {"version": "2021.8.4.0", "author": "Riley Housden"} + + +@api.post("/update") +def update(): + sys.exit(36) + + +@api.post("/restart") +def stop(): + sys.exit(26) + + +@api.get("/") +def quack(): + return "quack!" + + +@api.get("/target/points") +def list_points(name: str): + try: + target = Target.from_data(name) + return Response(status.HTTP_200_OK, target.points) + except FileNotFoundError: + return Response(status.HTTP_204_NO_CONTENT, {}) + + +@api.get("/target/points/add") +def add_point(name: str, datestr: str, value: int): + try: + target = Target.from_data(name) + except FileNotFoundError: + target = Target(name, []) + target.add_point(datestr, value) + return Response(status.HTTP_200_OK, target).to_json() + + +@api.put("/target/points/modify") +def modify_point(name: str, datestr: str, value: int): + target = Target.from_data(name) + target.modify_point(datestr, value) + return 200 + + +@api.delete("/target/points/delete") +def delete_point(name: str, datestr: str): + target = Target.from_data(name) + target.delete_point(datestr) + return 200 + + +@api.get("/target/rename") +def rename_target(name: str, new_name: str): + target = Target.from_data(name) + target.rename(new_name) + return 200 + + +@api.delete("/target/delete") +def delete_target(name: str): + target = Target.from_data(name) + target.delete() \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..cb2ab52 --- /dev/null +++ b/main.py @@ -0,0 +1,13 @@ +import subprocess + +script = "tracker_api/api.py" + +while True: + try: + subprocess.run(f"python {script}", check=True) + except subprocess.CalledProcessError as err: + if err.returncode == -1: + print("Stopping.") + break + if err.returncode == -2: + print("Run update check!") \ No newline at end of file diff --git a/response.py b/response.py new file mode 100644 index 0000000..0704789 --- /dev/null +++ b/response.py @@ -0,0 +1,15 @@ +import json + + +class ResponseEncoder(json.JSONEncoder): + def default(self, o): + return o.__dict__ + + +class Response: + def __init__(self, status_code, obj): + self.status_code = status_code + self.response = obj + + def to_json(self): + return json.dumps(self, indent=4, cls=ResponseEncoder) diff --git a/target.py b/target.py new file mode 100644 index 0000000..a29eec5 --- /dev/null +++ b/target.py @@ -0,0 +1,85 @@ +import json +from datetime import datetime +from json.encoder import JSONEncoder +from pathlib import Path + +DATA_DIR = Path.home().joinpath(".targetdata") + + +class TargetEncoder(JSONEncoder): + def default(self, o): + if isinstance(o, datetime): + return o.strftime("%m/%d/%Y - %H:%M") + else: + return o.__dict__ + + +class TargetPoint: + def __init__(self, datestr: str, value: int) -> None: + self.datetime = datetime.strptime(datestr, "%m/%d/%Y - %H:%M") + self.value = value + + +class Target: + def __init__(self, name: str, points: list[TargetPoint]): + self.name = name + self.points = points + + def rename(self, name): + """Rename the Target.""" + DATA_DIR.joinpath(f"{self.name}.json").rename( + DATA_DIR.joinpath(f"{name}.json")) + self.name = name + self.save() + + def delete(self): + """Delete the Target.""" + filepath = DATA_DIR.joinpath(f"{self.name}.json") + filepath.unlink() + + def to_json(self): + """Convert Target object to JSON.""" + return json.dumps(self, indent=4, cls=TargetEncoder) + + 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()) + + def modify_point(self, datestr: str, value: int): + """Modify a point. Change its assigned value to the one given.""" + date_time = datetime.strptime(datestr, "%m/%d/%Y - %H:%M") + for point in self.points: + if point.datetime == date_time: + point.value = value + break + self.save() + + def add_point(self, datestr: str, value: int): + """Add a point to the tracker.""" + point = TargetPoint(datestr, value) + self.points.append(point) + self.save() + + def delete_point(self, datestr: str): + """Remove a point from the tracker.""" + date_time = datetime.strptime(datestr, "%m/%d/%Y - %H:%M") + for point in self.points: + if point.datetime == date_time: + self.points.remove(point) + break + self.save() + + @classmethod + def from_data(cls, name): + """Load a target from the DATA_DIR.""" + filepath = DATA_DIR.joinpath(f"{name}.json") + return cls.from_json(filepath.read_text()) + + @classmethod + def from_json(cls, json_str): + """Load a target from a JSON string.""" + obj = json.loads(json_str) + return cls(obj['name'], obj['points'])