import httpx from typing import Optional, Union, List from functools import wraps from .Schema import ( RegisterUserRequest, LoginRequest, SetUserStatusRequest, APIResponse, ) from App.Portals.PortalRoutes import ANDROID from App.Portals.Model import Portal def require_base_url(func): """Decorator to set base_url before making a request.""" @wraps(func) async def wrapper(self, *args, **kwargs): await self.set_base_url() return await func(self, *args, **kwargs) return wrapper class AndroidClient: def __init__(self): self.client = httpx.AsyncClient() async def set_base_url(self): """Fetch the base_url from the database.""" portal = await Portal.get(name=ANDROID) self.client.base_url = portal.url @require_base_url async def register_user(self, request: RegisterUserRequest) -> APIResponse: """Register a new user.""" response = await self.client.post("/users/register", json=request.dict()) return APIResponse(**response.json()) @require_base_url async def login_user(self, request: LoginRequest) -> APIResponse: """Login an existing user.""" response = await self.client.post("/login", json=request.dict()) return APIResponse(**response.json()) @require_base_url async def logout_user(self, phone: str) -> APIResponse: """Logout a user by phone.""" response = await self.client.post(f"/logout/{phone}") return APIResponse(**response.json()) @require_base_url async def is_user_active(self, phone_number): """Retrieve all active users.""" response = await self.client.get("/users/active") try: data = response.json() except: return None if "active_users" in data: active_users = data["active_users"] for user in active_users: if phone_number == user["phone"]: return True @require_base_url async def get_active_users(self) -> APIResponse: """Retrieve all active users.""" response = await self.client.get("/users/active") print(response.json()) return APIResponse(**response.json()) @require_base_url async def remove_session(self, phone_number) -> APIResponse: """Enable or disable a user.""" path = f"/users/{phone_number}/remove-session" try: response = await self.client.post(path, json=None) return APIResponse(**response.json()) except: pass @require_base_url async def _disable_request(self, request: SetUserStatusRequest) -> APIResponse: """disable a user.""" path = f"/users/{request.phone}/disable" response = await self.client.post(path, json=None) return APIResponse(**response.json()) @require_base_url async def enable_user(self, request: SetUserStatusRequest) -> APIResponse: """Enable or disable a user.""" path = f"/users/{request.phone}/enable" response = await self.client.post(path, json=None) return APIResponse(**response.json()) @require_base_url async def get_users_list(self) -> APIResponse: """Retrieve all users (active and inactive).""" response = await self.client.get("/users") return APIResponse(**response.json()) @require_base_url async def get_user_stats(self, phone: Optional[str] = None) -> APIResponse: """Retrieve user statistics for a specific user or all users.""" url = f"/user/stats/{phone}" if phone else "/user/stats" response = await self.client.get(url) return APIResponse(**response.json()) @require_base_url async def send_message( self, message: str, phone_numbers: Union[str, List[str]], event: str = "string", ) -> APIResponse: """Send a message to a single phone number or a list of phone numbers.""" # Ensure phone_numbers is a list if isinstance(phone_numbers, str): phone_numbers = [phone_numbers] data = { "message": message, "phoneNumbers": phone_numbers, "event": event, } print(data) response = await self.client.post("/send_message", json=data) x = response.content print(x) if response.status_code < 200 or response.status_code >= 300: return response else: raise Exception(f"Error sending message : {x}") async def close(self): """Close the client session.""" await self.client.aclose() async def activate_user(self, phone_number: str): request = SetUserStatusRequest(phone=phone_number, disabled=False) await self.enable_user(request=request) # Replace this with actual API call logic return {"status": "success", "message": "User activated."} async def deactivate_user(self, phone_number: str): request = SetUserStatusRequest(phone=phone_number, disabled=False) await self._disable_request(request=request) # Replace this with actual API call logic return {"status": "success", "message": "User activated."}