Merge pull request #21142 from gavindsouza/server_script-cron

feat: Allow setting cron as Server Script frequency
This commit is contained in:
mergify[bot] 2023-05-29 13:26:11 +00:00 committed by GitHub
commit 95fc535f1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 6 deletions

View file

@ -9,6 +9,7 @@
"script_type",
"reference_doctype",
"event_frequency",
"cron_format",
"doctype_event",
"api_method",
"allow_guest",
@ -99,7 +100,7 @@
"fieldtype": "Select",
"label": "Event Frequency",
"mandatory_depends_on": "eval:doc.script_type == \"Scheduler Event\"",
"options": "All\nHourly\nDaily\nWeekly\nMonthly\nYearly\nHourly Long\nDaily Long\nWeekly Long\nMonthly Long"
"options": "All\nHourly\nDaily\nWeekly\nMonthly\nYearly\nHourly Long\nDaily Long\nWeekly Long\nMonthly Long\nCron"
},
{
"fieldname": "module",
@ -132,6 +133,12 @@
"fieldname": "rate_limit_seconds",
"fieldtype": "Int",
"label": "Time Window (Seconds)"
},
{
"depends_on": "eval:doc.event_frequency==='Cron'",
"fieldname": "cron_format",
"fieldtype": "Data",
"label": "Cron Format"
}
],
"index_web_pages_for_search": 1,
@ -141,7 +148,7 @@
"link_fieldname": "server_script"
}
],
"modified": "2023-05-16 11:03:58.282680",
"modified": "2023-05-27 16:33:16.595424",
"modified_by": "Administrator",
"module": "Core",
"name": "Server Script",

View file

@ -52,11 +52,16 @@ class ServerScript(Document):
def sync_scheduler_events(self):
"""Create or update Scheduled Job Type documents for Scheduler Event Server Scripts"""
if not self.disabled and self.event_frequency and self.script_type == "Scheduler Event":
setup_scheduler_events(script_name=self.name, frequency=self.event_frequency)
cron_format = self.cron_format if self.event_frequency == "Cron" else None
setup_scheduler_events(
script_name=self.name, frequency=self.event_frequency, cron_format=cron_format
)
def clear_scheduled_events(self):
"""Deletes existing scheduled jobs by Server Script if self.event_frequency has changed"""
if self.script_type == "Scheduler Event" and self.has_value_changed("event_frequency"):
"""Deletes existing scheduled jobs by Server Script if self.event_frequency or self.cron_format has changed"""
if self.script_type == "Scheduler Event" and (
self.has_value_changed("event_frequency") or self.has_value_changed("cron_format")
):
for scheduled_job in self.scheduled_jobs:
frappe.delete_doc("Scheduled Job Type", scheduled_job.name)
@ -171,7 +176,7 @@ class ServerScript(Document):
return items
def setup_scheduler_events(script_name, frequency):
def setup_scheduler_events(script_name: str, frequency: str, cron_format: str | None = None):
"""Creates or Updates Scheduled Job Type documents based on the specified script name and frequency
Args:
@ -188,6 +193,7 @@ def setup_scheduler_events(script_name, frequency):
"method": method,
"frequency": frequency,
"server_script": script_name,
"cron_format": cron_format,
}
).insert()
@ -200,6 +206,7 @@ def setup_scheduler_events(script_name, frequency):
return
doc.frequency = frequency
doc.cron_format = cron_format
doc.save()
frappe.msgprint(_("Scheduled execution for script {0} has updated").format(script_name))

View file

@ -3,6 +3,7 @@
import requests
import frappe
from frappe.core.doctype.scheduled_job_type.scheduled_job_type import sync_jobs
from frappe.frappeclient import FrappeClient, FrappeException
from frappe.tests.utils import FrappeTestCase
from frappe.utils import get_site_url
@ -283,3 +284,37 @@ frappe.qb.from_(todo).select(todo.name).where(todo.name == "{todo.name}").run()
script1.delete()
script2.delete()
frappe.db.commit()
def test_server_script_scheduled(self):
scheduled_script = frappe.get_doc(
doctype="Server Script",
name="scheduled_script_wo_cron",
script_type="Scheduler Event",
script="""frappe.flags = {"test": True}""",
event_frequency="Hourly",
).insert()
cron_script = frappe.get_doc(
doctype="Server Script",
name="scheduled_script_w_cron",
script_type="Scheduler Event",
script="""frappe.flags = {"test": True}""",
event_frequency="Cron",
cron_format="0 0 1 1 *", # 1st january
).insert()
# Ensure that jobs remain in DB after migrate
sync_jobs()
self.assertTrue(frappe.db.exists("Scheduled Job Type", {"server_script": scheduled_script.name}))
cron_job_name = frappe.db.get_value("Scheduled Job Type", {"server_script": cron_script.name})
self.assertTrue(cron_job_name)
cron_job = frappe.get_doc("Scheduled Job Type", cron_job_name)
self.assertEqual(cron_job.next_execution.day, 1)
self.assertEqual(cron_job.next_execution.month, 1)
cron_script.cron_format = "0 0 2 1 *" # 2nd january
cron_script.save()
cron_job.reload()
self.assertEqual(cron_job.next_execution.day, 2)