-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
151 lines (114 loc) · 3.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"use strict"
const DATABASENAME = "data.sqlite"
const inPutFileName = "./authedId.json" //読み込みファイルの名前
const baseUrl = 'https://mstdn.tamag.org'
const sqlite3 = require('sqlite3').verbose()
const db = new sqlite3.Database(DATABASENAME)
const Mastodon = require("mastodon-api")
const fs = require("fs").promises
const MeCab = new require('mecab-async')
const mecab = new MeCab()
const cron = require('node-cron')
let M
//main
const main = async()=>{
//アクセストークンの読み込み
const input = await fs.readFile(inPutFileName, "utf-8")
.catch((err)=>console.error(err))
const id_data = JSON.parse(input)
const info = {
access_token:id_data.accessToken,
timeout_ms: 60 * 1000,
api_url: `${baseUrl}/api/v1/`,
}
M = new Mastodon(info)
//購読を開始
const listener = M.stream('streaming/public/local')
listener.on('message', handleToot)
listener.on('error', err => console.error(err))
cron.schedule('*/30 * * * *', toot)
}
const handleToot = async(msg)=>{
if(!msg.data.content){return}
//成型(難しい!!)
const content = await msg.data.content
.replace(/(<("[^"]*"|'[^']*'|[^'">])*>)/g,"")
.replace(/(http|https):\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?/g,"")
const words = await mecabWakachi(content)
.catch((err)=>console.error(err))
console.log(words)
let tmpWord = ""
for(let nodeNum=0; nodeNum<words.length; nodeNum++){
const isEndNode = nodeNum>=words.length
await insertWord("insert into node values(?, ?, ?, ?, ?)"
,[nodeNum, tmpWord, words[nodeNum], msg.data.id, isEndNode], )
.catch((err)=>console.error(err))
tmpWord = words[nodeNum]
}
}
const toot = async function(){
let result
do{
result = await createToot()
}while(!result)
console.log(result)
M.post('statuses', {status:result}, function (err, data, res) {
if (!err)
console.log(res)
})
}
const createToot = async function(){
const head = await getWord('select * from node where nodeNum=0 order by random() limit 1')
.catch(err=>console.error(err))
if(!head){return "エラー:トゥートぅーがないよ!"}
let result = ""
let content = " "
let word = head.word2
let nodeNum = 0
while(true){
const sql = `select * from node where nodeNum>=${nodeNum} and word1="${word}" order by random() limit 1;`
content = await getWord(sql)
.catch(err=>console.error(err))
if(!content){return "エラー:文章の生成に失敗したよ"}
//次回はwordでサーチする
word = content.word2
//word1を追加する
result += content.word1
//次は自身より大きいnodeNumで検索する
nodeNum = content.nodeNum
//終端のnodeであればword2を追加して終了
if(content.isEndNode){
result += content.word2
break
}
}
return result
}
//windowsはこれないとうごかないっぽい
//コマンドが通るようにしている
if(process.platform === 'win32'){
mecab._shellCommand = function(str){
return 'echo '+ str + ' |' + this.command
}
}
//wakachiPromise化
const mecabWakachi = (str) => new Promise((resolve,reject)=>{
mecab.wakachi(str,(err,result)=>{
if(err){reject(err)}
resolve(result)
})
})
//DBをやることやる
const insertWord = (sql,arg) => new Promise((resolve, reject)=>{
db.run(sql,arg,(err)=>{
if(err){reject()}
resolve()
})
})
const getWord = (sql) => new Promise((resolve, reject)=>{
db.get(sql, (error, row) => {
if(error){reject()}
resolve(row)
})
})
main()