Skip to content

Commit 96480f5

Browse files
committed
/code/id access
1 parent eeae578 commit 96480f5

File tree

2 files changed

+174
-7
lines changed

2 files changed

+174
-7
lines changed

bot.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// load discord.js and make a new client object
2-
const fs = require("fs");
32
const sqlite3 = require("sqlite3");
43
const Discord = require("discord.js");
54
const client = new Discord.Client();
@@ -59,6 +58,12 @@ function getLatestTimestamp(message)
5958
return message.editedTimestamp || message.createdTimestamp;
6059
}
6160

61+
// create a new entry in the database for this message
62+
function createEntry(message)
63+
{
64+
insertRow("Message", [message.id, getChannelName(message.channel), message.author.tag]);
65+
}
66+
6267
// get an appropriate name for a discord channel
6368
function getChannelName(channel)
6469
{
@@ -71,12 +76,6 @@ function getChannelName(channel)
7176
return `#${channel.name}`;
7277
}
7378

74-
// create a new entry in the database for this message
75-
function createEntry(message)
76-
{
77-
insertRow("Message", [message.id, getChannelName(message.channel), message.author.tag]);
78-
}
79-
8079
// add a revision to a message in the database
8180
function storeRevision(message)
8281
{

server.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// !! we should probably factor common code out into its own files?
2+
3+
// load express and make a new express app
4+
const sqlite3 = require("sqlite3");
5+
const express = require("express");
6+
const frontend = express();
7+
8+
// load config file
9+
const config = require("./config");
10+
11+
// the sqlite database to be opened
12+
var database;
13+
14+
// open the database and assert the existance of the tables
15+
// exit on failure
16+
function prepareDatabase()
17+
{
18+
// load the database from file
19+
database = new sqlite3.Database(config.dbFilename, sqlite3.OPEN_READONLY, e => {
20+
if(e) exit(`Error opening database: ${e}`);
21+
});
22+
};
23+
24+
// close the database if its open
25+
function closeDatabase()
26+
{
27+
if(database) database.close().catch(console.error);
28+
}
29+
30+
// get a row in a table
31+
function selectRow(table, whereColumn, equals, callback)
32+
{
33+
// is this safe?
34+
const sql = `SELECT * FROM ${table} WHERE ${whereColumn} = "${equals}"`;
35+
database.all(sql, [], (e, rows) => {
36+
if(e) exit(`Error querying database: ${e}`);
37+
else callback(rows);
38+
});
39+
}
40+
41+
// take a timestamp and format it
42+
function formatDate(timestamp)
43+
{
44+
return new Date(timestamp).toUTCString();
45+
}
46+
47+
// format a massege for code blocks
48+
function formatMessage(string)
49+
{
50+
const regex = /\`\`\`(([a-z]+)\n)?\n*([\s\S]*?)\n*\`\`\`/g;
51+
return string.replace(regex, (match, p1, p2, p3, offset, string) =>
52+
`<div class="code">${p2 ? `<span class="lang">#${p2}</span><br />` : ""}${p3}</div>`);
53+
}
54+
55+
// make html output for a message
56+
function makeMessagePage(message, revisions)
57+
{
58+
// just something for now, i don't know what we actually want to do
59+
const header = `
60+
<span class="field">Message ID:</span> <span class="value">${message.msgId}</span><br />
61+
<span class="field">Author:</span> <span class="value">${message.author}</span><br />
62+
<span class="field">Channel:</span> <span class="value">${message.channel}</span><br />
63+
`;
64+
const body = revisions.map(revision => `
65+
<span class="timestamp">${formatDate(revision.date)}</span>
66+
<div class="messageBody">${formatMessage(revision.fullMessage)}</div>
67+
`).join("<br /><br />");
68+
69+
return `
70+
<style>
71+
.wrapper
72+
{
73+
width: 400px;
74+
}
75+
.field
76+
{
77+
font-weight: bold;
78+
}
79+
.timestamp
80+
{
81+
font-size: small;
82+
font-style: italic;
83+
}
84+
.lang
85+
{
86+
font-style: italic;
87+
font-size: small;
88+
background-color: #999;
89+
color: #FFF;
90+
}
91+
.messageBody
92+
{
93+
color: #111;
94+
background-color: #EEE;
95+
border: solid 1px #CCC;
96+
border-radius: 3px;
97+
padding: 8px;
98+
}
99+
.code
100+
{
101+
font-family: monospace;
102+
color: #EEE;
103+
background-color: #555;
104+
border: solid 1px #222;
105+
border-radius: 3px;
106+
padding: 3px;
107+
}
108+
</style>
109+
110+
<div class="wrapper">
111+
${header}
112+
<br />
113+
${body}
114+
</div>
115+
`;
116+
}
117+
118+
// request a message by id
119+
frontend.get("/code/:id", (request, response) => {
120+
// select the message by id
121+
selectRow("Message", "msgId", request.params.id, rows => {
122+
if(rows.length)
123+
{
124+
// assuming there's only one message per id
125+
// as there should be
126+
const message = rows[0];
127+
128+
// select all the revisions of this message
129+
selectRow("Content", "associatedMsg", message.msgId, rows => {
130+
if(rows.length)
131+
{
132+
// should we sort in sqlite instead of here?
133+
// sort the revisions by timestamp
134+
const sorted = rows.sort((a, b) => a.date - b.date);
135+
136+
// what should we actually be displaying here?
137+
// a pretty display for the user?
138+
// or some raw information?
139+
// also, should we just show the most recent revision?
140+
response.send(makeMessagePage(message, rows));
141+
}
142+
else response.send("No revisions found!");
143+
});
144+
}
145+
else response.send("Message not found!");
146+
});
147+
});
148+
149+
// exit with error message
150+
function exit(message)
151+
{
152+
console.error(message);
153+
closeDatabase();
154+
process.exit(1);
155+
}
156+
157+
// start the server!
158+
function main()
159+
{
160+
// open the database
161+
prepareDatabase();
162+
163+
// start the server listening
164+
frontend.listen(config.port, () => console.log(`Server running on port ${config.port}!`));
165+
}
166+
167+
// go!
168+
main();

0 commit comments

Comments
 (0)