async def get_or_create(cls, serialized=True, **kwargs): payload = await get_one(cls, **kwargs) if payload: return serialize_to_dict(payload) if serialized else payload # Create data = await create_one(cls, staff_id=kwargs["staff_id"]) return serialize_to_dict(data) if serialized else data
async def get_or_create(cls, **kwargs): created_attempt = await get_one(cls, **kwargs) # Update the number of attempts in Quiz, if no previous attempts of the user are found if not created_attempt: data = await create_one(cls, **kwargs) return serialize_to_dict(data) return serialize_to_dict(created_attempt)
async def get_or_create(cls, **kwargs): payload = await get_one(cls, **kwargs) if payload: return serialize_to_dict(payload) # Create data = await create_one(cls, staff_id=kwargs["staff_id"], chat_id=kwargs["chat_id"]) return serialize_to_dict(data)
async def update_or_create(cls, get_kwargs, update_kwargs): payload = await get_one(cls, **get_kwargs) if not payload: data = await create_one(cls, **update_kwargs, staff_id=get_kwargs["staff_id"]) return serialize_to_dict(data) # Update the existing one data = await update_one(payload, **update_kwargs) return serialize_to_dict(data)
async def modify_if_exists(cls, get_kwargs, update_kwargs): payload = await get_one(cls, **get_kwargs) if not payload: return None data = await update_one(payload, **update_kwargs) return serialize_to_dict(data)
async def remove_if_exists(cls, **kwargs): model = await get_one(cls, **kwargs) if model: await model.delete() return serialize_to_dict(model) return None
async def modify_if_exists(cls, get_kwargs, update_kwargs): model_id = get_kwargs.get("id") if not model_id: raise InvalidUsage("Missing field 'id' in query parameter") payload = await get_one(cls, id=model_id) if not payload: return None data = await update_one(payload, **update_kwargs) return serialize_to_dict(data)
async def auto_reassign_staff_to_chat(visitor_id): """Remove all the current subscribed staffs, and add a new one.""" settings = await get_settings_from_cache() if not settings.get("auto_reassign", 1): return None raw_current_staffs = await StaffSubscriptionChat.query.where( StaffSubscriptionChat.visitor_id == visitor_id ).gino.all() current_staffs = {item.staff_id for item in raw_current_staffs} all_volunteers = await cache.get("all_volunteers", namespace="staffs") if not all_volunteers: raw_volunteers = await User.query.where( and_(User.role_id == ROLES.inverse["agent"], User.disabled == False) ).gino.all() volunteers = [serialize_to_dict(user) for user in raw_volunteers] counter = 0 staff = volunteers[0] while staff["id"] in current_staffs: counter += 1 staff = volunteers[counter] await cache.set( "all_volunteers", {"counter": counter + 1, "staffs": volunteers}, namespace="staffs", ) else: counter = all_volunteers["counter"] if counter >= len(all_volunteers["staffs"]): counter = 0 staff = all_volunteers["staffs"][counter] while staff["id"] in current_staffs: counter += 1 if counter >= len(all_volunteers["staffs"]): counter = 0 staff = all_volunteers["staffs"][counter] await cache.set( "all_volunteers", {"counter": counter + 1, "staffs": all_volunteers["staffs"]}, namespace="staffs", ) # Remove all subscribed staffs for the visitor await delete_many(StaffSubscriptionChat, visitor_id=visitor_id) # Assign the chat to the staff if staff: await StaffSubscriptionChat.add_if_not_exists( staff_id=staff["id"], visitor_id=visitor_id ) return staff
async def get( cls, many=False, after_id=None, limit=15, offset=0, fields=None, in_column=None, in_values=None, not_in_column=None, not_in_values=None, allow_readonly=False, order_by="internal_id", **kwargs, ): """ Retrieve the row(s) of a model, using Keyset Pagination (after_id). Kwargs: after_id (str): The returned result will start from row with id == after_id (exclusive). Ignored if many=False. """ # Using an param `many` to optimize Select queries for single row if many: data = await get_many( cls, after_id=after_id, limit=limit, offset=offset, in_column=in_column, in_values=in_values, not_in_column=not_in_column, not_in_values=not_in_values, order_by=order_by, **kwargs, ) else: data = await get_one(cls, **kwargs) serialized_data = serialize_to_dict(data, fields=fields, allow_readonly=allow_readonly) # Raise NotFound if no single resource is found # Ignore if many=True, as returning an empty List is expected if not many and not serialized_data: raise_not_found_exception(cls, **kwargs) return serialized_data
async def auto_assign_staff_to_chat(visitor_id, exclude_staff_id=None): # If the setting for auto-assign is off, return None settings = await get_settings_from_cache() if not settings.get("auto_assign", 1): return None staff = None all_volunteers = await cache.get("all_volunteers", namespace="staffs") if not all_volunteers: raw_volunteers = await User.query.where( and_(User.role_id == ROLES.inverse["agent"], User.disabled == False) ).gino.all() volunteers = [serialize_to_dict(user) for user in raw_volunteers] counter = 0 # If the org has no volunteers if not volunteers: return None staff = volunteers[0] while staff["id"] == exclude_staff_id: counter += 1 staff = volunteers[counter] await cache.set( "all_volunteers", {"counter": counter + 1, "staffs": volunteers}, namespace="staffs", ) else: counter = all_volunteers["counter"] if not all_volunteers["staffs"]: return None if counter >= len(all_volunteers["staffs"]): counter = 0 staff = all_volunteers["staffs"][counter] while staff["id"] == exclude_staff_id: counter += 1 if counter >= len(all_volunteers["staffs"]): counter = 0 staff = all_volunteers["staffs"][counter] await cache.set( "all_volunteers", {"counter": counter + 1, "staffs": all_volunteers["staffs"]}, namespace="staffs", ) # Assign the chat to the staff if staff: await StaffSubscriptionChat.add_if_not_exists( staff_id=staff["id"], visitor_id=visitor_id ) return staff
async def modify(cls, get_kwargs, update_kwargs): model_id = get_kwargs.get("id") if not model_id: raise InvalidUsage("Missing field 'id' in query parameter") payload = await get_one(cls, id=model_id) if not payload: raise_not_found_exception(cls, id=model_id) try: data = await update_one(payload, **update_kwargs) except (UniqueViolationError, DuplicatedError): raise InvalidUsage("The {} already exists".format( cls.__tablename__)) return serialize_to_dict(data)
async def reset_all_volunteers_in_cache(): raw_volunteers = await User.query.where( and_(User.role_id == ROLES.inverse["agent"], User.disabled == False) ).gino.all() volunteers = [serialize_to_dict(user) for user in raw_volunteers] volunteers_data = await cache.get("all_volunteers", namespace="staffs") if not volunteers_data: await cache.set( "all_volunteers", {"counter": 0, "staffs": volunteers}, namespace="staffs" ) else: counter = volunteers_data.get("counter", 0) await cache.set( "all_volunteers", {"counter": counter, "staffs": volunteers}, namespace="staffs", )
async def get_first_message_of_chat(cls, chat_id, **kwargs): data = await get_one_oldest(cls, chat_id=chat_id, order_by="sequence_num") return serialize_to_dict(data)
async def add_if_not_exists(cls, **kwargs): try: data = await create_one(cls, **kwargs) except (UniqueViolationError, DuplicatedError): return None return serialize_to_dict(data)
async def add(cls, **kwargs): data = await create_one(cls, **kwargs) return serialize_to_dict(data)
async def get_latest_settings(): settings = serialize_to_dict(await Setting.query.gino.all()) return {setting["key"]: setting["value"] for setting in settings}