* - trigger new "cron" event - check cron string syntax - added croniter to requirements * - run scheduler ever 60 sec - trigger all enabled events - enqueue if now >= next time execution since last one * Update task-runner.md * fixed tests * fix triggering with now = True * modified sobstitution to cron_map modified annually label to annual * ability to use labels defined in cron_map in cron string definition
2.8 KiB
Executable file
2.8 KiB
Executable file
Scheduled Tasks
Finally, an application also has to send email notifications and do other kind of scheduled tasks. In Frappé, if you have setup the bench, the task / scheduler is setup via RQ using Redis Queue.
To add a new task handler, go to hooks.py and add a new handler. Default handlers are all, daily, weekly, monthly, cron. The all handler is called every 4 minutes by default.
# Scheduled Tasks
# ---------------
scheduler_events = {
"daily": [
"library_management.tasks.daily"
],
"cron": {
"0/10 * * * *": [
"library_management.task.run_every_ten_mins"
],
"15 18 * * *": [
"library_management.task.every_day_at_18_15"
]
}
}
Here we can point to a Python function and that function will be executed every day. Let us look what this function looks like:
# Copyright (c) 2013, Frappé
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import datediff, nowdate, format_date, add_days
def every_ten_minutes():
# stuff to do every 10 minutes
pass
def every_day_at_18_15():
# stuff to do every day at 6:15pm
pass
def daily():
loan_period = frappe.db.get_value("Library Management Settings",
None, "loan_period")
overdue = get_overdue(loan_period)
for member, items in overdue.iteritems():
content = """<h2>Following Items are Overdue</h2>
<p>Please return them as soon as possible</p><ol>"""
for i in items:
content += "<li>{0} ({1}) due on {2}</li>".format(i.article_name,
i.article,
format_date(add_days(i.transaction_date, loan_period)))
content += "</ol>"
recipient = frappe.db.get_value("Library Member", member, "email_id")
frappe.sendmail(recipients=[recipient],
sender="test@example.com",
subject="Library Articles Overdue", content=content, bulk=True)
def get_overdue(loan_period):
# check for overdue articles
today = nowdate()
overdue_by_member = {}
articles_transacted = []
for d in frappe.db.sql("""select name, article, article_name,
library_member, member_name
from `tabLibrary Transaction`
order by transaction_date desc, modified desc""", as_dict=1):
if d.article in articles_transacted:
continue
if d.transaction_type=="Issue" and \
datediff(today, d.transaction_date) > loan_period:
overdue_by_member.setdefault(d.library_member, [])
overdue_by_member[d.library_member].append(d)
articles_transacted.append(d.article)
We can place the above code in any accessible Python module. The route is defined in hooks.py, so for our purposes we would place this code in library_management/tasks.py.
Note:
- We get the loan period from Library Management Settings by using
frappe.db.get_value. - We run a query in the database with
frappe.db.sql - Email is sent via
frappe.sendmail
{next}