Compare commits

..

No commits in common. "minimal-css" and "main" have entirely different histories.

52 changed files with 385 additions and 601 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

@ -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/')

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

@ -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:]))

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: 4.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: 684 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 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;

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 MiB

View File

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

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

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

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

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

View File

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

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