Compare commits
No commits in common. "minimal-css" and "main" have entirely different histories.
minimal-cs
...
main
41
.gitignore
vendored
@ -1,23 +1,18 @@
|
||||
__pycache__
|
||||
*.md
|
||||
!POST_TEMPLATE.md
|
||||
!README.md
|
||||
|
||||
docker-compose.yaml
|
||||
*.sh
|
||||
|
||||
*.ini
|
||||
|
||||
# Ignore images in posts
|
||||
|
||||
|
||||
# Flask Data & Config
|
||||
*.ini
|
||||
data
|
||||
.flask_session
|
||||
*.json
|
||||
|
||||
|
||||
# Writing
|
||||
writing
|
||||
|
||||
__pycache__
|
||||
*.md
|
||||
!POST_TEMPLATE.md
|
||||
!README.md
|
||||
|
||||
docker-compose.yaml
|
||||
*.sh
|
||||
|
||||
*.ini
|
||||
|
||||
# Ignore images in posts
|
||||
*.jpg
|
||||
*.png
|
||||
*.gif
|
||||
|
||||
# Writing
|
||||
writing
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@ FROM python:3.12.2-slim-bookworm
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y
|
||||
|
||||
RUN groupadd -r app && useradd -r -g app app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN python3 -m pip install --upgrade pip
|
||||
@ -11,4 +13,6 @@ RUN python3 -m pip install -r requirements.txt
|
||||
|
||||
WORKDIR ./app
|
||||
|
||||
USER app
|
||||
|
||||
CMD ["python3", "-u", "app.py"]
|
||||
|
||||
109
app/app.py
@ -1,11 +1,11 @@
|
||||
import os
|
||||
import glob
|
||||
import configparser
|
||||
import random
|
||||
import base64
|
||||
import datetime
|
||||
|
||||
import requests
|
||||
import flask
|
||||
import flask_wtf.csrf
|
||||
import waitress
|
||||
import markdown
|
||||
|
||||
@ -13,31 +13,21 @@ from post import Post
|
||||
|
||||
app = flask.Flask(__name__, static_url_path='', static_folder='static')
|
||||
|
||||
# CONFIG
|
||||
CONFIG_PATH = "./config.ini"
|
||||
config = configparser.ConfigParser()
|
||||
config.read(CONFIG_PATH)
|
||||
|
||||
WRITING_FOLDER = 'static/writing/'
|
||||
POSTS_FOLDER = config['POSTS']['POSTS_FOLDER']
|
||||
STATUS_FILE = config['STATUS']['STATUS_FILE']
|
||||
PORT = int(config['NETWORK']['PORT'])
|
||||
DEV = int(config['NETWORK']['DEV'])
|
||||
|
||||
|
||||
# CSRF Protect
|
||||
app.config['SECRET_KEY'] = base64.b64decode(config["FLASK"]["SECRET"])
|
||||
csrf = flask_wtf.csrf.CSRFProtect()
|
||||
csrf.init_app(app)
|
||||
|
||||
MUSIC_API_TOKEN = config['AUTH']['MUSIC_API_TOKEN']
|
||||
MUSIC_API_URL = config['NETWORK']['MUSIC_API_URL']
|
||||
statuses = {}
|
||||
header_background_images = [
|
||||
"canal-banner2.jpg",
|
||||
"real-greensilt-banner.png"
|
||||
]
|
||||
|
||||
def get_posts(category_filter : str | None = None) -> list[tuple[dict, list]]:
|
||||
def get_posts(category_filter : str | None = None) -> list[Post]:
|
||||
post_files = glob.glob(f'{POSTS_FOLDER}/*')
|
||||
try:
|
||||
post_files.remove(f'{POSTS_FOLDER}/POST_TEMPLATE.md')
|
||||
@ -67,12 +57,7 @@ def get_posts(category_filter : str | None = None) -> list[tuple[dict, list]]:
|
||||
ordered_posts.append(most_recent)
|
||||
posts.remove(most_recent)
|
||||
|
||||
# Convert to dict
|
||||
posts = []
|
||||
for post in reversed(ordered_posts):
|
||||
posts.append(post.__dict__)
|
||||
|
||||
return posts
|
||||
return reversed(ordered_posts)
|
||||
|
||||
def read_status_file() -> dict:
|
||||
with open(STATUS_FILE, 'r', encoding='utf-8') as file:
|
||||
@ -105,9 +90,6 @@ def get_status() -> str:
|
||||
|
||||
return f'<div title="{selected_key}">{markdown.markdown(selected_status)}</div>'
|
||||
|
||||
def get_header_image() -> str:
|
||||
return header_background_images[random.randint(0, len(header_background_images) - 1)]
|
||||
|
||||
# Main Page
|
||||
@app.route('/')
|
||||
def index():
|
||||
@ -115,35 +97,40 @@ def index():
|
||||
# Get posts
|
||||
posts = get_posts()
|
||||
|
||||
post_bodies = []
|
||||
for post in posts:
|
||||
post_bodies.append(post.body)
|
||||
|
||||
# Get status
|
||||
status = get_status()
|
||||
|
||||
img = get_header_image()
|
||||
|
||||
return flask.render_template('index.html', posts=posts, status=status, title='0x01fe.net', header_background_image=img)
|
||||
return flask.render_template('index.html', posts=post_bodies, status=status)
|
||||
|
||||
# Posts
|
||||
@app.route('/post/<string:post_name>')
|
||||
def post(post_name: str):
|
||||
|
||||
for post in get_posts():
|
||||
if post['title'] == post_name:
|
||||
|
||||
return flask.render_template('index.html', posts=[post], status=get_status(), title='0x01fe.net')
|
||||
if post.title.replace(' ', '-') == post_name:
|
||||
return flask.render_template('index.html', posts=[post.body], status=get_status())
|
||||
|
||||
flask.abort(404)
|
||||
|
||||
# Category's Endpoint
|
||||
@app.route('/category/<string:category>/')
|
||||
def category_filter(category: str):
|
||||
# Games Page
|
||||
@app.route('/games/')
|
||||
def games():
|
||||
|
||||
# Get posts
|
||||
posts = get_posts(category_filter=category)
|
||||
posts = get_posts(category_filter="games")
|
||||
|
||||
post_bodies = []
|
||||
for post in posts:
|
||||
post_bodies.append(post.body)
|
||||
|
||||
# Get status
|
||||
status = get_status()
|
||||
|
||||
return flask.render_template('index.html', posts=posts, status=status, title=category.replace('-', ' '))
|
||||
return flask.render_template('games.html', posts=post_bodies, status=status)
|
||||
|
||||
# Music Page
|
||||
@app.route('/music/')
|
||||
@ -152,6 +139,10 @@ def music():
|
||||
# Get posts
|
||||
posts = get_posts(category_filter="music")
|
||||
|
||||
post_bodies = []
|
||||
for post in posts:
|
||||
post_bodies.append(post.body)
|
||||
|
||||
# Get status
|
||||
status = get_status()
|
||||
|
||||
@ -173,20 +164,64 @@ def music():
|
||||
|
||||
top_albums[album_index]['listen_time'] = hours
|
||||
|
||||
return flask.render_template('music.html', posts=post_bodies, status=status, top_albums=top_albums)
|
||||
|
||||
return flask.render_template('music.html', posts=posts, status=status, top_albums=top_albums)
|
||||
# Motion Pictures Page
|
||||
@app.route('/motion-pictures/')
|
||||
def motion_pictures():
|
||||
|
||||
# Get posts
|
||||
posts = get_posts(category_filter="motion-pictures")
|
||||
|
||||
post_bodies = []
|
||||
for post in posts:
|
||||
post_bodies.append(post.body)
|
||||
|
||||
# Get status
|
||||
status = get_status()
|
||||
|
||||
return flask.render_template('motion-pictures.html', posts=post_bodies, status=status)
|
||||
|
||||
# Programming Page
|
||||
@app.route('/programming/')
|
||||
def programming():
|
||||
|
||||
# Get posts
|
||||
posts_and_comments = get_posts(category_filter="programming")
|
||||
posts = get_posts(category_filter="programming")
|
||||
|
||||
post_bodies = []
|
||||
for post in posts:
|
||||
post_bodies.append(post.body)
|
||||
|
||||
# Get status
|
||||
status = get_status()
|
||||
|
||||
return flask.render_template('programming.html', posts=posts_and_comments, status=status)
|
||||
return flask.render_template('programming.html', posts=post_bodies, status=status)
|
||||
|
||||
@app.route('/writing/')
|
||||
def writing():
|
||||
|
||||
works = []
|
||||
|
||||
# Get all works in writing folder
|
||||
files = glob.glob(WRITING_FOLDER + '*')
|
||||
|
||||
for path in files:
|
||||
|
||||
date: str = datetime.datetime.fromtimestamp(os.path.getctime(path)).strftime("%B %d, %Y")
|
||||
name: str = path.split('/')[-1]
|
||||
|
||||
works.append({
|
||||
'date' : date,
|
||||
'name' : name,
|
||||
'path' : path
|
||||
})
|
||||
|
||||
return flask.render_template('writing.html', works=works)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# About Page
|
||||
@app.route('/about/')
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import flask
|
||||
import flask_wtf.csrf
|
||||
import wtforms
|
||||
|
||||
COMMENTS_PATH = "./data/comments.json"
|
||||
|
||||
if not os.path.exists('./data/'):
|
||||
os.mkdir('./data/')
|
||||
|
||||
if not os.path.exists(COMMENTS_PATH):
|
||||
with open(COMMENTS_PATH, 'w+') as file:
|
||||
file.write('{}')
|
||||
|
||||
comments = flask.Blueprint('comment', __name__, template_folder='./templates')
|
||||
|
||||
class CommentForm(flask_wtf.FlaskForm):
|
||||
textbox = wtforms.TextAreaField('Input')
|
||||
|
||||
@comments.route('/comment/<string:post_title>', methods=['POST'])
|
||||
def comment(post_title: str):
|
||||
form = CommentForm(csrf_enabled=True)
|
||||
|
||||
save_comment(form.textbox.data, post_title)
|
||||
|
||||
return flask.redirect('/')
|
||||
|
||||
def save_comment(content: str, post_title: str):
|
||||
with open(COMMENTS_PATH, 'r') as file:
|
||||
comment_data = json.loads(file.read())
|
||||
|
||||
# See if user is logged in, otherwise setup as anon
|
||||
if 'username' in flask.session:
|
||||
username = flask.session['username']
|
||||
else:
|
||||
username = 'Anon'
|
||||
|
||||
comment = {
|
||||
"username" : username,
|
||||
"content" : content
|
||||
}
|
||||
|
||||
# Add comment to JSON data
|
||||
if post_title in comment_data:
|
||||
comment_data[post_title].append(comment)
|
||||
else:
|
||||
comment_data[post_title] = [comment]
|
||||
|
||||
# Save JSON data
|
||||
with open(COMMENTS_PATH, 'w') as file:
|
||||
file.write(json.dumps(comment_data))
|
||||
|
||||
def get_comments(post_title : int) -> list[dict]:
|
||||
|
||||
with open(COMMENTS_PATH, 'r') as file:
|
||||
comment_data = json.loads(file.read())
|
||||
|
||||
if post_title in comment_data:
|
||||
return comment_data[post_title]
|
||||
else:
|
||||
return []
|
||||
|
||||
BIN
app/data/.flask_session/2029240f6d1128be89ddc32729463129
Normal file
BIN
app/data/.flask_session/aa43147407c8a8c678cd91f678f2a023
Normal file
8
app/data/comments.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"2" : [
|
||||
{
|
||||
"username" : "0x01FE",
|
||||
"content" : "Hello, this is an example comment!"
|
||||
}
|
||||
]
|
||||
}
|
||||
5
app/data/users.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"users" : {
|
||||
"0x01FE" : "cGFzc3dvcmQ="
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ class Post:
|
||||
category : str
|
||||
author : str
|
||||
date : datetime.datetime
|
||||
date_str : str
|
||||
body : str
|
||||
file : str
|
||||
title : str
|
||||
@ -20,11 +19,11 @@ class Post:
|
||||
|
||||
self.category = lines[1].split(":")[1].strip()
|
||||
self.author = lines[2].split(":")[1].strip()
|
||||
self.title = lines[6].replace('#', '').strip()
|
||||
self.url = '/post/' + self.title
|
||||
self.title = lines[6][2:-1]
|
||||
self.url = '/post/' + self.title.replace(' ', '-')
|
||||
|
||||
date = lines[3].split(":")[1].strip()
|
||||
self.date = datetime.datetime.strptime(date, "%d-%m-%Y")
|
||||
self.date_str = self.date.strftime("%B %d, %Y")
|
||||
|
||||
self.body = markdown.markdown(f'# [{self.title}]({self.url})\n' + ''.join(lines[7:]), extensions=['footnotes'])
|
||||
self.body = markdown.markdown(f'# [{self.title}]({self.url})\n' + ''.join(lines[7:]))
|
||||
|
||||
|
||||
@ -4,6 +4,6 @@ author: author
|
||||
date: date
|
||||
|
||||
# POST
|
||||
# TITLE
|
||||
## TITLE
|
||||
### DATE OR SUBTITLE
|
||||
POST TEXT
|
||||
|
||||
@ -101,7 +101,6 @@ Buildings that you know // People come and go // Are a certain way
|
||||
And then you get the news that obliterates your view // Amputate your truths // The signifiance has changed
|
||||
Hospital inane // Meaningless and grey // But lie within the walls and the signifiance will change
|
||||
What would it take for us to change the game? // Maybe our existence is signifiance in vain
|
||||
Is that what we consider changing? // Ah, save me
|
||||
|
||||
# Candles by King Gizzard & The Lizard Wizard
|
||||
This little man is too hot to handle // Set the funeral on fire with the candles
|
||||
@ -111,11 +110,3 @@ My little heart, as cold as a morgue // Let the weight of it drop like an iceber
|
||||
# Presumptuous by King Gizzard & The Lizard Wizard
|
||||
Eggshell, landmine, stepping stones // Kindred spirits at a crossroads
|
||||
The world we built is on a tilt // Bottled up inside and filled with guilt
|
||||
|
||||
# Exctintion by King Gizzard & The Lizard Wizard
|
||||
I see sullied, toxic seas, poisoned soil and felled trees / Once paradise, now wasteland / Shadow on the moon expands
|
||||
Set tries chaos, but too late to to unseal our futures fate
|
||||
Magenta beckons like a lighthouse / Hypnotised and pulled into a pulsar
|
||||
Mirage city on the ridge / Beowulf, can you land deadstick?
|
||||
Pilgrims with burnt offerings / Spacesick for the whole voyage
|
||||
Metal horses on the flight/ Together, transcend this life
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
.albums {
|
||||
height: 100%;
|
||||
|
||||
line-height: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.albums img {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
border: 0 0;
|
||||
}
|
||||
|
||||
|
||||
.body {
|
||||
height: 100%;
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
}
|
||||
.albums {
|
||||
height: 100%;
|
||||
|
||||
line-height: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.albums img {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
border: 0 0;
|
||||
}
|
||||
|
||||
|
||||
.body {
|
||||
height: 100%;
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 609 KiB |
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 684 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 832 KiB |
|
Before Width: | Height: | Size: 465 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 828 KiB |
|
Before Width: | Height: | Size: 684 KiB |
|
Before Width: | Height: | Size: 541 KiB |
|
Before Width: | Height: | Size: 639 KiB |
|
Before Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 1.6 MiB |
@ -1,12 +1,12 @@
|
||||
EOF Mark,
|
||||
Glassit-VSC,
|
||||
JSON formatter,
|
||||
Pylance,
|
||||
Remote - SSH,
|
||||
Synthwave '84 Blues,
|
||||
Trailing Spaces,
|
||||
Helm Intellisense,
|
||||
background,
|
||||
Helium Icon Theme,
|
||||
SQLite Viewer,
|
||||
EOF Mark,
|
||||
Glassit-VSC,
|
||||
JSON formatter,
|
||||
Pylance,
|
||||
Remote - SSH,
|
||||
Synthwave '84 Blues,
|
||||
Trailing Spaces,
|
||||
Helm Intellisense,
|
||||
background,
|
||||
Helium Icon Theme,
|
||||
SQLite Viewer,
|
||||
Docker
|
||||
|
Before Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 120 KiB |
@ -1,20 +1,25 @@
|
||||
/* Global Stuff */
|
||||
@import url('https://fonts.googleapis.com/css?family=PT%20Mono:700|PT%20Mono:400');
|
||||
|
||||
body {
|
||||
font-family: 'PT Mono';
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
font-family: 'PT Mono';
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
html {
|
||||
--text: black;
|
||||
--background: white;
|
||||
/* --background: #2b2d31; */
|
||||
--primary: hsl(135, 100%, 15%);
|
||||
--primary10: hsla(0, 0%, 53%, 0.1);
|
||||
--text: hsl(224, 83%, 91%);
|
||||
--background: hsl(224, 31%, 23%);
|
||||
--primary: hsl(229, 81%, 73%);
|
||||
--primary10: hsla(209, 61%, 71%, 10%);
|
||||
--primary20: hsla(209, 61%, 71%, 20%);
|
||||
--primary40: hsla(0, 0%, 53%, 0.4);
|
||||
--primary40: hsla(209, 61%, 71%, 40%);
|
||||
--secondary: hsl(277, 81%, 33%);
|
||||
--secondary10: hsla(277, 81%, 33%, 10%);
|
||||
--secondary20: hsla(277, 81%, 33%, 20%);
|
||||
--secondary30: hsla(277, 81%, 33%, 30%);
|
||||
--secondary40: hsla(277, 81%, 33%, 40%);
|
||||
--secondary50: hsla(0, 0%, 21%, 0.5);
|
||||
--secondary50: hsla(277, 81%, 33%, 50%);
|
||||
--accent: hsl(291, 81%, 60%);
|
||||
--accent75: hsla(291, 81%, 60%, 75%);
|
||||
--accent50: hsla(291, 81%, 60%, 50%);
|
||||
@ -38,43 +43,21 @@ a:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background-color: var(--secondary10);
|
||||
border-style: var(--borders-style);
|
||||
border-radius: 7.5px;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.post blockquote p {
|
||||
text-indent: 1.5em;
|
||||
}
|
||||
|
||||
.post blockquote li p {
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: 4em;
|
||||
}
|
||||
|
||||
|
||||
/* Other */
|
||||
|
||||
.header {
|
||||
font-family: 'PT Mono';
|
||||
|
||||
background-size: cover;
|
||||
text-align: center;
|
||||
|
||||
margin: 2em 25%;
|
||||
padding: 3em;
|
||||
margin: 0 30%;
|
||||
padding: 2em;
|
||||
|
||||
border-style: var(--borders-style);
|
||||
border-color: #1E2022;
|
||||
background-color: var(--background);
|
||||
border-radius: var(--border-radius);
|
||||
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header a {
|
||||
@ -87,7 +70,7 @@ li {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
margin: 0px 20%;
|
||||
margin: 0px 5%;
|
||||
|
||||
border-style: var(--borders-style);
|
||||
border-color: #1E2022;
|
||||
@ -116,9 +99,8 @@ li {
|
||||
/* box-shadow: -10px 10px var(--accent); */
|
||||
|
||||
/* Text Settings */
|
||||
/* font-weight: bold; */
|
||||
font-weight: bold;
|
||||
line-height: 30pt;
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
@ -220,55 +202,10 @@ li {
|
||||
}
|
||||
|
||||
.post p {
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
line-height: 2.25;
|
||||
text-indent: 3em;
|
||||
}
|
||||
|
||||
.post-date {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.comment-container {
|
||||
background-color: var(--primary40);
|
||||
border-style: var(--borders-style);
|
||||
border-radius: var(--border-radius);
|
||||
|
||||
padding: 1em;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.comment {
|
||||
background-color: var(--primary40);
|
||||
border-style: var(--borders-style);
|
||||
border-radius: 5px;
|
||||
|
||||
margin: 0.25em;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.comment h4 {
|
||||
margin: 0.25em;
|
||||
}
|
||||
|
||||
.comment p {
|
||||
margin: 0.25em;
|
||||
text-indent: 1em;
|
||||
}
|
||||
|
||||
.comment-editor textarea {
|
||||
width: 80%;
|
||||
height: 6em;
|
||||
padding: 0.75em;
|
||||
|
||||
border-style: solid;
|
||||
border-color: var(--secondary50);
|
||||
}
|
||||
|
||||
.comment-editor textarea:focus {
|
||||
border: 3px solid var(--accent);
|
||||
}
|
||||
|
||||
/* MUSIC */
|
||||
.albums {
|
||||
height: fit-content;
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=PT%20Mono:700|PT%20Mono:400');
|
||||
|
||||
.post img {
|
||||
width: 50%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family: 'PT Mono';
|
||||
background-size: cover;
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
margin: 1em 0;
|
||||
padding: 0.5em;
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
.post h1 {
|
||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||
font-weight: 100;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.post h2 {
|
||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||
font-weight: 300;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.post {
|
||||
margin-bottom: 8em;
|
||||
}
|
||||
|
||||
.post-date {
|
||||
float: right;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 6.2 MiB |
@ -2,32 +2,40 @@
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style2.css') }}">
|
||||
<title>0x01fe.net - {{ title }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - About</title>
|
||||
</header>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ status|safe }}</p>
|
||||
<h1>Stuff</h1>
|
||||
<ul class="sidebar">
|
||||
<li><a href="/"><u>Home</u></a></li>
|
||||
<li><a href="/category/games/">Games</a></li>
|
||||
<li><a href="/music/">Music</a></li>
|
||||
<li><a href="/category/motion-pictures/">Motion Picture</a></li>
|
||||
<li><a href="/programming/">Programming</a></li>
|
||||
<li><a href="/about/">About</a></li>
|
||||
</ul>
|
||||
<div class="dlog">
|
||||
<div class="post">
|
||||
<h2>About</h2>
|
||||
<p>
|
||||
Hi! I'm 0x01fe. This website is a personal project that allows me to express my thoughts online about things I like and also gives me something to program and tinker with on my spare time. If you want to contact me try hitting me up on discord at <u>0x01fe</u>.
|
||||
</p>
|
||||
<br>
|
||||
<h2>Why 0x01fe?</h2>
|
||||
<p>
|
||||
This is a pretty common question I get regarding my username so I thought I'd put a little section here about it. The thought process behind the username was "I like computers so what's a computer related username I could have?" and the first thing that came to mind was the master boot record boot sector (100% related to that other <a href="https://masterbootrecord.bandcamp.com/"><i>Master Boot Record</i></a>). So I opened up the <a href="https://en.wikipedia.org/wiki/Master_boot_record">Wikipedia Page</a> on the master boot record and scrolled until something called out to me. When I saw the starting byte of the boot signature in hex was <b>0x01fe</b> I thought "yeah that'd work", and I've stuck with it.
|
||||
</p>
|
||||
<div class="header">
|
||||
<h1>0x01fe.net</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="..">Home</a><br>
|
||||
<a href="../games/">Games</a><br>
|
||||
<a href="../music/">Music</a><br>
|
||||
<a href="../motion-pictures/">Motion Picture</a><br>
|
||||
<a href="../programming/">Programming</a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="."><u>About</u></a>
|
||||
</div>
|
||||
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
<div class="post">
|
||||
<h2>About</h2>
|
||||
<p>
|
||||
Hi! I'm 0x01fe. This website is a personal project that allows me to express my thoughts online about things I like and also gives me something to program and tinker with on my spare time. If you want to contact me try hitting me up on discord at <u>0x01fe</u>.
|
||||
</p>
|
||||
<br>
|
||||
<h2>Why 0x01fe?</h2>
|
||||
<p>
|
||||
This is a pretty common question I get regarding my username so I thought I'd put a little section here about it. The thought process behind the username was "I like computers so what's a computer related username I could have?" and the first thing that came to mind was the master boot record boot sector (100% related to that other <a href="https://masterbootrecord.bandcamp.com/"><i>Master Boot Record</i></a>). So I opened up the <a href="https://en.wikipedia.org/wiki/Master_boot_record">Wikipedia Page</a> on the master boot record and scrolled until something called out to me. When I saw the starting byte of the boot signature in hex was <b>0x01fe</b> I thought "yeah that'd work", and I've stuck with it.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='albumsquare.css') }}">
|
||||
<title>Album Square</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="albums">
|
||||
{% for album in top_albums %}
|
||||
<a title="{{ album.album_name}} by {{ album.artist_name }} - {{ album.listen_time }} Hours">
|
||||
<img src="{{ album.album_cover }}" style="width: {{ res }}px; height: {{ res }}px;">
|
||||
</a>
|
||||
{% if loop.index % limit == 0 %}
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='albumsquare.css') }}">
|
||||
<title>Album Square</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="albums">
|
||||
{% for album in top_albums %}
|
||||
<a title="{{ album.album_name}} by {{ album.artist_name }} - {{ album.listen_time }} Hours">
|
||||
<img src="{{ album.album_cover }}" style="width: {{ res }}px; height: {{ res }}px;">
|
||||
</a>
|
||||
{% if loop.index % limit == 0 %}
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
34
app/templates/games.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Games</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Games</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="..">Home</a><br>
|
||||
<a href="."><u>Games</u></a><br>
|
||||
<a href="../music/">Music</a><br>
|
||||
<a href="../motion-pictures/">Motion Picture</a><br>
|
||||
<a href="../programming/">Programming</a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="../about/">About</a>
|
||||
</div>
|
||||
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">{{ post|safe }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -2,28 +2,33 @@
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style2.css') }}">
|
||||
<title>0x01fe.net - {{ title }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net</title>
|
||||
</header>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ status|safe }}</p>
|
||||
<h1>Stuff</h1>
|
||||
<ul class="sidebar">
|
||||
<li><a href="/"><u>Home</u></a></li>
|
||||
<li><a href="/category/games/">Games</a></li>
|
||||
<li><a href="/music/">Music</a></li>
|
||||
<li><a href="/category/motion-pictures/">Motion Picture</a></li>
|
||||
<li><a href="/programming/">Programming</a></li>
|
||||
<li><a href="/about/">About</a></li>
|
||||
</ul>
|
||||
{% for post in posts %}
|
||||
<div class="post">
|
||||
<div class="post-date">
|
||||
{{ post.date_str }}
|
||||
</div>
|
||||
{{ post.body|safe }}
|
||||
<div class="header">
|
||||
<h1>0x01fe.net</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="."><u>Home</u></a><br>
|
||||
<a href="/games/">Games</a><br>
|
||||
<a href="/music/">Music</a><br>
|
||||
<a href="/motion-pictures/">Motion Picture</a><br>
|
||||
<a href="/programming/">Programming</a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="/about/">About</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">{{ post|safe }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
34
app/templates/motion-pictures.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Motion Pictures</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Motion Pictures</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="..">Home</a><br>
|
||||
<a href="../games/">Games</a><br>
|
||||
<a href="../music/">Music</a><br>
|
||||
<a href="."><u>Motion Picture</u></a><br>
|
||||
<a href="../programming/">Programming</a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="../about/">About</a>
|
||||
</div>
|
||||
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">{{ post|safe }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -2,47 +2,47 @@
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style2.css') }}">
|
||||
<title>0x01fe.net - {{ title }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Music</title>
|
||||
</header>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ status|safe }}</p>
|
||||
<h1>Stuff</h1>
|
||||
<ul class="sidebar">
|
||||
<li><a href="/"><u>Home</u></a></li>
|
||||
<li><a href="/category/games/">Games</a></li>
|
||||
<li><a href="/music/">Music</a></li>
|
||||
<li><a href="/category/motion-pictures/">Motion Picture</a></li>
|
||||
<li><a href="/programming/">Programming</a></li>
|
||||
<li><a href="/about/">About</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">
|
||||
<div class="post-date">
|
||||
{{ post.date_str }}
|
||||
</div>
|
||||
{{ post.body|safe }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="header">
|
||||
<h1>Music</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="..">Home</a><br>
|
||||
<a href="../games/">Games</a><br>
|
||||
<a href="."><u>Music</u></a><br>
|
||||
<a href="../motion-pictures/">Motion Picture</a><br>
|
||||
<a href="../programming/">Programming</a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="../about/">About</a>
|
||||
</div>
|
||||
|
||||
<div class="albums">
|
||||
<h1>Top Albums</h1>
|
||||
<div class="real-albums">
|
||||
{% for album in top_albums %}
|
||||
<a title="{{ album.album_name}} by {{ album.artist_name }} - {{ album.listen_time }} Hours">
|
||||
<img src="{{ album.album_cover }}">
|
||||
</a>
|
||||
{% if loop.index % 3 == 0 %}
|
||||
<br>
|
||||
{% endif %}
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">{{ post|safe }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="albums">
|
||||
<h1>Top Albums</h1>
|
||||
<div class="real-albums">
|
||||
{% for album in top_albums %}
|
||||
<a title="{{ album.album_name}} by {{ album.artist_name }} - {{ album.listen_time }} Hours">
|
||||
<img src="{{ album.album_cover }}">
|
||||
</a>
|
||||
{% if loop.index % 3 == 0 %}
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -2,38 +2,39 @@
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style2.css') }}">
|
||||
<title>0x01fe.net - {{ title }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Programming</title>
|
||||
</header>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ status|safe }}</p>
|
||||
<h1>Stuff</h1>
|
||||
<ul class="sidebar">
|
||||
<li><a href="/"><u>Home</u></a></li>
|
||||
<li><a href="/category/games/">Games</a></li>
|
||||
<li><a href="/music/">Music</a></li>
|
||||
<li><a href="/category/motion-pictures/">Motion Picture</a></li>
|
||||
<li><a href="/programming/">Programming</a></li>
|
||||
<li><a href="/about/">About</a></li>
|
||||
</ul>
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">
|
||||
<div class="post-date">
|
||||
{{ post.date_str }}
|
||||
</div>
|
||||
{{ post.body|safe }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="header">
|
||||
<h1>Programming</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="..">Home</a><br>
|
||||
<a href="../games/">Games</a><br>
|
||||
<a href="../music/">Music</a><br>
|
||||
<a href="../motion-pictures/">Motion Picture</a><br>
|
||||
<a href="."><u>Programming</u></a><br>
|
||||
<a href="/writing/">Writing</a><br>
|
||||
<a href="../about/">About</a>
|
||||
</div>
|
||||
|
||||
<!-- Other Sidear -->
|
||||
<div class="rightbar">
|
||||
<h2>Other</h2>
|
||||
<a href="">Technologies I Use</a>
|
||||
<!-- Main Page -->
|
||||
<!-- Get it? D-Log? Like digital log? -->
|
||||
<div class="dlog">
|
||||
{% for post in posts %}
|
||||
<div class="post">{{ post|safe }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Other Sidear -->
|
||||
<div class="rightbar">
|
||||
<h2>Other</h2>
|
||||
<a href="">Technologies I Use</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Login</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>0x01fe.net</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="/"><u>Home</u></a><br>
|
||||
<a href="/games/">Games</a><br>
|
||||
<a href="/music/">Music</a><br>
|
||||
<a href="/motion-pictures/">Motion Picture</a><br>
|
||||
<a href="/programming/">Programming</a><br>
|
||||
<a href="/about/">About</a><br>
|
||||
<a href="/login/">Login</a>
|
||||
</div>
|
||||
|
||||
<div class="dlog">
|
||||
<h1>Login</h1>
|
||||
<form method="post" action="/user/login/">
|
||||
{{ form.hidden_tag() }}
|
||||
Username: {{ form.username }} <br>
|
||||
Password: {{ form.password }} <br>
|
||||
<input type="submit" value="Login">
|
||||
</form>
|
||||
<br>
|
||||
|
||||
<h1>Need to Register?</h1>
|
||||
<a href="/user/register/">Register</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<header>
|
||||
<link rel="shortcut icon" href="index_favicon.ico">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<title>0x01fe.net - Register</title>
|
||||
</header>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>0x01fe.net</h1>
|
||||
{{ status|safe }}
|
||||
</div>
|
||||
<div class="container">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<a href="/"><u>Home</u></a><br>
|
||||
<a href="/games/">Games</a><br>
|
||||
<a href="/music/">Music</a><br>
|
||||
<a href="/motion-pictures/">Motion Picture</a><br>
|
||||
<a href="/programming/">Programming</a><br>
|
||||
<a href="/about/">About</a><br>
|
||||
<a href="/login/">Login</a>
|
||||
</div>
|
||||
|
||||
<div class="dlog">
|
||||
<h1>Register</h1>
|
||||
<form method="post" action="/user/add/">
|
||||
{{ form.hidden_tag() }}
|
||||
Username: {{ form.username }} <br>
|
||||
Password: {{ form.password }} <br>
|
||||
<input type="submit" value="Register">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
14
app/templates/writing.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<body>
|
||||
<a href="/">home</a>
|
||||
<p>
|
||||
This is just a little page where I post stuff I write. I was kind of unsure if I wanted this stuff out here but I think to those who know me it could serve as an interesting view into some thoughts that I don't often express elsewhere.
|
||||
</p>
|
||||
<br>
|
||||
<br>
|
||||
{% for work in works %}
|
||||
<a href="/{{ work.path }}">{{ work.name }}</a> {{ work.date }}
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
||||
102
app/user.py
@ -1,102 +0,0 @@
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
|
||||
import flask
|
||||
import flask_wtf.csrf
|
||||
import wtforms
|
||||
|
||||
user = flask.Blueprint('user', __name__, template_folder='./templates/user')
|
||||
USERS_PATH = "./data/users.json"
|
||||
class RegisterUserForm(flask_wtf.FlaskForm):
|
||||
username = wtforms.StringField("Username", [
|
||||
wtforms.validators.Length(min=4, max=32),
|
||||
wtforms.validators.DataRequired()
|
||||
])
|
||||
password = wtforms.PasswordField("Password", [
|
||||
wtforms.validators.Length(min=8, max=64),
|
||||
wtforms.validators.DataRequired()
|
||||
])
|
||||
|
||||
class LoginUserForm(flask_wtf.FlaskForm):
|
||||
username = wtforms.StringField("Username", [
|
||||
wtforms.validators.DataRequired()
|
||||
])
|
||||
password = wtforms.PasswordField("Password", [
|
||||
wtforms.validators.DataRequired()
|
||||
])
|
||||
|
||||
@user.route('/user/add/', methods=["POST"])
|
||||
def add_user():
|
||||
|
||||
# Get form data
|
||||
form = RegisterUserForm(csrf_enabled=True)
|
||||
|
||||
username = form.username.data
|
||||
password = form.password.data
|
||||
|
||||
# Read existing user data
|
||||
with open(USERS_PATH, 'r') as file:
|
||||
user_data = json.loads(file.read())
|
||||
|
||||
# check if user exists
|
||||
if username in user_data:
|
||||
return 'ERROR PROCESSING REQUEST - That user already exists'
|
||||
|
||||
# Store password / server side cookie
|
||||
user_data[username] = base64.b64encode(password.encode()).decode()
|
||||
flask.session['username'] = username
|
||||
|
||||
# Write user data
|
||||
with open(USERS_PATH, 'w') as file:
|
||||
file.write(json.dumps(user_data))
|
||||
|
||||
return flask.redirect('/')
|
||||
|
||||
@user.route('/user/register/')
|
||||
def register_page():
|
||||
form = RegisterUserForm()
|
||||
|
||||
return flask.render_template('register.html', form=form)
|
||||
|
||||
@user.route('/user/login/', methods=["POST"])
|
||||
def login_user():
|
||||
form = LoginUserForm(csrf_enabled=True)
|
||||
|
||||
username = form.username.data
|
||||
password = base64.b64encode(form.password.data.encode()).decode()
|
||||
|
||||
# Read existing user data
|
||||
with open(USERS_PATH, 'r') as file:
|
||||
user_data = json.loads(file.read())
|
||||
|
||||
# check if user exists
|
||||
if username not in user_data:
|
||||
return 'ERROR PROCESSING REQUEST - Bad username OR password'
|
||||
|
||||
# Does password match?
|
||||
if user_data[username] != password:
|
||||
return 'ERROR PROCESSING REQUEST - Bad username OR password'
|
||||
|
||||
flask.session['username'] = username
|
||||
|
||||
return flask.redirect('/')
|
||||
|
||||
@user.route('/login/')
|
||||
def login_page():
|
||||
form = LoginUserForm()
|
||||
|
||||
return flask.render_template('login.html', form=form)
|
||||
|
||||
@user.route('/logout/')
|
||||
def logout_user():
|
||||
|
||||
if 'username' in flask.session:
|
||||
flask.session.pop('username')
|
||||
|
||||
return flask.redirect('/')
|
||||
|
||||
# Check User file exists
|
||||
if not os.path.exists(USERS_PATH):
|
||||
with open(USERS_PATH, 'w+') as file:
|
||||
file.write('{}')
|
||||
@ -2,6 +2,4 @@ Markdown==3.5.2
|
||||
Flask==2.2.3
|
||||
waitress==2.1.2
|
||||
Werkzeug==2.2.3
|
||||
Flask-Session==0.5.0
|
||||
Flask-WTF==1.1.1
|
||||
requests==2.31.0
|
||||