""" LRU-Cache implementation for formatted (`format=`) answers """ import datetime import re import time import pylru import pytz CACHE_SIZE = 10000 CACHE = pylru.lrucache(CACHE_SIZE) def _update_answer(answer): def _now_in_tz(timezone): return datetime.datetime.now(pytz.timezone(timezone)).strftime("%H:%M:%S%z") if "%{{NOW(" in answer: answer = re.sub(r"%{{NOW\(([^}]*)\)}}", lambda x: _now_in_tz(x.group(1)), answer) return answer def get_signature(user_agent, query_string, client_ip_address, lang): """ Get cache signature based on `user_agent`, `url_string`, `lang`, and `client_ip_address` """ timestamp = int(time.time()) / 1000 signature = "%s:%s:%s:%s:%s" % \ (user_agent, query_string, client_ip_address, lang, timestamp) return signature def get(signature): """ If `update_answer` is not True, return answer as it is stored in the cache. Otherwise update it, using the `_update_answer` function. """ if signature in CACHE: return _update_answer(CACHE[signature]) return None def store(signature, value): """ Store in cache `value` for `signature` """ CACHE[signature] = value return _update_answer(value)