PEP-8 updates
This commit is contained in:
5
.pylintrc
Executable file
5
.pylintrc
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
[FORMAT]
|
||||||
|
max-line-length=140
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
disable=import-error
|
17
src/index.py
17
src/index.py
@@ -1,16 +1,17 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
from flask import Flask, render_template, Response
|
|
||||||
import traceback
|
import traceback
|
||||||
from os import environ
|
from os import environ
|
||||||
import threading
|
import threading
|
||||||
from requests import post
|
|
||||||
import logging
|
import logging
|
||||||
|
from requests import post
|
||||||
|
from flask import Flask, render_template
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
import projects
|
# These imports need to come after our app is defined as they add routes to it.
|
||||||
import contact
|
import projects # pylint: disable=wrong-import-position,unused-import
|
||||||
|
import contact # pylint: disable=wrong-import-position,unused-import
|
||||||
|
|
||||||
class DiscordLogger(logging.Handler):
|
class DiscordLogger(logging.Handler):
|
||||||
''' Simple logging handler to send a message to Discord '''
|
''' Simple logging handler to send a message to Discord '''
|
||||||
@@ -45,11 +46,13 @@ discord_logger = DiscordLogger(environ['DISCORD_ERR_HOOK'])
|
|||||||
app.logger.addHandler(discord_logger)
|
app.logger.addHandler(discord_logger)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index() -> str:
|
||||||
|
''' Load the homepage '''
|
||||||
return render_template('index.html')
|
return render_template('index.html')
|
||||||
|
|
||||||
@app.route('/error/<code>')
|
@app.route('/error/<code>')
|
||||||
def error(code):
|
def error(code) -> str:
|
||||||
|
''' Render a nicer error page for a given code '''
|
||||||
error_definitions = {
|
error_definitions = {
|
||||||
400: 'Bad Request',
|
400: 'Bad Request',
|
||||||
403: 'Forbidden',
|
403: 'Forbidden',
|
||||||
@@ -69,6 +72,6 @@ def error(code):
|
|||||||
505: 'Your browser tried to use a HTTP version I don\'t support. Check it is up to date.'
|
505: 'Your browser tried to use a HTTP version I don\'t support. Check it is up to date.'
|
||||||
}
|
}
|
||||||
|
|
||||||
return render_template('error.html',
|
return render_template('error.html',
|
||||||
error=f'{code}: {error_definitions.get(int(code))}',
|
error=f'{code}: {error_definitions.get(int(code))}',
|
||||||
description=error_desc.get(int(code)))
|
description=error_desc.get(int(code)))
|
||||||
|
@@ -2,21 +2,22 @@
|
|||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
import json
|
import json
|
||||||
from flask import Flask, render_template, Response, send_from_directory, request, make_response
|
|
||||||
from markdown import markdown
|
|
||||||
import frontmatter
|
|
||||||
from glob import glob
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from index import app
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from PIL import Image, UnidentifiedImageError
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from glob import glob
|
||||||
|
from PIL import Image, UnidentifiedImageError
|
||||||
|
import frontmatter
|
||||||
|
from markdown import markdown
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from flask import render_template, Response, send_from_directory, request, make_response
|
||||||
|
from index import app
|
||||||
|
|
||||||
md_directory = path.join(path.realpath(path.dirname(__file__)), path.normpath('projects/'))
|
md_directory = path.join(path.realpath(path.dirname(__file__)), path.normpath('projects/'))
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def processor():
|
def processor() -> dict:
|
||||||
def get_excerpt(post):
|
''' Jninja processors '''
|
||||||
|
def get_excerpt(post: frontmatter.Post) -> str:
|
||||||
html = markdown(post.content)
|
html = markdown(post.content)
|
||||||
post_soup = BeautifulSoup(html, 'html.parser')
|
post_soup = BeautifulSoup(html, 'html.parser')
|
||||||
all_text = ' '.join([x.get_text() for x in post_soup.findAll('p')])
|
all_text = ' '.join([x.get_text() for x in post_soup.findAll('p')])
|
||||||
@@ -25,31 +26,37 @@ def processor():
|
|||||||
|
|
||||||
@app.template_filter('category_title')
|
@app.template_filter('category_title')
|
||||||
def category_title(category_id: str) -> str:
|
def category_title(category_id: str) -> str:
|
||||||
with open(path.join(md_directory, 'categories.json')) as categories_file:
|
''' Jninja filter to get a category title by its ID '''
|
||||||
|
with open(path.join(md_directory, 'categories.json'), encoding='utf8') as categories_file:
|
||||||
categories = json.load(categories_file)
|
categories = json.load(categories_file)
|
||||||
|
|
||||||
return categories.get(category_id).get('title', '')
|
return categories.get(category_id).get('title', '')
|
||||||
|
|
||||||
@app.template_filter('human_date')
|
@app.template_filter('human_date')
|
||||||
def human_date(iso_date: str) -> str:
|
def human_date(iso_date: str) -> str:
|
||||||
|
''' Jninja filter to convert an ISO date to human readable. '''
|
||||||
try:
|
try:
|
||||||
return datetime.fromisoformat(str(iso_date)).strftime('%A %d %B %Y')
|
return datetime.fromisoformat(str(iso_date)).strftime('%A %d %B %Y')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return iso_date
|
return iso_date
|
||||||
|
|
||||||
@app.template_filter('to_html')
|
@app.template_filter('to_html')
|
||||||
def to_html(content):
|
def to_html(content: str) -> str:
|
||||||
|
''' Jninja filter to wrap markdown '''
|
||||||
return markdown(content)
|
return markdown(content)
|
||||||
|
|
||||||
def get_all_posts(directory: str) -> list:
|
def get_all_posts(directory: str) -> list:
|
||||||
|
''' Get all posts in the posts directory '''
|
||||||
abs_paths = [path.join(directory, x) for x in glob(f'{directory}/*.md')]
|
abs_paths = [path.join(directory, x) for x in glob(f'{directory}/*.md')]
|
||||||
return [frontmatter.load(x) for x in abs_paths]
|
return [frontmatter.load(x) for x in abs_paths]
|
||||||
|
|
||||||
def get_by_meta_key(directory: str, key: str, value: str):
|
def get_by_meta_key(directory: str, key: str, value: str) -> list:
|
||||||
|
''' Get posts by a metadata key value pair '''
|
||||||
return [x for x in get_all_posts(directory) if x.get(key) == value or type(x.get(key, [])) is list and value in x.get(key, [])]
|
return [x for x in get_all_posts(directory) if x.get(key) == value or type(x.get(key, [])) is list and value in x.get(key, [])]
|
||||||
|
|
||||||
@app.route('/projects/')
|
@app.route('/projects/')
|
||||||
def projects():
|
def projects() -> str:
|
||||||
|
''' Load the projects page '''
|
||||||
articles_to_return = sorted(
|
articles_to_return = sorted(
|
||||||
get_all_posts(
|
get_all_posts(
|
||||||
md_directory),
|
md_directory),
|
||||||
@@ -62,7 +69,7 @@ def projects():
|
|||||||
error='There\'s nothing here... yet.',
|
error='There\'s nothing here... yet.',
|
||||||
description='I\'m still working on this page. Check back soon for some content.')
|
description='I\'m still working on this page. Check back soon for some content.')
|
||||||
try:
|
try:
|
||||||
with open(path.join(md_directory, 'categories.json')) as categories_file:
|
with open(path.join(md_directory, 'categories.json'), encoding='utf8') as categories_file:
|
||||||
categories = json.load(categories_file)
|
categories = json.load(categories_file)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return render_template('error.html',
|
return render_template('error.html',
|
||||||
@@ -77,11 +84,12 @@ def projects():
|
|||||||
description='A selection of projects I\'ve been involved in1')
|
description='A selection of projects I\'ve been involved in1')
|
||||||
|
|
||||||
@app.route('/projects/category/<category>/')
|
@app.route('/projects/category/<category>/')
|
||||||
def category(category):
|
def category(category_id: str) -> str:
|
||||||
|
''' Load the page for a given category '''
|
||||||
try:
|
try:
|
||||||
with open(path.join(md_directory, 'categories.json')) as categories_file:
|
with open(path.join(md_directory, 'categories.json'), encoding='utf8') as categories_file:
|
||||||
categories = json.load(categories_file)
|
categories = json.load(categories_file)
|
||||||
the_category = categories.get(category)
|
the_category = categories.get(category_id)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return render_template('error.html',
|
return render_template('error.html',
|
||||||
error='There\'s nothing here... yet.',
|
error='There\'s nothing here... yet.',
|
||||||
@@ -92,7 +100,7 @@ def category(category):
|
|||||||
|
|
||||||
articles_to_return = sorted(
|
articles_to_return = sorted(
|
||||||
get_by_meta_key(
|
get_by_meta_key(
|
||||||
md_directory, 'categories', category),
|
md_directory, 'categories', category_id),
|
||||||
key=lambda d: d.metadata.get('date'),
|
key=lambda d: d.metadata.get('date'),
|
||||||
reverse=True
|
reverse=True
|
||||||
)
|
)
|
||||||
@@ -110,8 +118,9 @@ def category(category):
|
|||||||
current_category=category)
|
current_category=category)
|
||||||
|
|
||||||
@app.route('/projects/<article>')
|
@app.route('/projects/<article>')
|
||||||
def article(article):
|
def article(article_id: str) -> str:
|
||||||
articles = get_by_meta_key(md_directory, 'id', article)
|
''' Load a single article '''
|
||||||
|
articles = get_by_meta_key(md_directory, 'id', article_id)
|
||||||
|
|
||||||
if len(articles) == 0:
|
if len(articles) == 0:
|
||||||
return Response(status=404)
|
return Response(status=404)
|
||||||
@@ -124,23 +133,24 @@ def article(article):
|
|||||||
page_title=f'{the_article.metadata["title"]} - ')
|
page_title=f'{the_article.metadata["title"]} - ')
|
||||||
|
|
||||||
@app.route('/projects/image/<image>')
|
@app.route('/projects/image/<image>')
|
||||||
def image(image):
|
def image(image_name: str) -> Response:
|
||||||
|
''' Resize and return an image. '''
|
||||||
w = int(request.args.get('w', 0))
|
w = int(request.args.get('w', 0))
|
||||||
h = int(request.args.get('h', 0))
|
h = int(request.args.get('h', 0))
|
||||||
|
|
||||||
if w == 0 and h == 0:
|
if w == 0 and h == 0:
|
||||||
return send_from_directory(md_directory, path.join('images', image))
|
return send_from_directory(md_directory, path.join('images', image_name))
|
||||||
try:
|
try:
|
||||||
the_image = Image.open(path.join(md_directory, 'images', image))
|
the_image = Image.open(path.join(md_directory, 'images', image_name))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return Response(status=404)
|
return Response(status=404)
|
||||||
except UnidentifiedImageError:
|
except UnidentifiedImageError:
|
||||||
return send_from_directory(md_directory, path.join('images', image))
|
return send_from_directory(md_directory, path.join('images', image_name))
|
||||||
|
|
||||||
max_width, max_height = the_image.size
|
max_width, max_height = the_image.size
|
||||||
|
|
||||||
if (w >= max_width and h >= max_height):
|
if (w >= max_width and h >= max_height):
|
||||||
return send_from_directory(md_directory, path.join('images', image))
|
return send_from_directory(md_directory, path.join('images', image_name))
|
||||||
|
|
||||||
req_size = [max_width, max_height]
|
req_size = [max_width, max_height]
|
||||||
if w > 0:
|
if w > 0:
|
||||||
@@ -151,8 +161,7 @@ def image(image):
|
|||||||
resized_img = BytesIO()
|
resized_img = BytesIO()
|
||||||
the_image.thumbnail(tuple(req_size))
|
the_image.thumbnail(tuple(req_size))
|
||||||
the_image.save(resized_img, format=the_image.format)
|
the_image.save(resized_img, format=the_image.format)
|
||||||
|
|
||||||
response = make_response(resized_img.getvalue())
|
response = make_response(resized_img.getvalue())
|
||||||
response.headers.set('Content-Type', f'image/{the_image.format}')
|
response.headers.set('Content-Type', f'image/{the_image.format}')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user