stats
This commit is contained in:
parent
06285689d7
commit
3a6c14961a
@ -1,6 +1,6 @@
|
|||||||
const Database = require("better-sqlite3")
|
import Database from "better-sqlite3"
|
||||||
|
|
||||||
const DB = Database(process.env.DB || "./db.sqlite3")
|
export const DB = Database(process.env.DB || "./db.sqlite3")
|
||||||
|
|
||||||
const migrations = [
|
const migrations = [
|
||||||
`
|
`
|
||||||
@ -17,6 +17,12 @@ CREATE TABLE inventory (
|
|||||||
obtained_at INTEGER NOT NULL,
|
obtained_at INTEGER NOT NULL,
|
||||||
quantity REAL NOT NULL
|
quantity REAL NOT NULL
|
||||||
);
|
);
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
CREATE TABLE stats (
|
||||||
|
stat TEXT PRIMARY KEY,
|
||||||
|
value BLOB NOT NULL
|
||||||
|
);
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -39,7 +45,7 @@ DB.pragma("foreign_keys = 1")
|
|||||||
|
|
||||||
const preparedStatements = new Map()
|
const preparedStatements = new Map()
|
||||||
|
|
||||||
const SQL = (strings, ...params) => {
|
export const SQL = (strings, ...params) => {
|
||||||
const sql = strings.join("?")
|
const sql = strings.join("?")
|
||||||
let stmt
|
let stmt
|
||||||
const cachedValue = preparedStatements.get(sql)
|
const cachedValue = preparedStatements.get(sql)
|
||||||
@ -56,5 +62,3 @@ const SQL = (strings, ...params) => {
|
|||||||
statement: stmt
|
statement: stmt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { DB, SQL }
|
|
@ -1,10 +1,11 @@
|
|||||||
const irc = require("irc-upd")
|
import irc from "irc-upd"
|
||||||
const childProcess = require("child_process")
|
import * as childProcess from "child_process"
|
||||||
const syllables = require("syllable")
|
import syllables from "syllable"
|
||||||
const R = require("ramda")
|
import * as R from "ramda"
|
||||||
const pluralize = require("pluralize")
|
import pluralize from "pluralize"
|
||||||
|
const { HyperLogLog } = await import("hyperlolo")
|
||||||
|
|
||||||
const { DB, SQL } = require("./db")
|
const { DB, SQL } = await import("./db.mjs")
|
||||||
|
|
||||||
var client = new irc.Client(process.argv[2] || "irc.osmarks.net", "testbot", {
|
var client = new irc.Client(process.argv[2] || "irc.osmarks.net", "testbot", {
|
||||||
channels: ["#a", "#botrobots", "#b"],
|
channels: ["#a", "#botrobots", "#b"],
|
||||||
@ -62,12 +63,12 @@ const PLURALS = [
|
|||||||
["Category:English irregular plurals", "Categories:English irregular plurals"],
|
["Category:English irregular plurals", "Categories:English irregular plurals"],
|
||||||
["enigma", "enigmas"],
|
["enigma", "enigmas"],
|
||||||
["radix", "radixes"],
|
["radix", "radixes"],
|
||||||
["water", "water"],
|
|
||||||
["funny", "funnies"],
|
["funny", "funnies"],
|
||||||
["octopus", "octopoda"],
|
["octopus", "octopoda"],
|
||||||
["the place in the world which is northernmost", "the places in the world which are northernmost"],
|
["the place in the world which is northernmost", "the places in the world which are northernmost"],
|
||||||
["datum", "data"],
|
["datum", "data"],
|
||||||
["testbot", "testbots"],
|
["testbot", "testbots"],
|
||||||
|
["notion of LLM use", "notions of LLM use"],
|
||||||
["oil of vitriol", "oil of vitriol"],
|
["oil of vitriol", "oil of vitriol"],
|
||||||
["noun phrase", "noun phrases"],
|
["noun phrase", "noun phrases"],
|
||||||
["information", "information"],
|
["information", "information"],
|
||||||
@ -76,6 +77,8 @@ const PLURALS = [
|
|||||||
["potions of cryoapiocity", "potions of cryoapiocity"],
|
["potions of cryoapiocity", "potions of cryoapiocity"],
|
||||||
["sulfuric acid", "sulfuric acid"],
|
["sulfuric acid", "sulfuric acid"],
|
||||||
["dollar", "dollars"],
|
["dollar", "dollars"],
|
||||||
|
["acid", "acid"],
|
||||||
|
["water", "water"],
|
||||||
]
|
]
|
||||||
const PLURALS_KEEP_SAME = [
|
const PLURALS_KEEP_SAME = [
|
||||||
"mice",
|
"mice",
|
||||||
@ -84,7 +87,8 @@ const PLURALS_KEEP_SAME = [
|
|||||||
"dodecahedra",
|
"dodecahedra",
|
||||||
"those things which must not be seen",
|
"those things which must not be seen",
|
||||||
"announcements",
|
"announcements",
|
||||||
"rotations"
|
"rotations",
|
||||||
|
"spider-based countermeasures"
|
||||||
]
|
]
|
||||||
const SINGULARS_KEEP_SAME = [
|
const SINGULARS_KEEP_SAME = [
|
||||||
"mouse",
|
"mouse",
|
||||||
@ -93,12 +97,13 @@ const SINGULARS_KEEP_SAME = [
|
|||||||
"dodecahedron",
|
"dodecahedron",
|
||||||
"that thing which must not be seen",
|
"that thing which must not be seen",
|
||||||
"announcement",
|
"announcement",
|
||||||
"rotation"
|
"rotation",
|
||||||
|
"spider-based countermeasure"
|
||||||
]
|
]
|
||||||
|
|
||||||
const spliceIn = (xs, ys) => {
|
const spliceIn = (xs, ys) => {
|
||||||
const locations = new Map(ys.map((y, i) => [Math.floor(xs.length * (i / ys.length)), y]))
|
const locations = new Map(ys.map((y, i) => [Math.floor(xs.length * (i / ys.length)), y]))
|
||||||
const out = xs.map((x, i) => (locations.get(i) ? [x, locations.get(i)] : [x]))
|
const out = xs.map((x, i) => (locations.get(i) ? [locations.get(i), x] : [x]))
|
||||||
const realOut = []
|
const realOut = []
|
||||||
for (const x of out) {
|
for (const x of out) {
|
||||||
for (const y of x) {
|
for (const y of x) {
|
||||||
@ -144,7 +149,17 @@ client.addListener("message", async (nick, channel, message, ev) => {
|
|||||||
nick = e[1]
|
nick = e[1]
|
||||||
message = e[2]
|
message = e[2]
|
||||||
}
|
}
|
||||||
|
const allStatsRaw = SQL`SELECT * FROM stats`.all().map(x => [x.stat, x.value])
|
||||||
|
const origStats = new Map(allStatsRaw)
|
||||||
|
const allStats = new Map(allStatsRaw)
|
||||||
|
allStats.set("messages", (allStats.get("messages") ?? 0) + 1)
|
||||||
const res = /^([A-Za-z0-9_-]+)[:, ]*([A-Za-z0-9_-]+) *(.*)$/.exec(message)
|
const res = /^([A-Za-z0-9_-]+)[:, ]*([A-Za-z0-9_-]+) *(.*)$/.exec(message)
|
||||||
|
const uniqueUsersCounter = allStats.get("users") ? HyperLogLog.deserialize(allStats.get("users")) : new HyperLogLog({ hasherId: "jenkins32", precision: 5 })
|
||||||
|
uniqueUsersCounter.add(nick)
|
||||||
|
allStats.set("users", uniqueUsersCounter.serialize())
|
||||||
|
const uniqueMessagesCounter = allStats.get("uniqueMessages") ? HyperLogLog.deserialize(allStats.get("uniqueMessages")) : new HyperLogLog({ hasherId: "jenkins32", precision: 5 })
|
||||||
|
uniqueMessagesCounter.add(message)
|
||||||
|
allStats.set("uniqueMessages", uniqueMessagesCounter.serialize())
|
||||||
if (res) {
|
if (res) {
|
||||||
let [_, tnick, cmd, args] = res
|
let [_, tnick, cmd, args] = res
|
||||||
tnick = tnick.toLowerCase()
|
tnick = tnick.toLowerCase()
|
||||||
@ -152,21 +167,23 @@ client.addListener("message", async (nick, channel, message, ev) => {
|
|||||||
cmd = cmd.toLowerCase()
|
cmd = cmd.toLowerCase()
|
||||||
if (tnick === client.nick) {
|
if (tnick === client.nick) {
|
||||||
console.log(nick, cmd, channel)
|
console.log(nick, cmd, channel)
|
||||||
|
allStats.set("commands", (allStats.get("commands") ?? 0) + 1)
|
||||||
if (cmd === "starch") {
|
if (cmd === "starch") {
|
||||||
client.say(channel, `starch exists (${Math.random() * 20 + 80}% confidence).`)
|
client.say(channel, `Starch exists (${Math.random() * 20 + 80}% confidence).`)
|
||||||
} else if (cmd === "stats") {
|
} else if (cmd === "stats") {
|
||||||
client.say(channel, "haha no")
|
client.say(channel, `${allStats.get("commands")} run, ${allStats.get("messages")} messages seen, about ${Math.floor(uniqueUsersCounter.count())} nicks seen, about ${Math.floor(uniqueMessagesCounter.count())} unique messages seen.`)
|
||||||
} else if (cmd === "help") {
|
} else if (cmd === "help") {
|
||||||
client.say(channel, "nobody can help you now")
|
client.say(channel, "Nobody can help you now.")
|
||||||
} else if (cmd === "fortune") {
|
} else if (cmd === "fortune") {
|
||||||
childProcess.exec("fortune", (err, out) => {
|
childProcess.exec("fortune", (err, out) => {
|
||||||
if (err) { return console.warn(err) }
|
if (err) { return console.warn(err) }
|
||||||
client.say(channel, out)
|
client.say(channel, out)
|
||||||
})
|
})
|
||||||
} else if (cmd === "cat") {
|
} else if (cmd === "cat") {
|
||||||
client.say(channel, "meow")
|
client.say(channel, "Meow.")
|
||||||
} else if (cmd === "servers") {
|
} else if (cmd === "servers") {
|
||||||
scanlinks().then(links => client.say(channel, links.map(x => `${x[1]}: ${/^[0-9]+ (.*)$/.exec(x[3])[1]}`).join("\n")))
|
const links = await scanlinks()
|
||||||
|
client.say(channel, links.map(x => `${x[1]}: ${/^[0-9]+ (.*)$/.exec(x[3])[1]}`).join("\n"))
|
||||||
} else if (cmd === "take" || cmd === "have") {
|
} else if (cmd === "take" || cmd === "have") {
|
||||||
const things = args.split(/(,| and )/).map(x => x.trim().replace(",", "").replace(/^(an?|the) /, "")).filter(x => x !== "" && x !== "and")
|
const things = args.split(/(,| and )/).map(x => x.trim().replace(",", "").replace(/^(an?|the) /, "")).filter(x => x !== "" && x !== "and")
|
||||||
for (let thing of things) {
|
for (let thing of things) {
|
||||||
@ -199,7 +216,7 @@ client.addListener("message", async (nick, channel, message, ev) => {
|
|||||||
const inv = SQL`SELECT * FROM inventory ORDER BY obtained_at DESC LIMIT 10`.all()
|
const inv = SQL`SELECT * FROM inventory ORDER BY obtained_at DESC LIMIT 10`.all()
|
||||||
client.say(channel, inv.map(renderItem).join("\n"))
|
client.say(channel, inv.map(renderItem).join("\n"))
|
||||||
} else if (cmd === "deploy") {
|
} else if (cmd === "deploy") {
|
||||||
client.say(channel, `Deploying ${args}`)
|
client.say(channel, `Deploying ${args}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,10 +225,18 @@ client.addListener("message", async (nick, channel, message, ev) => {
|
|||||||
sylhist = R.takeLast(3, R.append(syllables(messageContent), sylhist))
|
sylhist = R.takeLast(3, R.append(syllables(messageContent), sylhist))
|
||||||
mhist = R.takeLast(50, R.append(messageContent, mhist))
|
mhist = R.takeLast(50, R.append(messageContent, mhist))
|
||||||
if (R.equals(sylhist, [5, 7, 5])) {
|
if (R.equals(sylhist, [5, 7, 5])) {
|
||||||
client.say(channel, "haiku detected!")
|
client.say(channel, "Haiku detected!")
|
||||||
logEv("haiku", R.takeLast(3, mhist).join("\n"))
|
logEv("haiku", R.takeLast(3, mhist).join("\n"))
|
||||||
}
|
}
|
||||||
console.log(sylhist)
|
console.log(sylhist)
|
||||||
|
|
||||||
|
DB.transaction(() => {
|
||||||
|
for (const [k, v] of allStats) {
|
||||||
|
if (origStats.get(k) !== v) {
|
||||||
|
SQL`INSERT OR REPLACE INTO stats VALUES (${k}, ${v})`.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
})
|
})
|
||||||
|
|
||||||
client.addListener("raw", ev => {
|
client.addListener("raw", ev => {
|
Loading…
x
Reference in New Issue
Block a user