134 lines
3.9 KiB
Python
134 lines
3.9 KiB
Python
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)
|