Compare commits

..

No commits in common. "v2" and "main" have entirely different histories.
v2 ... main

48 changed files with 289 additions and 604 deletions

11
.gitignore vendored
View File

@ -9,14 +9,9 @@ docker-compose.yaml
*.ini
# Ignore images in posts
# Flask Data & Config
*.ini
data
.flask_session
*.json
*.jpg
*.png
*.gif
# Writing
writing

View File

@ -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"]

View File

@ -2,54 +2,32 @@ import os
import glob
import configparser
import random
import base64
import datetime
import requests
import flask
import flask_wtf.csrf
import flask_session
import waitress
import markdown
from post import Post
import comment
import user
app = flask.Flask(__name__, static_url_path='', static_folder='static')
app.register_blueprint(comment.comments)
app.register_blueprint(user.user)
# 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)
# Session Setup
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_FILE_DIR'] = './data/.flask_session/'
flask_session.Session(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')
@ -79,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:
@ -117,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():
@ -127,59 +97,40 @@ def index():
# Get posts
posts = get_posts()
if 'username' in flask.session:
user = flask.session['username']
else:
user = 'Anon'
post_bodies = []
for post in posts:
post_bodies.append(post.body)
# Get status
status = get_status()
# Setup Comment Form
form = comment.CommentForm()
img = get_header_image()
return flask.render_template('index.html', posts=posts, status=status, form=form, user=user, 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:
if 'username' in flask.session:
user = flask.session['username']
else:
user = 'Anon'
# Setup Comment Form
form = comment.CommentForm()
return flask.render_template('index.html', posts=[post], status=get_status(), form=form, user=user, 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")
if 'username' in flask.session:
user = flask.session['username']
else:
user = 'Anon'
post_bodies = []
for post in posts:
post_bodies.append(post.body)
# Get status
status = get_status()
# Setup Comment Form
form = comment.CommentForm()
return flask.render_template('index.html', posts=posts, status=status, form=form, user=user, title=category.replace('-', ' '))
return flask.render_template('games.html', posts=post_bodies, status=status)
# Music Page
@app.route('/music/')
@ -188,10 +139,9 @@ def music():
# Get posts
posts = get_posts(category_filter="music")
if 'username' in flask.session:
user = flask.session['username']
else:
user = 'Anon'
post_bodies = []
for post in posts:
post_bodies.append(post.body)
# Get status
status = get_status()
@ -214,30 +164,64 @@ def music():
top_albums[album_index]['listen_time'] = hours
# Setup Comment Form
form = comment.CommentForm()
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, form=form, user=user)
# 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")
if 'username' in flask.session:
user = flask.session['username']
else:
user = 'Anon'
post_bodies = []
for post in posts:
post_bodies.append(post.body)
# Get status
status = get_status()
# Setup Comment Form
form = comment.CommentForm()
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)
return flask.render_template('programming.html', posts=posts_and_comments, form=form, user=user, status=status)
# About Page
@app.route('/about/')

View File

@ -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 []

8
app/data/comments.json Normal file
View File

@ -0,0 +1,8 @@
{
"2" : [
{
"username" : "0x01FE",
"content" : "Hello, this is an example comment!"
}
]
}

5
app/data/users.json Normal file
View File

@ -0,0 +1,5 @@
{
"users" : {
"0x01FE" : "cGFzc3dvcmQ="
}
}

View File

@ -1,19 +1,15 @@
import markdown
import datetime
import comment
class Post:
category : str
author : str
date : datetime.datetime
date_str : str
body : str
file : str
title : str
url : str
comments : list[dict]
def __init__(self, file_path):
self.file = file_path
@ -23,12 +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.comments = comment.get_comments(self.title)
self.body = markdown.markdown(f'# [{self.title}]({self.url})\n' + ''.join(lines[7:]))

View File

@ -4,6 +4,6 @@ author: author
date: date
# POST
# TITLE
## TITLE
### DATE OR SUBTITLE
POST TEXT

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 828 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 639 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

View File

@ -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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 MiB

View File

@ -13,13 +13,13 @@
<div class="container">
<!-- Sidebar -->
<div class="sidebar">
<a href="/"><u>Home</u></a><br>
<a href="/category/games/">Games</a><br>
<a href="/music/">Music</a><br>
<a href="/category/motion-pictures/">Motion Picture</a><br>
<a href="/programming/">Programming</a><br>
<a href="/about/">About</a><br>
<a href="/login/">Login</a>
<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 -->

34
app/templates/games.html Normal file
View 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>

View File

@ -3,54 +3,30 @@
<header>
<link rel="shortcut icon" href="index_favicon.ico">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>0x01fe.net - {{ title }}</title>
<title>0x01fe.net</title>
</header>
<body>
<div style="background-image: url({{ header_background_image }});" class="header">
<h1>{{ title }}</h1>
<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="/category/games/">Games</a><br>
<a href="."><u>Home</u></a><br>
<a href="/games/">Games</a><br>
<a href="/music/">Music</a><br>
<a href="/category/motion-pictures/">Motion Picture</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>
<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">
<div class="post-date">
{{ post.date_str }}
</div>
{{ post.body|safe }}
<div class="comment-container">
<h2>Comments</h2>
{% for comment in post.comments %}
<div class="comment">
<h4>{{ comment.username }}</h4>
<p>{{ comment.content }}</p>
</div>
{% endfor %}
{% if user %}
<div class="comment-editor">
<h4>{{ user }}</h4>
<form method="post" action="/comment/{{ post.title }}">
{{ form.hidden_tag() }}
{{ form.textbox }}
<input type="submit" value="Save">
</form>
</div>
{% endif %}
</div>
</div>
<div class="post">{{ post|safe }}</div>
{% endfor %}
</div>
</div>

View 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>

View File

@ -13,44 +13,20 @@
<div class="container">
<!-- Sidebar -->
<div class="sidebar">
<a href="/"><u>Home</u></a><br>
<a href="/category/games/">Games</a><br>
<a href="/music/">Music</a><br>
<a href="/category/motion-pictures/">Motion Picture</a><br>
<a href="/programming/">Programming</a><br>
<a href="/about/">About</a><br>
<a href="/login/">Login</a>
<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>
<!-- 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 class="comment-container">
<h2>Comments</h2>
{% for comment in post.comments %}
<div class="comment">
<h4>{{ comment.username }}</h4>
<p>{{ comment.content }}</p>
</div>
{% endfor %}
{% if user %}
<div class="comment-editor">
<h4>{{ user }}</h4>
<form method="post" action="/comment/{{ post.title }}">
{{ form.hidden_tag() }}
{{ form.textbox }}
<input type="submit" value="Save">
</form>
</div>
{% endif %}
</div>
</div>
<div class="post">{{ post|safe }}</div>
{% endfor %}
</div>

View File

@ -13,44 +13,20 @@
<div class="container">
<!-- Sidebar -->
<div class="sidebar">
<a href="/"><u>Home</u></a><br>
<a href="/category/games/">Games</a><br>
<a href="/music/">Music</a><br>
<a href="/category/motion-pictures/">Motion Picture</a><br>
<a href="/programming/">Programming</a><br>
<a href="/about/">About</a><br>
<a href="/login/">Login</a>
<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>
<!-- 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 class="comment-container">
<h2>Comments</h2>
{% for comment in post.comments %}
<div class="comment">
<h4>{{ comment.username }}</h4>
<p>{{ comment.content }}</p>
</div>
{% endfor %}
{% if user %}
<div class="comment-editor">
<h4>{{ user }}</h4>
<form method="post" action="/comment/{{ post.title }}">
{{ form.hidden_tag() }}
{{ form.textbox }}
<input type="submit" value="Save">
</form>
</div>
{% endif %}
</div>
</div>
<div class="post">{{ post|safe }}</div>
{% endfor %}
</div>

View File

@ -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>

View File

@ -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>

View 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>

View File

@ -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('{}')

View File

@ -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