Merge branch 'v2' of github.com:ikechan8370/chatgpt-plugin into v2

This commit is contained in:
ikechan8370 2023-06-17 15:31:27 +08:00
commit 85e9d079a5
3 changed files with 321 additions and 66 deletions

View file

@ -1817,10 +1817,10 @@ export class chatgpt extends plugin {
timeoutMs: 120000
// systemMessage: promptPrefix
}
// if (Math.floor(Math.random() * 100) < 5) {
// // 小概率再次发送系统消息
// option.systemMessage = promptPrefix
// }
if (Math.floor(Math.random() * 100) < 5) {
// 小概率再次发送系统消息
option.systemMessage = promptPrefix
}
if (conversation) {
option = Object.assign(option, conversation)
}

View file

@ -126,10 +126,6 @@ export class ChatgptManagement extends plugin {
reg: '^#chatgpt模式(帮助)?$',
fnc: 'modeHelp'
},
{
reg: '^#chatgpt(强制)?更新$',
fnc: 'updateChatGPTPlugin'
},
{
reg: '^#chatgpt版本(信息)',
fnc: 'versionChatGPTPlugin'
@ -235,7 +231,7 @@ export class ChatgptManagement extends plugin {
fnc: 'userPage'
},
{
reg: '^#(chatgpt)?(对话|管理|娱乐|绘图|人物设定|聊天记录)?指令表(帮助|搜索(.+))?',
reg: '^#?(chatgpt)(对话|管理|娱乐|绘图|人物设定|聊天记录)?指令表(帮助|搜索(.+))?',
fnc: 'commandHelp'
},
{
@ -1010,63 +1006,6 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
}
return true
}
// modified from miao-plugin
async updateChatGPTPlugin (e) {
let timer
if (!await this.checkAuth(e)) {
return true
}
let isForce = e.msg.includes('强制')
let command = 'git pull'
if (isForce) {
command = 'git checkout . && git pull'
e.reply('正在执行强制更新操作,请稍等')
} else {
e.reply('正在执行更新操作,请稍等')
}
const _path = process.cwd()
exec(command, { cwd: `${_path}/plugins/chatgpt-plugin/` }, async function (error, stdout, stderr) {
if (/(Already up[ -]to[ -]date|已经是最新的)/.test(stdout)) {
e.reply('目前已经是最新版ChatGPT了~')
return true
}
if (error) {
e.reply('ChatGPT更新失败\nError code: ' + error.code + '\n' + error.stack + '\n 请稍后重试。')
return true
}
e.reply('ChatGPT更新成功正在尝试重新启动Yunzai以应用更新...')
e.reply('更新日志:\n' + stdout)
timer && clearTimeout(timer)
let data = JSON.stringify({
isGroup: !!e.isGroup,
id: e.isGroup ? e.group_id : e.user_id,
time: new Date().getTime()
})
await redis.set('Yz:restart', data, { EX: 120 })
let npm = await checkPnpm()
timer = setTimeout(function () {
let command = `${npm} start`
if (process.argv[1].includes('pm2')) {
command = `${npm} run restart`
}
exec(command, function (error, stdout, stderr) {
if (error) {
e.reply('自动重启失败请手动重启以应用新版ChatGPT。\nError code: ' + error.code + '\n' + error.stack + '\n')
Bot.logger.error(`重启失败\n${error.stack}`)
return true
} else if (stdout) {
Bot.logger.mark('重启成功运行已转为后台查看日志请用命令npm run log')
Bot.logger.mark('停止后台运行命令npm stop')
process.exit()
}
})
}, 1000)
})
return true
}
async versionChatGPTPlugin (e) {
await renderUrl(e, `http://127.0.0.1:${Config.serverPort || 3321}/version`, { Viewport: { width: 800, height: 600 } })
}

316
apps/update.js Normal file
View file

