import json import math from channels.generic.websocket import AsyncJsonWebsocketConsumer from django.core.cache import cache from django.core.serializers.json import DjangoJSONEncoder from .config import kfet_config def to_ukf(balance, is_cof=False): """Convert euro to UKF.""" subvention = kfet_config.subvention_cof grant = (1 + subvention / 100) if is_cof else 1 return math.floor(balance * 10 * grant) # Storage class CachedMixin: """Object with cached properties. Attributes: cached (dict): Keys are cached properties. Associated value is the returned default by getters in case the key is missing from cache. cache_prefix (str): Used to prefix keys in cache. """ cached = {} cache_prefix = "" def __init__(self, cache_prefix=None, *args, **kwargs): super().__init__(*args, **kwargs) if cache_prefix is not None: self.cache_prefix = cache_prefix def cachekey(self, attr): return "{}__{}".format(self.cache_prefix, attr) def __getattr__(self, attr): if attr in self.cached: return cache.get(self.cachekey(attr), self.cached.get(attr)) elif hasattr(super(), "__getattr__"): return super().__getattr__(attr) else: raise AttributeError("can't get attribute") def __setattr__(self, attr, value): if attr in self.cached: cache.set(self.cachekey(attr), value) elif hasattr(super(), "__setattr__"): super().__setattr__(attr, value) else: raise AttributeError("can't set attribute") def clear_cache(self): cache.delete_many([self.cachekey(attr) for attr in self.cached.keys()]) # Consumers class DjangoJsonWebsocketConsumer(AsyncJsonWebsocketConsumer): """Custom Json Websocket Consumer. Encode to JSON with DjangoJSONEncoder. """ @classmethod async def encode_json(cls, content): # Remove the type value, only used by Channels to choose the group to send to content.pop("type") return json.dumps(content, cls=DjangoJSONEncoder) class PermConsumerMixin: """Add support to check permissions on consumers. Attributes: perms_connect (list): Required permissions to connect to this consumer. message.user is appended as argument to each connection_groups method call. """ http_user = True # Enable message.user perms_connect = [] async def connect(self): """Check permissions on connection.""" self.user = self.scope["user"] if self.user.has_perms(self.perms_connect): await super().connect() else: await self.close()