From 43712f05b97ec57ccfbf9eb21ed17b7da231cf30 Mon Sep 17 00:00:00 2001 From: Daniele Guido Date: Thu, 17 Oct 2024 16:35:32 +0200 Subject: [PATCH] update task celery to retrieve a serialized version f the bitmap (#73) --- .../management/commands/updateuserbitmap.py | 27 ++++++++++++++----- impresso/models/userBitmap.py | 27 ++++++++++++++++++- impresso/tasks.py | 4 +-- impresso/utils/tasks/userBitmap.py | 24 ++++++++++++++++- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/impresso/management/commands/updateuserbitmap.py b/impresso/management/commands/updateuserbitmap.py index 34fab13..7782f1a 100644 --- a/impresso/management/commands/updateuserbitmap.py +++ b/impresso/management/commands/updateuserbitmap.py @@ -9,9 +9,15 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument("username", type=str) parser.add_argument("bitmap", type=str, nargs="?", default=None) + parser.add_argument( + "--immediate", + action="store_true", + help="Run the task immediately instead of delaying it", + ) - def handle(self, username, *args, **options): + def handle(self, username, immediate=False, *args, **options): self.stdout.write(f"Get user with username: {username}") + self.stdout.write(f"Immediate: {immediate}") user = User.objects.get(username=username) self.stdout.write(f"User: pk={user.id} \033[34m{user.username}\033[0m") # currrent user bitmap @@ -31,14 +37,21 @@ def handle(self, username, *args, **options): self.stdout.write( f"SAVED ^ EXPECTED difference:\n \033[34m{bin(difference)}\033[0m" ) + if immediate: + # collection_id, user_id, items_ids_to_add=[], items_ids_to_remove=[] + instance = update_user_bitmap_task( + user_id=user.id, + ) + self.stdout.write( + f"\nTask returned this updated bitmap: \n \033[34m{instance.get('bitmap')}\033[0m\n\n" + ) + self.stdout.write( + f"Task returned this serialized object: \n \033[34m{instance}\033[0m\n\n" + ) + return # collection_id, user_id, items_ids_to_add=[], items_ids_to_remove=[] message = update_user_bitmap_task.delay( - collection_id=collection.id, user_id=user.id, - items_ids_to_add=items_to_add, - items_ids_to_remove=items_to_remove, - ) - self.stdout.write( - f"\n5. Task \033[36m{message.id}\033[0m launched, check celery." ) + self.stdout.write(f"\n5. Task \033[36m{message}\033[0m launched, check celery.") diff --git a/impresso/models/userBitmap.py b/impresso/models/userBitmap.py index 271e7a8..dd8c960 100644 --- a/impresso/models/userBitmap.py +++ b/impresso/models/userBitmap.py @@ -68,8 +68,33 @@ def get_up_to_date_bitmap(self): return bitmap + def get_bitmap_as_int(self): + return int.from_bytes(self.bitmap, byteorder="big") + + def get_user_plan(self): + if not self.bitmap: + return "GUEST" + if not self.date_accepted_terms: + return "GUEST" + bitmap_int = self.get_bitmap_as_int() + bitmap_length = bitmap_int.bit_length() + # Extract the first 5 bits + bitmap_plan = ( + bitmap_int >> (bitmap_length - UserBitmap.BITMAP_PLAN_MAX_LENGTH) + ) & 0b11111 + if bitmap_plan == UserBitmap.USER_PLAN_GUEST: + return "GUEST" + if bitmap_plan == UserBitmap.USER_PLAN_AUTH_USER: + return "AUTH_USER" + if bitmap_plan == UserBitmap.USER_PLAN_EDUCATIONAL: + return "EDUCATIONAL" + if bitmap_plan == UserBitmap.USER_PLAN_RESEARCHER: + return "RESEARCHER" + return "AUTH_USER" + def __str__(self): - return f"{self.user.username} Bitmap" + bitmap = self.get_bitmap_as_int() + return f"{self.user.username} Bitmap {bin(bitmap)}" class Meta: verbose_name = "User Bitmap" diff --git a/impresso/tasks.py b/impresso/tasks.py index e57dfac..99971a9 100644 --- a/impresso/tasks.py +++ b/impresso/tasks.py @@ -1038,5 +1038,5 @@ def update_user_bitmap_task(self, user_id): Update the user bitmap for the given user. """ logger.info(f"User bitmap update request for user {user_id}") - update_user_bitmap(user_id=user_id) - return + updated_bitmap = update_user_bitmap(user_id=user_id) + return updated_bitmap diff --git a/impresso/utils/tasks/userBitmap.py b/impresso/utils/tasks/userBitmap.py index 2eda935..73265d1 100644 --- a/impresso/utils/tasks/userBitmap.py +++ b/impresso/utils/tasks/userBitmap.py @@ -1,9 +1,31 @@ +import json +from django.core.serializers import serialize from ...models import UserBitmap def update_user_bitmap(user_id): + """ + Updates the bitmap for a given user. + + This function updates user bitmap to the most recent version taken into account user + groups, plan and terms of use acceptance. + + Args: + user_id (int): The ID of the user whose bitmap needs to be updated. + + Returns: + dict: A dictionary containing the updated bitmap as an integer. + """ user_bitmap = UserBitmap.objects.get(user_id=user_id) bitmap = user_bitmap.get_up_to_date_bitmap() - bitmap_bytes = bitmap.to_bytes((user_bitmap.bit_length() + 7) // 8, byteorder="big") + bitmap_bytes = bitmap.to_bytes((bitmap.bit_length() + 7) // 8, byteorder="big") user_bitmap.bitmap = bitmap_bytes user_bitmap.save() + serialized = json.loads(serialize("json", [user_bitmap]))[0].get("fields") + return { + "date_accepted_terms": serialized.get("date_accepted_terms"), + "bitmap_base64": serialized.get("bitmap"), + "subscriptions": serialized.get("subscriptions"), + "bitmap": bin(user_bitmap.get_bitmap_as_int()), + "plan": user_bitmap.get_user_plan(), + }