mirror of
https://github.com/koishijs/novelai-bot
synced 2025-01-08 11:17:32 +08:00
fix: fix download error, fix #32
This commit is contained in:
parent
41fc4aa548
commit
f44f3f35b7
@ -10,7 +10,7 @@
|
||||
- 高级请求语法
|
||||
- 自定义违禁词表
|
||||
- 发送一段时间后自动撤回
|
||||
- 连接到自建私服
|
||||
- 连接到私服 · NAIFU
|
||||
- img2img · 图片增强
|
||||
|
||||
得益于 Koishi 的插件化机制,只需配合其他插件即可实现更多功能:
|
||||
|
13
src/index.ts
13
src/index.ts
@ -1,5 +1,5 @@
|
||||
import { Context, Dict, Logger, Quester, Schema, segment, Session, Time } from 'koishi'
|
||||
import { download, headers, login, LoginError, resizeInput } from './utils'
|
||||
import { download, headers, login, NetworkError, resizeInput } from './utils'
|
||||
import {} from '@koishijs/plugin-help'
|
||||
import getImageSize from 'image-size'
|
||||
|
||||
@ -98,7 +98,7 @@ function errorHandler(session: Session, err: Error) {
|
||||
} else if (err.code === 'ETIMEDOUT') {
|
||||
return session.text('.request-timeout')
|
||||
} else if (err.code) {
|
||||
return session.text('.response-error', [err.code])
|
||||
return session.text('.request-failed', [err.code])
|
||||
}
|
||||
}
|
||||
logger.error(err)
|
||||
@ -178,8 +178,8 @@ export function apply(ctx: Context, config: Config) {
|
||||
try {
|
||||
token = await getToken()
|
||||
} catch (err) {
|
||||
if (err instanceof LoginError) {
|
||||
return session.text(err.message, [err.code])
|
||||
if (err instanceof NetworkError) {
|
||||
return session.text(err.message, err.params)
|
||||
}
|
||||
logger.error(err)
|
||||
return session.text('.unknown-error')
|
||||
@ -220,8 +220,13 @@ export function apply(ctx: Context, config: Config) {
|
||||
try {
|
||||
image = Buffer.from(await download(ctx, imgUrl))
|
||||
} catch (err) {
|
||||
if (err instanceof NetworkError) {
|
||||
return session.text(err.message, err.params)
|
||||
}
|
||||
logger.error(err)
|
||||
return session.text('.download-error')
|
||||
}
|
||||
|
||||
const size = getImageSize(image)
|
||||
Object.assign(parameters, {
|
||||
image: image.toString('base64'),
|
||||
|
@ -28,9 +28,12 @@ commands:
|
||||
waiting: 少女繪畫中
|
||||
nickname: AI 繪師
|
||||
invalid-size: 增強功能僅適用於 Novel AI 生成圖。若要使用 img2img 功能請直接使用「約稿」而非「增強」。
|
||||
file-too-large: 文件體積過大。
|
||||
unsupported-file-type: 不支持的文件格式。
|
||||
download-error: 圖片解析失敗。
|
||||
unknown-error: 發生未知的錯誤。
|
||||
response-error: 發生未知的錯誤 ({0})。
|
||||
request-failed: 請求失敗 ({0})。
|
||||
request-timeout: 請求超時。
|
||||
invalid-password: 電郵地址或密碼不正確。
|
||||
invalid-token: 令牌無效或已過期,請聯繫管理員。
|
||||
|
@ -28,9 +28,12 @@ commands:
|
||||
waiting: 在画了在画了
|
||||
nickname: AI 画师
|
||||
invalid-size: 增强功能仅适用于被生成的图片。普通的 img2img 请直接使用「约稿」而不是「增强」。
|
||||
file-too-large: 文件体积过大。
|
||||
unsupported-file-type: 不支持的文件格式。
|
||||
download-error: 图片解析失败。
|
||||
unknown-error: 发生未知错误。
|
||||
response-error: 发生未知错误 ({0})。
|
||||
request-failed: 请求失败 ({0})。
|
||||
request-timeout: 请求超时。
|
||||
invalid-password: 邮箱或密码错误。
|
||||
invalid-token: 令牌无效或已过期,请联系管理员。
|
||||
|
20
src/utils.ts
20
src/utils.ts
@ -12,7 +12,7 @@ export async function download(ctx: Context, url: string, headers = {}): Promise
|
||||
if (url.startsWith('data:')) {
|
||||
const [, type, base64] = url.match(/^data:(image\/\w+);base64,(.*)$/)
|
||||
if (!ALLOWED_TYPES.includes(type)) {
|
||||
throw new Error('unsupported image type')
|
||||
throw new NetworkError('.unsupported-file-type')
|
||||
}
|
||||
const binary = atob(base64)
|
||||
const result = new Uint8Array(binary.length)
|
||||
@ -23,10 +23,10 @@ export async function download(ctx: Context, url: string, headers = {}): Promise
|
||||
} else {
|
||||
const head = await ctx.http.head(url, { headers })
|
||||
if (+head['content-length'] > MAX_CONTENT_SIZE) {
|
||||
throw new Error('file too large')
|
||||
throw new NetworkError('.file-too-large')
|
||||
}
|
||||
if (ALLOWED_TYPES.includes(head['content-type'])) {
|
||||
throw new Error('unsupported file type')
|
||||
if (!ALLOWED_TYPES.includes(head['content-type'])) {
|
||||
throw new NetworkError('.unsupported-file-type')
|
||||
}
|
||||
return ctx.http.get(url, { responseType: 'arraybuffer', headers })
|
||||
}
|
||||
@ -69,8 +69,8 @@ export const headers = {
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
|
||||
}
|
||||
|
||||
export class LoginError extends Error {
|
||||
constructor(message: string, public code: number) {
|
||||
export class NetworkError extends Error {
|
||||
constructor(message: string, public params = {}) {
|
||||
super(message)
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ export class LoginError extends Error {
|
||||
const code = e.response?.status
|
||||
for (const key in mapping) {
|
||||
if (code === +key) {
|
||||
throw new LoginError(mapping[key], code)
|
||||
throw new NetworkError(mapping[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,16 +127,16 @@ export interface Subscription {
|
||||
trainingStepsLeft: TrainingStepsLeft
|
||||
}
|
||||
|
||||
export async function login(ctx: Context) {
|
||||
export async function login(ctx: Context): Promise<string> {
|
||||
if (ctx.config.type === 'token') {
|
||||
await ctx.http.get<Subscription>(ctx.config.endpoint + '/user/subscription', {
|
||||
headers: { authorization: 'Bearer ' + ctx.config.token },
|
||||
}).catch(LoginError.catch({ 401: '.invalid-token' }))
|
||||
}).catch(NetworkError.catch({ 401: '.invalid-token' }))
|
||||
return ctx.config.token
|
||||
} else if (ctx.config.type === 'login') {
|
||||
return ctx.http.post(ctx.config.endpoint + '/user/login', {
|
||||
key: await calcAccessKey(ctx.config.email, ctx.config.password),
|
||||
}).catch(LoginError.catch({ 401: '.invalid-password' })).then(res => res.accessToken)
|
||||
}).catch(NetworkError.catch({ 401: '.invalid-password' })).then(res => res.accessToken)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user