Make it possible to create tasks without timer.

This commit is contained in:
arabcoders 2025-06-03 19:11:55 +03:00
parent 23c74d8447
commit bdf50d0ed8
5 changed files with 45 additions and 20 deletions

View file

@ -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"] = ""

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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,
}