Users having the ability (permissions) to create Custom Field and Property Setter can do everything that a Customize Form can do, irrespective of whether the user has the System Manager role. So the button in the "Menu" should be visible based on permission instead of Role
Converted all possible usages of re.* that weren't compiling the regex
separately and re-using it. Separated out the compiled patterns as
global variables. Repetitive patterns could be made DRY-er.
Would be nicer to have all regexes in a single module so that we could
re-use better, keep track of outdated, and keep checks for possible
reDos' etc
it knows
* Hide Preview if request is errored. EAFP.
* Set file attachment limit based on how many attachments have already
been added. If 1 attachment exists and the limit is 3, File uploader
will allow you to select only 2 more files.
From 115 µs ± 2.31 µs to 2.69 µs ± 27 ns per call
Changes:
* Use request_cache over get_installed_apps, _load_app_hooks
* Refactor logic for default - so that None is an acceptable value
* Remove handling of webnotes app in get_hooks - 8yo code ^_^
Sped up request_cache access times multi-fold with the help of a
benchmarking script. Access times for this generic cache is comparable
to specific caches written (eg: get_meta's local cache) by an additional
overhead of 15% as compared to implementing it in each function separately
* Got rid of logging
* Optimized bits with the help of benchmarking script against
frappe.get_meta's performance
* Use hash instead of json.dumps
Decorator to cache method calls across requests. The cache is stored in
frappe.utils.caching._SITE_CACHE. The cache persists on the parent process.
It offers a light-weight cache for the current process without the additional
overhead of serializing / deserializing Python objects.
Note: This cache isn't shared among workers. If you need to share data across
workers, use redis (frappe.cache API) instead.
Usage:
from frappe.utils.caching import site_cache
@site_cache
def calculate_pi():
import math, time
precision = get_precision("Math Constant", "Pi") # depends on
site data
return round(math.pi, precision)
calculate_pi(10) # will calculate value
calculate_pi(10) # will return value from cache
calculate_pi.clear_cache() # clear this function's cache for all sites
calculate_pi(10) # will calculate value