Make it possible to create tasks without timer.
This commit is contained in:
parent
23c74d8447
commit
bdf50d0ed8
5 changed files with 45 additions and 20 deletions
|
|
@ -1007,9 +1007,6 @@ class HttpAPI(Common):
|
|||
if not item.get("id", None) or not validate_uuid(item.get("id"), version=4):
|
||||
item["id"] = str(uuid.uuid4())
|
||||
|
||||
if not item.get("timer", None) or str(item.get("timer")).strip() == "":
|
||||
item["timer"] = f"{random.randint(1,59)} */1 * * *" # noqa: S311
|
||||
|
||||
if not item.get("template", None):
|
||||
item["template"] = ""
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class Tasks(metaclass=Singleton):
|
|||
self.load()
|
||||
self._notify.subscribe(
|
||||
Events.TASKS_ADD,
|
||||
lambda data, _, **kwargs: self.add(**data.data), # noqa: ARG005
|
||||
lambda data, _, **kwargs: self.save(**data.data), # noqa: ARG005
|
||||
f"{__class__.__name__}.add",
|
||||
)
|
||||
|
||||
|
|
@ -145,6 +145,7 @@ class Tasks(metaclass=Singleton):
|
|||
for i, task in enumerate(tasks):
|
||||
try:
|
||||
task, task_status = clean_item(task, keys=("cookies", "config"))
|
||||
self.validate(task)
|
||||
task = Task(**task)
|
||||
if task_status:
|
||||
need_save = True
|
||||
|
|
@ -152,9 +153,13 @@ class Tasks(metaclass=Singleton):
|
|||
LOG.error(f"Failed to parse task at list position '{i}'. '{e!s}'.")
|
||||
continue
|
||||
|
||||
self._tasks.append(task)
|
||||
|
||||
if not task.timer:
|
||||
continue
|
||||
|
||||
try:
|
||||
self._scheduler.add(timer=task.timer, func=self._runner, args=(task,), id=task.id)
|
||||
self._tasks.append(task)
|
||||
|
||||
try:
|
||||
from cronsim import CronSim
|
||||
|
|
@ -221,14 +226,19 @@ class Tasks(metaclass=Singleton):
|
|||
msg = "No name found."
|
||||
raise ValueError(msg)
|
||||
|
||||
if not task.get("timer"):
|
||||
msg = "No timer found."
|
||||
raise ValueError(msg)
|
||||
|
||||
if not task.get("url"):
|
||||
msg = "No URL found."
|
||||
raise ValueError(msg)
|
||||
|
||||
if task.get("timer"):
|
||||
try:
|
||||
from cronsim import CronSim
|
||||
|
||||
CronSim(task.get("timer"), datetime.now(UTC))
|
||||
except Exception as e:
|
||||
msg = f"Invalid timer format. '{e!s}'."
|
||||
raise ValueError(msg) from e
|
||||
|
||||
if task.get("cli"):
|
||||
try:
|
||||
from .Utils import arg_converter
|
||||
|
|
|
|||
|
|
@ -126,16 +126,15 @@
|
|||
CRON expression timer.
|
||||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="timer" placeholder="leave empty to run once every hour."
|
||||
v-model="form.timer" :disabled="addInProgress">
|
||||
<input type="text" class="input" id="timer" v-model="form.timer" :disabled="addInProgress"
|
||||
placeholder="0 12 * * 5">
|
||||
</div>
|
||||
<span class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>
|
||||
The CRON timer expression to use for this task. If not set, the task will run once an hour in a
|
||||
random
|
||||
minute. For more information on CRON expressions, see <NuxtLink to="https://crontab.guru/"
|
||||
target="_blank">crontab.guru</NuxtLink>.
|
||||
The CRON timer expression to use for this task. If not set, the task will be disabled. For more
|
||||
information on CRON expressions, see <NuxtLink to="https://crontab.guru/" target="_blank">
|
||||
crontab.guru</NuxtLink>.
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ div.is-centered {
|
|||
<div class="content">
|
||||
<p class="is-text-overflow">
|
||||
<span class="icon"><i class="fa-solid fa-clock" /></span>
|
||||
<span>{{ tryParse(item.timer) }} - {{ item.timer }}</span>
|
||||
<span v-if="item.timer">{{ tryParse(item.timer) }} - {{ item.timer }}</span>
|
||||
<span v-else>No timer is set</span>
|
||||
</p>
|
||||
<p class="is-text-overflow" v-if="item.folder">
|
||||
<span class="icon"><i class="fa-solid fa-folder" /></span>
|
||||
|
|
@ -102,7 +103,7 @@ div.is-centered {
|
|||
</div>
|
||||
<div class="card-footer-item">
|
||||
<button class="button is-purple is-fullwidth" @click="runNow(item)"
|
||||
:class="{ 'is-loading': runNowInProgress }">
|
||||
:class="{ 'is-loading': item?.in_progress }">
|
||||
<span class="icon"><i class="fa-solid fa-up-right-from-square" /></span>
|
||||
<span>Run now</span>
|
||||
</button>
|
||||
|
|
@ -135,7 +136,6 @@ const toggleForm = ref(false)
|
|||
const isLoading = ref(false)
|
||||
const initialLoad = ref(true)
|
||||
const addInProgress = ref(false)
|
||||
const runNowInProgress = ref(false)
|
||||
|
||||
watch(() => config.app.basic_mode, async () => {
|
||||
if (!config.app.basic_mode) {
|
||||
|
|
@ -241,6 +241,7 @@ const deleteItem = async item => {
|
|||
}
|
||||
|
||||
const updateItem = async ({ reference, task }) => {
|
||||
task = cleanObject(task, ['in_progress'])
|
||||
if (reference) {
|
||||
// -- find the task index.
|
||||
const index = tasks.value.findIndex((t) => t?.id === reference)
|
||||
|
|
@ -297,7 +298,7 @@ const runNow = async item => {
|
|||
return
|
||||
}
|
||||
|
||||
runNowInProgress.value = true
|
||||
item.in_progress = true
|
||||
|
||||
let data = {
|
||||
url: item.url,
|
||||
|
|
@ -320,7 +321,7 @@ const runNow = async item => {
|
|||
|
||||
setTimeout(async () => {
|
||||
await nextTick()
|
||||
runNowInProgress.value = false
|
||||
item.in_progress = false
|
||||
}, 500)
|
||||
}
|
||||
|
||||
|
|
@ -360,4 +361,5 @@ const exportItem = async item => {
|
|||
return copyText(base64UrlEncode(JSON.stringify(data)));
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -476,6 +476,22 @@ const toggleClass = (target, className) => {
|
|||
target.classList.add(className)
|
||||
}
|
||||
|
||||
const cleanObject = (item, fields = []) => {
|
||||
if (!item || typeof item !== 'object' || fields.length < 1) {
|
||||
return item
|
||||
}
|
||||
|
||||
const cleaned = {}
|
||||
|
||||
for (const key of Object.keys(item)) {
|
||||
if (false === fields.includes(key)) {
|
||||
cleaned[key] = item[key]
|
||||
}
|
||||
}
|
||||
|
||||
return cleaned
|
||||
}
|
||||
|
||||
export {
|
||||
ag_set,
|
||||
ag,
|
||||
|
|
@ -502,4 +518,5 @@ export {
|
|||
base64UrlDecode,
|
||||
has_data,
|
||||
toggleClass,
|
||||
cleanObject,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue