133 lines
3.7 KiB
Python
Executable file
133 lines
3.7 KiB
Python
Executable file
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
|
|
import os
|
|
import math
|
|
|
|
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.dev/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://waka.mootfrost.dev/api/compat/wakatime/v1/users/Mootfrost/stats/last_7_days').json()
|
|
global code_stats
|
|
code_stats.clear()
|
|
|
|
for el in resp['data']['languages']:
|
|
hours = el['hours']
|
|
minutes = el['minutes']
|
|
|
|
code_stats[el['name']] = ''
|
|
if hours > 0:
|
|
code_stats[el['name']] = get_declension(hours, 'час', 'часа', 'часов') + ' '
|
|
if minutes > 0:
|
|
code_stats[el['name']] += get_declension(minutes, 'минуту', 'минуты', 'минут') + ' '
|
|
if code_stats[el['name']] == '':
|
|
code_stats.pop(el['name'])
|
|
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)
|