feat: setter and getter
This commit is contained in:
parent
ba3f5ae0b2
commit
c1fab17950
9 changed files with 1968 additions and 62 deletions
5
jest.config.js
Normal file
5
jest.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
|
@ -3,7 +3,6 @@
|
|||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.7.1",
|
||||
"dokdo": "^0.6.2",
|
||||
|
@ -12,16 +11,20 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@migan/prettier-config": "^1.0.0",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node": "^18.11.18",
|
||||
"jest": "^29.4.0",
|
||||
"prettier": "^2.8.3",
|
||||
"ts-jest": "^29.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsup": "^6.5.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "ts-node-esm src",
|
||||
"start": "node dist"
|
||||
"dev": "ts-node src",
|
||||
"start": "node dist",
|
||||
"test": "jest"
|
||||
},
|
||||
"prettier": "@migan/prettier-config"
|
||||
}
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
import sqlite3 from 'sqlite3'
|
||||
import type { Client, Message } from 'discord.js'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { join } from 'node:path'
|
||||
import Database from './Database'
|
||||
|
||||
type TrainType = 'muffinOnly' | 'All'
|
||||
|
||||
export default class ChatBot {
|
||||
private db = new sqlite3.Database(
|
||||
join(dirname(fileURLToPath(import.meta.url)), '..', 'db', 'db.sqlite3')
|
||||
)
|
||||
private trainType: TrainType = 'All'
|
||||
get trainType(): TrainType {
|
||||
return this._trainType
|
||||
}
|
||||
|
||||
set trainType(value: TrainType) {
|
||||
this._trainType = value
|
||||
}
|
||||
private db = new Database(join(__dirname, '..', 'db', 'db.sqlite3'))
|
||||
private _trainType: TrainType = 'All'
|
||||
public constructor() {}
|
||||
|
||||
public getResponse(msg: Message, sendMsg?: boolean): ChatBot {
|
||||
this.db.all(
|
||||
'SELECT text FROM statement;',
|
||||
(err, rows: Array<{ text: string }>) => {
|
||||
if (err) throw err
|
||||
this.db
|
||||
.get()
|
||||
.then(rows => {
|
||||
const a = msg.content.replace('머핀아', '')
|
||||
let r = rows[Math.floor(Math.random() * rows.length)].text
|
||||
if (!r) r = '살ㄹ려주세요'
|
||||
|
@ -26,22 +29,20 @@ export default class ChatBot {
|
|||
msg.channel.sendTyping()
|
||||
setTimeout(() => msg.channel.send(r), 1000)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
.catch(console.error)
|
||||
return this
|
||||
}
|
||||
|
||||
public train(client: Client): ChatBot {
|
||||
const sql = `INSERT INTO statement(text, persona) VALUES(?, ?);`
|
||||
client.on('messageCreate', msg => {
|
||||
if (msg.author.bot) return
|
||||
if (msg.author.id === '1026185545837191238') {
|
||||
this.db.run(
|
||||
`INSERT INTO statement(text, persona) VALUES('${msg.content}', 'muffin');`,
|
||||
err => {
|
||||
if (err) throw err
|
||||
this.getResponse(msg)
|
||||
}
|
||||
)
|
||||
this.db.run(sql, [msg.content, 'muffin'], err => {
|
||||
if (err) throw err
|
||||
this.getResponse(msg)
|
||||
})
|
||||
} else {
|
||||
if (this.trainType !== 'All') return
|
||||
if (!msg.content.startsWith('머핀아 ')) return
|
||||
|
@ -49,9 +50,8 @@ export default class ChatBot {
|
|||
.replaceAll("'", '')
|
||||
.slice(0, 50)
|
||||
.toLowerCase()}`
|
||||
const text = msg.content.replace('머핀아 ', '').replaceAll("'", '')
|
||||
const sql = `INSERT INTO statement(text, persona) VALUES('${text}', '${user}');`
|
||||
this.db.run(sql, err => {
|
||||
const text = msg.content.replace('머핀아 ', '')
|
||||
this.db.run(sql, [text, user], err => {
|
||||
if (err) throw err
|
||||
})
|
||||
}
|
||||
|
@ -59,18 +59,6 @@ export default class ChatBot {
|
|||
return this
|
||||
}
|
||||
|
||||
public changeTrainType(): TrainType {
|
||||
switch (this.trainType) {
|
||||
case 'muffinOnly':
|
||||
this.trainType = 'All'
|
||||
break
|
||||
case 'All':
|
||||
this.trainType = 'muffinOnly'
|
||||
break
|
||||
}
|
||||
return this.trainType
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.db.close()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ActivityType, Client, GatewayIntentBits, Message } from 'discord.js'
|
||||
import ChatBot from './ChatBot.js'
|
||||
import ChatBot from './ChatBot'
|
||||
import Dokdo from 'dokdo'
|
||||
import 'dotenv/config'
|
||||
|
||||
|
@ -56,8 +56,19 @@ export default class MuffinAI extends Client {
|
|||
this.destroy()
|
||||
} else if (msg.content.startsWith('멒힌아 모드변경')) {
|
||||
if (!isNotOwner(msg)) return
|
||||
const a = this.chatBot.changeTrainType()
|
||||
switch (a) {
|
||||
switch (this.chatBot.trainType) {
|
||||
case 'muffinOnly':
|
||||
this.chatBot.trainType = 'All'
|
||||
msg.channel.send('다음 모드로 변경: 전체 학습')
|
||||
break
|
||||
case 'All':
|
||||
this.chatBot.trainType = 'muffinOnly'
|
||||
msg.channel.send('다음 모드로 변경: 머핀만 학습')
|
||||
break
|
||||
}
|
||||
} else if (msg.content.startsWith('멒힌아 현재모드')) {
|
||||
if (!isNotOwner(msg)) return
|
||||
switch (this.chatBot.trainType) {
|
||||
case 'muffinOnly':
|
||||
msg.channel.send('현재 모드: 머핀만 학습')
|
||||
break
|
||||
|
|
42
src/Database.ts
Normal file
42
src/Database.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import sqlite3 from 'sqlite3'
|
||||
|
||||
interface ResponseData {
|
||||
id: number
|
||||
text: string
|
||||
search_text: string
|
||||
conversation: string
|
||||
created_at: string
|
||||
in_response_to: string | null
|
||||
search_in_response_to: string
|
||||
persona: string
|
||||
}
|
||||
|
||||
export default class Database {
|
||||
private db: sqlite3.Database
|
||||
public constructor(dbPath: string) {
|
||||
this.db = new sqlite3.Database(dbPath)
|
||||
}
|
||||
|
||||
public get(): Promise<ResponseData[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.serialize(() => {
|
||||
this.db.all('SELECT * FROM statement;', (err, rows) => {
|
||||
if (err) reject(err)
|
||||
resolve([...rows])
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public run(
|
||||
sql: string,
|
||||
params: any[],
|
||||
callBack: (err: Error | null) => void
|
||||
) {
|
||||
this.db.run(sql, params, callBack)
|
||||
}
|
||||
|
||||
public close() {
|
||||
this.db.close()
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
import('./Client.js').then(a => new a.default().login())
|
||||
import('./Client').then(a => new a.default().login())
|
||||
|
|
43
tests/Database.test.ts
Normal file
43
tests/Database.test.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import Database from '../src/Database'
|
||||
import sqlite3 from 'sqlite3'
|
||||
|
||||
describe('Test Database', () => {
|
||||
const DBPATH = `${__dirname}/../db/db.sqlite3`
|
||||
const db = new sqlite3.Database(DBPATH)
|
||||
const getData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all('SELECT * FROM statement;', async (err, rows) => {
|
||||
if (err) reject(err)
|
||||
resolve(rows)
|
||||
}).close()
|
||||
})
|
||||
}
|
||||
|
||||
test('Get rows', () => {
|
||||
getData().then(async rows =>
|
||||
expect(await new Database(DBPATH).get()).toEqual(rows)
|
||||
)
|
||||
})
|
||||
|
||||
test('Insert row', () => {
|
||||
const db = new Database(DBPATH)
|
||||
return db.get().then(async data1 => {
|
||||
db.run('INSERT INTO statement(text) VALUES(?)', ['TEST'], err => {
|
||||
if (err) throw err
|
||||
})
|
||||
const data2 = await db.get()
|
||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||
})
|
||||
})
|
||||
|
||||
test('Delete row', () => {
|
||||
const db = new Database(DBPATH)
|
||||
return db.get().then(async data1 => {
|
||||
db.run('DELETE FROM statement WHERE text=?;', ['TEST'], err => {
|
||||
if (err) throw err
|
||||
})
|
||||
const data2 = await db.get()
|
||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||
})
|
||||
})
|
||||
})
|
|
@ -26,10 +26,10 @@
|
|||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "Node16",
|
||||
"module": "commonjs",
|
||||
/* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "Node16" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "moduleResolution": "Node16" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
|
|
Loading…
Reference in a new issue