@@ -2,22 +2,37 @@ | |||
 | |||
This is the source code of my personal website, | |||
[Kirsle.net](http://www.kirsle.net/). It runs on top of my Python CMS called | |||
[Rophako](https://github.com/kirsle/rophako). | |||
This is the source code of my personal website, [Kirsle.net][1]. It runs on | |||
top of my Go blog application, [kirsle/blog][2]. | |||
This Git repo only contains templates and design files for the main Kirsle.net | |||
website. This means only the files that are served directly by the Python CMS | |||
website. This means only the files that are served directly by the Go CMS | |||
(all pages with the "solar" web design) are here; but there are a decently | |||
large number of static files and one-off CGI scripts that get served directly | |||
by nginx instead. For example the `projects/` folder where I keep downloads of | |||
my various software projects, and the `creativity/` and `wizards` folders. | |||
my various software projects, and the `creativity/` and `wizards/` folders. | |||
So, feel free to look around in this repo, but you won't find anything too | |||
interesting in here. It's mostly just Jinja2 HTML templates and the odd web | |||
design file (CSS, JS, and some images). | |||
interesting in here. It's mostly just Go HTML templates, Markdown pages, and the | |||
odd web design file (CSS, JS, and some images). | |||
For the version of Kirsle.net that ran on my Python CMS, [Rophako][3], check | |||
out the `rophako` branch of this repo. | |||
## Dev Environment Quick Start | |||
Run `bootstrap.py` to automatically clone and configure the Rophako CMS to run | |||
a local dev instance of Kirsle.net. | |||
```bash | |||
# Make sure you have a Go environment set up. Quickly: | |||
export GOPATH="${HOME}/go" | |||
export PATH="${PATH}:${GOPATH}/bin" | |||
# Install my Go blog | |||
go get github.com/kirsle/blog/... | |||
# Run it on the kirsle.net www folder. | |||
blog ./www | |||
``` | |||
[1]: https://www.kirsle.net/ | |||
[2]: https://github.com/kirsle/blog | |||
[3]: https://github.com/kirsle/rophako |
@@ -1,82 +0,0 @@ | |||
#!/usr/bin/env python3 | |||
"""Bootstrap script to set up a local dev instance of Kirsle.net | |||
This will `git clone` an instance of the Rophako CMS and configure it to run | |||
this local website. When the dev Rophako instance already exists, running this | |||
script again acts as a shortcut to running `python runserver.py` from within | |||
the Rophako git repo. | |||
This script is only designed to work in Python 3 and requires the `git` and | |||
`pyvenv` commands. | |||
This performs the following tasks: | |||
* Clones Rophako into ./rophako | |||
* Sets up a Python 3 virtual environment via `pyvenv` at ./rophako/pyvenv | |||
* Installs requirements via `pip` into its virtual environment | |||
* Symlinks settings.yml and kirsle_legacy.py into the Rophako root | |||
* Runs the server | |||
""" | |||
import os | |||
import os.path | |||
import subprocess | |||
import sys | |||
def main(): | |||
# Make sure we have everything we need. | |||
check_depends() | |||
# Do we already have Rophako? | |||
if os.path.isdir("./rophako"): | |||
os.chdir("./rophako") | |||
else: | |||
# Clone it. | |||
must_run(["git", "clone", "https://github.com/kirsle/rophako"]) | |||
os.chdir("./rophako") | |||
# Make the Python environment. | |||
must_run(["pyvenv", "pyvenv"]) | |||
must_run(["pyvenv/bin/pip", "install", "-r", "requirements.txt"]) | |||
# Configure it. | |||
os.symlink("../settings.yml", "settings.yml") | |||
os.symlink("../kirsle_legacy.py", "kirsle_legacy.py") | |||
print("=" * 80) | |||
print("Success! Rophako has been cloned and configured! The server") | |||
print("will now start. To quickly start the server again in the") | |||
print("future, just run bootstrap.py again.") | |||
print("=" * 80) | |||
# Run Rophako. | |||
must_run(["pyvenv/bin/python", "runserver.py"]) | |||
def check_depends(): | |||
# Make sure we have access to required commands. | |||
errors = False | |||
for command in [ "git", "pyvenv" ]: | |||
try: | |||
subprocess.check_call(["which", command], | |||
stdout=subprocess.PIPE, | |||
stderr=subprocess.PIPE, | |||
) | |||
except subprocess.CalledProcessError: | |||
print("You seem to be missing the command: {}".format(command)) | |||
errors = True | |||
if errors: | |||
print("Make sure the required commands are installed and try again.") | |||
sys.exit(1) | |||
def must_run(args, **kwargs): | |||
"""Calls subprocess to run a command which must succeed or die.""" | |||
result = subprocess.call(args, **kwargs) | |||
if result != 0: | |||
print("Errors were detected in the command I tried to run: {}".format( | |||
" ".join(args), | |||
)) | |||
sys.exit(1) | |||
if __name__ == "__main__": | |||
main() |
@@ -1,3 +1,7 @@ | |||
# Apache config from when kirsle.net ran on Apache. | |||
# | |||
# This is for a Python mod_wsgi site. | |||
## SSL main site www.kirsle.net | |||
<VirtualHost *:443> | |||
ServerName www.kirsle.net |
@@ -1,3 +1,5 @@ | |||
# nginx config for kirsle.net | |||
server { | |||
server_name www.kirsle.net; | |||
listen 443 ssl; | |||
@@ -96,4 +98,3 @@ server { | |||
return 301 https://www.kirsle.net$request_uri; | |||
} | |||
@@ -1,127 +0,0 @@ | |||
# -*- coding: utf-8 -*- | |||
# Legacy endpoint compatibility from kirsle.net. | |||
from flask import g, request, redirect, url_for, flash | |||
import re | |||
import os | |||
import json | |||
from rophako.settings import Config | |||
from rophako.app import app | |||
from rophako.utils import template, login_required | |||
import rophako.model.blog as Blog | |||
import rophako.jsondb as JsonDB | |||
@app.route("/+") | |||
def google_plus(): | |||
return redirect("https://plus.google.com/+NoahPetherbridge/posts") | |||
@app.route("/blog.html") | |||
def ancient_legacy_blog(): | |||
post_id = request.args.get("id", None) | |||
if post_id is None: | |||
return redirect(url_for("blog.index")) | |||
# Look up the friendly ID. | |||
post = Blog.get_entry(post_id) | |||
if not post: | |||
flash("That blog entry wasn't found.") | |||
return redirect(url_for("blog.index")) | |||
return redirect(url_for("blog.entry", fid=post["fid"]), code=301) | |||
@app.route("/blog/kirsle/<fid>") | |||
def legacy_blog(fid): | |||
return redirect(url_for("blog.entry", fid=fid), code=301) | |||
@app.route("/rss.cgi") | |||
def legacy_rss(): | |||
return redirect(url_for("blog.rss"), code=301) | |||
@app.route("/firered/<page>") | |||
@app.route("/firered") | |||
def legacy_firered(page=""): | |||
g.info["page"] = str(page) or "1" | |||
return template("firered.html") | |||
@app.route("/download", methods=["GET", "POST"]) | |||
def legacy_download(): | |||
form = None | |||
if request.method == "POST": | |||
form = request.form | |||
else: | |||
# CNET links to the MS-DOS download using semicolon delimiters in the | |||
# query string. Fix that if detected. | |||
query = request.query_string.decode() | |||
if not '&' in query and ';' in query: | |||
url = re.sub(r';|%3b', '&', request.url, flags=re.IGNORECASE) | |||
return redirect(url) | |||
form = request.args | |||
method = form.get("method", "index") | |||
project = form.get("project", "") | |||
filename = form.get("file", "") | |||
root = "/home/kirsle/www/projects" | |||
if project and filename: | |||
# Filter the sections. | |||
project = re.sub(r'[^A-Za-z0-9]', '', project) # Project name is alphanumeric only. | |||
filename = re.sub(r'[^A-Za-z0-9\-_\.]', '', filename) | |||
# Check that all the files exist. | |||
if os.path.isdir(os.path.join(root, project)) and os.path.isfile(os.path.join(root, project, filename)): | |||
# Hit counters. | |||
hits = { "hits": 0 } | |||
db = "data/downloads/{}-{}".format(project, filename) | |||
if JsonDB.exists(db.format(project, filename)): | |||
hits = JsonDB.get(db) | |||
# Actually getting the file? | |||
if method == "get": | |||
# Up the hit counter. | |||
hits["hits"] += 1 | |||
JsonDB.commit(db, hits) | |||
g.info["method"] = method | |||
g.info["project"] = project | |||
g.info["file"] = filename | |||
g.info["hits"] = hits["hits"] | |||
return template("download.html") | |||
flash("The file or project wasn't found.") | |||
return redirect(url_for("index")) | |||
@app.route("/<page>.html") | |||
def legacy_url(page): | |||
return redirect("/{}".format(page), code=301) | |||
@app.route("/metacity") | |||
def legacy_metacity(): | |||
return redirect("https://github.com/kirsle/linux-themes", code=301) | |||
@app.route("/ssl_test") | |||
@login_required | |||
def ssl_test(): | |||
return "<pre>{}</pre>".format(json.dumps({ | |||
"SSLify criteria": { | |||
"request.is_secure": request.is_secure, | |||
"app.debug": app.debug, | |||
"X-Forwarded-Proto is http": request.headers.get("X-Forwarded-Proto", "http") == "https", | |||
}, | |||
"App Configuration": { | |||
"Session cookies secure": app.config["SESSION_COOKIE_SECURE"], | |||
"config.FORCE_SSL": Config.security.force_ssl, | |||
}, | |||
})) |