""" AUTHOR: Khushal P Soonderji DATE: Monday, 2nd Dec., 2024 OBJECTIVE: To receive requests for synchronising mails from various mail clients to the database. Sync'ing means we pull the mail from the mail client (like GMail) and store it to our database. The mail is then ready for showing on the UI at any time. REFERENCES: N/A DOWNLOADS: N/A NOTES: N/A """ # ***************************************************************************************************************** # ***** **** # *** IMPORT *** # ***** **** # ***************************************************************************************************************** # To make sibling directories accessible for imports: import sys sys.path.append(".") sys.path.append("..") # For using Quart: from quart import Blueprint, current_app, request # My utils: from utils_v2.string import json from utils_v2.api.codes import StatusCodes, HttpCodes from utils_v2.api.response import ResponseModel from utils_v2.api.async_quart import ( set_api_version, read_input, get_session_info, log_request_to_mongo, log_chain_to_mongo, should_not_be_under_maintenance, only_whitelisted_ips, limit_rate, validate_input, handle_cancelled_request ) # GMail-related utils: from utils_v2.goog.gmail.gmail_client import SCOPES_GMAIL_MAIL_MANAGEMENT # Common: from shared import constants # Data Models: from models.data.mail.sync import MailSyncRequestHeaders, MailSyncRequestData # For asynchronous activities: import asyncio # ***************************************************************************************************************** # ***** **** # *** MACROS / ONE-TIME INIT *** # ***** **** # ***************************************************************************************************************** # Related to Quart: mail_sync_bp = Blueprint("mail_sync", __name__) # ***************************************************************************************************************** # ***** **** # *** VARIABLES *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** FUNCTIONS *** # ***** **** # ***************************************************************************************************************** @mail_sync_bp.record_once def init(blueprint_setup_state): # This gets called when the blueprint is registered. # Consider this to be a one-time setup for the whole blueprint: pass # --------------------------------------------------------------------------------------------------------------------- @mail_sync_bp.route("/sync", methods = ["GET"]) @set_api_version(api_version = "1.0.0") @read_input(sanitize_headers = False, sanitize_data = False) @get_session_info(key = "X-Session-Token", session_coro = "get_session") @log_request_to_mongo( attr_name = "logs_mongo", project = constants.PROJECT_NAME, log_type = constants.MODULE_NAME, operation = "mailOAuthUrlReqApi", log_input = True, log_output = True, sensitive_keys = ["sessionToken"] ) @log_chain_to_mongo(attr_name = "logs_mongo") @should_not_be_under_maintenance(attr_name = "is_under_maintenance") @validate_input( header_validator = lambda x: MailSyncRequestHeaders(**x).model_dump(), data_validator = lambda x: MailSyncRequestData(**x) ) @handle_cancelled_request() async def sync_mail( inbound_headers: dict | MailSyncRequestHeaders = None, inbound_data: dict | MailSyncRequestData = None, inbound_files: dict = None, **kwargs ): """ Use this when the user wants to pull old mails from some mail client (like GMail) and save it to the database for ready access on the UI. :param inbound_headers: auto-extracted by the decorators. :param inbound_data: auto-extracted by the decorators. :param inbound_files: auto-extracted by the decorators. :param kwargs: Any number of extra inputs supplied by the decorators. :return: A standard response structure. """ # ┏┓ # ┃┃┏┓┏┓┏┓┏┓┏┓┏┏┓┏┏ # ┣┛┛ ┗ ┣┛┛ ┗┛┗┗ ┛┛ # ┛ # If the session token is invalid/expired: if kwargs.get("session_info") is None: return ResponseModel( status_code = StatusCodes.FAILED, http_code = HttpCodes.UNAUTHORIZED ) # Start by assuming failure: auth_url = None # ┏┓ ┏┳┓ ┓ # ┃┓┏┓╋ ┃ ┏┓┃┏┏┓┏┓ # ┗┛┗ ┗ ┻ ┗┛┛┗┗ ┛┗ # Make a user identifier from the session info: user_tokens = await current_app.mail_oauth_model.get_token( mongo_conn = current_app.data_mongo, user = kwargs["session_info"] ) print("MAIL TOKEN(S):", json.to_string(user_tokens)) # ┳┓ # ┣┫┏┓┏┏┓┏┓┏┓┏┏┓ # ┛┗┗ ┛┣┛┗┛┛┗┛┗ # ┛ # Done here: return ResponseModel(status_code = StatusCodes.OK) # ***************************************************************************************************************** # ***** **** # *** MAIN PROGRAM *** # ***** **** # ***************************************************************************************************************** if __name__ == "__main__": pass