mirror of
https://github.com/chubin/wttr.in
synced 2025-01-12 12:08:47 +00:00
lru cache for formatted answers (fixes #346)
This commit is contained in:
parent
e78e6e6f22
commit
de1b79d705
3 changed files with 66 additions and 4 deletions
50
lib/cache.py
Normal file
50
lib/cache.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
"""
|
||||
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)
|
|
@ -481,13 +481,12 @@ def textual_information(data_parsed, geo_data, config):
|
|||
output.append('Timezone: %s' % timezone)
|
||||
|
||||
tmp_output = []
|
||||
tmp_output.append(' Now: %s'
|
||||
% datetime.datetime.now(pytz.timezone(timezone)).strftime("%H:%M:%S%z"))
|
||||
tmp_output.append(' Now: %%{{NOW(%s)}}' % timezone)
|
||||
tmp_output.append('Dawn: %s'
|
||||
% str(sun['dawn'].strftime("%H:%M:%S")))
|
||||
tmp_output.append('Sunrise: %s'
|
||||
% str(sun['sunrise'].strftime("%H:%M:%S")))
|
||||
tmp_output.append(' Noon: %s'
|
||||
tmp_output.append(' Zenith: %s'
|
||||
% str(sun['noon'].strftime("%H:%M:%S ")))
|
||||
tmp_output.append('Sunset: %s'
|
||||
% str(sun['sunset'].strftime("%H:%M:%S")))
|
||||
|
|
|
@ -25,6 +25,8 @@ from limits import Limits
|
|||
from wttr import get_wetter, get_moon
|
||||
from wttr_line import wttr_line
|
||||
|
||||
import cache
|
||||
|
||||
if not os.path.exists(os.path.dirname(LOG_FILE)):
|
||||
os.makedirs(os.path.dirname(LOG_FILE))
|
||||
logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG, format='%(asctime)s %(message)s')
|
||||
|
@ -211,6 +213,12 @@ def wttr(location, request):
|
|||
html_output = get_output_format(request, query)
|
||||
user_agent = request.headers.get('User-Agent', '').lower()
|
||||
|
||||
# generating cache signature
|
||||
cache_signature = cache.get_signature(user_agent, request.url, ip_addr, lang)
|
||||
answer = cache.get(cache_signature)
|
||||
if answer:
|
||||
return _wrap_response(answer, html_output)
|
||||
|
||||
if location in PLAIN_TEXT_PAGES:
|
||||
help_ = show_text_file(location, lang)
|
||||
if html_output:
|
||||
|
@ -242,8 +250,13 @@ def wttr(location, request):
|
|||
# We are ready to return the answer
|
||||
try:
|
||||
if fmt or 'format' in query:
|
||||
response_text = wttr_line(
|
||||
location, override_location_name, full_address, query, lang, fmt)
|
||||
fmt = fmt or query.get('format')
|
||||
response_text = cache.store(cache_signature, response_text)
|
||||
|
||||
return _wrap_response(
|
||||
wttr_line(location, override_location_name, full_address, query, lang, fmt),
|
||||
response_text,
|
||||
html_output)
|
||||
|
||||
if png_filename:
|
||||
|
|
Loading…
Reference in a new issue