23 changed files with 221 additions and 452 deletions
@ -1,6 +1,9 @@ |
|||||
|
*.sw* |
||||
*.pyc |
*.pyc |
||||
*.log |
.vim-session |
||||
*.scssc |
*~ |
||||
*.swp |
venv |
||||
*.bak |
build |
||||
*venv* |
node_modules |
||||
|
.sass_cache/* |
||||
|
deploy.sh |
||||
|
Binary file not shown.
Binary file not shown.
@ -1,59 +0,0 @@ |
|||||
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() |
|
File diff suppressed because one or more lines are too long
@ -1,154 +0,0 @@ |
|||||
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("/blog/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}">Last One</button> <button class="{⁗btn btn-primary ⁗ + (this.nomore ? ⁗disabled⁗ : ⁗ ⁗) + this.nextloading}" onclick="{next}">Next One</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("/blog/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) { |
|
||||
}); |
|
@ -0,0 +1,34 @@ |
|||||
|
{ |
||||
|
"name": "riotblog", |
||||
|
"version": "1.0.0", |
||||
|
"description": "Riot Blog", |
||||
|
"main": "src/scripts/riotblog.js", |
||||
|
"scripts": { |
||||
|
"test": "echo \"Error: no test specified\" && exit 1", |
||||
|
"build": "rollup src/scripts/riotblog.js" |
||||
|
}, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/nisstyre56/riotblog.git" |
||||
|
}, |
||||
|
"author": "Wesley Kerfoot", |
||||
|
"license": "AGPL-3.0", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/nisstyre56/riotblog/issues" |
||||
|
}, |
||||
|
"homepage": "https://github.com/nisstyre56/riotblog#readme", |
||||
|
"devDependencies": { |
||||
|
"ramda": "^0.23.0", |
||||
|
"riot": "^3.3.1", |
||||
|
"riot-route": "^3.1.0", |
||||
|
"rollup": "^0.41.4", |
||||
|
"rollup-plugin-buble": "^0.15.0", |
||||
|
"rollup-plugin-commonjs": "^7.0.0", |
||||
|
"rollup-plugin-node-resolve": "^2.0.0", |
||||
|
"rollup-plugin-riot": "^1.1.0", |
||||
|
"whatwg-fetch": "^2.0.2" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"whatwg-fetch": "^2.0.2" |
||||
|
} |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
import riot from 'rollup-plugin-riot' |
||||
|
import nodeResolve from 'rollup-plugin-node-resolve' |
||||
|
import commonjs from 'rollup-plugin-commonjs' |
||||
|
import buble from 'rollup-plugin-buble' |
||||
|
|
||||
|
export default { |
||||
|
entry: 'src/scripts/riotblog.js', |
||||
|
dest: 'build/bundle.js', |
||||
|
plugins: [ |
||||
|
riot(), |
||||
|
nodeResolve({ jsnext: true }), |
||||
|
commonjs(), |
||||
|
buble() |
||||
|
], |
||||
|
format: 'iife' |
||||
|
} |
@ -1,7 +1,15 @@ |
|||||
|
import riot from 'riot'; |
||||
|
import './comments.tag'; |
||||
|
import './comment.tag'; |
||||
|
import './bbutton.tag'; |
||||
|
import './post.tag'; |
||||
|
import './posts.tag'; |
||||
|
|
||||
riot.mount("post", |
riot.mount("post", |
||||
{ |
{ |
||||
"creator" : "wes", |
"creator" : "wes", |
||||
"title" : "A cool post here" |
"title" : "A cool post here" |
||||
}); |
}); |
||||
|
|
||||
|
riot.mount("comments"); |
||||
riot.mount("bbutton"); |
riot.mount("bbutton"); |
||||
|
@ -1,154 +0,0 @@ |
|||||
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) { |
|
||||
}); |
|
@ -1,51 +1,83 @@ |
|||||
.post-text, .blog-title, .post, .postnav { |
.post-text, .blog-title, .post, .postnav { |
||||
text-align: center; } |
text-align: center; |
||||
|
} |
||||
|
|
||||
.post-content { |
.post-content { |
||||
max-width: 50%; |
max-width: 50%; |
||||
text-align: justify; |
text-align: justify; |
||||
font-size: 1.5em; } |
font-size: 1.5em; |
||||
|
} |
||||
|
|
||||
@media (max-width: 700px) { |
@media (max-width: 700px) { |
||||
.post-content { |
.post-content { |
||||
max-width: 70%; } } |
max-width: 70%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@media (max-width: 500px) { |
@media (max-width: 500px) { |
||||
.post-content { |
.post-content { |
||||
max-width: 90%; } } |
max-width: 90%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
.comment-block, .comments, .maxwarn { |
.comment-block, .comments, .maxwarn { |
||||
max-width: 30%; } |
max-width: 30%; |
||||
|
} |
||||
|
|
||||
@media (max-width: 700px) { |
@media (max-width: 700px) { |
||||
.comment-block, .comments, .maxwarn { |
.comment-block, .comments, .maxwarn { |
||||
max-width: 50%; } } |
max-width: 50%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@media (max-width: 500px) { |
@media (max-width: 500px) { |
||||
.comment-block, .comments, .maxwarn { |
.comment-block, .comments, .maxwarn { |
||||
max-width: 70%; } } |
max-width: 70%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
.comments { |
.comments { |
||||
margin-top: 5%; } |
margin-top: 5%; |
||||
|
} |
||||
|
|
||||
.comment { |
.comment { |
||||
margin-top: 2%; |
margin-top: 2%; |
||||
max-width: 40%; } |
max-width: 40%; |
||||
|
} |
||||
|
|
||||
@media (max-width: 700px) { |
@media (max-width: 700px) { |
||||
.comment { |
.comment { |
||||
max-width: 65%; } } |
max-width: 65%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@media (max-width: 500px) { |
@media (max-width: 500px) { |
||||
.comment { |
.comment { |
||||
max-width: 85%; } } |
max-width: 85%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
.comments-loader { |
.comments-loader { |
||||
margin-top: 2%; } |
margin-top: 2%; |
||||
|
} |
||||
|
|
||||
.comment-body { |
.comment-body { |
||||
margin-left: 10px; |
margin-left: 10px; |
||||
margin-right: 10px; } |
margin-right: 10px; |
||||
|
} |
||||
|
|
||||
.rounded-button { |
.rounded-button { |
||||
border-radius: 13px; } |
border-radius: 13px; |
||||
|
} |
||||
|
|
||||
.maxinput { |
.maxinput { |
||||
background-color: grey; } |
background-color: grey; |
||||
|
} |
||||
|
|
||||
.maxwarn { |
.maxwarn { |
||||
margin-top: 15px; } |
margin-top: 15px; |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
margin-top: 10%; |
||||
|
} |
||||
|
@ -0,0 +1,39 @@ |
|||||
|
{% 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">nowhere</h1> |
||||
|
</section> |
||||
|
</header> |
||||
|
{% endblock %} |
||||
|
|
||||
|
<html> |
||||
|
<body> |
||||
|
{% block content %} |
||||
|
|
||||
|
<posteditor> |
||||
|
</posteditor> |
||||
|
|
||||
|
{% endblock %} |
||||
|
|
||||
|
<footer class="footer"> |
||||
|
</footer> |
||||
|
|
||||
|
{% block styles %} |
||||
|
|
||||
|
<link rel="stylesheet" href="/blog/styles/spectre.min.css"> |
||||
|
<link rel="stylesheet" href="/blog/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="/blog/scripts/tags.min.js"></script> |
||||
|
<script type="text/javascript" src="/blog/scripts/riotblog.min.js"></script> |
||||
|
{% endblock %} |
||||
|
|
||||
|
</body> |
||||
|
</html> |
Loading…
Reference in new issue