from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi import Request import uvicorn import requests import threading import time from datetime import datetime from models.Project import Project import argparse import logging import config # Parse arguments parser = argparse.ArgumentParser() parser.add_argument('--host', dest='host', type=str, help='Hostname of the server') parser.add_argument('--port', dest='port', type=int, help='Port of the server') args = parser.parse_args() # Initialize global application app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="static/templates") # Initialize global variables repos = [] code_stats = {} def get_declension(num: int, one: str, two: str, five: str): n = num % 100 if 11 <= n <= 19: return f'{str(num)} {five}' else: i = n % 10 if i == 1: return f'{str(num)} {one}' elif i in [2, 3, 4]: return f'{str(num)} {two}' else: return f'{str(num)} {five}' def load_projects(): while True: try: resp = requests.get("https://git.mootfrost.ru/api/v1/repos/search", params={'limit': 64, 'sort': 'updated', 'order': 'desc'}).json() global repos repos.clear() for repo in resp['data']: repos.append(Project(repo["name"], repo["description"], repo["html_url"])) logging.info(f'{datetime.now()}: Projects updated') except Exception as e: logging.error(f'{datetime.now()}: Error while updating projects: {e}') time.sleep(7200) def load_code_stats(): while True: resp = requests.get("https://wakatime.com/api/v1/users/Mootfrost/stats/").json() global code_stats code_stats.clear() total = resp['data']['categories'][0] code_stats['total'] = get_declension(total['hours'], 'час', 'часа', 'часов') + ' ' + \ get_declension(total['minutes'], 'минуту', 'минуты', 'минут') # WakaTime дает рэйндж только в хьюман ридбил формате, а не в дате... code_stats['since'] = datetime.strptime(resp['data']['human_readable_range'] .replace('since ', ''), '%b %d %Y') \ .strftime('%d.%m.%Y') langs = resp['data']['languages'] code_stats['languages'] = {} for lang in langs[:5]: code_stats['languages'][lang['name']] = f"{round(lang['percent'])}%" time.sleep(7200) @app.on_event("startup") def start(): threading.Thread(target=load_projects).start() threading.Thread(target=load_code_stats).start() @app.get("/api/get_repos") def get_repos(): return repos @app.get("/api/get_code_stats") def get_code_stats(): return code_stats @app.get("/api/get_age") def get_age(): today = datetime.today() age = today.year - config.birthdate.year - ( (today.month, today.day) < (config.birthdate.month, config.birthdate.day)) return get_declension(age, 'год', 'года', 'лет') @app.get("/") def main_page(request: Request): return templates.TemplateResponse("index.html", {"request": request}) @app.get("/about") def about_page(request: Request): return templates.TemplateResponse("about.html", {"request": request}) @app.get("/projects") def projects_page(request: Request): return templates.TemplateResponse("projects.html", {"request": request}) if __name__ == "__main__": host = args.host if args.host else config.HOST port = args.port if args.port else config.PORT uvicorn.run(app, host=host, port=port)