diff --git a/README.md b/README.md index c86dc6c..504a6ad 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,5 @@ Contains code for queries, mutations, types and models for the clubs data and se _URL_ -> http://clubs/graphql (For using in single gateway) > ### QUERIES -#### Club -- - -#### Members -- > ### MUTATIONS -#### Club -- - -#### Members -- \ No newline at end of file diff --git a/db.py b/db.py index f9a7d55..2684453 100644 --- a/db.py +++ b/db.py @@ -17,7 +17,6 @@ # get database db = client[MONGO_DATABASE] clubsdb = db.clubs -membersdb = db.members try: # check if the clubs index exists @@ -29,17 +28,5 @@ print("The clubs index was created.") print(clubsdb.index_information()) - - # check if the members index exists - if "unique_members" in membersdb.index_information(): - print("The members index exists.") - else: - # create the index - membersdb.create_index( - [("cid", 1), ("uid", 1)], unique=True, name="unique_members" - ) - print("The members index was created.") - - print(membersdb.index_information()) except Exception: pass diff --git a/main.py b/main.py index 4f6859e..c711250 100644 --- a/main.py +++ b/main.py @@ -11,21 +11,17 @@ from otypes import Context, PyObjectIdType # import all queries and mutations -from queries_clubs import queries as queries_clubs -from queries_members import queries as queries_members -from mutations_clubs import mutations as mutations_clubs -from mutations_members import mutations as mutations_members +from queries import queries +from mutations import mutations # check whether running in debug mode DEBUG = int(getenv("GLOBAL_DEBUG", 0)) # create query types -queries = queries_clubs + queries_members Query = create_type("Query", queries) # create mutation types -mutations = mutations_clubs + mutations_members Mutation = create_type("Mutation", mutations) @@ -49,6 +45,6 @@ async def get_context() -> Context: app = FastAPI( debug=DEBUG, title="CC Clubs Microservice", - desciption="Handles Data of Clubs and Members", + desciption="Handles Data of Clubs", ) app.include_router(gql_app, prefix="/graphql") diff --git a/models.py b/models.py index afdb16d..18c73c4 100644 --- a/models.py +++ b/models.py @@ -9,7 +9,6 @@ EmailStr, Field, field_validator, - ValidationInfo, ) from pydantic_core import core_schema from typing import Any, List @@ -65,71 +64,6 @@ class EnumCategories(str, Enum): other = "other" -class Roles(BaseModel): - rid: str | None = Field(None, description="Unique Identifier for a role") - name: str = Field(..., min_length=1, max_length=99) - start_year: int = Field(..., ge=2010, le=2050) - end_year: int | None = Field(None, gt=2010, le=2051) - approved: bool = False - rejected: bool = False - deleted: bool = False - - # Validators - @field_validator("end_year") - def check_end_year(cls, value, info: ValidationInfo): - if value is not None and value < info.data["start_year"]: - return None - return value - - @field_validator("rejected") - def check_status(cls, value, info: ValidationInfo): - if info.data["approved"] is True and value is True: - raise ValueError("Role cannot be both approved and rejected") - return value - - model_config = ConfigDict( - arbitrary_types_allowed=True, - str_max_length=100, - validate_assignment=True, - validate_default=True, - validate_return=True, - extra="forbid", - str_strip_whitespace=True, - ) - - -class Member(BaseModel): - id: PyObjectId = Field(default_factory=PyObjectId, alias="_id") - cid: str = Field(..., description="Club ID") - uid: str = Field(..., description="User ID") - roles: List[Roles] = Field( - ..., description="List of Roles for that specific person" - ) - - poc: bool = Field(default_factory=(lambda: 0 == 1), description="Club POC") - - @field_validator("uid", mode="before") - @classmethod - def transform_uid(cls, v): - return v.lower() - - # TODO[pydantic]: The following keys were removed: `json_encoders`. - # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information. - model_config = ConfigDict( - arbitrary_types_allowed=True, - str_strip_whitespace=True, - str_max_length=600, - validate_assignment=True, - validate_default=True, - validate_return=True, - extra="forbid", - json_encoders={ObjectId: str}, - populate_by_name=True, - ) - - # Separate Coordinator & other members roles option in frontend, for better filtering for all_members_query - - class Social(BaseModel): website: AnyHttpUrl | None = None instagram: AnyHttpUrl | None = None @@ -192,5 +126,5 @@ def _check_email(cls, v): ) -# TO ADD CLUB SUBSCRIPTION MODEL - v2 +# TODO: ADD CLUB SUBSCRIPTION MODEL - v2 # ADD Descriptions for non-direct fields diff --git a/mutations_clubs.py b/mutations.py similarity index 96% rename from mutations_clubs.py rename to mutations.py index 053a222..bf0b816 100644 --- a/mutations_clubs.py +++ b/mutations.py @@ -4,7 +4,7 @@ from datetime import datetime from db import clubsdb -from utils import update_role, update_events_cid, update_members_cid, getUser +from utils import update_role, update_events_members_cid, getUser # import all models and types from otypes import Info @@ -16,10 +16,6 @@ SimpleClubType, ) -""" -CLUB MUTATIONS -""" - @strawberry.mutation def createClub(clubInput: FullClubInput, info: Info) -> SimpleClubType: @@ -121,11 +117,10 @@ def editClub(clubInput: FullClubInput, info: Info) -> FullClubType: if exists["cid"] != club_input["cid"]: return1 = update_role(exists["cid"], info.context.cookies, role="public") return2 = update_role(club_input["cid"], info.context.cookies, role="club") - return3 = update_events_cid( + return3 = update_events_members_cid( exists["cid"], club_input["cid"], cookies=info.context.cookies ) - return4 = update_members_cid(exists["cid"], club_input["cid"]) - if not return1 or not return2 or not return3 or not return4: + if not return1 or not return2 or not return3: raise Exception("Error in updating the role/cid.") result = Club.parse_obj(clubsdb.find_one({"code": club_input["code"]})) diff --git a/mutations_members.py b/mutations_members.py deleted file mode 100644 index 4c49d05..0000000 --- a/mutations_members.py +++ /dev/null @@ -1,367 +0,0 @@ -import strawberry - -from fastapi.encoders import jsonable_encoder -from datetime import datetime - -from db import membersdb -from utils import unique_roles_id, non_deleted_members - -# import all models and types -from otypes import Info -from models import Member -from otypes import FullMemberInput, SimpleMemberInput, MemberType -from utils import getUser - -""" -MEMBER MUTATIONS -""" - - -@strawberry.mutation -def createMember(memberInput: FullMemberInput, info: Info) -> MemberType: - """ - Mutation to create a new member by that specific 'club' or cc - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - role = user["role"] - uid = user["uid"] - member_input = jsonable_encoder(memberInput.to_pydantic()) - - if (member_input["cid"] != uid or user["role"] != "club") and user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - if membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - } - ): - raise Exception("A record with same uid and cid already exists") - - # Check whether this uid is valid or not - userMember = getUser(member_input["uid"], info.context.cookies) - if userMember is None: - raise Exception("Invalid User ID") - - if len(member_input["roles"]) == 0: - raise Exception("Roles cannot be empty") - - for i in member_input["roles"]: - if i["end_year"] and i["start_year"] > i["end_year"]: - raise Exception("Start year cannot be greater than end year") - - roles0 = [] - for role in member_input["roles"]: - if role["start_year"] > datetime.now().year: - role["start_year"] = datetime.now().year - role["end_year"] = None - roles0.append(role) - - roles = [] - for role in roles0: - role["approved"] = user["role"] == "cc" - roles.append(role) - - member_input["roles"] = roles - - # DB STUFF - created_id = membersdb.insert_one(member_input).inserted_id - unique_roles_id(member_input["uid"], member_input["cid"]) - - created_sample = Member.parse_obj( - membersdb.find_one({"_id": created_id}, {"_id": 0}) - ) - - return MemberType.from_pydantic(created_sample) - - -@strawberry.mutation -def editMember(memberInput: FullMemberInput, info: Info) -> MemberType: - """ - Mutation to edit an already existing member+roles of that specific 'club' - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - uid = user["uid"] - member_input = jsonable_encoder(memberInput.to_pydantic()) - - if (member_input["cid"] != uid or user["role"] != "club") and user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - if len(member_input["roles"]) == 0: - raise Exception("Roles cannot be empty") - - for i in member_input["roles"]: - if i["end_year"] and i["start_year"] > i["end_year"]: - raise Exception("Start year cannot be greater than end year") - - member_ref = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - } - ) - - if member_ref is None: - raise Exception("No such Record!") - else: - member_ref = Member.parse_obj(member_ref) - - member_roles = member_ref.roles - - roles = [] - for role in member_input["roles"]: - if role["start_year"] > datetime.now().year: - role["start_year"] = datetime.now().year - role["end_year"] = None - role_new = role.copy() - - # if role's start_year, end_year, name is same as existing role, then keep the existing approved status - found_existing_role = False - for i in member_roles: - if ( - i.start_year == role_new["start_year"] - and i.end_year == role_new["end_year"] - and i.name == role_new["name"] - ): - role_new["approved"] = i.approved - role_new["rejected"] = i.rejected - role_new["deleted"] = i.deleted - - found_existing_role = True - - # Remove the existing role from member_roles - member_roles.remove(i) - break - - if not found_existing_role: - role_new["approved"] = user["role"] == "cc" - roles.append(role_new) - - # DB STUFF - membersdb.update_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"$set": {"roles": roles, "poc": member_input["poc"]}}, - ) - - unique_roles_id(member_input["uid"], member_input["cid"]) - - return non_deleted_members(member_input) - - -@strawberry.mutation -def deleteMember(memberInput: SimpleMemberInput, info: Info) -> MemberType: - """ - Mutation to delete an already existing member (role) of that specific 'club' - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - uid = user["uid"] - member_input = jsonable_encoder(memberInput) - - if (member_input["cid"] != uid or user["role"] != "club") and user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - existing_data = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"_id": 0}, - ) - if existing_data is None: - raise Exception("No such Record") - - if "rid" not in member_input or not member_input["rid"]: - membersdb.delete_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - } - ) - - return MemberType.from_pydantic(Member.parse_obj(existing_data)) - - roles = [] - for i in existing_data["roles"]: - if i["rid"] == member_input["rid"]: - i["deleted"] = True - roles.append(i) - - # DB STUFF - membersdb.update_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"$set": {"roles": roles}}, - ) - - unique_roles_id(member_input["uid"], member_input["cid"]) - - return non_deleted_members(member_input) - - -@strawberry.mutation -def approveMember(memberInput: SimpleMemberInput, info: Info) -> MemberType: - """ - Mutation to approve a member role by 'cc' - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - member_input = jsonable_encoder(memberInput) - - if user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - existing_data = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"_id": 0}, - ) - if existing_data is None: - raise Exception("No such Record") - - # if "rid" not in member_input: - # raise Exception("rid is required") - - roles = [] - for i in existing_data["roles"]: - if not member_input["rid"] or i["rid"] == member_input["rid"]: - i["approved"] = True - i["rejected"] = False - roles.append(i) - - # DB STUFF - membersdb.update_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"$set": {"roles": roles}}, - ) - - unique_roles_id(member_input["uid"], member_input["cid"]) - - return non_deleted_members(member_input) - - -@strawberry.mutation -def rejectMember(memberInput: SimpleMemberInput, info: Info) -> MemberType: - """ - Mutation to reject a member role by 'cc' - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - member_input = jsonable_encoder(memberInput) - - if user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - existing_data = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"_id": 0}, - ) - if existing_data is None: - raise Exception("No such Record") - - # if "rid" not in member_input: - # raise Exception("rid is required") - - roles = [] - for i in existing_data["roles"]: - if not member_input["rid"] or i["rid"] == member_input["rid"]: - i["approved"] = False - i["rejected"] = True - roles.append(i) - - # DB STUFF - membersdb.update_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"$set": {"roles": roles}}, - ) - - unique_roles_id(member_input["uid"], member_input["cid"]) - - return non_deleted_members(member_input) - - -# @strawberry.mutation -# def leaveClubMember(memberInput: SimpleMemberInput, info: Info) -> MemberType: -# user = info.context.user -# if user is None: -# raise Exception("Not Authenticated") - -# role = user["role"] -# uid = user["uid"] -# member_input = jsonable_encoder(memberInput.to_pydantic()) - -# if member_input["cid"] != uid and role != "club": -# raise Exception("Not Authenticated to access this API") - -# created_id = clubsdb.update_one( -# { -# "$and": [ -# {"cid": member_input["cid"]}, -# {"uid": member_input["uid"]}, -# {"start_year": member_input["start_year"]}, -# {"deleted": False}, -# ] -# }, -# {"$set": {"end_year": datetime.now().year}}, -# ) - -# created_sample = Member.parse_obj(membersdb.find_one({"_id": created_id})) -# return MemberType.from_pydantic(created_sample) - - -# register all mutations -mutations = [ - createMember, - editMember, - deleteMember, - approveMember, - rejectMember, -] diff --git a/otypes.py b/otypes.py index cfd81e5..69906d9 100644 --- a/otypes.py +++ b/otypes.py @@ -8,7 +8,7 @@ from typing import Union, Dict, List, Optional from functools import cached_property -from models import PyObjectId, Club, Social, Member, Roles +from models import PyObjectId, Club, Social # custom context class @@ -40,18 +40,6 @@ def cookies(self) -> Union[Dict, None]: # TYPES -@strawberry.experimental.pydantic.type(model=Roles, all_fields=True) -class RolesType: - pass - - -@strawberry.experimental.pydantic.type( - model=Member, fields=["id", "cid", "uid", "roles", "poc"] -) -class MemberType: - pass - - @strawberry.experimental.pydantic.type(model=Social) class SocialsType: website: Optional[str] = strawberry.UNSET @@ -136,23 +124,3 @@ class SimpleClubInput: class FullClubInput: banner: Optional[str] = strawberry.UNSET logo: Optional[str] = strawberry.UNSET - - -# MEMBERS INPUTS -@strawberry.experimental.pydantic.input( - model=Roles, fields=["name", "start_year", "end_year"] -) -class RolesInput: - pass - - -@strawberry.experimental.pydantic.input(model=Member, fields=["cid", "uid", "roles"]) -class FullMemberInput: - poc: Optional[bool] = strawberry.UNSET - - -@strawberry.input -class SimpleMemberInput: - cid: str - uid: str - rid: Optional[str] diff --git a/queries_clubs.py b/queries.py similarity index 99% rename from queries_clubs.py rename to queries.py index f45e545..696ef9d 100644 --- a/queries_clubs.py +++ b/queries.py @@ -11,10 +11,6 @@ from models import Club from otypes import SimpleClubType, FullClubType, SimpleClubInput -""" -Club Queries -""" - # fetch all active clubs @strawberry.field diff --git a/queries_members.py b/queries_members.py deleted file mode 100644 index e55e737..0000000 --- a/queries_members.py +++ /dev/null @@ -1,238 +0,0 @@ -import strawberry - -from fastapi.encoders import jsonable_encoder -from typing import List - -from db import membersdb - -# import all models and types -from otypes import Info - -from models import Member -from otypes import SimpleClubInput, SimpleMemberInput -from otypes import MemberType - -""" -Member Queries -""" - - -@strawberry.field -def member(memberInput: SimpleMemberInput, info: Info) -> MemberType: - """ - Description: - Returns member details for a specific club - Scope: CC & Specific Club - Return Type: MemberType - Input: SimpleMemberInput (cid, uid) - """ - user = info.context.user - if user is None: - raise Exception("Not Authenticated") - - uid = user["uid"] - member_input = jsonable_encoder(memberInput) - - if (member_input["cid"] != uid or user["role"] != "club") and user["role"] != "cc": - raise Exception("Not Authenticated to access this API") - - member = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"_id": 0}, - ) - if member is None: - raise Exception("No such Record") - - return MemberType.from_pydantic(Member.parse_obj(member)) - - -@strawberry.field -def memberRoles(uid: str, info: Info) -> List[MemberType]: - """ - Description: - Returns member roles from each club - Scope: CC & Specific Club - Return Type: uid (str) - Input: SimpleMemberInput (cid, uid, roles) - """ - user = info.context.user - if user is None: - role = "public" - else: - role = user["role"] - - results = membersdb.find({"uid": uid}, {"_id": 0}) - - if not results: - raise Exception("No Member Result/s Found") - - members = [] - for result in results: - roles = result["roles"] - roles_result = [] - - for i in roles: - if i["deleted"] is True: - continue - if role != "cc": - if i["approved"] is False: - continue - roles_result.append(i) - - if len(roles_result) > 0: - result["roles"] = roles_result - members.append(MemberType.from_pydantic(Member.parse_obj(result))) - - return members - - -@strawberry.field -def members(clubInput: SimpleClubInput, info: Info) -> List[MemberType]: - """ - Description: - For CC: - Returns all the non-deleted members. - For Specific Club: - Returns all the non-deleted members of that club. - For Public: - Returns all the non-deleted and approved members. - Scope: CC + Club (For All Members), Public (For Approved Members) - Return Type: List[MemberType] - Input: SimpleClubInput (cid) - """ - user = info.context.user - if user is None: - role = "public" - else: - role = user["role"] - - club_input = jsonable_encoder(clubInput) - - if role not in ["cc"] or club_input["cid"] != "clubs": - results = membersdb.find({"cid": club_input["cid"]}, {"_id": 0}) - else: - results = membersdb.find({}, {"_id": 0}) - - if results: - members = [] - for result in results: - roles = result["roles"] - roles_result = [] - - for i in roles: - if i["deleted"] is True: - continue - if not ( - role in ["cc"] - or (role in ["club"] and user["uid"] == club_input["cid"]) - ): - if i["approved"] is False: - continue - roles_result.append(i) - - if len(roles_result) > 0: - result["roles"] = roles_result - members.append(MemberType.from_pydantic(Member.parse_obj(result))) - - return members - - else: - raise Exception("No Member Result/s Found") - - -@strawberry.field -def currentMembers(clubInput: SimpleClubInput, info: Info) -> List[MemberType]: - """ - Description: - For Everyone: - Returns all the current non-deleted and approved members of the given clubid. - - Scope: Anyone (Non-Admin Function) - Return Type: List[MemberType] - Input: SimpleClubInput (cid) - """ - user = info.context.user - if user is None: - role = "public" - else: - role = user["role"] - - club_input = jsonable_encoder(clubInput) - - if club_input["cid"] == "clubs": - if role != "cc": - raise Exception("Not Authenticated") - - results = membersdb.find({}, {"_id": 0}) - else: - results = membersdb.find({"cid": club_input["cid"]}, {"_id": 0}) - - if results: - members = [] - for result in results: - roles = result["roles"] - roles_result = [] - - for i in roles: - if i["deleted"] is True or i["end_year"] is not None: - continue - if i["approved"] is False: - continue - roles_result.append(i) - - if len(roles_result) > 0: - result["roles"] = roles_result - members.append(MemberType.from_pydantic(Member.parse_obj(result))) - - return members - else: - raise Exception("No Member Result/s Found") - - -@strawberry.field -def pendingMembers(info: Info) -> List[MemberType]: - """ - Description: Returns all the non-deleted and non-approved members. - Scope: CC - Return Type: List[MemberType] - Input: None - """ - user = info.context.user - if user is None or user["role"] not in ["cc"]: - raise Exception("Not Authenticated") - - results = membersdb.find({}, {"_id": 0}) - - if results: - members = [] - for result in results: - roles = result["roles"] - roles_result = [] - - for i in roles: - if i["deleted"] or i["approved"] or i["rejected"]: - continue - roles_result.append(i) - - if len(roles_result) > 0: - result["roles"] = roles_result - members.append(MemberType.from_pydantic(Member.parse_obj(result))) - - return members - else: - raise Exception("No Member Result/s Found") - - -# register all queries -queries = [ - member, - memberRoles, - members, - currentMembers, - pendingMembers, -] diff --git a/utils.py b/utils.py index becaf43..4b146dd 100644 --- a/utils.py +++ b/utils.py @@ -1,12 +1,6 @@ import requests -from datetime import datetime import os -from db import membersdb - -from models import Member -from otypes import MemberType - inter_communication_secret = os.getenv("INTER_COMMUNICATION_SECRET") @@ -43,10 +37,11 @@ def update_role(uid, cookies=None, role="club"): return None -def update_events_cid(old_cid, new_cid, cookies=None): +def update_events_members_cid(old_cid, new_cid, cookies=None) -> bool: """ - Function to call the updateEventsCid mutation + Function to call the updateEventsCid & updateMembersCid mutation """ + return1, return2 = None, None try: query = """ mutation UpdateEventsCid($oldCid: String!, $newCid: String!, $interCommunicationSecret: String) { @@ -69,87 +64,40 @@ def update_events_cid(old_cid, new_cid, cookies=None): "http://gateway/graphql", json={"query": query, "variables": variables} ) - return result.json() + return1 = result.json() except Exception: - return None - - -def update_members_cid(old_cid, new_cid): - updation = { - "$set": { - "cid": new_cid, + return False + + try: + query = """ + mutation UpdateMembersCid($oldCid: String!, $newCid: String!, $interCommunicationSecret: String) { + updateMembersCid(oldCid: $oldCid, newCid: $newCid, interCommunicationSecret: $interCommunicationSecret) + } + """ + variables = { + "oldCid": old_cid, + "newCid": new_cid, + "interCommunicationSecret": inter_communication_secret, } - } - upd_ref = membersdb.update_many({"cid": old_cid}, updation) - return upd_ref.modified_count - - -def non_deleted_members(member_input) -> MemberType: - """ - Function to return non-deleted members for a particular cid, uid - Only to be used in admin functions, as it returns both approved/non-approved members. - """ - updated_sample = membersdb.find_one( - { - "$and": [ - {"cid": member_input["cid"]}, - {"uid": member_input["uid"]}, - ] - }, - {"_id": 0}, - ) - if updated_sample is None: - raise Exception("No such Record") - - roles = [] - for i in updated_sample["roles"]: - if i["deleted"] is True: - continue - roles.append(i) - updated_sample["roles"] = roles - - return MemberType.from_pydantic(Member.parse_obj(updated_sample)) + if cookies: + result = requests.post( + "http://gateway/graphql", + json={"query": query, "variables": variables}, + cookies=cookies, + ) + else: + result = requests.post( + "http://gateway/graphql", json={"query": query, "variables": variables} + ) + return2 = result.json() + except Exception: + return False -def unique_roles_id(uid, cid): - """ - Function to give unique ids for each of the role in roles list - """ - pipeline = [ - { - "$set": { - "roles": { - "$map": { - "input": {"$range": [0, {"$size": "$roles"}]}, - "in": { - "$mergeObjects": [ - {"$arrayElemAt": ["$roles", "$$this"]}, - { - "rid": { - "$toString": { - "$add": [ - {"$toLong": datetime.now()}, - "$$this", - ] - } - } - }, - ] - }, - } - } - } - } - ] - membersdb.update_one( - { - "$and": [ - {"cid": cid}, - {"uid": uid}, - ] - }, - pipeline, - ) + if return1 and return2: + return True + else: + return False def getUser(uid, cookies=None):