From 50f4abacb03340a443d014ccca18c23fa6407c98 Mon Sep 17 00:00:00 2001 From: Igor Chubin Date: Sun, 17 Feb 2019 14:07:02 +0100 Subject: [PATCH] caching separated into cache.py --- lib/adapter/adapter.py | 8 ++++++ lib/adapter/cmd.py | 3 +++ lib/adapter/learnxiny.py | 3 +++ lib/adapter/question.py | 4 ++- lib/cache.py | 45 +++++++++++++++++++++++++++++++ lib/fmt/comments.py | 23 +++++----------- lib/{get_answer.py => routing.py} | 1 + 7 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 lib/cache.py rename lib/{get_answer.py => routing.py} (99%) diff --git a/lib/adapter/adapter.py b/lib/adapter/adapter.py index 8cf6113..259fb2b 100644 --- a/lib/adapter/adapter.py +++ b/lib/adapter/adapter.py @@ -4,6 +4,7 @@ class Adapter(object): _adapter_name = None _output_format = 'code' + _cache_needed = False def __init__(self): self._list = {None: self._get_list()} @@ -30,6 +31,13 @@ class Adapter(object): """ return topic in self._list[None] + def is_cache_needed(self): + """ + Return True if answers should be cached. + Return False if answers should not be cached. + """ + return self._cache_needed + @abc.abstractmethod def _get_page(self, topic, request_options=None): """ diff --git a/lib/adapter/cmd.py b/lib/adapter/cmd.py index 906e7b3..63c7f70 100644 --- a/lib/adapter/cmd.py +++ b/lib/adapter/cmd.py @@ -18,6 +18,7 @@ class Tldr(Adapter): _adapter_name = "tldr" _output_format = "code" + _cache_needed = True def _get_list(self, prefix=None): return [filename[:-3] @@ -47,6 +48,7 @@ class Cheat(Adapter): _adapter_name = "cheat" _output_format = "code" + _cache_needed = True def _get_list(self, prefix=None): return _get_filenames(PATH_CHEAT_PAGES) @@ -75,6 +77,7 @@ class Translation(Adapter): _adapter_name = "translation" _output_format = "text" + _cache_needed = True def _get_list(self, prefix=None): return [] diff --git a/lib/adapter/learnxiny.py b/lib/adapter/learnxiny.py index 94e1113..c34e33c 100644 --- a/lib/adapter/learnxiny.py +++ b/lib/adapter/learnxiny.py @@ -794,6 +794,9 @@ _ADAPTERS = {cls.prefix: cls() for cls in vars()['LearnXYAdapter'].__subclasses_ class LearnXinY(Adapter): + _output_format = 'code' + _cache_needed = True + def __init__(self): self.adapters = _ADAPTERS Adapter.__init__(self) diff --git a/lib/adapter/question.py b/lib/adapter/question.py index 22dd84e..c98d0fb 100644 --- a/lib/adapter/question.py +++ b/lib/adapter/question.py @@ -13,11 +13,13 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from globals import MYDIR from adapter import Adapter +from languages_data import SO_NAME class Question(Adapter): _adapter_name = "question" - _output_format = "code" + _output_format = "text+code" + _cache_needed = True def _get_page(self, topic, request_options=None): """ diff --git a/lib/cache.py b/lib/cache.py new file mode 100644 index 0000000..78b339d --- /dev/null +++ b/lib/cache.py @@ -0,0 +1,45 @@ +import os +import json +import redis +from globals import REDISHOST + +if os.environ.get('REDIS_HOST', '').lower() != 'none': + _REDIS = redis.StrictRedis(host=REDISHOST, port=6379, db=0) +else: + _REDIS = None + +if os.environ.get('REDIS_PREFIX', '').lower() != 'none': + _REDIS_PREFIX = os.environ.get('REDIS_PREFIX', '') + ':' +else: + _REDIS_PREFIX = '' + +def put(key, value): + """ + Save `value` with `key`, and serialize it if needed + """ + + if _REDIS_PREFIX: + key = _REDIS_PREFIX + key + + if _REDIS: + if isinstance(value, (dict, list)): + value = json.dumps(value) + + _REDIS.set(key, value) + +def get(key): + """ + Read `value` by `key`, and deserialize it if needed + """ + + if _REDIS_PREFIX: + key = _REDIS_PREFIX + key + + if _REDIS: + value = _REDIS.get(key) + try: + value = json.loads(value) + except (ValueError, TypeError): + pass + return value + return None diff --git a/lib/fmt/comments.py b/lib/fmt/comments.py index a6b7dc6..49c766b 100644 --- a/lib/fmt/comments.py +++ b/lib/fmt/comments.py @@ -31,19 +31,14 @@ import re from itertools import groupby, chain from tempfile import NamedTemporaryFile -import redis +import cache MYDIR = os.path.abspath(os.path.join(__file__, '..', '..')) sys.path.append("%s/lib/" % MYDIR) from languages_data import VIM_NAME -from globals import PATH_VIM_ENVIRONMENT, REDISHOST +from globals import PATH_VIM_ENVIRONMENT # pylint: enable=wrong-import-position,wrong-import-order -if os.environ.get('REDIS_HOST', '').lower() != 'none': - REDIS = redis.StrictRedis(host=REDISHOST, port=6379, db=1) -else: - REDIS = None - FNULL = open(os.devnull, 'w') TEXT = 0 CODE = 1 @@ -301,16 +296,12 @@ def beautify(text, lang, options): # if mode is unknown, just don't transform the text at all return text - if REDIS: - digest = "t:%s:%s:%s" % (hashlib.md5(text).hexdigest(), lang, mode) - answer = REDIS.get(digest) - if answer: - return answer - + digest = "t:%s:%s:%s" % (hashlib.md5(text).hexdigest(), lang, mode) + answer = cache.get(digest) + if answer: + return answer answer = _beautify(text, lang, **beauty_options) - - if REDIS: - REDIS.set(digest, answer) + cache.put(digest, answer) return answer diff --git a/lib/get_answer.py b/lib/routing.py similarity index 99% rename from lib/get_answer.py rename to lib/routing.py index 82a0c69..d2028f4 100644 --- a/lib/get_answer.py +++ b/lib/routing.py @@ -18,6 +18,7 @@ from languages_data import LANGUAGE_ALIAS, SO_NAME, rewrite_editor_section_name import fmt.comments +import cache import adapter.cheat_sheets import adapter.cmd import adapter.internal