Initial Commit
This commit is contained in:
commit
13075f7fa3
4 changed files with 183 additions and 0 deletions
70
api.py
Normal file
70
api.py
Normal file
|
@ -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()
|
13
main.py
Normal file
13
main.py
Normal file
|
@ -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!")
|
15
response.py
Normal file
15
response.py
Normal file
|
@ -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)
|
85
target.py
Normal file
85
target.py
Normal file
|
@ -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'])
|
Loading…
Reference in a new issue