Merge pull request #1 from 0x01FE/python+markdown

Markdown Posts
This commit is contained in:
0x01FE 2024-03-22 14:01:47 -05:00 committed by GitHub
commit dd77ac8fd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 623 additions and 148 deletions

8
.gitignore vendored
View File

@ -1 +1,7 @@
*.woff __pycache__
*.md
!POST_TEMPLATE.md
!README.md
docker-compose.yaml
*.sh

18
Dockerfile Normal file
View File

@ -0,0 +1,18 @@
# syntax=docker/dockerfile:1
FROM python:3.12.2-slim-bookworm
RUN apt-get update && apt-get upgrade -y
RUN useradd -m app
USER app
COPY . .
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install -r requirements.txt
WORKDIR ./app
CMD ["python3", "-u", "app.py"]

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# My-Website
Code of the website hosted at https://www.0x01fe.net
Could I gitignore the config files?
Yes.
Do I?
no.

155
app/app.py Normal file
View File

@ -0,0 +1,155 @@
import glob
import configparser
import random
import flask
import waitress
import markdown
from post import Post
app = flask.Flask(__name__, static_url_path='', static_folder='static')
CONFIG_PATH = "./config.ini"
config = configparser.ConfigParser()
config.read(CONFIG_PATH)
POSTS_FOLDER = config['POSTS']['POSTS_FOLDER']
STATUS_FILE = config['STATUS']['STATUS_FILE']
PORT = int(config['NETWORK']['PORT'])
DEV = int(config['NETWORK']['DEV'])
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')
except ValueError as e:
print(e)
print(f'Couldn\'t remove the template file probably; {post_files}')
exit()
posts: list[Post] = []
for post_file in post_files:
post = Post(post_file)
if not category_filter:
posts.append(post)
elif category_filter == post.category:
posts.append(post)
# Order Posts by Date
ordered_posts = []
for i in range(len(posts)):
most_recent = posts[0]
for p in posts:
if p.date < most_recent.date:
most_recent = p
ordered_posts.append(most_recent)
posts.remove(most_recent)
return reversed(ordered_posts)
def get_status() -> str:
with open(STATUS_FILE, 'r', encoding='utf-8') as file:
statuses = file.readlines()
status = random.randint(0, len(statuses) - 1)
return markdown.markdown(statuses[status])
# Main Page
@app.route('/')
def index():
# Get posts
posts = get_posts()
post_bodies = []
for post in posts:
post_bodies.append(post.body)
# Get status
status = get_status()
return flask.render_template('index.html', posts=post_bodies, status=status)
# Games Page
@app.route('/games/')
def games():
# Get posts
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('games.html', posts=post_bodies, status=status)
# Music Page
@app.route('/music/')
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()
return flask.render_template('music.html', posts=post_bodies, status=status)
# 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 = 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=post_bodies, status=status)
# About Page
@app.route('/about/')
def about():
# Get status
status = get_status()
return flask.render_template('about.html', status=status)
if __name__ == "__main__":
if DEV:
app.run(port=PORT)
else:
waitress.serve(app, host='0.0.0.0', port=PORT)

9
app/config.ini Normal file
View File

@ -0,0 +1,9 @@
[POSTS]
posts_folder=./posts
[STATUS]
status_file=./resources/status.text
[NETWORK]
PORT=1111
DEV=0

25
app/post.py Normal file
View File

@ -0,0 +1,25 @@
import markdown
import datetime
class Post:
category : str
author : str
date : datetime.datetime
body : str
file : str
def __init__(self, file_path):
self.file = file_path
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
self.category = lines[1].split(":")[1].strip()
self.author = lines[2].split(":")[1].strip()
date = lines[3].split(":")[1].strip()
self.date = datetime.datetime.strptime(date, "%d-%m-%Y")
self.body = markdown.markdown(''.join(lines[6:]))

View File

@ -0,0 +1,9 @@
# Metadata
category: category
author: author
date: date
# POST
## TITLE
### DATE OR SUBTITLE
POST TEXT

31
app/resources/status.text Normal file
View File

