Initial commit with features and everything.

This commit is contained in:
csd4ni3l
2025-09-07 18:22:10 +02:00
commit d01ab6087e
14 changed files with 1683 additions and 0 deletions

57
utils/constants.py Normal file
View File

@@ -0,0 +1,57 @@
import re
HACKATIME_URL = "https://hackatime.hackclub.com/api/v1"
LOGO_ASCII_ART = """
_____ _ _____ _ _
/ ____(_) / ____| | | | |
| (___ _ ___ __ _ ___ | | __ _| | ___ _ __ __| | __ _ _ __
\___ \| |/ _ \/ _` |/ _ \ | | / _` | |/ _ \ '_ \ / _` |/ _` | '__|
____) | | __/ (_| | __/ | |___| (_| | | __/ | | | (_| | (_| | |
|_____/|_|\___|\__, |\___| \_____\__,_|_|\___|_| |_|\__,_|\__,_|_|
__/ |
|___/
"""
PROJECT_INFO = """
Project by csd4ni3l made for Hack Club Siege!
Website: https://csd4ni3l.hu
Github: https://github.com/csd4ni3l/siege-calendar"""
HOME_SCREEN = """
Welcome to Siege Calendar, please press one of the following keys to interact!
It's currently {siege_week}! Siege that castle, or else...
t - Today's Coding Stats
a - All Time Coding Stats
p - Projects
h - Shop
g - Goals
s - Statistics
c - Calendar
q - Quit"""
GOALS_SCREEN = """
Welcome to the Goals section, please press one of the following keys to interact!
a - Add Goal
r - Remove Goal
q - Quit
Your current goals are:
{goals}
"""
SHOP_SCREEN = """
Welcome to the Shop, please add your bought items here, so the program knows of it!
Available items:
"""
shop_items = [
["Mercenaries", "Saves you 1 hour from the current week", 15, 9999],
["8 GB RAM Upgrade", "Up to 7, stacks", 75, 7],
["SSD upgrade 1TB", "Can be bought once", 100, 1],
["SSD upgrade 2TB", "Can be bought once", 150, 1],
["CPU Upgrade", "to i5-1334U", 300, 1],
["FW 13 Upgrade", "CPU needs to be bought first", 150, 1]
]

56
utils/hackatime.py Normal file
View File

@@ -0,0 +1,56 @@
import os, requests, configparser
from datetime import date, datetime, timedelta
from utils.constants import HACKATIME_URL
class Client:
def __init__(self):
self.config = configparser.ConfigParser()
self.config.read(os.path.expanduser("~/.wakatime.cfg"))
self.api_url = HACKATIME_URL
self.api_key = self.config["settings"]["api_key"]
self.headers = {"Authorization": f"Bearer {self.api_key}"}
def get_date(self):
return date.today().strftime("%Y-%m-%d")
def add_day(self, date_str):
dt = datetime.strptime(date_str, "%Y-%m-%d")
next_day = dt + timedelta(days=1)
return next_day.strftime("%Y-%m-%d")
def request(self, path):
response = requests.get(f"{self.api_url}{path}", headers=self.headers)
if response.status_code == 200:
return response.json()
else:
return response.status_code
def get_stats(self, start_date="2025-09-01", end_date="2025-12-01"):
response = self.request(f"/users/my/stats?start_date={start_date}&end_date={end_date}&features=projects,languages")["data"]
if not response.get("languages"): # no time for range, prevent crash
return None, 0
top_language = response["languages"][0]["name"]
top_project = response["projects"][0]["name"]
total_time = response["human_readable_total"]
total_time_seconds = response["total_seconds"]
daily_average = response["human_readable_daily_average"]
daily_average_seconds = response["daily_average"]
return top_language, \
[(language_dict["name"], language_dict["text"], language_dict["percent"]) for language_dict in response["languages"]], \
top_project, \
[(language_dict["name"], language_dict["text"], language_dict["percent"]) for language_dict in response["projects"]], \
total_time, \
total_time_seconds, \
daily_average, \
daily_average_seconds
def get_stats_for_day(self, date="2025-09-01"):
return self.get_stats(date, self.add_day(date))
def get_stats_for_today(self):
return self.get_stats_for_day(self.get_date())

57
utils/utils.py Normal file
View File

@@ -0,0 +1,57 @@
import sys, time
from datetime import date, datetime
def slow_print(text, interval=.03):
for char in text:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(interval)
sys.stdout.write('\n')
def getchar():
try:
import msvcrt
ch = msvcrt.getch()
try:
return ch.decode()
except UnicodeDecodeError:
return ch
except ImportError:
import tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def is_valid_date(date_str: str) -> bool:
try:
datetime.strptime(date_str, "%Y-%m-%d")
return True
except ValueError:
return False
def get_siege_days_passed(current_date=None):
if current_date is None:
current_date = date.today()
start = date(2025, 9, 1)
return (current_date - start).days
def siege_week(current_date=None):
week = get_siege_days_passed(current_date) // 7
if week < 0:
return "Not started yet"
elif week < 3:
return f"Prep Week {week + 1}"
elif week < 13:
return f"Siege Week {week - 2}"
else:
return "Event finished"