Docker registry repo name fix
This commit is contained in:
commit
bd73da85ed
44 changed files with 991 additions and 0 deletions
44
.drone.yml
Normal file
44
.drone.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
kind: pipeline
|
||||
name: default
|
||||
type: docker
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: docker/compose:latest
|
||||
volumes:
|
||||
- name: docker_sock
|
||||
path: /var/run/docker.sock
|
||||
commands:
|
||||
- docker-compose build
|
||||
- name: push
|
||||
image: docker/compose:latest
|
||||
volumes:
|
||||
- name: docker_sock
|
||||
path: /var/run/docker.sock
|
||||
environment:
|
||||
REGISTRY_USERNAME:
|
||||
from_secret: REGISTRY_USERNAME
|
||||
REGISTRY_PASSWORD:
|
||||
from_secret: REGISTRY_PASSWORD
|
||||
commands:
|
||||
- docker login https://registry.mootfrost.ru -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD
|
||||
- docker-compose push
|
||||
- name: deploy
|
||||
image: docker/compose:latest
|
||||
volumes:
|
||||
- name: docker_sock
|
||||
path: /var/run/docker.sock
|
||||
commands:
|
||||
- docker-compose up -d
|
||||
- name: prune
|
||||
image: docker/compose:latest
|
||||
volumes:
|
||||
- name: docker_sock
|
||||
path: /var/run/docker.sock
|
||||
commands:
|
||||
- docker image prune -f
|
||||
|
||||
volumes:
|
||||
- name: docker_sock
|
||||
host:
|
||||
path: /var/run/docker.sock
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
.idea/
|
||||
__pycache__/
|
||||
key.pem
|
||||
origin.pem
|
||||
venv/
|
||||
Dockerfile.save
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
FROM python:3.8-slim-buster
|
||||
|
||||
ARG HOST
|
||||
ARG PORT
|
||||
|
||||
WORKDIR .
|
||||
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD [ "python", "main.py" ]
|
6
config.py
Normal file
6
config.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from datetime import datetime
|
||||
|
||||
HOST = '0.0.0.0'
|
||||
PORT = 7632
|
||||
|
||||
birthdate = datetime(2007, 10, 13)
|
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
mootfrost-dev_backend:
|
||||
image: registry.mootfrost.ru/mootfrost-dev/backend
|
||||
container_name: mootfrost-dev_backend
|
||||
build: .
|
||||
ports:
|
||||
- "7632:7632"
|
127
main.py
Normal file
127
main.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
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 config
|
||||
|
||||
|
||||
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()
|
||||
|
||||
app = FastAPI()
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
templates = Jinja2Templates(directory="static/templates")
|
||||
|
||||
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"]))
|
||||
except Exception as e:
|
||||
print(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()
|
||||
return today.year - config.birthdate.year - ((today.month, today.day) < (config.birthdate.month, config.birthdate.day))
|
||||
|
||||
|
||||
@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)
|
8
models/Project.py
Normal file
8
models/Project.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Project:
|
||||
name: str
|
||||
description: str
|
||||
url: str
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
uvicorn
|
||||
fastapi
|
||||
requests
|
||||
jinja2
|
BIN
static/resources/fonts/.DS_Store
vendored
Normal file
BIN
static/resources/fonts/.DS_Store
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Black.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Black.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Bold.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Bold.woff
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Italic.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Italic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Light.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Light.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Medium.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Medium.woff
Normal file
Binary file not shown.
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Regular.woff
Normal file
BIN
static/resources/fonts/tisa-sans-pro/Tisa Sans Pro Regular.woff
Normal file
Binary file not shown.
112
static/resources/fonts/tisa-sans-pro/style.css
Normal file
112
static/resources/fonts/tisa-sans-pro/style.css
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* #### Generated By: http://www.cufonfonts.com #### */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Regular';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Regular'), url('Tisa Sans Pro Regular.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Italic'), url('Tisa Sans Pro Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Extra Light';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Extra Light'), url('Tisa Sans Pro ExtraLight.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Extra Light Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Extra Light Italic'), url('Tisa Sans Pro ExtraLight Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Light';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Light'), url('Tisa Sans Pro Light.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Light Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Light Italic'), url('Tisa Sans Pro Light Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Medium';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Medium'), url('Tisa Sans Pro Medium.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Medium Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Medium Italic'), url('Tisa Sans Pro Medium Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Bold';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Bold'), url('Tisa Sans Pro Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Bold Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Bold Italic'), url('Tisa Sans Pro Bold Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Extra Bold';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Extra Bold'), url('Tisa Sans Pro ExtraBold.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Extra Bold Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Extra Bold Italic'), url('Tisa Sans Pro ExtraBold Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Black Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Black Italic'), url('Tisa Sans Pro Black Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tisa Sans Pro Black';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Tisa Sans Pro Black'), url('Tisa Sans Pro Black.woff') format('woff');
|
||||
}
|
BIN
static/resources/images/.DS_Store
vendored
Normal file
BIN
static/resources/images/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
static/resources/images/discord.png
Normal file
BIN
static/resources/images/discord.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
static/resources/images/favicon.png
Normal file
BIN
static/resources/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
static/resources/images/git.png
Normal file
BIN
static/resources/images/git.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 977 B |
11
static/resources/images/gitea.svg
Normal file
11
static/resources/images/gitea.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Created with Vectornator (http://vectornator.io/) -->
|
||||
<svg height="100%" stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;" version="1.1" viewBox="0 0 640 640" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:vectornator="http://vectornator.io" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs/>
|
||||
<g id="Untitled" vectornator:layerName="Untitled">
|
||||
<path d="M395.9 484.2L269 423.2C256.5 417.2 251.1 402 257.2 389.4L318.2 262.5C324.2 250 339.4 244.6 352 250.7C369.2 259 379.1 263.7 379.1 263.7L379 154.5L395.7 154.4L395.8 271.5C395.8 271.5 453.2 295.7 478.9 311.6C482.6 313.9 489.1 318.4 491.8 326C493.9 332.1 493.8 339.1 490.8 345.3L429.8 472.2C423.6 484.9 408.4 490.3 395.9 484.2Z" fill="#ffffff" fill-rule="evenodd" opacity="0" stroke="none"/>
|
||||
<path d="M622.7 149.8C618.6 145.7 613.1 145.8 613.1 145.8C613.1 145.8 495.9 152.4 435.2 153.8C421.9 154.1 408.7 154.4 395.6 154.5L395.6 271.7C390.1 269.1 384.5 266.4 379 263.8C379 227.4 378.9 154.6 378.9 154.6C349.9 155 289.7 152.4 289.7 152.4C289.7 152.4 148.3 145.3 132.9 143.9C123.1 143.3 110.4 141.8 93.9 145.4C85.2 147.2 60.4 152.8 40.1 172.3C-4.9 212.4 6.6 276.2 8 285.8C9.7 297.5 14.9 330 39.7 358.3C85.5 414.4 184.1 413.1 184.1 413.1C184.1 413.1 196.2 442 214.7 468.6C239.7 501.7 265.4 527.5 290.4 530.6C353.4 530.6 479.3 530.5 479.3 530.5C479.3 530.5 491.3 530.6 507.6 520.2C521.6 511.7 534.1 496.8 534.1 496.8C534.1 496.8 547 483 565 451.5C570.5 441.8 575.1 432.4 579.1 423.5C579.1 423.5 634.3 306.4 634.3 192.4C633.2 157.9 624.7 151.8 622.7 149.8ZM125.6 353.9C99.7 345.4 88.7 335.2 88.7 335.2C88.7 335.2 69.6 321.8 60 295.4C43.5 251.2 58.6 224.2 58.6 224.2C58.6 224.2 67 201.7 97.1 194.2C110.9 190.5 128.1 191.1 128.1 191.1C128.1 191.1 135.2 250.5 143.8 285.3C151 314.5 168.6 363 168.6 363C168.6 363 142.5 359.9 125.6 353.9ZM425.9 461.5C425.9 461.5 419.8 476 406.3 476.9C400.5 477.3 396 475.7 396 475.7C396 475.7 395.7 475.6 390.7 473.6L277.8 418.6C277.8 418.6 266.9 412.9 265 403C262.8 394.9 267.7 384.9 267.7 384.9L322 273C322 273 326.8 263.3 334.2 260C334.8 259.7 336.5 259 338.7 258.5C346.8 256.4 356.7 261.3 356.7 261.3L467.4 315C467.4 315 480 320.7 482.7 331.2C484.6 338.6 482.2 345.2 480.9 348.4C474.6 363.8 425.9 461.5 425.9 461.5Z" fill="#000000" fill-rule="evenodd" opacity="1" stroke="none"/>
|
||||
<path d="M326.8 380.1C318.6 380.2 311.4 385.9 309.5 393.9C307.6 401.9 311.5 410.2 318.6 413.9C326.3 417.9 336.1 415.7 341.3 408.5C346.4 401.4 345.6 391.6 339.5 385.4L363.5 336.3C365 336.4 367.2 336.5 369.7 335.8C373.8 334.9 376.8 332.2 376.8 332.2C381 334 385.4 336 390 338.3C394.8 340.7 399.3 343.2 403.4 345.6C404.3 346.1 405.2 346.7 406.2 347.5C407.8 348.8 409.6 350.6 410.9 353C412.8 358.5 409 367.9 409 367.9C406.7 375.5 390.6 408.5 390.6 408.5C382.5 408.3 375.3 413.5 372.9 421C370.3 429.1 374 438.3 381.8 442.3C389.6 446.3 399.2 444 404.3 437C409.3 430.2 408.9 420.7 403.2 414.4C405.1 410.7 406.9 407 408.8 403.1C413.8 392.7 422.3 372.7 422.3 372.7C423.2 371 428 362.4 425 351.4C422.5 340 412.4 334.7 412.4 334.7C400.2 326.8 383.2 319.5 383.2 319.5C383.2 319.5 383.2 315.4 382.1 312.4C381 309.3 379.3 307.3 378.2 306.1C382.9 296.4 387.6 286.8 392.3 277.1C388.2 275.1 384.2 273.1 380.1 271C375.3 280.8 370.4 290.7 365.6 300.5C358.9 300.4 352.7 304 349.5 309.9C346.1 316.2 346.8 324 351.4 329.7C351.4 329.7 326.8 380.1 326.8 380.1Z" fill="#000000" fill-rule="evenodd" opacity="1" stroke="none"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
3
static/resources/images/github.svg
Normal file
3
static/resources/images/github.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 512"><!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
10
static/resources/images/telegram.svg
Normal file
10
static/resources/images/telegram.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M479.7,101.7l-67.9,320.3c-5.1,22.6-18.5,28.2-37.5,17.6l-103.5-76.2l-49.9,48c-5.5,5.5-10.1,10.1-20.8,10.1l7.4-105.4
|
||||
l191.8-173.3c8.3-7.4-1.8-11.6-13-4.1L149.3,287.9L47.3,256c-22.2-6.9-22.6-22.2,4.6-32.8L451.1,69.3
|
||||
C469.6,62.4,485.7,73.4,479.7,101.7z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 631 B |
BIN
static/resources/scripts/.DS_Store
vendored
Normal file
BIN
static/resources/scripts/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
static/resources/scripts/plugins/.DS_Store
vendored
Normal file
BIN
static/resources/scripts/plugins/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
static/resources/scripts/plugins/particles/.DS_Store
vendored
Normal file
BIN
static/resources/scripts/plugins/particles/.DS_Store
vendored
Normal file
Binary file not shown.
9
static/resources/scripts/plugins/particles/particles.min.js
vendored
Normal file
9
static/resources/scripts/plugins/particles/particles.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
114
static/resources/scripts/script.js
Normal file
114
static/resources/scripts/script.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
particlesJS('particles-js',
|
||||
|
||||
{
|
||||
"particles": {
|
||||
"number": {
|
||||
"value": 50,
|
||||
"density": {
|
||||
"enable": true,
|
||||
"value_area": 800
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"value": "#646464"
|
||||
},
|
||||
"shape": {
|
||||
"type": "circle",
|
||||
"stroke": {
|
||||
"width": 0,
|
||||
"color": "#000000"
|
||||
},
|
||||
"polygon": {
|
||||
"nb_sides": 5
|
||||
},
|
||||
"image": {
|
||||
"src": "img/github.svg",
|
||||
"width": 100,
|
||||
"height": 100
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"value": 0.5,
|
||||
"random": false,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 1,
|
||||
"opacity_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"value": 3,
|
||||
"random": true,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 40,
|
||||
"size_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"line_linked": {
|
||||
"enable": true,
|
||||
"distance": 150,
|
||||
"color": "#646464",
|
||||
"opacity": 0.4,
|
||||
"width": 1
|
||||
},
|
||||
"move": {
|
||||
"enable": true,
|
||||
"speed": 2,
|
||||
"direction": "none",
|
||||
"random": false,
|
||||
"straight": false,
|
||||
"out_mode": "bounce",
|
||||
"bounce": false,
|
||||
"attract": {
|
||||
"enable": false,
|
||||
"rotateX": 600,
|
||||
"rotateY": 1200
|
||||
}
|
||||
}
|
||||
},
|
||||
"interactivity": {
|
||||
"detect_on": "canvas",
|
||||
"events": {
|
||||
"onhover": {
|
||||
"enable": true,
|
||||
"mode": "grab"
|
||||
},
|
||||
"onclick": {
|
||||
"enable": true,
|
||||
"mode": "push"
|
||||
},
|
||||
"resize": true
|
||||
},
|
||||
"modes": {
|
||||
"grab": {
|
||||
"distance": 200,
|
||||
"line_linked": {
|
||||
"opacity": 1
|
||||
}
|
||||
},
|
||||
"bubble": {
|
||||
"distance": 400,
|
||||
"size": 40,
|
||||
"duration": 2,
|
||||
"opacity": 8,
|
||||
"speed": 3
|
||||
},
|
||||
"repulse": {
|
||||
"distance": 200,
|
||||
"duration": 0.4
|
||||
},
|
||||
"push": {
|
||||
"particles_nb": 4
|
||||
},
|
||||
"remove": {
|
||||
"particles_nb": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"retina_detect": true
|
||||
}
|
||||
|
||||
);
|
34
static/resources/styles/about.style.css
Normal file
34
static/resources/styles/about.style.css
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* Импорт родительского класса */
|
||||
@import url(style.css);
|
||||
|
||||
/* Применение своих параметров к блоку заголовка */
|
||||
.title-container {
|
||||
}
|
||||
|
||||
/* Применение своих параметров к блоку описания */
|
||||
.description-container {
|
||||
}
|
||||
|
||||
/* Переопределение размера блока текста описания (возможно изменение размера 700px) */
|
||||
.title-menu {
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.about-contents {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Прекращение центрирования (возможно изменение предела 700px) */
|
||||
@media (max-width: 700px) {
|
||||
.contents {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.title-menu {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
transform: translate(0, calc(-50% + 33px));
|
||||
}
|
||||
}
|
29
static/resources/styles/index.style.css
Normal file
29
static/resources/styles/index.style.css
Normal file
|
@ -0,0 +1,29 @@
|
|||
@import url(style.css);
|
||||
|
||||
/* Применение своих параметров к блоку заголовка */
|
||||
.title-container {
|
||||
|
||||
}
|
||||
|
||||
/* Применение своих параметров к блоку ссылок на социальные сети */
|
||||
.socials-container {
|
||||
|
||||
}
|
||||
|
||||
/* Применение своих параметров к блоку ссылок на страницы */
|
||||
.links-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Стили после этого комментария редактированию НЕ ПОДЛЕЖАТ */
|
||||
|
||||
.links-container a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.title-menu {
|
||||
width: fit-content;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
pointer-events: none;
|
||||
}
|
56
static/resources/styles/projects.style.css
Normal file
56
static/resources/styles/projects.style.css
Normal file
|
@ -0,0 +1,56 @@
|
|||
@import url(style.css);
|
||||
|
||||
|
||||
.title-div {
|
||||
|
||||
}
|
||||
|
||||
.projects-container {
|
||||
box-sizing: border-box;
|
||||
width: 1320px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.project-container {
|
||||
flex-flow: row wrap;
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
background-color: black;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.project-container:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.projects-contents {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.projects-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
font-family: "Tisa Sans Pro Regular";
|
||||
}
|
||||
|
||||
@media (max-width: 1330px) {
|
||||
.projects-container {
|
||||
width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.projects-container {
|
||||
width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.projects-container {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
56
static/resources/styles/projects.style.css.save
Normal file
56
static/resources/styles/projects.style.css.save
Normal file
|
@ -0,0 +1,56 @@
|
|||
@import url(000style.css);
|
||||
|
||||
|
||||
.title-div {
|
||||
|
||||
}
|
||||
|
||||
.projects-container {
|
||||
box-sizing: border-box;
|
||||
width: 1320px;
|
||||
overflow-wrap: anywhere;
|
||||
font-family: "Tisa Sans Pro";
|
||||
}
|
||||
|
||||
.project-container {
|
||||
flex-flow: row wrap;
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
background-color: black;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.project-container:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.projects-contents {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.projects-title {
|
||||
font-size: 21px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
@media (max-width: 1330px) {
|
||||
.projects-container {
|
||||
width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.projects-container {
|
||||
width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.projects-container {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
153
static/resources/styles/style.css
Normal file
153
static/resources/styles/style.css
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* Импорт класса шрифтов */
|
||||
@import url(../fonts/tisa-sans-pro/style.css);
|
||||
|
||||
/* Применение своих параметров к блоку заголовка на всех страницах */
|
||||
.title-menu, .title-menu, footer {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Применение своих параметров к блоку контента на всех страницах */
|
||||
.contents-div {
|
||||
|
||||
}
|
||||
|
||||
/* Стили после этого комментария редактированию НЕ ПОДЛЕЖАТ */
|
||||
|
||||
html, body {
|
||||
font-family: 'Tisa Sans Pro Light';
|
||||
background-color: #cdcdcd;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.particles-js-canvas-el {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 72px;
|
||||
}
|
||||
|
||||
p, a {
|
||||
font-size: 20px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
margin: 10px;
|
||||
font-weight: lighter;
|
||||
font-family: "Tisa Sans Pro";
|
||||
}
|
||||
|
||||
.center {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.top {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.horizontal-container {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.vertical-container {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.centered-container {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.contents {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button-div {
|
||||
margin: 5px;
|
||||
width: 200px;
|
||||
padding: 10px;
|
||||
|
||||
background-color: black;
|
||||
color: white;
|
||||
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
|
||||
pointer-events: all;
|
||||
|
||||
box-shadow: -5px 5px 15px rgba(0, 0, 0, 0.5);
|
||||
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.button-div:hover {
|
||||
background-color: #444;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.circle-button-div {
|
||||
border-radius: 75px;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
hr.rounded {
|
||||
border-top: 1px solid #bbb;
|
||||
border-radius: 5px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.button-image-link {
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
}
|
||||
|
||||
.button-image {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
|
||||
filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(299deg) brightness(102%) contrast(102%);
|
||||
}
|
||||
.title-menu {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
|
||||
p, a {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
67
static/templates/about.html
Normal file
67
static/templates/about.html
Normal file
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="/static/resources/styles/about.style.css"/>
|
||||
<link rel="icon" type="image/x-icon" href="/static/resources/images/favicon.png">
|
||||
<title>Mootfrost — обо мне</title>
|
||||
<meta name="description" content="About mootfrost.">
|
||||
</head>
|
||||
|
||||
<body id="particles-js" ondragstart="return false;" ondrop="return false;">
|
||||
<div class="title-menu top title-container">
|
||||
<div class="title-div">
|
||||
<h1 class="title">обо мне:</h1>
|
||||
</div>
|
||||
<div class="contents-div description-container">
|
||||
<p class="about-contents" id="about">
|
||||
Семейкин Андрей, {age} лет. Живу в Москве<br/><br/>
|
||||
В основном пишу на C#, Python, JS. Немного знаю C++<br/>
|
||||
</p>
|
||||
<p class="about-contents" id="code-stats">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="unselectable">
|
||||
<p class="footer-text">v0.5</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
<script src="/static/resources/scripts/plugins/particles/particles.min.js"></script>
|
||||
<script src="/static/resources/scripts/script.js"></script>
|
||||
<script>
|
||||
async function load_code_stats() {
|
||||
let resp = await fetch('/api/get_code_stats', {
|
||||
method: 'GET',
|
||||
},
|
||||
);
|
||||
let code_stats = await resp.json()
|
||||
console.log(code_stats)
|
||||
let about = document.getElementById('code-stats')
|
||||
|
||||
about.innerHTML += `С ${code_stats['since']}: ` + code_stats['total'] + '<br/>'
|
||||
|
||||
about.innerHTML += 'Из них на:' + '<br/>'
|
||||
for (let language in code_stats['languages']) {
|
||||
about.innerHTML += language + ' - ' + code_stats['languages'][language] + '<br/>'
|
||||
}
|
||||
about.innerHTML += ''
|
||||
}
|
||||
load_code_stats()
|
||||
|
||||
async function load_age() {
|
||||
let resp = await fetch('/api/get_age', {
|
||||
method: 'GET',
|
||||
},
|
||||
);
|
||||
let age = await resp.json()
|
||||
console.log(age)
|
||||
let about = document.getElementById('about')
|
||||
|
||||
about.innerHTML = about.textContent.replace('{age}', age)
|
||||
}
|
||||
load_age()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
48
static/templates/index.html
Normal file
48
static/templates/index.html
Normal file
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="/static/resources/styles/index.style.css"/>
|
||||
<link rel="icon" type="image/x-icon" href="/static/resources/images/favicon.png">
|
||||
<title>Mootfrost</title>
|
||||
<meta name="description" content="mootfrost.">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
|
||||
<body ondragstart="return false;" ondrop="return false;">
|
||||
<div id="particles-js">
|
||||
<div class="title-menu center">
|
||||
<div class="title-div horizontal-container title-container">
|
||||
<h1 class="title">mootfrost</h1>
|
||||
</div>
|
||||
|
||||
<div class="contents-div">
|
||||
<div class="horizontal-container socials-container">
|
||||
<div class="button-div circle-button-div"><a class="button-image-link" href="https://github.com/Mootfrost777"><img class="button-image" src="/static/resources/images/github.svg"></a></div>
|
||||
<div class="button-div circle-button-div"><a class="button-image-link" href="https://git.mootfrost.ru"><img class="button-image" src="/static/resources/images/gitea.svg"></a></div>
|
||||
<div class="button-div circle-button-div"><a class="button-image-link" href="https://t.me/mootfrost"><img class="button-image" src="/static/resources/images/telegram.svg"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="centered-container links-container">
|
||||
<div class="vertical-container">
|
||||
<a href="https://mootfrost.ru/about"><div class="button-div">Обо мне</div></a>
|
||||
<a href="https://mootfrost.ru/projects"><div class="button-div">Проекты</div></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p class="footer-text">v0.5</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/resources/scripts/plugins/particles/particles.min.js"></script>
|
||||
<script src="/static/resources/scripts/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
72
static/templates/projects.html
Normal file
72
static/templates/projects.html
Normal file
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="/static/resources/styles/projects.style.css"/>
|
||||
<link rel="icon" type="image/x-icon" href="/static/resources/images/favicon.png">
|
||||
<title>Mootfrost - проекты</title>
|
||||
<meta name="description" content="mootfrost.">
|
||||
</head>
|
||||
<body id="particles-js" ondragstart="return false;" ondrop="return false;">
|
||||
<div class="title-menu top">
|
||||
<div class="title-div title-container">
|
||||
<h1 class="title unselectable">проекты:</h1>
|
||||
<div class="contents-div projects-container horizontal-container" id="projects-list">
|
||||
<template> href="https://google.com" class="projects-contents"><div class="button-div project-container">
|
||||
<h2 class="projects-title">Name</h2>
|
||||
<hr class="rounded">
|
||||
<p class="projects-contents">Description</p>
|
||||
</div></a> </template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p class="footer-text">v0.5</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
<script src="/static/resources/scripts/plugins/particles/particles.min.js"></script>
|
||||
<script src="/static/resources/scripts/script.js"></script>
|
||||
<script>
|
||||
async function load_projects()
|
||||
{
|
||||
let resp = await fetch('/api/get_repos', {
|
||||
method: 'GET',
|
||||
},
|
||||
);
|
||||
let projects = await resp.json()
|
||||
let proj_list = document.getElementById('projects-list')
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
let project = projects[i]
|
||||
|
||||
let h2 = document.createElement('h2')
|
||||
h2.textContent = project['name']
|
||||
h2.classList.add('projects-title')
|
||||
|
||||
let hr = document.createElement('hr')
|
||||
hr.classList.add('rounded')
|
||||
|
||||
let p = document.createElement('p')
|
||||
p.classList.add('projects-contents')
|
||||
p.textContent = project['description']
|
||||
|
||||
let div = document.createElement('div')
|
||||
div.classList.add('button-div')
|
||||
div.classList.add('project-container')
|
||||
div.appendChild(h2)
|
||||
div.appendChild(hr)
|
||||
div.appendChild(p)
|
||||
|
||||
let a = document.createElement('a')
|
||||
a.classList.add('projects-contents')
|
||||
a.href = project['url']
|
||||
a.appendChild(div)
|
||||
proj_list.appendChild(a)
|
||||
}
|
||||
}
|
||||
load_projects()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Add table
Reference in a new issue