- # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
- # MIT License. See license.txt
- from __future__ import unicode_literals
- import json
- import frappe
- from frappe import _
- from frappe.utils import add_to_date, get_link_to_form
-
-
- def cache_source(function):
- def wrapper(*args, **kwargs):
- if kwargs.get("chart_name"):
- chart = frappe.get_doc('Dashboard Chart', kwargs.get("chart_name"))
- else:
- chart = kwargs.get("chart")
- no_cache = kwargs.get("no_cache")
- if no_cache:
- return function(chart = chart, no_cache = no_cache)
- chart_name = frappe.parse_json(chart).name
- cache_key = "chart-data:{}".format(chart_name)
- if int(kwargs.get("refresh") or 0):
- results = generate_and_cache_results(chart, chart_name, function, cache_key)
- else:
- cached_results = frappe.cache().get_value(cache_key)
- if cached_results:
- results = frappe.parse_json(frappe.safe_decode(cached_results))
- else:
- results = generate_and_cache_results(chart, chart_name, function, cache_key)
- return results
- return wrapper
-
- def generate_and_cache_results(chart, chart_name, function, cache_key):
- try:
- results = function(chart_name = chart_name)
- except TypeError as e:
- if e.message == "'NoneType' object is not iterable":
- # Probably because of invalid link filter
- #
- # Note: Do not try to find the right way of doing this because
- # it results in an inelegant & inefficient solution
- # ref: https://github.com/frappe/frappe/pull/9403
- frappe.throw(_('Please check the filter values set for Dashboard Chart: {}').format(
- get_link_to_form(chart.doctype, chart.name)), title=_('Invalid Filter Value'))
- return
- else:
- raise
-
- frappe.cache().set_value(cache_key, json.dumps(results, default=str))
- frappe.db.set_value("Dashboard Chart", chart_name, "last_synced_on", frappe.utils.now(), update_modified = False)
- return results