@ -0,0 +1,31 @@
Catchy Right?
Everybody's lazy when they're tired
As long as there is delusion, there is hope
It's 510.
Mindful of the weary inkling that is lurking
Mortal traffic lights signaling when to stay or go
Cyber surgeon, Javascript person
Bone-dried swamplands swallow me
House of dust, land of bone
I ate dirt, I drank stone
Come on, snake, punish me
Drip, drip from the tap, don't slip on the drip
His name really is Tim.
Just wait until you see the 1 in 1000 message.
I'm open to suggestions on how to improve the look of the website
Open the curtains
Don't miss a moment of this experiment
Needles
Sally forth Rocinante!
The multitude tightens its hold.
It's amazing what you'll find face to face
It's not hard to go the distance / When you finally get involved face to face
A tourist in a dream / A visitor, it seems / A half-forgotten song / Where do I belong?
What do you mean ... You can't see it?
I don't believe you / your eyes deceive you / better check yourself in
You will say I'm crazy / I will go on my way 'cause it's what I need
I'd cross a thousand seas just to prove I'm not mad
I thought I saw a statue blink, and a bird with no head, Land on a golden thread, I rub my eyes, What am I saying? There's nothing there
Solar Sect of Mystic Wisdom
~ Nuclear Fusion
Check out [NEUPINK](https://neupink.bandcamp.com/album/swordflower-hills-killer-2)!

150
app/static/style.css Normal file
View File

@ -0,0 +1,150 @@
/* 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: 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(209, 61%, 71%, 40%);
--secondary: hsl(277, 81%, 33%);
--accent: hsl(291, 81%, 60%);
--accent75: hsla(291, 81%, 60%, 75%);
--accent50: hsla(291, 81%, 60%, 50%);
--main-background: var(--primary10);
--borders-style: hidden;
--border-radius: 15px;
}
body {
color: var(--text);
background-color: var(--background);
}
a {
color: var(--text);
}
a:hover {
color: var(--accent);
}
/* Other */
.header {
text-align: center;
margin: 0 30%;
padding: 2em;
border-style: var(--borders-style);
border-color: #1E2022;
background-color: var(--background);
border-radius: var(--border-radius);
}
.header a {
text-decoration: none;
color: var(--primary);
}
.container {
display: flex;
flex-direction: row;
margin: 0px 10%;
border-style: var(--borders-style);
border-color: #1E2022;
background-color: var(--main-background);
border-radius: var(--border-radius);
}
.sidebar {
height: fit-content;
align-self: flex-start;
position: sticky;
top: 10px;
padding: 20pt;
margin: 5em 0;
margin-left: 2em;
border-style: var(--borders-style);
border-radius: var(--border-radius);
border-color: #1E2022;
background-color: var(--main-background);
opacity: 0.9;
/* Text Settings */
font-weight: bold;
line-height: 30pt;
}
.sidebar a {
text-decoration: none;
}
.dlog {
flex: 3;
display: flex;
flex-direction: column;
padding: 10pt;
margin: 0 5%;
margin-left: 0;
border-style: var(--borders-style);
border-radius: var(--border-radius);
border-color: #1E2022;
/* background-color: var(--main-background); */
}
.post {
border-style: var(--borders-style);
border-radius: var(--border-radius);
padding: 1.5em 2em;
margin: 1em 2em;
/* background-color: var(--main-background); */
}
.post h2 {
text-decoration: underline;
text-decoration-style: solid;
text-decoration-thickness: 0.25em;
text-underline-offset: 6px;
text-decoration-color: var(--accent75);
}
.post h3 {
font-weight: 300;
font-size: 18px;
}
.post p {
line-height: 2.25;
text-indent: 3em;
}

41
app/templates/about.html Normal file
View File

@ -0,0 +1,41 @@
<!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 - About</title>
</header>
<body>
<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="."><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>
</html>

33
app/templates/games.html Normal file
View File

@ -0,0 +1,33 @@
<!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="../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>

33
app/templates/index.html Normal file
View File

@ -0,0 +1,33 @@
<!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</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>
</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

@ -0,0 +1,33 @@
<!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="../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>

33
app/templates/music.html Normal file
View File

@ -0,0 +1,33 @@
<!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 - Music</title>
</header>
<body>
<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="../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

@ -0,0 +1,33 @@
<!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 - Programming</title>
</header>
<body>
<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="../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

@ -1,41 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<header>
<link rel="shortcut icon" href="index_favicon.ico">
<link rel="stylesheet" href="index_style.css">
<title>0x01fe.net</title>
</header>
<body>
<div class="header">
<h1>0x01fe.net</h1>
<h4>Catchy Right‽</h4>
</div>
<div class="container">
<!-- Sidebar -->
<div class="sidebar">
<a href="./index.html">Home</a><br>
<a href="">Media</a><br>
<a href="">Programming</a><br>
<a href="">About</a>
</div>
<!-- Main Page -->
<!-- Get it? D-Log? Like digital log? -->
<div class="dlog">
<div class="post">
<h2>It's Peaks, <i>Peaks of Yore</i></h1>
<h3>March 8th, 2024</h3>
<p>Excuse the awful title please, but it truly is peak. <a href="https://store.steampowered.com/app/2236070/Peaks_of_Yore/"><i>Peaks of Yore</i></a> has been a more enjoyable title than I could've ever expected. At first glance it seems like a "rage bait" game akin to the likes of <i>Getting Over It With Bennett Foddy</i> or <i>Super Meatboy</i>, but after the first few fundamental courses you realize the controls aren't fighting you, you just haven't mastered them yet.</p>
</div>
<div class="post">
<h2>Post Title</h1>
<p>foobar</p>
</div>
<div class="post">
<h2>Post Title</h1>
<p>foobar</p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,106 +0,0 @@
/* Global Settings */
@font-face {
font-family: ibmplexmono;
src: url(./IBMPlexMono-Regular.woff) format('woff');
}
body {
/* font-family: 'Courier New', Courier, monospace; */
font-family: ibmplexmono;
}
a {
color: black;
text-decoration: none;
}
a:hover {
color: hotpink;
}
/* Other */
.header {
text-align: center;
margin: 10pt;
border-style: solid;
border-color: #1E2022;
background-color: #F0F5F9;
border-radius: 5pt;
}
.header h1 {
font-family: Arial, Helvetica, sans-serif;
}
.container {
display: flex;
flex-direction: row;
border-style: solid;
border-color: #1E2022;
background-color: #F0F5F9;
}
.sidebar {
order: 1;
float: left;
padding: 20pt;
padding-bottom: 25%;
margin: 15pt;
border-style: solid;
border-radius: 10px;
border-color: #1E2022;
background-color: #C9D6DF;
opacity: 0.9;
/* Text Settings */
font-weight: bold;
line-height: 30pt;
}
.dlog {
order: 2;
flex: 3;
text-align: center;
display: flex;
flex-direction: column;
padding: 10pt;
margin: 15pt;
margin-left: 15%;
margin-right: 15%;
border-style: solid;
border-radius: 10px;
border-color: #1E2022;
background-color: #C9D6DF;
}
.post {
/* opacity: 0.9; */
border: 2px solid #52616B;
border-radius: 10px;
padding: 10pt;
margin: 10pt;
margin-left: 20pt;
margin-right: 20pt;
background-color: #C9D6DF;
}

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
Markdown==3.5.2
Flask==2.2.3
waitress==2.1.2
Werkzeug==2.2.3