動くようにした

This commit is contained in:
mattyatea 2023-01-28 12:40:31 +09:00
parent 658f7b4451
commit 4974e52112
24 changed files with 298 additions and 133 deletions

View File

@ -17,9 +17,9 @@ RUN if [ $enable_mecab -ne 0 ]; then apt-get update \
&& echo "dicdir = /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/" > /etc/mecabrc \ && echo "dicdir = /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/" > /etc/mecabrc \
&& apt-get purge git make curl xz-utils file -y; fi && apt-get purge git make curl xz-utils file -y; fi
COPY ../NullcatChan-old /nullcat-chan COPY . /NullcatChan
WORKDIR /nullcat-chan WORKDIR /NullcatChan
RUN npm install && npm run build RUN npm install && npm run build
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]

View File

@ -3,7 +3,7 @@ services:
app: app:
build: build:
dockerfile: Dockerfile_production dockerfile: Dockerfile_production
context: ../NullcatChan-old context: ../NullcatChan
args: args:
- enable_mecab=1 - enable_mecab=1
volumes: volumes:

View File

@ -2,8 +2,8 @@
"version": "2.1.0", "version": "2.1.0",
"main": "./built/index.js", "main": "./built/index.js",
"scripts": { "scripts": {
"docker:dev": "cross-env DOCKER_ENV=development docker-compose -f docker-compose.yml -f docker-compose_development.yml up -d --build && docker-compose logs -f", "docker:dev": "cross-env DOCKER_ENV=development docker compose -f docker-compose.yml -f docker-compose_development.yml up -d --build && docker compose logs -f",
"docker": "cross-env DOCKER_ENV=production docker-compose up -d --build && docker-compose logs -f", "docker": "cross-env DOCKER_ENV=production docker compose up -d --build && docker compose logs -f",
"dev": "cross-env NODE_ENV=development node ./built", "dev": "cross-env NODE_ENV=development node ./built",
"start": "cross-env NODE_ENV=production node ./built", "start": "cross-env NODE_ENV=production node ./built",
"build": "tsc", "build": "tsc",
@ -25,7 +25,7 @@
"@types/ws": "7.4.6", "@types/ws": "7.4.6",
"accurate-interval": "1.0.9", "accurate-interval": "1.0.9",
"autobind-decorator": "2.4.0", "autobind-decorator": "2.4.0",
"canvas": "2.8.0", "canvas": "2.11.0",
"chalk": "4.1.1", "chalk": "4.1.1",
"cjp": "1.2.3", "cjp": "1.2.3",
"gomamayo-js": "0.2.1", "gomamayo-js": "0.2.1",

View File

@ -1,8 +1,8 @@
import { User } from "./misskey/user" import { User } from "./misskey/user"
import IModule from "../../NullcatChan-old/src/module" import IModule from "../../NullcatChan/src/module"
import NullcatChan from "../../NullcatChan-old/src/nullcat-chan" import NullcatChan from "../../NullcatChan/src/nullcat-chan"
import getDate from "../../NullcatChan-old/src/utils/get-date" import getDate from "../../NullcatChan/src/utils/get-date"
import { genItem } from "../../NullcatChan-old/src/vocabulary" import { genItem } from "../../NullcatChan/src/vocabulary"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
export type FriendDoc = { export type FriendDoc = {

View File

@ -1,109 +1,107 @@
// Nullcat chan! bootstrapper // Nullcat chan! bootstrapper
import * as chalk from "chalk" import * as chalk from "chalk"
import "module-alias/register" import "module-alias/register"
import * as request from "request-promise-native" import * as request from "request-promise-native"
import config from "./config" import config from "./config"
import BirthdayModule from "../../NullcatChan-old/src/modules/birthday" import BirthdayModule from "../../NullcatChan/src/modules/birthday"
import CoreModule from "../../NullcatChan-old/src/modules/core" import CoreModule from "../../NullcatChan/src/modules/core"
import EmojiReactModule from "../../NullcatChan-old/src/modules/emoji-react" import EmojiReactModule from "../../NullcatChan/src/modules/emoji-react"
import FeelingModule from "../../NullcatChan-old/src/modules/feeling" import FeelingModule from "../../NullcatChan/src/modules/feeling"
import FollowModule from "../../NullcatChan-old/src/modules/follow" import FollowModule from "../../NullcatChan/src/modules/follow"
import FortuneModule from "../../NullcatChan-old/src/modules/fortune" import FortuneModule from "../../NullcatChan/src/modules/fortune"
import GitHubStatusModule from "../../NullcatChan-old/src/modules/github-status" import GitHubStatusModule from "../../NullcatChan/src/modules/github-status"
import CloudflareStatus from "../../NullcatChan-old/src/modules/cloudflare-status"; import CloudflareStatus from "../../NullcatChan/src/modules/cloudflare-status";
import GomamayoModule from "../../NullcatChan-old/src/modules/gomamayo" import GomamayoModule from "../../NullcatChan/src/modules/gomamayo"
import JihouModule from "../../NullcatChan-old/src/modules/jihou" import JihouModule from "../../NullcatChan/src/modules/jihou"
import KeywordModule from "../../NullcatChan-old/src/modules/keyword" import KeywordModule from "../../NullcatChan/src/modules/keyword"
import KiatsuModule from "../../NullcatChan-old/src/modules/kiatsu" import KiatsuModule from "../../NullcatChan/src/modules/kiatsu"
import NotingModule from "../../NullcatChan-old/src/modules/noting" import NotingModule from "../../NullcatChan/src/modules/noting"
import PingModule from "../../NullcatChan-old/src/modules/ping" import PingModule from "../../NullcatChan/src/modules/ping"
import ReminderModule from "../../NullcatChan-old/src/modules/reminder" import ReminderModule from "../../NullcatChan/src/modules/reminder"
import RoguboModule from "../../NullcatChan-old/src/modules/rogubo" import ServerModule from "../../NullcatChan/src/modules/server"
import ServerModule from "../../NullcatChan-old/src/modules/server" import SleepReportModule from "../../NullcatChan/src/modules/sleep-report"
import SleepReportModule from "../../NullcatChan-old/src/modules/sleep-report" import TalkModule from "../../NullcatChan/src/modules/talk"
import TalkModule from "../../NullcatChan-old/src/modules/talk" import TimerModule from "../../NullcatChan/src/modules/timer"
import TimerModule from "../../NullcatChan-old/src/modules/timer" import TraceMoeModule from "../../NullcatChan/src/modules/trace-moe"
import TraceMoeModule from "../../NullcatChan-old/src/modules/trace-moe" import ValentineModule from "../../NullcatChan/src/modules/valentine"
import ValentineModule from "../../NullcatChan-old/src/modules/valentine" import WhatModule from "../../NullcatChan/src/modules/what"
import WhatModule from "../../NullcatChan-old/src/modules/what" import YarukotoModule from "../../NullcatChan/src/modules/yarukoto"
import YarukotoModule from "../../NullcatChan-old/src/modules/yarukoto" import NullcatChan from "../../NullcatChan/src/nullcat-chan"
import NullcatChan from "../../NullcatChan-old/src/nullcat-chan" import _log from "../../NullcatChan/src/utils/log"
import _log from "../../NullcatChan-old/src/utils/log" import ShellGeiModule from "../../NullcatChan/src/modules/shellgei"
import ShellGeiModule from "../../NullcatChan-old/src/modules/shellgei" import SversionModule from "../../NullcatChan/src/modules/version"
import SversionModule from "../../NullcatChan-old/src/modules/Sversion" import AyashiiModule from "../../NullcatChan/src/modules/ayashii"
import AyashiiModule from "../../NullcatChan-old/src/modules/ayashii"
const promiseRetry = require("promise-retry")
const promiseRetry = require("promise-retry")
const pkg = require("../../NullcatChan/package.json")
const pkg = require("../../NullcatChan-old/package.json")
console.log(" _ __ ____ __ ________ __ ")
console.log(" _ __ ____ __ ________ __ ") console.log(" / | / /_ __/ / /________ _/ /_/ ____/ /_ ____ _____ / / ")
console.log(" / | / /_ __/ / /________ _/ /_/ ____/ /_ ____ _____ / / ") console.log(" / |/ / / / / / / ___/ __ `/ __/ / / __ \\/ __ `/ __ \\/ / ")
console.log(" / |/ / / / / / / ___/ __ `/ __/ / / __ \\/ __ `/ __ \\/ / ") console.log(" / /| / /_/ / / / /__/ /_/ / /_/ /___/ / / / /_/ / / / /_/ ")
console.log(" / /| / /_/ / / / /__/ /_/ / /_/ /___/ / / / /_/ / / / /_/ ") console.log("/_/ |_/\\__,_/_/_/\\___/\\__,_/\\__/\\____/_/ /_/\\__,_/_/ /_(_)\n")
console.log("/_/ |_/\\__,_/_/_/\\___/\\__,_/\\__/\\____/_/ /_/\\__,_/_/ /_(_)\n")
function log(msg: string): void {
function log(msg: string): void { _log(`[Boot]: ${msg}`)
_log(`[Boot]: ${msg}`) }
}
log(chalk.bold(`Nullcat chan! v${pkg._v}`))
log(chalk.bold(`Nullcat chan! v${pkg._v}`))
promiseRetry(
promiseRetry( (retry) => {
(retry) => { log(`Account fetching... ${chalk.gray(config.host)}`)
log(`Account fetching... ${chalk.gray(config.host)}`)
// アカウントをフェッチ
// アカウントをフェッチ return request
return request .post(`${config.apiUrl}/i`, {
.post(`${config.apiUrl}/i`, { json: {
json: { i: config.i,
i: config.i, },
}, })
}) .catch(retry)
.catch(retry) },
}, {
{ retries: 3,
retries: 3, }
} )
) .then((account) => {
.then((account) => { const acct = `@${account.username}`
const acct = `@${account.username}` log(chalk.green(`Account fetched successfully: ${chalk.underline(acct)}`))
log(chalk.green(`Account fetched successfully: ${chalk.underline(acct)}`))
log("Starting Nullcat chan...")
log("Starting Nullcat chan...")
// ぬるきゃっとちゃん起動
// ぬるきゃっとちゃん起動 new NullcatChan(account, [
new NullcatChan(account, [ new CoreModule(),
new CoreModule(), new EmojiReactModule(),
new EmojiReactModule(), new FortuneModule(),
new FortuneModule(), new TimerModule(),
new TimerModule(), new TalkModule(),
new TalkModule(), new FollowModule(),
new FollowModule(), new BirthdayModule(),
new BirthdayModule(), new ValentineModule(),
new ValentineModule(), new KeywordModule(),
new KeywordModule(), new SleepReportModule(),
new SleepReportModule(), new NotingModule(),
new NotingModule(), new ReminderModule(),
new ReminderModule(), new GomamayoModule(),
new GomamayoModule(), new GitHubStatusModule(),
new GitHubStatusModule(), new CloudflareStatus(),
new CloudflareStatus(), new YarukotoModule(),
new YarukotoModule(), new KiatsuModule(),
new RoguboModule(), new JihouModule(),
new KiatsuModule(), new WhatModule(),
new JihouModule(), new FeelingModule(),
new WhatModule(), new TraceMoeModule(),
new FeelingModule(), new ServerModule(),
new TraceMoeModule(), new ShellGeiModule(),
new ServerModule(), new SversionModule(),
new ShellGeiModule(), new AyashiiModule(),
new SversionModule(), new PingModule(),
new AyashiiModule(), ])
new PingModule(), })
]) .catch((e) => {
}) log(chalk.red("Failed to fetch the account"))
.catch((e) => { })
log(chalk.red("Failed to fetch the account"))
})

View File

@ -1,9 +1,9 @@
import config from "@/config" import config from "@/config"
import Friend from "@/friend" import Friend from "@/friend"
import { User } from "./misskey/user" import { User } from "./misskey/user"
import NullcatChan from "../../NullcatChan-old/src/nullcat-chan" import NullcatChan from "../../NullcatChan/src/nullcat-chan"
import includes from "../../NullcatChan-old/src/utils/includes" import includes from "../../NullcatChan/src/utils/includes"
import or from "../../NullcatChan-old/src/utils/or" import or from "../../NullcatChan/src/utils/or"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
import * as chalk from "chalk" import * as chalk from "chalk"
const delay = require("timeout-as-promise") const delay = require("timeout-as-promise")

View File

@ -1,4 +1,4 @@
import NullcatChan, { InstallerResult } from "./nullcat-chan" import NullcatChan, { InstallerResult } from "@/nullcat-chan"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
export default abstract class Module { export default abstract class Module {

View File

@ -0,0 +1,61 @@
import config from '@/config';
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import fetch from 'node-fetch';
import { z } from 'zod';
export default class extends Module {
public readonly name = 'cloudflare-status';
private readonly schema = z.object({
status: z.object({
description: z.string(),
indicator: z.enum(['none', 'minor', 'major', 'critical'])
})
});
private indicator: z.infer<typeof this.schema>['status']['indicator'] = 'none';
private description: z.infer<typeof this.schema>['status']['description'] = '';
@autobind
public install() {
setInterval(this.updateStatus, 10 * 60 * 1000);
this.updateStatus();
return {
mentionHook: this.mentionHook
};
}
@autobind
private async updateStatus() {
try {
const response = await fetch('https://www.cloudflarestatus.com/api/v2/status.json');
const data = await response.json();
const result = this.schema.safeParse(data);
if (result.success) {
this.indicator = result.data.status.indicator;
this.description = result.data.status.description;
} else {
this.log('Validation failed.');
console.warn(result.error);
}
} catch (error) {
this.log('Failed to fetch status from Cloudflare.');
console.warn(error);
}
}
@autobind
private async mentionHook(msg: Message) {
if (msg.text?.toLowerCase().includes('cloudflare')) {
msg.reply(`いまのCloudflareのステータスだよ\n\nじょうきょう: ${this.indicator}\nせつめい: ${this.description}\nhttps://www.cloudflarestatus.com`);
return true;
} else {
return false;
}
}
}

View File

@ -1,7 +1,7 @@
import Message from "@/message" import Message from "@/message"
import Module from "@/module" import Module from "@/module"
import serifs from "@/serifs" import serifs from "@/serifs"
import { safeForInterpolate } from "../../../../NullcatChan-old/src/utils/safe-for-interpolate" import { safeForInterpolate } from "../../../../NullcatChan/src/utils/safe-for-interpolate"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
const titles = ["さん", "くん", "君", "ちゃん", "様", "先生"] const titles = ["さん", "くん", "君", "ちゃん", "様", "先生"]

View File

@ -1,7 +1,7 @@
import { Note } from "../../misskey/note" import { Note } from "../../misskey/note"
import Module from "@/module" import Module from "@/module"
import Stream from "@/stream" import Stream from "@/stream"
import includes from "../../../../NullcatChan-old/src/utils/includes" import includes from "../../../../NullcatChan/src/utils/includes"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
const delay = require("timeout-as-promise") const delay = require("timeout-as-promise")

View File

@ -2,7 +2,7 @@ import config from "@/config"
import Message from "@/message" import Message from "@/message"
import Module from "@/module" import Module from "@/module"
import serifs, { getSerif } from "@/serifs" import serifs, { getSerif } from "@/serifs"
import { acct } from "../../../../NullcatChan-old/src/utils/acct" import { acct } from "../../../../NullcatChan/src/utils/acct"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
import * as loki from "lokijs" import * as loki from "lokijs"

View File

@ -1,8 +1,8 @@
import Message from "@/message" import Message from "@/message"
import Module from "@/module" import Module from "@/module"
import { HandlerResult } from "../../nullcat-chan" import { HandlerResult } from "@/nullcat-chan"
import serifs, { getSerif } from "@/serifs" import serifs, { getSerif } from "@/serifs"
import getDate from "../../../../NullcatChan-old/src/utils/get-date" import getDate from "../../../../NullcatChan/src/utils/get-date"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
export default class extends Module { export default class extends Module {

View File

@ -0,0 +1,101 @@
import autobind from 'autobind-decorator';
import Module from '@/module';
import Message from '@/message';
/**
*
*/
interface Version {
/**
* (meta.Sversion)
*/
server: string;
/**
* (meta.clientVersion)
*/
client: string;
}
export default class extends Module {
public readonly name = 'version';
private latest?: Version;
@autobind
public install() {
this.versionCheck();
setInterval(this.versionCheck, 1000 * 60 * 60 * 1);
return {
mentionHook: this.mentionHook
};
}
public versionCheck = () => {
// バージョンチェック
this.getVersion()
.then(fetched => {
this.log(`Version fetched: ${JSON.stringify(fetched)}`);
if (this.latest != null && fetched != null) {
const serverChanged = this.latest.server !== fetched.server;
if (serverChanged) {
let v = '';
v += (serverChanged ? '**' : '') + `${this.latest.server}${this.mfmVersion(fetched.server)}\n` + (serverChanged ? '**' : '');
this.log(`Version changed: ${v}`);
this.nullcatChan.post({ text: `ぼくのおうちが${v}にリフォームされたよ!!` });
} else {
// 変更なし
}
}
this.latest = fetched;
})
.catch(e => this.log(`warn: ${e}`));
};
@autobind
private async mentionHook(msg: Message) {
if (msg.text == null) return false;
const query = msg.text.match(/サーバーバージョン/);
if (query == null) return false;
this.nullcatChan
.api('meta')
.then(meta => {
msg.reply(`${this.mfmVersion(meta.version)} みたいだよ!`);
})
.catch(() => {
msg.reply(`取得失敗しちゃった:cry_nullcatchan:`);
});
return true;
}
/**
*
*/
private getVersion = (): Promise<Version> => {
return this.nullcatChan.api('meta').then(meta => {
return {
server: meta.version,
client: meta.clientVersion
};
});
};
private mfmVersion = (v): string => {
if (v == null) return v;
return v.match(/^\d+\.\d+\.\d+$/) ? `[${v}](https://github.com/syuilo/misskey/releases/tag/${v})` : v;
};
private wait = (ms: number): Promise<void> => {
return new Promise(resolve => {
setTimeout(() => resolve(), ms);
});
};
}

View File

@ -1,4 +1,4 @@
import toHiragana from '../../NullcatChan-old/src/utils/to-hiragana'; import toHiragana from '../../NullcatChan/src/utils/to-hiragana';
const fs = require('fs'); const fs = require('fs');
const readline = require('readline'); const readline = require('readline');

View File

@ -4,9 +4,9 @@ import config from "./config"
import Friend, { FriendDoc } from "./friend" import Friend, { FriendDoc } from "./friend"
import Message from "./message" import Message from "./message"
import { User } from "./misskey/user" import { User } from "./misskey/user"
import Module from "../../NullcatChan-old/src/module" import Module from "../../NullcatChan/src/module"
import Stream from "./stream" import Stream from "./stream"
import log from "../../NullcatChan-old/src/utils/log" import log from "../../NullcatChan/src/utils/log"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
import * as chalk from "chalk" import * as chalk from "chalk"
import * as fs from "fs" import * as fs from "fs"
@ -15,7 +15,7 @@ import * as request from "request-promise-native"
import { v4 as uuid } from "uuid" import { v4 as uuid } from "uuid"
const delay = require("timeout-as-promise") const delay = require("timeout-as-promise")
const pkg = require("../../NullcatChan-old/package.json") const pkg = require("../../NullcatChan/package.json")
type MentionHook = (msg: Message) => Promise<boolean | HandlerResult> type MentionHook = (msg: Message) => Promise<boolean | HandlerResult>
type ContextHook = (key: any, msg: Message, data?: any) => Promise<void | boolean | HandlerResult> type ContextHook = (key: any, msg: Message, data?: any) => Promise<void | boolean | HandlerResult>

5
src/utils/to-hiragana.ts Normal file
View File

@ -0,0 +1,5 @@
const moji = require('moji');
export default function toHiragana(str: string): string {
return moji(str).convert('HK', 'ZK').convert('KK', 'HG').toString();
}

View File

@ -14,7 +14,7 @@
"noLib": false, "noLib": false,
"outDir": "built", "outDir": "built",
"rootDir": "src", "rootDir": "src",
"baseUrl": "../NullcatChan-old", "baseUrl": "../NullcatChan",
"paths": { "paths": {
"@/*": ["src/*"] "@/*": ["src/*"]
} }