@ -0,0 +1,316 @@
// modified from StarRail-plugin | 已经过StarRail-plugin作者本人同意
import plugin from '../../../lib/plugins/plugin.js'
import { createRequire } from 'module'
import _ from 'lodash'
import { Restart } from '../../other/restart.js'
import fs from 'fs'
import {} from "../utils/common.js";
const _path = process.cwd()
const require = createRequire(import.meta.url)
const { exec, execSync } = require('child_process')
const checkAuth = async function (e) {
if (!e.isMaster) {
e.reply(`只有主人才能命令ChatGPT哦~(*/ω\*)`)
return false
}
return true
}
// 是否在更新中
let uping = false
/**
* 处理插件更新
*/
export class Update extends plugin {
constructor () {
super({
name: 'chatgpt更新插件',
event: 'message',
priority: 1000,
rule: [
{
reg: '^#?(chatgpt|柴特寄批踢|GPT|ChatGPT|柴特鸡批踢|Chat|CHAT|CHATGPT|柴特|ChatGPT-Plugin|ChatGPT-plugin|chatgpt-plugin)(插件)?(强制)?更新$',
fnc: 'update'
}
]
})
}
/**
* rule - 更新chatgpt插件
* @returns
*/
async update () {
if (!this.e.isMaster) return false
/** 检查是否正在更新中 */
if (uping) {
await this.reply('已有命令更新中..请勿重复操作')
return
}
/** 检查git安装 */
if (!(await this.checkGit())) return
const isForce = this.e.msg.includes('强制')
/** 执行更新 */
await this.runUpdate(isForce)
/** 是否需要重启 */
if (this.isUp) {
// await this.reply("更新完毕,请重启云崽后生效")
setTimeout(() => this.restart(), 2000)
}
}
restart () {
new Restart(this.e).restart()
}
/**
* chatgpt插件更新函数
* @param {boolean} isForce 是否为强制更新
* @returns
*/
async runUpdate (isForce) {
let command = 'git -C ./plugins/chatgpt-plugin/ pull --no-rebase'
if (isForce) {
command = `git -C ./plugins/chatgpt-plugin/ checkout . && ${command}`
this.e.reply('正在执行强制更新操作,请稍等')
} else {
this.e.reply('正在执行更新操作,请稍等')
}
/** 获取上次提交的commitId用于获取日志时判断新增的更新日志 */
this.oldCommitId = await this.getcommitId('chatgpt-plugin')
uping = true
let ret = await this.execSync(command)
uping = false
if (ret.error) {
logger.mark(`${this.e.logFnc} 更新失败chatgpt-plugin`)
this.gitErr(ret.error, ret.stdout)
return false
}
/** 获取插件提交的最新时间 */
let time = await this.getTime('chatgpt-plugin')
if (/(Already up[ -]to[ -]date|已经是最新的)/.test(ret.stdout)) {
await this.reply(`chatgpt-plugin已经是最新版本\n最后更新时间:${time}`)
} else {
await this.reply(`chatgpt-plugin\n最后更新时间:${time}`)
this.isUp = true
/** 获取chatgpt组件的更新日志 */
let log = await this.getLog('chatgpt-plugin')
await this.reply(log)
}
logger.mark(`${this.e.logFnc} 最后更新时间:${time}`)
return true
}
/**
* 获取chatgpt插件的更新日志
* @param {string} plugin 插件名称
* @returns
*/
async getLog (plugin = '') {
let cm = `cd ./plugins/${plugin}/ && git log -20 --oneline --pretty=format:"%h||[%cd] %s" --date=format:"%m-%d %H:%M"`
let logAll
try {
logAll = await execSync(cm, { encoding: 'utf-8' })
} catch (error) {
logger.error(error.toString())
this.reply(error.toString())
}
if (!logAll) return false
logAll = logAll.split('\n')
let log = []
for (let str of logAll) {
str = str.split('||')
if (str[0] == this.oldCommitId) break
if (str[1].includes('Merge branch')) continue
log.push(str[1])
}
let line = log.length
log = log.join('\n\n')
if (log.length <= 0) return ''
let end = ''
end =
'更多详细信息请前往github查看\nhttps://github.com/ikechan8370/chatgpt-plugin'
log = await this.makeForwardMsg(`chatgpt-plugin更新日志${line}`, log, end)
return log
}
/**
* 获取上次提交的commitId
* @param {string} plugin 插件名称
* @returns
*/
async getcommitId (plugin = '') {
let cm = `git -C ./plugins/${plugin}/ rev-parse --short HEAD`
let commitId = await execSync(cm, { encoding: 'utf-8' })
commitId = _.trim(commitId)
return commitId
}
/**
* 获取本次更新插件的最后一次提交时间
* @param {string} plugin 插件名称
* @returns
*/
async getTime (plugin = '') {
let cm = `cd ./plugins/${plugin}/ && git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"`
let time = ''
try {
time = await execSync(cm, { encoding: 'utf-8' })
time = _.trim(time)
} catch (error) {
logger.error(error.toString())
time = '获取时间失败'
}
return time
}
/**
* 制作转发消息
* @param {string} title 标题 - 首条消息
* @param {string} msg 日志信息
* @param {string} end 最后一条信息
* @returns
*/
async makeForwardMsg (title, msg, end) {
let nickname = (this.e.bot ?? Bot).nickname
if (this.e.isGroup) {
let info = await (this.e.bot ?? Bot).getGroupMemberInfo(this.e.group_id, (this.e.bot ?? Bot).uin)
nickname = info.card || info.nickname
}
let userInfo = {
user_id: (this.e.bot ?? Bot).uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
},
{
...userInfo,
message: msg
}
]
if (end) {
forwardMsg.push({
...userInfo,
message: end
})
}
/** 制作转发内容 */
if (this.e.isGroup) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
}
/** 处理描述 */
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${title}</title>`)
return forwardMsg
}
/**
* 处理更新失败的相关函数
* @param {string} err
* @param {string} stdout
* @returns
*/
async gitErr (err, stdout) {
let msg = '更新失败!'
let errMsg = err.toString()
stdout = stdout.toString()
if (errMsg.includes('Timed out')) {
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
await this.reply(msg + `\n连接超时:${remote}`)
return
}
if (/Failed to connect|unable to access/g.test(errMsg)) {
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
await this.reply(msg + `\n连接失败:${remote}`)
return
}
if (errMsg.includes('be overwritten by merge')) {
await this.reply(
msg +
`存在冲突:\n${errMsg}\n` +
'请解决冲突后再更新,或者执行#强制更新,放弃本地修改'
)
return
}
if (stdout.includes('CONFLICT')) {
await this.reply([
msg + '存在冲突\n',
errMsg,
stdout,
'\n请解决冲突后再更新或者执行#强制更新,放弃本地修改'
])
return
}
await this.reply([errMsg, stdout])
}
/**
* 异步执行git相关命令
* @param {string} cmd git命令
* @returns
*/
async execSync (cmd) {
return new Promise((resolve, reject) => {
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
resolve({ error, stdout, stderr })
})
})
}
/**
* 检查git是否安装
* @returns
*/
async checkGit () {
let ret = await execSync('git --version', { encoding: 'utf-8' })
if (!ret || !ret.includes('git version')) {
await this.reply('请先安装git')
return false
}
return true
}
}