From 118b8c549f07c07ffcb728ebd7674ed1efee7172 Mon Sep 17 00:00:00 2001 From: grant-kun Date: Thu, 10 Nov 2022 11:34:39 -0600 Subject: [PATCH] forums --- .gitignore | 3 +- package.json | 4 +- pages/forums.gemini | 8 +++ pages/index.gemini | 4 ++ readme.md | 7 ++- server.ts | 141 ++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 pages/forums.gemini diff --git a/.gitignore b/.gitignore index d9ce058..04d5ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ cert.pem key.pem node_modules git -package-lock.json \ No newline at end of file +package-lock.json +sql \ No newline at end of file diff --git a/package.json b/package.json index c65591e..d81e952 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "main":"server.ts", + "main": "server.ts", "scripts": { "start": "ts-node server.ts" }, @@ -7,6 +7,8 @@ "fs": "^0.0.1-security", "gemini-server": "^2.0.0", "git-parse": "^3.0.0", + "sequelize": "^6.25.5", + "sqlite3": "^5.1.2", "ts-node": "^10.9.1" }, "devDependencies": { diff --git a/pages/forums.gemini b/pages/forums.gemini new file mode 100644 index 0000000..3a42ff3 --- /dev/null +++ b/pages/forums.gemini @@ -0,0 +1,8 @@ +# forums + +=> gemini://{domain}/forums/submissive create + +## top forums + +{forums} + diff --git a/pages/index.gemini b/pages/index.gemini index c2dd899..5e78f74 100644 --- a/pages/index.gemini +++ b/pages/index.gemini @@ -2,8 +2,12 @@ i am grant:) a software engineer^^ +i love any lisp-esque languages/syntax, +and functional languages + => gemini://{domain}/git my git servers:) => gemini://{domain}/aboutme about me +=> gemini://{domain}/forums forums ## languages: diff --git a/readme.md b/readme.md index 74ac071..d6c00ad 100644 --- a/readme.md +++ b/readme.md @@ -1 +1,6 @@ -to generate keys : `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'` \ No newline at end of file +to generate keys : `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'` + +todo: +-create uid on thread creation, that can be used to edit/delete +-allow viewing of individual messages +-allow anyone to view database(and a parsed version) \ No newline at end of file diff --git a/server.ts b/server.ts index 4fb5697..9febddc 100644 --- a/server.ts +++ b/server.ts @@ -1,5 +1,6 @@ import { existsSync,readFileSync, writeFileSync,mkdirSync,unlinkSync,rmSync,readdirSync} from "fs"; import gemini, { Request, Response, TitanRequest, NextFunction } from "gemini-server"; +import { Sequelize, DataTypes } from "sequelize"; process.title = "gemini-server" const {gitToJs} = require("git-parse") const options = { @@ -13,7 +14,61 @@ mkdirSync("git") }catch(e){} const app = gemini(options); let git = readdirSync("git") +const sequelize = new Sequelize({ + dialect: 'sqlite', + storage: 'sql/forums.sqlite', + logging: false +}); +const forums = sequelize.define('forums', { + topic: { + type: DataTypes.STRING, + allowNull: false + }, + created: { + type: DataTypes.STRING, + allowNull: false + }, + thread:{ + type: DataTypes.STRING, + allowNull: false, + + } +}, {}); + //make sure it exists +(async()=>{ +sequelize.sync(); +/* +await sequelize.sync({force:true}); // clear table +let thread2 = await forums.create({topic:"test2",created:"time",thread:[]}) +thread2.set({ + topic:"test33", + thread:[{ + "hello":"world", + "main":"test4", + "comments":[] + },], +}) +thread2.save() +sequelize.sync({alter:true}) +*/ +})() +function datefmt (date:any, fstr:any, utc:any) { + utc = utc ? 'getUTC' : 'get'; + return fstr.replace (/%[YmdHMS]/g, function (m:any) { + switch (m) { + case '%Y': return date[utc + 'FullYear'] (); // no leading zeros required + case '%m': m = 1 + date[utc + 'Month'] (); break; + case '%d': m = date[utc + 'Date'] (); break; + case '%H': m = date[utc + 'Hours'] (); break; + case '%M': m = date[utc + 'Minutes'] (); break; + case '%S': m = date[utc + 'Seconds'] (); break; + default: return m.slice (1); // unknown code, remove % + } + // add leading zero if required + return ('0' + m).slice (-2); + }); +} app.use(async(_req: Request, res: Response) => { if(_req.url.pathname.includes('/git')){ let gitlist = '' @@ -147,7 +202,6 @@ app.use(async(_req: Request, res: Response) => { bb.splice(bb.indexOf(n),1) } } - console.log(bb) if(!(bb.length==2)){ bb.splice(bb.length-1,1) if(!bb.includes("source")){ @@ -161,7 +215,6 @@ app.use(async(_req: Request, res: Response) => { try{ let gitDir = readdirSync("."+x.join("/")) //let t = `=> gemini://${_req.url.host+x.join('/')} ${x.join('/')}\n\n` - console.log(`gemini://${_req.url.host}/${bb.join("/") }`) let t = `=> gemini://${_req.url.host}${_req.url.pathname} [d] .\n=> gemini://${_req.url.host}/${bb.join("/") } [d] ..\n` for(let i of gitDir){ try{ @@ -195,8 +248,73 @@ app.use(async(_req: Request, res: Response) => { } } - } else if(_req.url.pathname.includes('/forum')) { - + } else if(_req.url.pathname.includes('/forums')) { + if(_req.url.pathname=="/forums"){ + let a:any = Math.random() + let topics = await forums.findAll() + let top = '' + for(let topic of topics){ + top+=`=> gemini://${_req.url.host}/${_req.url.pathname}/${topic.getDataValue('id')} ${topic.getDataValue('topic')}\n` + } + + let t= readFileSync("./pages/forums.gemini").toString().replace(/{domain}/g,_req.url.host).replace(/{forums}/g,top) + writeFileSync("tmp/"+a+".gemini",t) + res.file("tmp/"+a+".gemini"); + unlinkSync("tmp/"+a+".gemini") + + } else if(_req.url.pathname=="/forums/submissive"){ + + + if(_req.query!=null){ + _req.query=_req.query+'' + _req.query=decodeURI(_req.query) + let thread = await forums.create({topic:_req.query,created:datefmt(new Date(),"%Y-%m-%d %H:%M:%S", true),thread:"[]"}) + thread.save() + sequelize.sync({alter:true}) + res.redirect(thread.getDataValue('id')+'') + return + } else { + res.input("forum name") + return + } + } else { + let foru = _req.url.pathname.split('/forums/')[1] + //console.log(foru) + + let all = await forums.findAll() + let id = parseInt(foru) + //for() + // // @ts-ignore + for(let a of all){ + if(a.getDataValue('id')==id){ + if(foru.split('/').length>=2){ + //extra command TwT + if(_req.query!=null){ + _req.query=_req.query+'' + _req.query=decodeURI(_req.query) + let parse = (JSON.parse(a.getDataValue('thread'))) + parse[parse.length]={m:_req.query,date:datefmt(new Date(),"%Y-%m-%d %H:%M:%S", true)} + a.setDataValue('thread',JSON.stringify(parse)) + a.save() + sequelize.sync({alter:true}) + viewForum(res,_req,a) + return + + } else { + res.input("comment") + return + } + } else { + viewForum(res,_req,a) + } + return + } + + + } + // !404 + } + }else { let a:any = Math.random() let t = readFileSync("./pages/404.gemini").toString().replace(/{domain}/g,_req.url.host) @@ -206,6 +324,19 @@ app.use(async(_req: Request, res: Response) => { } }); +function viewForum(res:any,_req:any,a:any){ + let z = Math.random() + //console.log(a.getDataValue('thread')) + let com = '' + for(let c of (JSON.parse(a.getDataValue('thread')))){ + com+=`\n### ${c.date}\n\n${c.m}\n__________` + } + let s = (`# ${a.dataValues.topic}\n\nlast - ${a.dataValues.createdAt}\nupdated - ${a.dataValues.updatedAt}\n\n=> gemini://${_req.url.host}${_req.url.pathname}/sub comment\ + \n\n## thread\n\n${com}`) + writeFileSync("tmp/"+z+".gemini",s) + res.file("tmp/"+z+".gemini"); + unlinkSync("tmp/"+z+".gemini") +} app.on("/", (_req: Request, res: Response) => { let a:any = Math.random() let t = readFileSync("./pages/index.gemini").toString().replace(/{domain}/g,_req.url.host) @@ -213,6 +344,7 @@ app.on("/", (_req: Request, res: Response) => { res.file("tmp/"+a+".gemini"); unlinkSync("tmp/"+a+".gemini") }); + app.on("/aboutme", (_req: Request, res: Response) => { let a:any = Math.random() let t = readFileSync("./pages/aboutme.gemini").toString().replace(/{domain}/g,_req.url.host) @@ -220,6 +352,7 @@ app.on("/aboutme", (_req: Request, res: Response) => { res.file("tmp/"+a+".gemini"); unlinkSync("tmp/"+a+".gemini") }); + app.listen(() => { console.log("Listening..."); });