mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-22 17:31:03 +01:00
@@ -7,8 +7,12 @@
|
||||
- **版本升级检测**. 检测最新版本,通知用户升级.
|
||||
- **批量操作爬虫**. 允许用户批量运行/停止爬虫任务,以及批量删除爬虫.
|
||||
- **复制爬虫**. 允许用户复制已存在爬虫来创建新爬虫.
|
||||
- **微信群二维码**.
|
||||
|
||||
### Bug 修复
|
||||
- **定时任务爬虫选择问题**. 字段不会随着爬虫变化而响应.
|
||||
- **定时任务冲突问题**. 两个不同的爬虫设置定时任务,时间设置成相同的话,可能会有bug. [#515](https://github.com/crawlab-team/crawlab/issues/515) [#565](https://github.com/crawlab-team/crawlab/issues/565)
|
||||
- **任务日志问题**. 在同一时间触发的不同任务可能会写入同一个日志文件. [#577](https://github.com/crawlab-team/crawlab/issues/577)
|
||||
|
||||
# 0.4.6 (2020-02-13)
|
||||
### 功能 / 优化
|
||||
|
||||
@@ -7,8 +7,12 @@
|
||||
- **Upgrade Check**. Check latest version and notifiy users to upgrade.
|
||||
- **Spiders Batch Operation**. Allow users to run/stop spider tasks and delete spiders in batches.
|
||||
- **Copy Spiders**. Allow users to copy an existing spider to create a new one.
|
||||
- **Wechat Group QR Code**.
|
||||
|
||||
### Bug Fixes
|
||||
- **Schedule Spider Selection Issue**. Fields not responding to spider change.
|
||||
- **Cron Jobs Conflict**. Possible bug when two spiders set to the same time of their cron jobs. [#515](https://github.com/crawlab-team/crawlab/issues/515) [#565](https://github.com/crawlab-team/crawlab/issues/565)
|
||||
- **Task Log Issue**. Different tasks write to the same log file if triggered at the same time. [#577](https://github.com/crawlab-team/crawlab/issues/577)
|
||||
|
||||
# 0.4.6 (2020-02-13)
|
||||
### Features / Enhancement
|
||||
|
||||
@@ -313,13 +313,13 @@ func MakeLogDir(t model.Task) (fileDir string, err error) {
|
||||
}
|
||||
|
||||
// 获取日志文件路径
|
||||
func GetLogFilePaths(fileDir string) (filePath string) {
|
||||
func GetLogFilePaths(fileDir string, t model.Task) (filePath string) {
|
||||
// 时间戳
|
||||
ts := time.Now()
|
||||
tsStr := ts.Format("20060102150405")
|
||||
|
||||
// stdout日志文件
|
||||
filePath = filepath.Join(fileDir, tsStr+".log")
|
||||
filePath = filepath.Join(fileDir, t.Id+"_"+tsStr+".log")
|
||||
|
||||
return filePath
|
||||
}
|
||||
@@ -419,7 +419,7 @@ func ExecuteTask(id int) {
|
||||
return
|
||||
}
|
||||
// 获取日志文件路径
|
||||
t.LogPath = GetLogFilePaths(fileDir)
|
||||
t.LogPath = GetLogFilePaths(fileDir, t)
|
||||
|
||||
// 工作目录
|
||||
cwd := filepath.Join(
|
||||
@@ -571,7 +571,7 @@ func GetTaskLog(id string) (logStr string, err error) {
|
||||
log.Errorf(err.Error())
|
||||
}
|
||||
|
||||
fileP := GetLogFilePaths(fileDir)
|
||||
fileP := GetLogFilePaths(fileDir, task)
|
||||
|
||||
// 获取日志文件路径
|
||||
fLog, err := os.Create(fileP)
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.cron-wrapper {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.el-tabs {
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -41,7 +45,14 @@
|
||||
</style>
|
||||
<template>
|
||||
<div id="change-crontab">
|
||||
<!-- <el-button class="language" type="text" @click="i18n=(i18n==='en'?'cn':'en')">{{i18n}}</el-button>-->
|
||||
<div class="cron-wrapper">
|
||||
<label>
|
||||
{{$t('Cron Expression')}}:
|
||||
</label>
|
||||
<el-tag type="success" size="small">
|
||||
{{cron}}
|
||||
</el-tag>
|
||||
</div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane>
|
||||
<span slot="label"><i class="el-icon-date"></i> {{text.Minutes.name}}</span>
|
||||
@@ -388,9 +399,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getValue () {
|
||||
return this.cron
|
||||
},
|
||||
change () {
|
||||
this.$emit('change', this.cron)
|
||||
this.close()
|
||||
@@ -398,6 +406,22 @@ export default {
|
||||
close () {
|
||||
this.$emit('close')
|
||||
},
|
||||
submit () {
|
||||
if (!this.validate()) {
|
||||
this.$message.error(this.$t('Cron expression is invalid'))
|
||||
return false
|
||||
}
|
||||
this.$emit('submit', this.cron)
|
||||
return true
|
||||
},
|
||||
validate () {
|
||||
if (!this.minutesText) return false
|
||||
if (!this.hoursText) return false
|
||||
if (!this.daysText) return false
|
||||
if (!this.monthsText) return false
|
||||
if (!this.weeksText) return false
|
||||
return true
|
||||
},
|
||||
updateCronItem (key, value) {
|
||||
if (value === undefined) {
|
||||
this[key].cronEvery = '0'
|
||||
|
||||
@@ -289,6 +289,8 @@ export default {
|
||||
'[minute] [hour] [day] [month] [day of week]': '[分] [时] [天] [月] [星期几]',
|
||||
'Enable/Disable': '启用/禁用',
|
||||
'Cron': 'Cron',
|
||||
'Cron Expression': 'Cron 表达式',
|
||||
'Cron expression is invalid': 'Cron 表达式不正确',
|
||||
|
||||
// 网站
|
||||
'Site': '网站',
|
||||
@@ -407,6 +409,7 @@ export default {
|
||||
'Release Note': '发布记录',
|
||||
'How to Upgrade': '升级方式',
|
||||
'Release': '发布',
|
||||
'Add Wechat to join discussion group': '添加微信 tikazyq1 加入交流群',
|
||||
|
||||
// 登录
|
||||
'Sign in': '登录',
|
||||
|
||||
@@ -61,6 +61,20 @@
|
||||
<span style="margin-left: 5px;">{{$t('Upgrade')}}</span>
|
||||
</el-badge>
|
||||
</div>
|
||||
<el-popover
|
||||
class="wechat right"
|
||||
trigger="click"
|
||||
>
|
||||
<div style="margin-bottom: 5px">
|
||||
<label>{{$t('Add Wechat to join discussion group')}}</label>
|
||||
</div>
|
||||
<div>
|
||||
<img class="wechat-img" src="http://static-docs.crawlab.cn/wechat.jpg">
|
||||
</div>
|
||||
<div slot="reference">
|
||||
<i class="fa fa-wechat"></i>
|
||||
</div>
|
||||
</el-popover>
|
||||
<div class="github right">
|
||||
<!-- Place this tag where you want the button to render. -->
|
||||
<github-button
|
||||
@@ -277,6 +291,12 @@ docker-compose up -d
|
||||
}
|
||||
}
|
||||
|
||||
.wechat {
|
||||
color: #606266;
|
||||
margin-right: 35px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right
|
||||
}
|
||||
@@ -287,3 +307,8 @@ docker-compose up -d
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.wechat-img {
|
||||
width: 240px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,13 +27,16 @@
|
||||
:title="$t(dialogTitle)"
|
||||
:visible.sync="dialogVisible"
|
||||
width="640px"
|
||||
:before-close="onDialogClose">
|
||||
<el-form label-width="180px"
|
||||
class="add-form"
|
||||
:model="scheduleForm"
|
||||
:inline-message="true"
|
||||
ref="scheduleForm"
|
||||
label-position="right">
|
||||
:before-close="onDialogClose"
|
||||
>
|
||||
<el-form
|
||||
label-width="180px"
|
||||
class="add-form"
|
||||
:model="scheduleForm"
|
||||
:inline-message="true"
|
||||
ref="scheduleForm"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item :label="$t('Schedule Name')" prop="name" required>
|
||||
<el-input id="schedule-name" v-model="scheduleForm.name" :placeholder="$t('Schedule Name')"></el-input>
|
||||
</el-form-item>
|
||||
@@ -62,6 +65,7 @@
|
||||
:placeholder="$t('Spider')"
|
||||
filterable
|
||||
:disabled="isDisabledSpiderSchedule"
|
||||
@change="onSpiderChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="op in spiderList"
|
||||
@@ -111,21 +115,23 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('Cron')" prop="cron" required>
|
||||
<el-popover v-model="isShowCron" trigger="focus">
|
||||
<template>
|
||||
<vue-cron-linux :data="scheduleForm.cron" :i18n="lang" @change="onCronChange"/>
|
||||
</template>
|
||||
<template slot="reference">
|
||||
<el-input
|
||||
id="cron"
|
||||
ref="cron"
|
||||
v-model="scheduleForm.cron"
|
||||
:placeholder="`${$t('[minute] [hour] [day] [month] [day of week]')}`"
|
||||
>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-popover>
|
||||
<!--<el-button size="small" style="width:100px" type="primary" @click="onShowCronDialog">{{$t('schedules.add_cron')}}</el-button>-->
|
||||
<el-input
|
||||
class="cron"
|
||||
ref="cron"
|
||||
v-model="scheduleForm.cron"
|
||||
:placeholder="`${$t('[minute] [hour] [day] [month] [day of week]')}`"
|
||||
style="width: calc(100% - 100px)"
|
||||
>
|
||||
</el-input>
|
||||
<el-button
|
||||
class="cron-edit"
|
||||
type="primary"
|
||||
icon="el-icon-edit"
|
||||
style="width: 100px"
|
||||
@click="onShowCronDialog"
|
||||
>
|
||||
{{$t('Edit')}}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('Execute Command')" prop="cmd">
|
||||
<el-input
|
||||
@@ -157,9 +163,14 @@
|
||||
</el-dialog>
|
||||
|
||||
<!--cron generation popup-->
|
||||
<!--<el-dialog title="生成 Cron" :visible.sync="showCron">-->
|
||||
<!--<vcrontab @hide="showCron=false" @fill="onCrontabFill" :expression="expression"></vcrontab>-->
|
||||
<!--</el-dialog>-->
|
||||
<el-dialog title="生成 Cron" :visible.sync="cronDialogVisible">
|
||||
<vue-cron-linux ref="vue-cron-linux" :data="scheduleForm.cron" :i18n="lang" @submit="onCronChange"/>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="cronDialogVisible = false">{{$t('Cancel')}}</el-button>
|
||||
<el-button size="small" type="primary" @click="onCronDialogSubmit">{{$t('Confirm')}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<!--./cron generation popup-->
|
||||
|
||||
<el-card style="border-radius: 0" class="schedule-list">
|
||||
<!--filter-->
|
||||
@@ -286,7 +297,7 @@ export default {
|
||||
isEdit: false,
|
||||
dialogTitle: '',
|
||||
dialogVisible: false,
|
||||
showCron: false,
|
||||
cronDialogVisible: false,
|
||||
expression: '',
|
||||
spiderList: [],
|
||||
nodeList: [],
|
||||
@@ -556,12 +567,29 @@ export default {
|
||||
this.$set(this.scheduleForm, 'cron', value)
|
||||
this.$st.sendEv('定时任务', '配置Cron')
|
||||
},
|
||||
onCronDialogSubmit () {
|
||||
const valid = this.$refs['vue-cron-linux'].submit()
|
||||
if (valid) {
|
||||
this.cronDialogVisible = false
|
||||
}
|
||||
},
|
||||
onOpenParameters () {
|
||||
this.isParametersVisible = true
|
||||
},
|
||||
onParametersConfirm (value) {
|
||||
this.scheduleForm.param = value
|
||||
this.isParametersVisible = false
|
||||
},
|
||||
async onSpiderChange (spiderId) {
|
||||
await this.$store.dispatch('spider/getSpiderData', spiderId)
|
||||
if (this.spiderForm.type === 'customized' && this.spiderForm.is_scrapy) {
|
||||
this.$set(this.scheduleForm, 'scrapy_spider', this.spiderForm.spider_names[0])
|
||||
this.$set(this.scheduleForm, 'scrapy_log_level', 'INFO')
|
||||
}
|
||||
},
|
||||
onShowCronDialog () {
|
||||
this.cronDialogVisible = true
|
||||
this.$st.sendEv('定时任务', '点击编辑Cron')
|
||||
}
|
||||
},
|
||||
created () {
|
||||
@@ -626,4 +654,20 @@ export default {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.cron {
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
|
||||
.cron >>> .el-input__inner {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.cron-edit {
|
||||
width: 100px;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user