From 6c3ae7cb4e1ddcf6a4274ae7f0439df46336d5b6 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Sat, 24 Feb 2018 16:38:17 +0100 Subject: [PATCH 1/3] fix mypy --- openslides/utils/autoupdate.py | 10 +++++----- openslides/utils/views.py | 4 ++-- setup.cfg | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openslides/utils/autoupdate.py b/openslides/utils/autoupdate.py index 8926e9400..b433adaa6 100644 --- a/openslides/utils/autoupdate.py +++ b/openslides/utils/autoupdate.py @@ -3,7 +3,7 @@ import threading import time import warnings from collections import OrderedDict, defaultdict -from typing import Any, Dict, Generator, Iterable, List, Tuple, Union +from typing import Any, Dict, Generator, Iterable, List, Tuple, Union, Optional from channels import Channel, Group from channels.asgi import get_channel_layer @@ -317,12 +317,12 @@ def send_data_site(message: ChannelMessageFormat) -> None: send_or_wait(Channel(channel_name).send, {'text': json.dumps(output)}) -def to_ordered_dict(d): +def to_ordered_dict(d: Optional[Dict]) -> Optional[OrderedDict]: """ Little helper to hash information dict in inform_*_data. """ if isinstance(d, dict): - result = OrderedDict([(key, to_ordered_dict(d[key])) for key in sorted(d.keys())]) + result = OrderedDict([(key, to_ordered_dict(d[key])) for key in sorted(d.keys())]) # type: Optional[OrderedDict] else: result = d return result @@ -404,11 +404,11 @@ class AutoupdateBundleMiddleware: """ Middleware to handle autoupdate bundling. """ - def __init__(self, get_response): + def __init__(self, get_response: Any) -> None: self.get_response = get_response # One-time configuration and initialization. - def __call__(self, request): + def __call__(self, request: Any) -> Any: thread_id = threading.get_ident() autoupdate_bundle[thread_id] = {} diff --git a/openslides/utils/views.py b/openslides/utils/views.py index 6da9b231b..016748b20 100644 --- a/openslides/utils/views.py +++ b/openslides/utils/views.py @@ -82,6 +82,6 @@ class BinaryTemplateView(TemplateView): """ Loads the specified binary template and encode it with base64. """ - def load_template(self): + def load_template(self) -> str: with open(finders.find(self.template_name), 'rb') as template: - return base64.b64encode(template.read()) + return base64.b64encode(template.read()).decode() diff --git a/setup.cfg b/setup.cfg index a07430750..86bcf93e6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,10 +20,10 @@ strict_optional = true check_untyped_defs = true [mypy-openslides.utils.*] -disallow_any = unannotated +disallow_untyped_defs = true [mypy-openslides.core.config] -disallow_any = unannotated +disallow_untyped_defs = true [mypy-tests.*] ignore_errors = true From c47d054c6753c10ed421e6de1524e7b8ea00567e Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Sat, 24 Feb 2018 16:52:48 +0100 Subject: [PATCH 2/3] Activate the restricted_data_cache again. restricted_data_cache.update_element(...) only adds an element to the cache, when there are already other elements in the cache. So then add_element is never used, the cache is never created. --- openslides/utils/autoupdate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openslides/utils/autoupdate.py b/openslides/utils/autoupdate.py index b433adaa6..06aaa8b7a 100644 --- a/openslides/utils/autoupdate.py +++ b/openslides/utils/autoupdate.py @@ -100,7 +100,7 @@ def ws_add_site(message: Any) -> None: output.append(formatted_data) # Cache restricted data for user - restricted_data_cache.update_element( + restricted_data_cache.add_element( user_id, collection.collection_string, data['id'], From 5aa8f6193ee23c32da940c483d55e3b5327c966a Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Sat, 24 Feb 2018 17:54:59 +0100 Subject: [PATCH 3/3] Add methods to delete the restricted_data_cache --- openslides/users/models.py | 1 - openslides/utils/autoupdate.py | 2 +- openslides/utils/cache.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/openslides/users/models.py b/openslides/users/models.py index a28f33719..f9e173f35 100644 --- a/openslides/users/models.py +++ b/openslides/users/models.py @@ -1,5 +1,4 @@ import smtplib - from random import choice from django.contrib.auth.hashers import make_password diff --git a/openslides/utils/autoupdate.py b/openslides/utils/autoupdate.py index 06aaa8b7a..65aed3244 100644 --- a/openslides/utils/autoupdate.py +++ b/openslides/utils/autoupdate.py @@ -3,7 +3,7 @@ import threading import time import warnings from collections import OrderedDict, defaultdict -from typing import Any, Dict, Generator, Iterable, List, Tuple, Union, Optional +from typing import Any, Dict, Generator, Iterable, List, Optional, Tuple, Union from channels import Channel, Group from channels.asgi import get_channel_layer diff --git a/openslides/utils/cache.py b/openslides/utils/cache.py index 1cb16d31f..9e2e6ebc4 100644 --- a/openslides/utils/cache.py +++ b/openslides/utils/cache.py @@ -396,6 +396,34 @@ class RestrictedDataCache: self.get_cache_key(user_id), "{}/{}".format(collection_string, id)) + def del_user(self, user_id: int) -> None: + """ + Removes all elements for one user from the cache. + """ + redis = get_redis_connection() + redis.delete(self.get_cache_key(user_id)) + + def del_all(self) -> None: + """ + Deletes all elements from the cache. + + This method uses the redis command SCAN. See + https://redis.io/commands/scan#scan-guarantees for its limitations. If + an element is added to the cache while del_all() is in process, it is + possible, that it is not deleted. + """ + redis = get_redis_connection() + + # Get all keys that start with self.base_cache_key and delete them + match = cache.make_key('{}:*'.format(self.base_cache_key)) + cursor = 0 + while True: + cursor, keys = redis.scan(cursor, match) + for key in keys: + redis.delete(key) + if cursor == 0: + return + def exists_for_user(self, user_id: int) -> bool: """ Returns True if the cache for the user exists, else False.