aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--requirements.txt1
-rw-r--r--server.py21
-rw-r--r--siteconfig.py32
-rw-r--r--view_functions.py71
-rw-r--r--views.py94
5 files changed, 134 insertions, 85 deletions
diff --git a/requirements.txt b/requirements.txt
index 63d0835..b3c4209 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,4 @@ pip==20.3.4
setuptools==44.1.1
Werkzeug==2.0.1
Flask-Compress==1.10.1
+Flask-Caching==1.10.1
diff --git a/server.py b/server.py
index 8937d4b..85ffad0 100644
--- a/server.py
+++ b/server.py
@@ -1,10 +1,20 @@
+"""
+server.py - sets up and runs the flask server
+"""
import os
from flask import Flask
from siteconfig import siteconfig
from flask_compress import Compress
+from flask_caching import Cache
app = Flask(__name__)
compress = Compress()
+cache = Cache(
+ config={
+ 'CACHE_TYPE': siteconfig.CACHE_TYPE,
+ 'CACHE_DEFAULT_TIMEOUT': siteconfig.CACHE_DEFAULT_TIMEOUT,
+ }
+)
from views import *
@@ -25,17 +35,22 @@ def setup():
else:
s = "./templates/site/"
top_dirs = [
- x for x in os.listdir(s) \
- if os.path.isdir(s + x) and not x.startswith(".")
+ x
+ for x in os.listdir(s)
+ if os.path.isdir(s + x) and not x.startswith(".")
]
app.config.update({'MAIN_SITE_DIRS': sorted(top_dirs)})
app.config.update({'DOMAIN': siteconfig.DOMAIN})
app.config.update({'HOME_TITLE': siteconfig.HOME_TITLE})
- app.config.update({'COMPRESS_MIMETYPES': siteconfig.COMPRESS_MIMETYPES})
+ app.config.update(
+ {'COMPRESS_MIMETYPES': siteconfig.COMPRESS_MIMETYPES}
+ )
+
# Setup needs to come first to be compatible with wsgi
setup()
if __name__ == "__main__":
compress.init_app(app)
+ cache.init_app(app)
app.run()
diff --git a/siteconfig.py b/siteconfig.py
index fa73b46..4e0ef90 100644
--- a/siteconfig.py
+++ b/siteconfig.py
@@ -1,15 +1,20 @@
+"""
+siteconfig.py - user editable configuration file
+"""
+
+
class siteconfig:
# REQUIRED SETTINGS#
- DOMAIN = "example.net" # Your site here!
- HOME_TITLE = "WELCOME" # Goes right under
- # your site
- LINKS_FILE = ".links" # ".lnx" if you like
- DESC_FILE = ".description" # ".desc"
- DEFAULT_MIMETYPE = "application/octet-stream"
+ DOMAIN = "example.net" # Your site here!
+ HOME_TITLE = "WELCOME" # Goes right under
+ # your site
+ LINKS_FILE = ".links" # ".lnx" if you like
+ DESC_FILE = ".description" # ".desc"
+ DEFAULT_MIMETYPE = "application/octet-stream"
# ^This usually prompts a browser to download a file if the mime
# type is unknown. A good alternative might be "text/plain"
-
+
# Add your desired mimetypes to the csv file
MIMETYPES = {}
with open('mimetypes.csv') as f:
@@ -23,9 +28,18 @@ class siteconfig:
# ./templates/site/. You can change this to only specific directories, but
# these still have to be in ./templates/site
MAIN_SITE_DIRS = None # ["dir1", "dir2", "dir3"]
+
# Set a custom secret key. If not set, it will be generated
# Most of the time, you don't need to set this!
- SECRET_KEY = None # Something random.
- # Special option for Flask Compress
+ SECRET_KEY = None # Something random.
+
+ # Option for Flask Compress
# see here https://pypi.org/project/Flask-Compress/
COMPRESS_MIMETYPES = list(MIMETYPES.values())
+
+ # Option for Flask Caching
+ # https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching
+ CACHE_TYPE = "SimpleCache"
+
+ # Time in seconds that your files stay cached for
+ CACHE_DEFAULT_TIMEOUT = 300
diff --git a/view_functions.py b/view_functions.py
new file mode 100644
index 0000000..64dcfe0
--- /dev/null
+++ b/view_functions.py
@@ -0,0 +1,71 @@
+"""
+view_functions.py - defines functions called by views to display the correct data
+about files and paths.
+"""
+import os
+from siteconfig import siteconfig
+from server import app
+
+
+def default_context():
+ """
+ default_context - returns the minimum info needed to render a template--the
+ domain name (for the home directory), and the top site directories which
+ make up the navbar
+ """
+ return {
+ 'domain': app.config['DOMAIN'],
+ 'navbar': sorted(app.config['MAIN_SITE_DIRS']),
+ }
+
+
+def index_dir(path):
+ """
+ index_dir - Given a directory at `path`, list it's contents,
+ and sort each item as a file or a directory or a special file.
+
+ return - a tuple with the values:
+ > a list of directories in `path`,
+ > a list of files in `path`,
+ > (if present), a list of external links to add to the index.html of the
+ directory
+ > (if present), a short description (string) of what the directory contains
+
+ Lists are sorted alphabetically.
+
+ *Special files include '.links' and '.description' the format of these
+ files is unquoted CSV and text/html. Both are displayed on the index.html
+ for the given `path`
+ """
+ dirs = []
+ files = []
+ links = []
+ description = False
+ contents = os.listdir(path)
+ for obj in contents:
+ if os.path.isfile(path + '/' + obj):
+ if obj == siteconfig.LINKS_FILE:
+ with open(path + '/' + obj) as f:
+ links = f.readlines()
+ elif obj == siteconfig.DESC_FILE:
+ description = True
+ elif obj.startswith('.'):
+ continue
+ else:
+ files.append(obj)
+ elif os.path.isdir(path + '/' + obj):
+ if obj.startswith('.'):
+ continue
+ else:
+ dirs.append(obj)
+
+ return sorted(dirs), sorted(files), sorted(links), description
+
+
+def is_hidden_path(path):
+ """
+ Tests if last object specified in `path` is hidden.
+ Inspired by Unix. On Windows, directories won't actually be "hidden" but
+ they are still not indexed by this program
+ """
+ return path.split('/')[-1].startswith('.')
diff --git a/views.py b/views.py
index f7711b8..dd37902 100644
--- a/views.py
+++ b/views.py
@@ -1,81 +1,25 @@
+"""
+views.py - defines the logic that generates views that a user sees when
+browsing to certain pages
+"""
import os
from flask import request, send_from_directory, abort
from flask import render_template, render_template_string
from siteconfig import siteconfig
-from server import app
+from server import app, cache
+from view_functions import default_context, index_dir, is_hidden_path
# bit of a hack.
# Brackets don't play nicely with Jinja so instead of using .format,
# we just replace the special character $
-CONTENT_BLOCK = "{% extends 'base.html' %}{% block content %}${% endblock %}"
-
-
-def default_context():
- """
- default_context - returns the minimum info needed to render a template--the
- domain name (for the home directory), and the top site directories which
- make up the navbar
- """
- return {
- 'domain': app.config['DOMAIN'],
- 'navbar': sorted(app.config['MAIN_SITE_DIRS']),
- }
-
-
-def index_dir(path):
- """
- index_dir - Given a directory at `path`, list it's contents,
- and sort each item as a file or a directory or a special file.
-
- return - a tuple with the values:
- > a list of directories in `path`,
- > a list of files in `path`,
- > (if present), a list of external links to add to the index.html of the
- directory
- > (if present), a short description (string) of what the directory contains
-
- Lists are sorted alphabetically.
-
- *Special files include '.links' and '.description' the format of these
- files is unquoted CSV and text/html. Both are displayed on the index.html
- for the given `path`
- """
- dirs = []
- files = []
- links = []
- description = False
- contents = os.listdir(path)
- for obj in contents:
- if os.path.isfile(path + '/' + obj):
- if obj == siteconfig.LINKS_FILE:
- with open(path + '/' + obj) as f:
- links = f.readlines()
- elif obj == siteconfig.DESC_FILE:
- description = True
- elif obj.startswith('.'):
- continue
- else:
- files.append(obj)
- elif os.path.isdir(path + '/' + obj):
- if obj.startswith('.'):
- continue
- else:
- dirs.append(obj)
-
- return sorted(dirs), sorted(files), sorted(links), description
-
-
-def is_hidden_path(path):
- """
- Tests if last object specified in `path` is hidden.
- Inspired by Unix. On Windows, directories won't actually be "hidden" but
- they are still not indexed by this program
- """
- return path.split('/')[-1].startswith('.')
+CONTENT_BLOCK = (
+ "{% extends 'base.html' %}{% block content %}${% endblock %}"
+)
@app.route("/")
@app.route("/site")
+@cache.cached()
def home():
"""
home - renders the template `home.html` as the main index file
@@ -84,12 +28,15 @@ def home():
edit, though you can optionally change the title here if you wish
"""
context = default_context()
- context.update({'title': app.config['HOME_TITLE'], 'parent_dir': '/site/'})
+ context.update(
+ {'title': app.config['HOME_TITLE'], 'parent_dir': '/site/'}
+ )
return render_template("site/home.html", **context)
# from: https://pythonise.com/series/learning-flask/sending-files-with-flask
@app.route("/site/<path:path>")
+@cache.cached()
def render_file(path):
"""
render_file - renders an HTML document for the given `path`.
@@ -124,7 +71,8 @@ def render_file(path):
'templates/site/',
path,
mimetype=siteconfig.MIMETYPES.get(
- f".{ path.split('.')[-1] }", siteconfig.DEFAULT_MIMETYPE
+ f".{ path.split('.')[-1] }",
+ siteconfig.DEFAULT_MIMETYPE,
),
)
elif os.path.isdir(abs_path):
@@ -146,11 +94,11 @@ def render_file(path):
@app.route("/raw/<path:path>")
+@cache.cached()
def send_file_from_site(path):
"""
- send_file - instead of rendering a file within a template as with
- `render_file`, send the raw file to the user, when site is replace with
- path.
+ send_file_from_site - instead of rendering a file within a template
+ as with `render_file`, send the raw file to the user
"""
return send_from_directory(
'templates/site/',
@@ -162,10 +110,10 @@ def send_file_from_site(path):
@app.route("/static/<path:path>")
+@cache.cached()
def send_file_from_static(path):
"""
- send_file - instead of rendering a file within a template as with
- `render_file`, send the raw file to the user
+ send_file_from_static - send files from the static directory
"""
return send_from_directory(
'static/',