import glob
import configparser
import random
import base64
import requests
import flask
import flask_wtf.csrf
import waitress
import markdown
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)
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]]:
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)
# Convert to dict
posts = []
for post in reversed(ordered_posts):
posts.append(post.__dict__)
return posts
def read_status_file() -> dict:
with open(STATUS_FILE, 'r', encoding='utf-8') as file:
data = file.readlines()
result = {}
current_key = None
for line in data:
if line[0] == '#':
# Empty Key-Value pairs will cause errors
if current_key:
if not result[current_key]:
result.pop(current_key)
current_key = line.replace('#', '').strip()
result[current_key] = []
elif not (line == '\n'):
result[current_key].append(line)
return result
def get_status() -> str:
keys = list(statuses.keys())
selected_key = keys[random.randint(0, len(keys) - 1)]
section: list = statuses[selected_key]
selected_status = section[random.randint(0, len(section) - 1)]
return f'
{markdown.markdown(selected_status)}
'
def get_header_image() -> str:
return header_background_images[random.randint(0, len(header_background_images) - 1)]
# Main Page
@app.route('/')
def index():
# Get posts
posts = get_posts()
# 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)
# Posts
@app.route('/post/')
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')
flask.abort(404)
# Category's Endpoint
@app.route('/category//')
def category_filter(category: str):
# Get posts
posts = get_posts(category_filter=category)
# Get status
status = get_status()
return flask.render_template('index.html', posts=posts, status=status, title=category.replace('-', ' '))
# Music Page
@app.route('/music/')
def music():
# Get posts
posts = get_posts(category_filter="music")
# Get status
status = get_status()
# Get top albums
r = requests.get(
MUSIC_API_URL +'/top/albums',
headers={
'token' : MUSIC_API_TOKEN,
'user' : '1',
'limit' : '9'
})
top_albums = r.json()['top']
for album_index in range(0, len(top_albums)):
album = top_albums[album_index]
time = int(album['listen_time'])
hours = round(time/1000/60/60, 1)
top_albums[album_index]['listen_time'] = hours
return flask.render_template('music.html', posts=posts, status=status, top_albums=top_albums)
# Programming Page
@app.route('/programming/')
def programming():
# Get posts
posts_and_comments = get_posts(category_filter="programming")
# Get status
status = get_status()
return flask.render_template('programming.html', posts=posts_and_comments, status=status)
# About Page
@app.route('/about/')
def about():
# Get status
status = get_status()
return flask.render_template('about.html', status=status)
# MISC
@app.route('/albumsquare//')
def album_square(user_id, rows : int):
limit = rows ** 2
res = (1080/(rows))-rows
# Get top albums
r = requests.get(
MUSIC_API_URL +'/top/albums',
headers={
'token' : MUSIC_API_TOKEN,
'user' : user_id,
'limit' : str(limit)
})
top_albums = r.json()['top']
for album_index in range(0, len(top_albums)):
album = top_albums[album_index]
time = int(album['listen_time'])
hours = round(time/1000/60/60, 1)
top_albums[album_index]['listen_time'] = hours
return flask.render_template('album_square.html', top_albums=top_albums, limit=rows, res=res)
if __name__ == "__main__":
statuses = read_status_file()
if DEV:
app.run(port=PORT)
else:
waitress.serve(app, host='0.0.0.0', port=PORT)