diff --git a/server/entertainment_decider/extras/__init__.py b/server/entertainment_decider/extras/__init__.py new file mode 100644 index 0000000..5da4ee9 --- /dev/null +++ b/server/entertainment_decider/extras/__init__.py @@ -0,0 +1 @@ +from .chain import Chain diff --git a/server/entertainment_decider/extras/chain.py b/server/entertainment_decider/extras/chain.py new file mode 100644 index 0000000..09fb93b --- /dev/null +++ b/server/entertainment_decider/extras/chain.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +from typing import Callable, Generic, TypeVar + + +T = TypeVar("T") +S = TypeVar("S") + + +class Chain(Generic[T]): + + __value: T + + def __init__(self, start_value: T) -> None: + super().__init__() + self.__value = start_value + + def use(self, converter: Callable[[T], S]) -> Chain[S]: + return Chain(converter(self.__value)) + + # infix notation + def __or__(self, converter: Callable[[T], S]) -> Chain[S]: + return self.use(converter=converter) + + def get(self) -> T: + return self.__value diff --git a/server/entertainment_decider/models.py b/server/entertainment_decider/models.py index 6a8985a..d38820a 100644 --- a/server/entertainment_decider/models.py +++ b/server/entertainment_decider/models.py @@ -30,6 +30,7 @@ from pony import orm from pony.orm.core import Query as PonyQuery from .common import trim +from .extras import Chain db = orm.Database() @@ -284,26 +285,32 @@ class PreferenceScore: @classmethod def from_base64(cls, in_data: str, encoding: str = "utf-8") -> PreferenceScore: - data = in_data.encode(encoding) - data = base64.decodebytes(data) - data = gzip.decompress(data) - data = data.decode(encoding) - data = PreferenceScore.from_json(data) - return data + return ( + Chain(in_data) + | (lambda d: d.encode(encoding=encoding)) + | base64.decodebytes + | gzip.decompress + | (lambda d: d.decode(encoding=encoding)) + | PreferenceScore.from_json + ).get() def to_json(self) -> str: return json.dumps({tag.id: score for tag, score in self.points.items()}) def to_base64(self, encoding: str = "utf-8") -> str: - data = self.to_json() - data = data.encode(encoding) - data = gzip.compress( - data=data, - compresslevel=9, - ) - data = base64.encodebytes(data) - data = data.decode(encoding) - return data + return ( + Chain(self) + | PreferenceScore.to_json + | (lambda d: d.encode(encoding=encoding)) + | ( + lambda d: gzip.compress( + data=d, + compresslevel=9, + ) + ) + | base64.encodebytes + | (lambda d: d.decode(encoding=encoding)) + ).get() class PreferenceScoreAppender: