(20241203) Mails sync'ing, listing, and fetching done.

This commit is contained in:
2024-12-03 16:01:08 +05:30
parent 3b5a1fc92f
commit bef8f6ef0d
8 changed files with 137 additions and 223 deletions
+54 -5
View File
@@ -108,11 +108,12 @@ class MailRetrieveModel(BaseModel):
:return: Either the JSON that describes the mail or None if such a mail does not exist.
"""
# Get the data from the database:
mail_data = await mongo_conn.find_one(
collection = self.MAIL_COLLECTION,
filter = {"_id": ObjectId(mail_identifier)},
projection = {
"mailId": "_id",
"_id": True,
"serviceType": True,
"client": True,
"payload.ts": True,
@@ -125,13 +126,22 @@ class MailRetrieveModel(BaseModel):
"payload.attachments": True,
"payload.labels": True,
"payload.snippet": True,
"payload.aiSnippet": "payload.aiSnippet.snippet",
"payload.aiSnippet": True,
}
)
if mail_data: mail_data["mailId"] = str(mail_data["mailId"])
# Format the data:
if mail_data:
mail_data["mailId"] = str(mail_data.pop("_id"))
mail_data["payload"]["ts"] = mail_data["payload"]["ts"].isoformat()
mail_data["payload"]["readTs"] = mail_data["payload"]["readTs"].isoformat()
if ai_snippet := mail_data["payload"].pop("aiSnippet"):
mail_data["payload"]["aiSnippet"] = ai_snippet["snippet"]
# Done here:
return mail_data
async def list_by_account_identifier(
async def list_for_account_identifier(
self,
mongo_conn: AsyncMongo,
account_identifier: str | ObjectId,
@@ -139,7 +149,46 @@ class MailRetrieveModel(BaseModel):
skip: int = 0
):
pass
"""
To enlist mails for one account.
:param mongo_conn: The instance of the database connector to use to get the mail's data.
:param account_identifier: The id of the document in the database that holds the tokens to access the account.
:param limit: How many records to fetch.
:param skip: How many initial records to skip. useful for pagination.
:return: Either the JSON that describes the mails or None if something failed.
"""
# Get the data from the database:
mails_list = await mongo_conn.find_many(
collection = self.MAIL_COLLECTION,
filter = {"accountId": ObjectId(account_identifier)},
projection = {
"_id": True,
"serviceType": True,
"client": True,
"payload.ts": True,
"payload.readTs": True,
"payload.from": True,
"payload.labels": True,
"payload.snippet": True,
"payload.aiSnippet": True,
},
limit = limit,
skip = skip,
sort = {"payload.ts": -1}
)
# Format the data:
if mails_list:
for mail_data in mails_list:
mail_data["mailId"] = str(mail_data.pop("_id"))
mail_data["payload"]["ts"] = mail_data["payload"]["ts"].isoformat()
mail_data["payload"]["readTs"] = mail_data["payload"]["readTs"].isoformat()
if ai_snippet := mail_data["payload"].pop("aiSnippet"):
mail_data["payload"]["aiSnippet"] = ai_snippet["snippet"]
# Done here:
return mails_list
# *****************************************************************************************************************
+18 -4
View File
@@ -75,7 +75,7 @@ REGEX_SESSION_TOKEN = r"^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]
# *****************************************************************************************************************
class MailGetRequestHeaders(BaseModel):
class MailListRequestHeaders(BaseModel):
sessionToken: str = Field(
description = "the session token of the user who is requesting the service",
@@ -99,10 +99,24 @@ class MailGetRequestHeaders(BaseModel):
# ---------------------------------------------------------------------------------------------------------------------
class MailGetRequestData(BaseModel):
class MailListByAccountIdRequestData(BaseModel):
mailId: str = Field(
description = "the mail identifier (Mongo ObjectId) of the document that holds the mail",
accountId: str = Field(
description = "the account identifier (Mongo ObjectId) granted by 'MailOAuthModel.get_account_identifier'",
frozen = True
)
count: int = Field(
description = "the no. of mails to list",
default = 25,
ge = 1,
le = 500,
frozen = True
)
fromCount: int = Field(
description = "the no. of mails to skip before picking mails to list; useful for pagination",
default = 0,
frozen = True
)
+6 -107
View File
@@ -6,11 +6,11 @@
DATE:
Monday, 2nd Dec., 2024.
Tuesday, 3rd Dec., 2024.
OBJECTIVE:
To provide the structure for the request that will come in to sync the mails of a particular user.
To provide a structure to query the full payload of an email.
REFERENCES:
@@ -75,7 +75,7 @@ REGEX_SESSION_TOKEN = r"^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]
# *****************************************************************************************************************
class MailSyncRequestHeaders(BaseModel):
class MailGetRequestHeaders(BaseModel):
sessionToken: str = Field(
description = "the session token of the user who is requesting the service",
@@ -99,114 +99,13 @@ class MailSyncRequestHeaders(BaseModel):
# ---------------------------------------------------------------------------------------------------------------------
class MailSyncRequestData(BaseModel):
class MailGetRequestData(BaseModel):
accountId: str = Field(
description = "the account identifier (Mongo ObjectId) granted by 'MailOAuthModel.get_account_identifier'",
mailId: str = Field(
description = "the mail identifier (Mongo ObjectId) of the document that holds the mail",
frozen = True
)
maxCount: int = Field(
description = "the max. no. of e-mails to sync at a given time",
default = 100,
ge = 1,
le = 100,
frozen = True
)
startDate: PastDatetime = Field(
description = "the starting date from which the user wants to sync their mail",
default_factory = lambda: date_time.get_current_utc_date_time() - datetime.timedelta(days = 1),
frozen = True
)
endDate: PastDatetime = Field(
description = "the ending date till which the user wants to sync their mail",
default_factory = lambda: date_time.get_current_utc_date_time() - datetime.timedelta(seconds = 1),
frozen = True
)
forceSync: bool = Field(
description = "use this to forcefully re-sync mails when you need to overwrite existing data in mongodb",
default = False
)
# ┏┓ ┏•
# ┃ ┏┓┏┓╋┓┏┓
# ┗┛┗┛┛┗┛┗┗┫
# ┛
class Config:
extra = "forbid"
# ┓┏ ┓• ┓ •
# ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓
# ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗
@field_validator("startDate", "endDate", mode = "before")
def to_datetime(cls, value):
if not isinstance(value, datetime.datetime):
value = date_time.parse_date_time(
input_value = value,
timezone = date_time.TIMEZONE_UTC
)
return value
# ---------------------------------------------------------------------------------------------------------------------
class MailSyncOneResult(BaseModel):
success: bool = Field(
description = "whether, or not, the mail was successfully sync'd",
default = False
)
message: str | None = Field(
description = "a brief message to summarize the result of the process",
default = None
)
mailMessage: dict | None = Field(
description = "the actual data of the mail; can be null in a successful process if the mail is already sync'd",
default = None
)
# ┏┓ ┏•
# ┃ ┏┓┏┓╋┓┏┓
# ┗┛┗┛┛┗┛┗┗┫
# ┛
class Config:
extra = "forbid"
# ---------------------------------------------------------------------------------------------------------------------
class MailSyncManyResults(BaseModel):
totalCount: int = Field(
description = "the total no. of mails that were to be sync'd",
default = 0
)
successCount: int = Field(
description = "the no. of mails that were successfully sync'd",
default = 0
)
failureCount: int = Field(
description = "the no. of mails that were successfully sync'd",
default = 0
)
message: str = Field(
description = "a brief message to summarize the results of the process",
default = None
)
# ┏┓ ┏•
# ┃ ┏┓┏┓╋┓┏┓
# ┗┛┗┛┛┗┛┗┗┫