Initial commit
This commit is contained in:
commit
a874a96592
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
node_modules/
|
||||
bin/*.exe
|
||||
site/
|
||||
blog/
|
||||
config/*.json
|
178
app.js
Normal file
178
app.js
Normal file
|
@ -0,0 +1,178 @@
|
|||
const http=require('http')
|
||||
const spawn=require('child_process').spawn
|
||||
const promisify=require('util').promisify
|
||||
const path=require('path')
|
||||
const url=require('url')
|
||||
const fs=require('fs')
|
||||
const mime=require('mime')
|
||||
|
||||
let _configObj=JSON.parse(fs.readFileSync("config/config.json"))
|
||||
const SOURCE_DIR=_configObj.source
|
||||
const ROOT_DIR=_configObj.dist
|
||||
const LISTEN_PORT=_configObj.port
|
||||
|
||||
async function RemoveSingleFile(filename) {
|
||||
try {
|
||||
let stats=await promisify(fs.stat)(filename)
|
||||
if(stats.isFile()) {
|
||||
console.log(`Deleting: ${filename}`)
|
||||
await promisify(fs.unlink)(filename)
|
||||
} else {
|
||||
await RemoveDirStep(filename)
|
||||
await promisify(fs.rmdir)(filename)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[Error] RemoveSingleFile: ${e.toString()}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function RemoveDirStep(dir) {
|
||||
try {
|
||||
let files=await promisify(fs.readdir)(dir)
|
||||
if(files && files.length>0) {
|
||||
let pArr=new Array
|
||||
files.forEach((val)=>{
|
||||
pArr.push(RemoveSingleFile(path.join(dir,val)))
|
||||
})
|
||||
return Promise.all(pArr)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[Error] RemoveDirStep: ${e.toString()}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function ClearSite() {
|
||||
console.log("Clearing site...")
|
||||
await RemoveDirStep(ROOT_DIR)
|
||||
console.log("[Done] Site cleaned.")
|
||||
}
|
||||
|
||||
async function GenerateSingle(val) {
|
||||
try {
|
||||
let stat=await promisify(fs.stat)(path.join(SOURCE_DIR,val))
|
||||
if(stat && stat.isFile()) {
|
||||
if(path.extname(val).toLowerCase()==".md") {
|
||||
return new Promise((resolve,reject)=>{
|
||||
console.log(`Generating: ${val}`)
|
||||
let child=spawn('bin/pandoc',['-f','markdown','-t','html',path.join(SOURCE_DIR,val),'-o',path.join(ROOT_DIR,path.dirname(val),path.basename(val,path.extname(val)) + '.html')])
|
||||
child.on('close',()=>{
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
console.log(`Copying: ${val}`)
|
||||
await promisify(fs.copy)(path.join(SOURCE_DIR,val),path.join(ROOT_DIR,val))
|
||||
}
|
||||
} else if(stat && stat.isDirectory()) {
|
||||
await promisify(fs.mkdir)(path.join(ROOT_DIR,val))
|
||||
await GenerateStep(val)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[Error] GenerateSingle: ${e.toString()}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function GenerateStep(dir) {
|
||||
try {
|
||||
let files=await promisify(fs.readdir)(path.join(SOURCE_DIR,dir))
|
||||
if(files && files.length>0) {
|
||||
let pArr=new Array
|
||||
files.forEach((val)=>{
|
||||
pArr.push(GenerateSingle(path.join(dir,val)))
|
||||
})
|
||||
await Promise.all(pArr)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[Error] GenerateStep: ${e.toString()}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function BuildSite() {
|
||||
console.log("Building site...")
|
||||
try {
|
||||
await GenerateStep("")
|
||||
} catch (e) {
|
||||
console.log(`[Error] BuildSite: ${e.toString()}`)
|
||||
}
|
||||
console.log("[Done] Site building done.")
|
||||
}
|
||||
|
||||
async function RebuildSite() {
|
||||
await ClearSite()
|
||||
await BuildSite()
|
||||
}
|
||||
|
||||
async function request_handler(req,res) {
|
||||
let obj=url.parse(req.url,true)
|
||||
if(req.method=="GET") {
|
||||
let normPath=path.normalize(obj.pathname)
|
||||
let localPath=path.join(ROOT_DIR,normPath)
|
||||
try {
|
||||
let stats=await promisify(fs.stat)(localPath)
|
||||
if(stats && stats.isFile()) {
|
||||
let mimeType=mime.getType(localPath)
|
||||
if(mimeType=="text/html") {
|
||||
res.setHeader('Content-Type',mimeType + ";charset=utf-8")
|
||||
} else {
|
||||
res.setHeader('Content-Type',mimeType)
|
||||
}
|
||||
fs.createReadStream(localPath).pipe(res)
|
||||
} else {
|
||||
let files=await promisify(fs.readdir)(localPath)
|
||||
res.writeHead(200,"OK")
|
||||
res.write(`
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
<title>Index of ${normPath}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Index of ${normPath}</h1>
|
||||
<table>
|
||||
`)
|
||||
let pArr=new Array
|
||||
files.forEach((val)=>{
|
||||
pArr.push(new Promise((resolve,reject)=>{
|
||||
fs.stat(path.join(localPath,val),(err,stats)=>{
|
||||
if(err) return reject(err)
|
||||
else if(!stats) return reject("no stats returned.")
|
||||
else {
|
||||
return resolve({
|
||||
name:val,
|
||||
isfile:stats.isFile()
|
||||
})
|
||||
}
|
||||
})
|
||||
}))
|
||||
})
|
||||
for(let i=0;i<pArr.length;i++) {
|
||||
let j=await pArr[i]
|
||||
if(j.isfile) {
|
||||
res.write(`<li><a href='${j.name}'>${path.basename(j.name,path.extname(j.name))}</a></li>`)
|
||||
} else {
|
||||
res.write(`<li>Directory <a href='${j.name}'>${path.basename(j.name,path.extname(j.name))}</a></li>`)
|
||||
}
|
||||
}
|
||||
res.write(`
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
res.end()
|
||||
}
|
||||
} catch (e) {
|
||||
res.writeHead(500,"Server error")
|
||||
res.end(`Error: ${e.toString()}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await RebuildSite()
|
||||
http.createServer(request_handler).listen(LISTEN_PORT)
|
||||
}
|
||||
|
||||
let _tmBefore=new Date()
|
||||
main().then(()=>{
|
||||
console.log(`Server started in ${(new Date()-_tmBefore)/1000}s.`)
|
||||
})
|
3
bin/readme.md
Normal file
3
bin/readme.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Binary files
|
||||
|
||||
Place `pandoc` executable binary file in this directory.
|
5
config/config.json.example
Normal file
5
config/config.json.example
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"source":"blog",
|
||||
"dist":"site",
|
||||
"port":12345
|
||||
}
|
21
package.json
Normal file
21
package.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "kblog",
|
||||
"version": "1.0.0",
|
||||
"description": "Kiritow's Blog Backend",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://kiritow.com:3000/Kiritow/kblog"
|
||||
},
|
||||
"keywords": [
|
||||
"blog"
|
||||
],
|
||||
"author": "Kiritow",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime": "^2.4.0"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user