import math import json from django.core.cache import cache from django.core.serializers.json import DjangoJSONEncoder from channels.channel import Group from channels.generic.websockets import JsonWebsocketConsumer 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(JsonWebsocketConsumer): """Custom Json Websocket Consumer. Encode to JSON with DjangoJSONEncoder. """ @classmethod def encode_json(cls, content): 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 = [] def connect(self, message, **kwargs): """Check permissions on connection.""" if message.user.has_perms(self.perms_connect): super().connect(message, **kwargs) else: self.close() def raw_connect(self, message, **kwargs): # Same as original raw_connect method of JsonWebsocketConsumer # We add user to connection_groups call. groups = self.connection_groups(user=message.user, **kwargs) for group in groups: Group(group, channel_layer=message.channel_layer).add(message.reply_channel) self.connect(message, **kwargs) def raw_disconnect(self, message, **kwargs): # Same as original raw_connect method of JsonWebsocketConsumer # We add user to connection_groups call. groups = self.connection_groups(user=message.user, **kwargs) for group in groups: Group(group, channel_layer=message.channel_layer).discard(message.reply_channel) self.disconnect(message, **kwargs) def connection_groups(self, user, **kwargs): """`message.user` is available as `user` arg. Original behavior.""" return super().connection_groups(user=user, **kwargs)