diff --git a/back/api/subscription.ts b/back/api/subscription.ts index adcdef4c..eacb0608 100644 --- a/back/api/subscription.ts +++ b/back/api/subscription.ts @@ -38,6 +38,9 @@ export default (app: Router) => { dependences: Joi.string().optional().allow('').allow(null), pull_type: Joi.string().optional().allow('').allow(null), pull_option: Joi.object().optional().allow('').allow(null), + extensions: Joi.string().optional().allow('').allow(null), + sub_before: Joi.string().optional().allow('').allow(null), + sub_after: Joi.string().optional().allow('').allow(null), schedule_type: Joi.string().required(), alias: Joi.string().required(), }), @@ -167,6 +170,9 @@ export default (app: Router) => { pull_type: Joi.string().optional().allow('').allow(null), pull_option: Joi.object().optional().allow('').allow(null), schedule_type: Joi.string().optional().allow('').allow(null), + extensions: Joi.string().optional().allow('').allow(null), + sub_before: Joi.string().optional().allow('').allow(null), + sub_after: Joi.string().optional().allow('').allow(null), alias: Joi.string().required(), id: Joi.number().required(), }), diff --git a/back/data/subscription.ts b/back/data/subscription.ts index 3d8839a8..ce83cb71 100644 --- a/back/data/subscription.ts +++ b/back/data/subscription.ts @@ -25,6 +25,9 @@ export class Subscription { log_path?: string; alias: string; command?: string; + extensions?: string; + sub_before?: string; + sub_after?: string; constructor(options: Subscription) { this.id = options.id; @@ -48,6 +51,9 @@ export class Subscription { this.schedule_type = options.schedule_type; this.alias = options.alias; this.interval_schedule = options.interval_schedule; + this.extensions = options.extensions; + this.sub_before = options.sub_before; + this.sub_after = options.sub_after; } } @@ -85,6 +91,9 @@ export const SubscriptionModel = sequelize.define( blacklist: DataTypes.STRING, status: DataTypes.NUMBER, dependences: DataTypes.STRING, + extensions: DataTypes.STRING, + sub_before: DataTypes.STRING, + sub_after: DataTypes.STRING, branch: DataTypes.STRING, pull_type: DataTypes.STRING, pull_option: DataTypes.JSON, diff --git a/back/services/schedule.ts b/back/services/schedule.ts index d713da26..ee64a5e4 100644 --- a/back/services/schedule.ts +++ b/back/services/schedule.ts @@ -21,14 +21,16 @@ export interface TaskCallbacks { onStart?: ( cp: ChildProcessWithoutNullStreams, startTime: dayjs.Dayjs, - ) => void; + ) => Promise; onEnd?: ( cp: ChildProcessWithoutNullStreams, endTime: dayjs.Dayjs, diff: number, - ) => void; - onLog?: (message: string) => void; - onError?: (message: string) => void; + ) => Promise; + onLog?: (message: string) => Promise; + onError?: (message: string) => Promise; + onBefore?: () => Promise; + onAfter?: () => Promise; } @Service() @@ -44,33 +46,34 @@ export default class ScheduleService { async runTask(command: string, callbacks: TaskCallbacks = {}) { return new Promise(async (resolve, reject) => { try { + await callbacks.onBefore?.(); const startTime = dayjs(); const cp = spawn(command, { shell: '/bin/bash' }); - callbacks.onStart?.(cp, startTime); + await callbacks.onStart?.(cp, startTime); - cp.stdout.on('data', (data) => { - callbacks.onLog?.(data.toString()); + cp.stdout.on('data', async (data) => { + await callbacks.onLog?.(data.toString()); }); - cp.stderr.on('data', (data) => { + cp.stderr.on('data', async (data) => { this.logger.error( '执行任务 %s 失败,时间:%s, 错误信息:%j', command, new Date().toLocaleString(), data.toString(), ); - callbacks.onError?.(data.toString()); + await callbacks.onError?.(data.toString()); }); - cp.on('error', (err) => { + cp.on('error', async (err) => { this.logger.error( '创建任务 %s 失败,时间:%s, 错误信息:%j', command, new Date().toLocaleString(), err, ); - callbacks.onError?.(JSON.stringify(err)); + await callbacks.onError?.(JSON.stringify(err)); }); cp.on('exit', async (code, signal) => { @@ -82,7 +85,12 @@ export default class ScheduleService { cp.on('close', async (code) => { const endTime = dayjs(); this.logger.info(`${command} pid: ${cp.pid} closed ${code}`); - callbacks.onEnd?.(cp, endTime, endTime.diff(startTime, 'seconds')); + await callbacks.onEnd?.( + cp, + endTime, + endTime.diff(startTime, 'seconds'), + ); + await callbacks.onAfter?.(); resolve(null); }); } catch (error) { @@ -92,7 +100,7 @@ export default class ScheduleService { new Date().toLocaleString(), error, ); - callbacks.onError?.(JSON.stringify(error)); + await callbacks.onError?.(JSON.stringify(error)); resolve(null); } }); diff --git a/back/services/subscription.ts b/back/services/subscription.ts index 9432c9f3..fbdde7ed 100644 --- a/back/services/subscription.ts +++ b/back/services/subscription.ts @@ -97,13 +97,13 @@ export default class SubscriptionService { private formatCommand(doc: Subscription, url?: string) { let command = 'ql '; let _url = url || this.formatUrl(doc).url; - const { type, whitelist, blacklist, dependences, branch } = doc; + const { type, whitelist, blacklist, dependences, branch, extensions } = doc; if (type === 'file') { command += `raw "${_url}"`; } else { command += `repo "${_url}" "${whitelist || ''}" "${blacklist || ''}" "${ dependences || '' - }" "${branch || ''}"`; + }" "${branch || ''}" "${extensions || ''}"`; } return command; } @@ -219,6 +219,40 @@ export default class SubscriptionService { const absolutePath = await this.handleLogPath(sub.log_path as string); fs.appendFileSync(absolutePath, `\n${message}`); }, + onBefore: async () => { + return new Promise((resolve, reject) => { + if (doc.sub_before) { + exec(doc.sub_before, async (err, stdout, stderr) => { + const absolutePath = await this.handleLogPath( + doc.log_path as string, + ); + fs.appendFileSync( + absolutePath, + stdout || stderr || `${JSON.stringify(err || {})}`, + ); + }); + } else { + resolve(); + } + }); + }, + onAfter: async () => { + return new Promise((resolve, reject) => { + if (doc.sub_after) { + exec(doc.sub_after, async (err, stdout, stderr) => { + const absolutePath = await this.handleLogPath( + doc.log_path as string, + ); + fs.appendFileSync( + absolutePath, + stdout || stderr || `${JSON.stringify(err || {})}`, + ); + }); + } else { + resolve(); + } + }); + }, }; } diff --git a/shell/update.sh b/shell/update.sh index b3729202..369146fb 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -141,6 +141,7 @@ update_repo() { local blackword="$3" local dependence="$4" local branch="$5" + local extensions="$6" local tmp="${url%/*}" local authorTmp1="${tmp##*/}" local authorTmp2="${authorTmp1##*:}" @@ -159,7 +160,7 @@ update_repo() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新${repo_path}成功...\n" - diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" + diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" else echo -e "\n更新${repo_path}失败,请检查网络...\n" fi @@ -341,8 +342,9 @@ diff_scripts() { local path="$3" local blackword="$4" local dependence="$5" + local extensions="$6" - gen_list_repo "$repo_path" "$author" "$path" "$blackword" "$dependence" + gen_list_repo "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" local list_add="$dir_list_tmp/${uniq_path}_add.list" local list_drop="$dir_list_tmp/${uniq_path}_drop.list" @@ -378,6 +380,9 @@ gen_list_repo() { local cmd="find ." local index=0 + if [[ $6 ]]; then + file_extensions="$6" + fi for extension in $file_extensions; do if [[ $index -eq 0 ]]; then cmd="${cmd} -name \"*.${extension}\"" @@ -458,6 +463,7 @@ main() { local p4=$4 local p5=$5 local p6=$6 + local p7=$7 local log_time=$(date "+%Y-%m-%d-%H-%M-%S") local log_path="$dir_log/update/${log_time}_$p1.log" local begin_time=$(date '+%Y-%m-%d %H:%M:%S') @@ -479,7 +485,7 @@ main() { get_user_info get_uniq_path "$p2" "$p6" if [[ -n $p2 ]]; then - update_repo "$p2" "$p3" "$p4" "$p5" "$p6" + update_repo "$p2" "$p3" "$p4" "$p5" "$p6" "$p7" else echo -e "命令输入错误...\n" usage diff --git a/src/pages/subscription/modal.tsx b/src/pages/subscription/modal.tsx index 3e46a4fc..3f5da049 100644 --- a/src/pages/subscription/modal.tsx +++ b/src/pages/subscription/modal.tsx @@ -357,6 +357,37 @@ const SubscriptionModal = ({ placeholder="请输入脚本依赖文件关键词,多个关键词竖线分割" /> + value.trim()} + tooltip="仓库需要拉取的文件后缀,多个后缀空格分隔" + > + + + value.trim()} + tooltip="仓库需要拉取的文件后缀,多个后缀空格分隔" + > + + + value.trim()} + > + + )}