35 changed files with 556 additions and 150 deletions
@ -0,0 +1,4 @@ |
|||||
|
:set -isrc |
||||
|
:set -hide-package MonadCatchIO-mtl |
||||
|
:set -hide-package monads-fd |
||||
|
:set -XOverloadedStrings |
@ -0,0 +1,59 @@ |
|||||
|
from __future__ import with_statement |
||||
|
from fabric.api import * |
||||
|
from fabric.contrib.console import confirm |
||||
|
from fabric.contrib.project import rsync_project |
||||
|
import fabric.operations as op |
||||
|
|
||||
|
env.hosts = ["wes@mgoal.ca:444"] |
||||
|
|
||||
|
@task |
||||
|
def buildTags(): |
||||
|
with lcd("./build"): |
||||
|
local("riot ../src/tags scripts/tags.min.js") |
||||
|
|
||||
|
@task |
||||
|
def buildScss(): |
||||
|
with lcd("./build"): |
||||
|
local("sassc ../src/styles/riotblog.scss > styles/riotblog.min.css") |
||||
|
|
||||
|
@task |
||||
|
def minifyJS(): |
||||
|
with lcd("./build"): |
||||
|
local("uglifyjs ../src/scripts/riotblog.js > scripts/riotblog.min.js") |
||||
|
|
||||
|
@task |
||||
|
def buildVenv(): |
||||
|
local("virtualenv -p $(which python3) ./venv") |
||||
|
with prefix("source ./venv/bin/activate"): |
||||
|
local("pip3 install -r requirements.txt") |
||||
|
local("mv venv ./build/") |
||||
|
|
||||
|
@task |
||||
|
def copyFiles(): |
||||
|
local("cp ./{blog.ini,blog.service} ./build/") |
||||
|
local("cp ./src/*py ./build/") |
||||
|
local("cp ./src/styles/*.css ./build/styles/") |
||||
|
local("cp -r ./src/templates ./build/templates") |
||||
|
|
||||
|
@task |
||||
|
def upload(): |
||||
|
run("mkdir -p ~/build") |
||||
|
rsync_project(local_dir="./build/", remote_dir="~/build/", delete=True, exclude=[".git"]) |
||||
|
|
||||
|
@task |
||||
|
def serveUp(): |
||||
|
sudo("cp -r /home/wes/build /srv/riotblog") |
||||
|
sudo("cp /home/wes/build/blog.service /etc/systemd/system/blog.service") |
||||
|
sudo("systemctl enable blog.service") |
||||
|
|
||||
|
@task(default=True) |
||||
|
def build(): |
||||
|
local("rm -r ./build") |
||||
|
local("mkdir -p build/{scripts,styles}") |
||||
|
buildTags() |
||||
|
buildScss() |
||||
|
minifyJS() |
||||
|
buildVenv() |
||||
|
copyFiles() |
||||
|
upload() |
||||
|
serveUp() |
@ -1,6 +0,0 @@ |
|||||
default: |
|
||||
sass blog.scss > styles/blog.min.css |
|
||||
riot tags/ scripts/tags.js |
|
||||
|
|
||||
watch: |
|
||||
while true; do make ; inotifywait -qre close_write .; done |
|
@ -0,0 +1,17 @@ |
|||||
|
[uwsgi] |
||||
|
wsgi_file = /srv/http/riotblog/website.py |
||||
|
chdir = /srv/http/riotblog/ |
||||
|
module = website |
||||
|
callable = app |
||||
|
virtualenv = /srv/http/riotblog/venv |
||||
|
uid = http |
||||
|
gid = http |
||||
|
|
||||
|
master = true |
||||
|
processes = 5 |
||||
|
|
||||
|
socket = /tmp/blog.sock |
||||
|
chown-socket = http:http |
||||
|
chmod-socket = 660 |
||||
|
vacuum = true |
||||
|
die-on-term = true |
@ -1,69 +0,0 @@ |
|||||
@mixin responsive-block($bw) { |
|
||||
@media (max-width: 700px) { |
|
||||
max-width: $bw+20%; |
|
||||
} |
|
||||
@media (max-width: 500px) { |
|
||||
max-width: $bw+40%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.post-text { |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.blog-title { |
|
||||
@extend .post-text; |
|
||||
} |
|
||||
|
|
||||
.post { |
|
||||
@extend .post-text; |
|
||||
} |
|
||||
|
|
||||
.post-content { |
|
||||
max-width: 50%; |
|
||||
text-align: justify; |
|
||||
font-size: 1.5em; |
|
||||
@include responsive-block(50); |
|
||||
} |
|
||||
|
|
||||
.comment-block { |
|
||||
max-width: 30%; |
|
||||
@include responsive-block(30); |
|
||||
} |
|
||||
|
|
||||
.comments { |
|
||||
margin-top: 5%; |
|
||||
@extend .comment-block; |
|
||||
} |
|
||||
|
|
||||
.comment { |
|
||||
margin-top: 2%; |
|
||||
max-width: 40%; |
|
||||
@include responsive-block(45); |
|
||||
} |
|
||||
|
|
||||
.comments-loader { |
|
||||
margin-top: 2%; |
|
||||
} |
|
||||
|
|
||||
.comment-body { |
|
||||
margin-left: 10px; |
|
||||
margin-right: 10px; |
|
||||
} |
|
||||
|
|
||||
.postnav { |
|
||||
@extend .post-text; |
|
||||
} |
|
||||
|
|
||||
.rounded-button { |
|
||||
border-radius: 13px; |
|
||||
} |
|
||||
|
|
||||
.maxinput { |
|
||||
background-color: grey; |
|
||||
} |
|
||||
|
|
||||
.maxwarn { |
|
||||
margin-top: 15px; |
|
||||
@extend .comment-block; |
|
||||
} |
|
@ -0,0 +1,12 @@ |
|||||
|
[Unit] |
||||
|
Description=My Blargh |
||||
|
After=network.target |
||||
|
|
||||
|
[Service] |
||||
|
User=http |
||||
|
Group=http |
||||
|
WorkingDirectory=/srv/http/riotblog |
||||
|
ExecStart=/usr/bin/uwsgi --ini /srv/http/riotblog/blog.ini |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=multi.user.target |
@ -0,0 +1,17 @@ |
|||||
|
[uwsgi] |
||||
|
wsgi_file = /srv/http/riotblog/website.py |
||||
|
chdir = /srv/http/riotblog/ |
||||
|
module = website |
||||
|
callable = app |
||||
|
virtualenv = /srv/http/riotblog/venv |
||||
|
uid = http |
||||
|
gid = http |
||||
|
|
||||
|
master = true |
||||
|
processes = 5 |
||||
|
|
||||
|
socket = /tmp/blog.sock |
||||
|
chown-socket = http:http |
||||
|
chmod-socket = 660 |
||||
|
vacuum = true |
||||
|
die-on-term = true |
@ -0,0 +1,12 @@ |
|||||
|
[Unit] |
||||
|
Description=My Blargh |
||||
|
After=network.target |
||||
|
|
||||
|
[Service] |
||||
|
User=http |
||||
|
Group=http |
||||
|
WorkingDirectory=/srv/http/riotblog |
||||
|
ExecStart=/usr/bin/uwsgi --ini /srv/http/riotblog/blog.ini |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=multi.user.target |
@ -0,0 +1 @@ |
|||||
|
riot.mount("post",{creator:"wes",title:"A cool post here"});riot.mount("bbutton"); |
@ -0,0 +1,57 @@ |
|||||
|
.post-text, .blog-title, .post, .postnav { |
||||
|
text-align: center; } |
||||
|
|
||||
|
.post-content { |
||||
|
max-width: 50%; |
||||
|
text-align: justify; |
||||
|
font-size: 1.5em; } |
||||
|
|
||||
|
@media (max-width: 700px) { |
||||
|
.post-content { |
||||
|
max-width: 70%; } } |
||||
|
|
||||
|
@media (max-width: 500px) { |
||||
|
.post-content { |
||||
|
max-width: 90%; } } |
||||
|
|
||||
|
.comment-block, .comments, .maxwarn { |
||||
|
max-width: 30%; } |
||||
|
|
||||
|
@media (max-width: 700px) { |
||||
|
.comment-block, .comments, .maxwarn { |
||||
|
max-width: 50%; } } |
||||
|
|
||||
|
@media (max-width: 500px) { |
||||
|
.comment-block, .comments, .maxwarn { |
||||
|
max-width: 70%; } } |
||||
|
|
||||
|
.comments { |
||||
|
margin-top: 5%; } |
||||
|
|
||||
|
.comment { |
||||
|
margin-top: 2%; |
||||
|
max-width: 40%; } |
||||
|
|
||||
|
@media (max-width: 700px) { |
||||
|
.comment { |
||||
|
max-width: 65%; } } |
||||
|
|
||||
|
@media (max-width: 500px) { |
||||
|
.comment { |
||||
|
max-width: 85%; } } |
||||
|
|
||||
|
.comments-loader { |
||||
|
margin-top: 2%; } |
||||
|
|
||||
|
.comment-body { |
||||
|
margin-left: 10px; |
||||
|
margin-right: 10px; } |
||||
|
|
||||
|
.rounded-button { |
||||
|
border-radius: 13px; } |
||||
|
|
||||
|
.maxinput { |
||||
|
background-color: grey; } |
||||
|
|
||||
|
.maxwarn { |
||||
|
margin-top: 15px; } |
@ -0,0 +1,57 @@ |
|||||
|
from __future__ import with_statement |
||||
|
from fabric.api import * |
||||
|
from fabric.contrib.console import confirm |
||||
|
from fabric.contrib.project import rsync_project |
||||
|
import fabric.operations as op |
||||
|
|
||||
|
env.hosts = ["wes@mgoal.ca:444"] |
||||
|
|
||||
|
@task |
||||
|
def buildTags(): |
||||
|
with lcd("./build"): |
||||
|
local("riot ../src/tags scripts/tags.min.js") |
||||
|
|
||||
|
@task |
||||
|
def buildScss(): |
||||
|
with lcd("./build"): |
||||
|
local("sassc ../src/styles/riotblog.scss > styles/riotblog.min.css") |
||||
|
|
||||
|
@task |
||||
|
def minifyJS(): |
||||
|
with lcd("./build"): |
||||
|
local("uglifyjs ../src/scripts/riotblog.js > scripts/riotblog.min.js") |
||||
|
|
||||
|
@task |
||||
|
def buildVenv(): |
||||
|
local("virtualenv -p $(which python3) ./venv") |
||||
|
with prefix("source ./venv/bin/activate"): |
||||
|
local("pip3 install -r requirements.txt") |
||||
|
local("mv venv ./build/") |
||||
|
|
||||
|
@task |
||||
|
def copyFiles(): |
||||
|
local("cp ./{blog.ini,blog.service} ./build/") |
||||
|
local("cp ./src/*py ./build/") |
||||
|
local("cp ./src/styles/*.css ./build/styles/") |
||||
|
local("cp -r ./src/templates ./build/templates") |
||||
|
|
||||
|
@task |
||||
|
def upload(): |
||||
|
run("mkdir -p ~/build") |
||||
|
rsync_project(local_dir="./build/", remote_dir="~/build/", delete=True, exclude=[".git"]) |
||||
|
|
||||
|
@task |
||||
|
def serveUp(): |
||||
|
sudo("cp -r /home/wes/build /srv/riotblog") |
||||
|
|
||||
|
@task(default=True) |
||||
|
def build(): |
||||
|
local("rm -r ./build") |
||||
|
local("mkdir -p build/{scripts,styles}") |
||||
|
buildTags() |
||||
|
buildScss() |
||||
|
minifyJS() |
||||
|
buildVenv() |
||||
|
copyFiles() |
||||
|
upload() |
||||
|
serveUp() |
@ -0,0 +1,10 @@ |
|||||
|
appdirs==1.4.0 |
||||
|
click==6.7 |
||||
|
Flask==0.12 |
||||
|
itsdangerous==0.24 |
||||
|
Jinja2==2.9.5 |
||||
|
MarkupSafe==0.23 |
||||
|
packaging==16.8 |
||||
|
pyparsing==2.1.10 |
||||
|
six==1.10.0 |
||||
|
Werkzeug==0.11.15 |
@ -1,33 +0,0 @@ |
|||||
Name: riotblog |
|
||||
Version: 0.1 |
|
||||
Synopsis: Project Synopsis Here |
|
||||
Description: Project Description Here |
|
||||
License: AllRightsReserved |
|
||||
Author: Author |
|
||||
Maintainer: maintainer@example.com |
|
||||
Stability: Experimental |
|
||||
Category: Web |
|
||||
Build-type: Simple |
|
||||
Cabal-version: >=1.2 |
|
||||
|
|
||||
Executable riotblog |
|
||||
hs-source-dirs: src |
|
||||
main-is: Main.hs |
|
||||
|
|
||||
Build-depends: |
|
||||
base >= 4 && < 5, |
|
||||
bytestring >= 0.9.1 && < 0.11, |
|
||||
monad-control >= 1.0 && < 1.1, |
|
||||
mtl >= 2 && < 3, |
|
||||
snap-core >= 1.0 && < 1.1, |
|
||||
snap-server >= 1.0 && < 1.1, |
|
||||
text -any, |
|
||||
unordered-containers -any, |
|
||||
data-default -any, |
|
||||
shakespeare >=2.0.11.2 |
|
||||
|
|
||||
if impl(ghc >= 6.12.0) |
|
||||
ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2 |
|
||||
-fno-warn-unused-do-bind |
|
||||
else |
|
||||
ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2 |
|
@ -1,28 +0,0 @@ |
|||||
{-# LANGUAGE OverloadedStrings #-} |
|
||||
module Main where |
|
||||
|
|
||||
import Control.Applicative |
|
||||
import Snap.Core |
|
||||
import Snap.Util.FileServe |
|
||||
import Snap.Http.Server |
|
||||
import qualified Data.Text.IO as TIO (readFile) |
|
||||
import Data.Text |
|
||||
import qualified Data.HashMap.Strict as HM |
|
||||
import Text.Hamlet |
|
||||
|
|
||||
main :: IO () |
|
||||
main = quickHttpServe site |
|
||||
|
|
||||
site :: Snap () |
|
||||
site = |
|
||||
ifTop (writeBS "Hello, world! Hey Hey Hey") <|> |
|
||||
route [ ("foo", writeBS "bar") |
|
||||
, ("echo/:echoparam", echoHandler) |
|
||||
] <|> |
|
||||
dir "static" (serveDirectory ".") |
|
||||
|
|
||||
echoHandler :: Snap () |
|
||||
echoHandler = do |
|
||||
param <- getParam "echoparam" |
|
||||
maybe (writeBS "must specify echo/param in URL") |
|
||||
writeBS param |
|
@ -0,0 +1,18 @@ |
|||||
|
from json import dumps |
||||
|
|
||||
|
def comment(author, title, text): |
||||
|
return { |
||||
|
"title" : title, |
||||
|
"author" : author, |
||||
|
"text" : text |
||||
|
} |
||||
|
|
||||
|
|
||||
|
testcomments = { |
||||
|
1 : dumps( |
||||
|
[ |
||||
|
comment("Anonymous Coward", "Some comment?", "super duper awesome comment here"), |
||||
|
comment("Anonymous Coward 3", "Something? IDEK", "super duper worse comment here"), |
||||
|
comment("Anonymous Coward 2", "Some other comment?", "super duper dang terrible comment here") |
||||
|
]) |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
from functools import total_ordering |
@ -0,0 +1,154 @@ |
|||||
|
riot.tag2('bbutton', '<button class="btn rounded-button"> </button>', '', '', function(opts) { |
||||
|
}); |
||||
|
|
||||
|
riot.tag2('comment', '<div class="comment centered"> <div class="card"> <div class="card-header"> <h4 class="card-title">{title} by {author}</h4> </div> <div class="card-body comment-body"> {R.join(⁗ ⁗)(R.repeat(text, 20))} </div> </div> </div>', '', '', function(opts) { |
||||
|
}); |
||||
|
|
||||
|
riot.tag2('comments', '<div if="{loading}" class="loading comments-loader"> </div> <comment if="{!loading}" each="{comments}" data="{this}"></comment> <textarea onfocus="{clearplaceholder}" onblur="{checkplaceholder}" oninput="{echo}" __disabled="{disabled}" class="{⁗form-input comments centered ⁗ + maxed}" name="textarea" rows="10" cols="50" maxlength="{maxlength}"> {placeholder} </textarea> <div if="{warn}" class="toast toast-danger maxwarn centered"> <button onclick="{closewarning}" class="btn btn-clear float-right"> </button> You\'ve reached the max comment size </div>', '', '', function(opts) { |
||||
|
|
||||
|
comments = []; |
||||
|
maxlength = 700; |
||||
|
|
||||
|
placeholder = "Comment here!"; |
||||
|
focused = false; |
||||
|
maxed = false; |
||||
|
warn = false; |
||||
|
disabled = ""; |
||||
|
loading = true; |
||||
|
|
||||
|
this.clearplaceholder = function() { |
||||
|
if (!this.focused) { |
||||
|
this.update({ |
||||
|
"placeholder" : "", |
||||
|
"focused" : true |
||||
|
}) |
||||
|
} |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.checkplaceholder = function() { |
||||
|
if (this.textarea.value.trim().length == 0) { |
||||
|
this.update({ |
||||
|
"placeholder" : "Comment here!", |
||||
|
"focused" : false |
||||
|
}); |
||||
|
} |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.closewarning = function() { |
||||
|
this.update({"warn" : false}); |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.echo = function(ev) { |
||||
|
if (this.textarea.value.length >= maxlength) { |
||||
|
this.update({ |
||||
|
"maxed" : "maxinput", |
||||
|
"warn" : true |
||||
|
}); |
||||
|
} |
||||
|
else { |
||||
|
this.update({ |
||||
|
"maxed" : false, |
||||
|
"warn" : false |
||||
|
}); |
||||
|
window.setTimeout(this.closewarning, 5000); |
||||
|
} |
||||
|
}.bind(this) |
||||
|
|
||||
|
var self = this; |
||||
|
|
||||
|
this.getComments = function(pid) { |
||||
|
fetch("/comments/"+pid) |
||||
|
.then( |
||||
|
function(resp) { |
||||
|
return resp.text(); |
||||
|
}) |
||||
|
.then( |
||||
|
function(body) { |
||||
|
self.update( |
||||
|
{ |
||||
|
"comments" : JSON.parse(body), |
||||
|
"loading" : false |
||||
|
}); |
||||
|
}); |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.on("mount", |
||||
|
function() { |
||||
|
this.getComments(self.opts.pid); |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
riot.tag2('post', '<div class="postnav centered"> <button class="{⁗btn btn-primary ⁗ + (this.pid <= 1 ? ⁗disabled⁗ : ⁗ ⁗) + this.prevloading}" onclick="{prev}">Previous Post</button> <button class="{⁗btn btn-primary ⁗ + (this.nomore ? ⁗disabled⁗ : ⁗ ⁗) + this.nextloading}" onclick="{next}">Next Post</button> </div> <h4 class="post centered" if="{nomore}"> No More Posts! </h4> <div if="{!(loading || nomore)}" class="post centered"> <h4>{opts.title}</h4> <h5>By {opts.creator}</h5> <p class="post-content centered text-break">{content}</p> <div class="divider"></div> <comments pid="{pid}"> </comments> </div>', '', '', function(opts) { |
||||
|
var self = this; |
||||
|
|
||||
|
this.loading = false; |
||||
|
this.prevloading = ""; |
||||
|
this.nextloading = ""; |
||||
|
|
||||
|
this.nomore = false |
||||
|
this.pid = 1; |
||||
|
content = ""; |
||||
|
|
||||
|
this.prev = function() { |
||||
|
if (self.prevloading || self.nextloading) { |
||||
|
return; |
||||
|
} |
||||
|
self.prevloading = " loading"; |
||||
|
if (self.nomore) { |
||||
|
self.nomore = false; |
||||
|
} |
||||
|
if (self.pid > 1) { |
||||
|
self.pid--; |
||||
|
self.setPost(self.pid); |
||||
|
self.update(); |
||||
|
} |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.next = function() { |
||||
|
if (self.nextloading || self.prevloading) { |
||||
|
return; |
||||
|
} |
||||
|
self.nextloading = " loading"; |
||||
|
console.log(self.pid); |
||||
|
console.log(self.nomore); |
||||
|
if (!self.nomore) { |
||||
|
self.pid++; |
||||
|
self.setPost(self.pid); |
||||
|
self.update(); |
||||
|
} |
||||
|
}.bind(this) |
||||
|
|
||||
|
this.setPost = function(pid) { |
||||
|
self.update(); |
||||
|
self.loading = true; |
||||
|
fetch("/switchpost/"+pid) |
||||
|
.then( |
||||
|
function(resp) { |
||||
|
return resp.text(); |
||||
|
}) |
||||
|
.then( |
||||
|
function(body) { |
||||
|
if (body === "false") { |
||||
|
self.nomore = true; |
||||
|
route("/"); |
||||
|
self.update() |
||||
|
} |
||||
|
else { |
||||
|
self.content = R.join(" ")(R.repeat(body, 20)); |
||||
|
route("/"+pid); |
||||
|
} |
||||
|
|
||||
|
self.loading = false; |
||||
|
self.prevloading = ""; |
||||
|
self.nextloading = ""; |
||||
|
self.update(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
this.on("mount", function() { this.setPost(self.pid) }); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
riot.tag2('posts', '<yield></yield>', '', '', function(opts) { |
||||
|
}); |
File diff suppressed because one or more lines are too long
@ -0,0 +1,42 @@ |
|||||
|
{% block head %} |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
|
<header class="text-center nav navbar"> |
||||
|
<section class="centered page-top navbar-section"> |
||||
|
<h1 class="blog-title">blog</h1> |
||||
|
</section> |
||||
|
</header> |
||||
|
{% endblock %} |
||||
|
|
||||
|
<html> |
||||
|
<body> |
||||
|
{% block content %} |
||||
|
|
||||
|
<posts> |
||||
|
<post></post> |
||||
|
</posts> |
||||
|
<editor> |
||||
|
</editor> |
||||
|
|
||||
|
{% endblock %} |
||||
|
|
||||
|
<footer class="footer"> |
||||
|
</footer> |
||||
|
|
||||
|
{% block styles %} |
||||
|
|
||||
|
<link rel="stylesheet" href="/styles/spectre.min.css"> |
||||
|
<link rel="stylesheet" href="/styles/riotblog.min.css"> |
||||
|
|
||||
|
{% endblock %} |
||||
|
|
||||
|
{% block scripts %} |
||||
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js"></script> |
||||
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script> |
||||
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/riot/2.6.7/riot+compiler.min.js"></script> |
||||
|
<script type="text/javascript" src="//cdn.jsdelivr.net/riot-route/3.0.2/route.min.js"></script> |
||||
|
<script type="text/javascript" src="/scripts/tags.min.js"></script> |
||||
|
<script type="text/javascript" src="/scripts/riotblog.min.js"></script> |
||||
|
{% endblock %} |
||||
|
|
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,88 @@ |
|||||
|
#! /usr/bin/python3 |
||||
|
from functools import partial |
||||
|
|
||||
|
from flask import abort, Flask, render_template, flash, request, send_from_directory |
||||
|
from flask_appconfig import AppConfig |
||||
|
|
||||
|
from time import sleep |
||||
|
|
||||
|
from urllib.parse import unquote |
||||
|
from urllib.parse import quote, unquote |
||||
|
from json import dumps, loads |
||||
|
|
||||
|
from comment import testcomments |
||||
|
|
||||
|
from werkzeug.contrib.cache import MemcachedCache |
||||
|
cache = MemcachedCache(['127.0.0.1:11211']) |
||||
|
|
||||
|
import os |
||||
|
|
||||
|
def cacheit(key, thunk): |
||||
|
""" |
||||
|
Tries to find a cached version of ``key'' |
||||
|
If there is no cached version then it will |
||||
|
evaluate thunk (which must be a generator) |
||||
|
and cache that, then return the result |
||||
|
""" |
||||
|
cached = cache.get(quote(key)) |
||||
|
if cached is None: |
||||
|
result = list(thunk()) |
||||
|
cache.set(quote(key), result) |
||||
|
return result |
||||
|
return cached |
||||
|
|
||||
|
def NeverWhere(configfile=None): |
||||
|
|
||||
|
app = Flask(__name__) |
||||
|
app.config["TEMPLATES_AUTO_RELOAD"] = True |
||||
|
#def favicon(): |
||||
|
#return send_from_directory("/srv/http/goal/favicon.ico", |
||||
|
#'favicon.ico', mimetype='image/vnd.microsoft.icon') |
||||
|
|
||||
|
@app.route("/", methods=("GET", "POST")) |
||||
|
def index(): |
||||
|
print("matched index") |
||||
|
return render_template("index.html") |
||||
|
|
||||
|
@app.route("/scripts/<filename>", methods=("GET", "POST")) |
||||
|
def send_script(filename): |
||||
|
print("matched scripts route") |
||||
|
return send_from_directory("./scripts", filename) |
||||
|
|
||||
|
@app.route("/styles/<filename>", methods=("GET", "POST")) |
||||
|
def send_style(filename): |
||||
|
return send_from_directory("./styles", filename) |
||||
|
|
||||
|
@app.route("/switchpost/<pid>") |
||||
|
def switchPost(pid): |
||||
|
posts = { |
||||
|
"1" : "Post one is changed! ", |
||||
|
"2" : "Post two here and it's changed! " |
||||
|
} |
||||
|
return posts.get(pid, "false") |
||||
|
|
||||
|
|
||||
|
@app.route("/comments/<pid>") |
||||
|
def comments(pid): |
||||
|
sleep(5); |
||||
|
try: |
||||
|
return testcomments.get(int(pid), dumps([])) |
||||
|
except ValueError as e: |
||||
|
print(e) |
||||
|
return dumps([]) |
||||
|
|
||||
|
@app.route("/insert/<pid>") |
||||
|
def insert(pid): |
||||
|
print("inserting new post") |
||||
|
|
||||
|
@app.route("/<path:path>") |
||||
|
def page_not_found(path): |
||||
|
return "Custom failure message" |
||||
|
|
||||
|
app.run(debug=True) |
||||
|
return app |
||||
|
|
||||
|
app = NeverWhere() |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
NeverWhere("./appconfig").run(host="localhost", port=8001, debug=True) |
@ -1,7 +0,0 @@ |
|||||
flags: {} |
|
||||
extra-package-dbs: [] |
|
||||
packages: |
|
||||
- '.' |
|
||||
extra-deps: |
|
||||
- ginger-0.3.7.2 |
|
||||
resolver: lts-7.12 |
|
Loading…
Reference in new issue