add s3 migration
This commit is contained in:
parent
023691d062
commit
e79646cc04
246
aws-s3-migration/aws-s3-migrate-documents.py
Normal file
246
aws-s3-migration/aws-s3-migrate-documents.py
Normal file
@ -0,0 +1,246 @@
|
||||
import json
|
||||
import os
|
||||
import mysql.connector
|
||||
import boto3
|
||||
import sys
|
||||
|
||||
# --- Configuration Loading ---
|
||||
|
||||
CONFIG_FILE = 'config.json'
|
||||
|
||||
def load_config():
|
||||
"""Loads configuration from config.json."""
|
||||
if not os.path.exists(CONFIG_FILE):
|
||||
print(f"Error: Configuration file '{CONFIG_FILE}' not found.")
|
||||
sys.exit(1)
|
||||
try:
|
||||
with open(CONFIG_FILE, 'r') as f:
|
||||
return json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error decoding JSON in config file: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# --- S3 Helper Functions ---
|
||||
|
||||
def generate_new_s3_key(old_key, prefix):
|
||||
"""
|
||||
Generates a new S3 key by prepending the destination prefix to the old key,
|
||||
thereby preserving the original path structure.
|
||||
"""
|
||||
if not isinstance(old_key, str) or not old_key:
|
||||
return None
|
||||
|
||||
# Ensure the prefix ends with a slash if it's not empty and doesn't already end with one.
|
||||
prefixed_path = prefix
|
||||
if prefix and not prefix.endswith('/'):
|
||||
prefixed_path += '/'
|
||||
|
||||
# Combine the prefix and the old key. If the old key starts with a slash, strip it.
|
||||
final_key = old_key.lstrip('/')
|
||||
|
||||
return f"{prefixed_path}{final_key}"
|
||||
|
||||
|
||||
def move_s3_object(s3_client, source_bucket, source_key, dest_bucket, dest_key):
|
||||
"""
|
||||
Performs the S3 'move' operation (Copy + Delete).
|
||||
|
||||
Returns True on success, False otherwise.
|
||||
"""
|
||||
copy_source = {
|
||||
'Bucket': source_bucket,
|
||||
'Key': source_key
|
||||
}
|
||||
|
||||
try:
|
||||
print(f" -> Copying '{source_key}' to '{dest_key}' in '{dest_bucket}'...")
|
||||
# 1. Copy the object
|
||||
s3_client.copy_object(
|
||||
CopySource=copy_source,
|
||||
Bucket=dest_bucket,
|
||||
Key=dest_key
|
||||
)
|
||||
print(" -> Copy object successful.")
|
||||
|
||||
# print(f" -> Deleting original object from '{source_bucket}/{source_key}'...")
|
||||
# # 2. Delete the original object
|
||||
# s3_client.delete_object(
|
||||
# Bucket=source_bucket,
|
||||
# Key=source_key
|
||||
# )
|
||||
# print(" -> Delete object successful.")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" -> S3 Move FAILED for {source_key}: {e}")
|
||||
return False
|
||||
|
||||
# --- MySQL Helper Functions ---
|
||||
|
||||
def fetch_documents(db_config_full):
|
||||
"""
|
||||
Connects to MySQL and fetches all documents (ID and S3Key).
|
||||
NOTE: db_config_full includes the 'table' key, which must be filtered out for the connection.
|
||||
"""
|
||||
conn = None
|
||||
cursor = None
|
||||
|
||||
# Separate connection parameters from the table name
|
||||
table_name = db_config_full['table']
|
||||
connection_config = {k: v for k, v in db_config_full.items() if k != 'table'}
|
||||
|
||||
try:
|
||||
# Connect using only valid connection parameters
|
||||
conn = mysql.connector.connect(**connection_config)
|
||||
cursor = conn.cursor()
|
||||
|
||||
print(f"Fetching document IDs and S3Keys from table: {table_name}...")
|
||||
|
||||
# Select all ID and S3Key (or whatever column holds the key)
|
||||
query = f"SELECT ID, S3Key FROM {table_name} order by UploadedAt desc limit 10"
|
||||
cursor.execute(query)
|
||||
|
||||
# Fetch results as a list of dictionaries/tuples
|
||||
documents = cursor.fetchall()
|
||||
print(f"Found {len(documents)} documents to process.")
|
||||
return documents
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print(f"MySQL Error: {err}")
|
||||
return []
|
||||
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if conn and conn.is_connected():
|
||||
conn.close()
|
||||
|
||||
def update_document_key(db_config_full, doc_id, new_s3_key):
|
||||
"""
|
||||
Updates the S3Key for a specific document ID in the database.
|
||||
NOTE: db_config_full includes the 'table' key, which must be filtered out for the connection.
|
||||
"""
|
||||
conn = None
|
||||
cursor = None
|
||||
|
||||
# Separate connection parameters from the table name
|
||||
table_name = db_config_full['table']
|
||||
connection_config = {k: v for k, v in db_config_full.items() if k != 'table'}
|
||||
|
||||
try:
|
||||
# Connect using only valid connection parameters
|
||||
conn = mysql.connector.connect(**connection_config)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Prepare the UPDATE query
|
||||
update_query = (
|
||||
f"UPDATE {table_name} SET S3Key = %s WHERE ID = %s"
|
||||
)
|
||||
|
||||
cursor.execute(update_query, (new_s3_key, doc_id))
|
||||
|
||||
# Commit the transaction to apply the changes
|
||||
conn.commit()
|
||||
print(f" -> DB Update SUCCESS for ID {doc_id}.")
|
||||
return True
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print(f" -> DB Update FAILED for ID {doc_id}: {err}. Rolling back.")
|
||||
if conn:
|
||||
conn.rollback()
|
||||
return False
|
||||
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if conn and conn.is_connected():
|
||||
conn.close()
|
||||
|
||||
# --- Main Migration Logic ---
|
||||
|
||||
def main():
|
||||
"""Executes the S3 migration and database update workflow."""
|
||||
config = load_config()
|
||||
|
||||
# Initialize S3 Client
|
||||
aws_config = config['aws']
|
||||
try:
|
||||
s3_client = boto3.client(
|
||||
's3',
|
||||
aws_access_key_id=aws_config['aws_access_key_id'],
|
||||
aws_secret_access_key=aws_config['aws_secret_access_key'],
|
||||
region_name=aws_config['aws_region']
|
||||
)
|
||||
print("S3 client initialized successfully.")
|
||||
except Exception as e:
|
||||
print(f"Failed to initialize S3 client: {e}")
|
||||
return
|
||||
|
||||
# Fetch Documents
|
||||
documents = fetch_documents(config['mysql'])
|
||||
if not documents:
|
||||
print("No documents found or failed to connect to the database. Exiting.")
|
||||
return
|
||||
|
||||
source_bucket = aws_config['source_bucket']
|
||||
dest_bucket = aws_config['destination_bucket']
|
||||
key_prefix = aws_config['destination_key_prefix']
|
||||
|
||||
success_count = 0
|
||||
failure_count = 0
|
||||
|
||||
print("\n--- Starting Document Migration Process ---")
|
||||
|
||||
for doc_id, old_s3_key in documents:
|
||||
print(f"\nProcessing Document ID: {doc_id}, Old Key: {old_s3_key}")
|
||||
|
||||
if not old_s3_key:
|
||||
print(f" -> Skipping ID {doc_id}: S3Key is empty.")
|
||||
failure_count += 1
|
||||
continue
|
||||
|
||||
# 1. Generate new key, preserving path structure
|
||||
new_s3_key = generate_new_s3_key(old_s3_key, key_prefix)
|
||||
if not new_s3_key:
|
||||
print(f" -> Skipping ID {doc_id}: Could not generate new key from old key.")
|
||||
failure_count += 1
|
||||
continue
|
||||
|
||||
print(f" -> Calculated New Key: {new_s3_key}")
|
||||
|
||||
# 2. Move S3 object (Copy + Delete)
|
||||
move_successful = move_s3_object(
|
||||
s3_client,
|
||||
source_bucket,
|
||||
old_s3_key,
|
||||
dest_bucket,
|
||||
new_s3_key
|
||||
)
|
||||
|
||||
if move_successful:
|
||||
# 3. Update database
|
||||
db_update_successful = update_document_key(
|
||||
config['mysql'],
|
||||
doc_id,
|
||||
new_s3_key
|
||||
)
|
||||
|
||||
if db_update_successful:
|
||||
success_count += 1
|
||||
else:
|
||||
# If DB update fails, the S3 object is MOVED. Log critical error.
|
||||
print(f"CRITICAL: DB update failed for ID {doc_id}. Object is MOVED to {dest_bucket}/{new_s3_key}. Manual DB correction needed.")
|
||||
failure_count += 1
|
||||
else:
|
||||
# If S3 move failed, the object remains in the source bucket.
|
||||
print(f"S3 move failed for ID {doc_id}. Object remains in {source_bucket}/{old_s3_key}. DB not updated.")
|
||||
failure_count += 1
|
||||
|
||||
|
||||
print("\n--- Migration Summary ---")
|
||||
print(f"Total documents processed: {len(documents)}")
|
||||
print(f"Successful migrations (S3 Move + DB Update): {success_count}")
|
||||
print(f"Failed migrations: {failure_count}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
18
aws-s3-migration/config.json
Normal file
18
aws-s3-migration/config.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"mysql": {
|
||||
"host": "147.93.98.152",
|
||||
"user": "devuser",
|
||||
"password": "AppUser@123$",
|
||||
"database": "MarcoBMSStage",
|
||||
"table": "Documents"
|
||||
},
|
||||
"aws": {
|
||||
"aws_access_key_id": "AKIARZDBH3VDKXLBMDX6",
|
||||
"aws_secret_access_key": "ZEnwQuN9vWi+KodD+gvNEz46VCZ6/4ue3UKLbTTs",
|
||||
"aws_region": "us-east-1",
|
||||
"source_bucket": "testenv-marco-pms-documents",
|
||||
"destination_bucket": "tryenv-marco-pms-documents",
|
||||
"destination_key_prefix": "",
|
||||
"destination_key_prefix_how": "IMPORTANT: The original S3Key (e.g., 'reports/2024/doc.pdf') will be APPENDED to this prefix, preserving the path structure. Resulting Key: 'migrated_files/reports/2024/doc.pdf'"
|
||||
}
|
||||
}
|
||||
1
aws-s3-migration/readme.MD
Normal file
1
aws-s3-migration/readme.MD
Normal file
@ -0,0 +1 @@
|
||||
https://wiki.marcoaiot.com/index.php/AWS_S3_Migration_Script
|
||||
@ -473,8 +473,8 @@
|
||||
<!-- Left Column -->
|
||||
<div style="width:50%; box-sizing:border-box;display:flex; justify-content:center; align-items:center;">
|
||||
<!-- Medium -->
|
||||
<div class="donut thin donut-warning" style="--percentage: 73;">
|
||||
<span>73%</span>
|
||||
<div class="donut thin donut-warning" style="--percentage: 0;">
|
||||
<span>0%</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
2670
python-email-sender/body copy 2.html
Normal file
2670
python-email-sender/body copy 2.html
Normal file
File diff suppressed because it is too large
Load Diff
636
python-email-sender/body copy.html
Normal file
636
python-email-sender/body copy.html
Normal file
File diff suppressed because one or more lines are too long
914
python-email-sender/body.html
Normal file
914
python-email-sender/body.html
Normal file
@ -0,0 +1,914 @@
|
||||
<!DOCTYPE HTML
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
|
||||
<head>
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<!--[if !mso]><!-->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->
|
||||
<title></title>
|
||||
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 710px) {
|
||||
.u-row {
|
||||
width: 690px !important;
|
||||
}
|
||||
|
||||
.u-row .u-col {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
.u-row .u-col-33p33 {
|
||||
width: 229.97699999999998px !important;
|
||||
}
|
||||
|
||||
|
||||
.u-row .u-col-50 {
|
||||
width: 345px !important;
|
||||
}
|
||||
|
||||
|
||||
.u-row .u-col-100 {
|
||||
width: 690px !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 710px) {
|
||||
.u-row-container {
|
||||
max-width: 100% !important;
|
||||
padding-left: 0px !important;
|
||||
padding-right: 0px !important;
|
||||
}
|
||||
|
||||
.u-row {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.u-row .u-col {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
min-width: 320px !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.u-row .u-col>div {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
.u-row .u-col img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
table,
|
||||
td,
|
||||
tr {
|
||||
border-collapse: collapse;
|
||||
vertical-align: top
|
||||
}
|
||||
|
||||
.ie-container table,
|
||||
.mso-container table {
|
||||
table-layout: fixed
|
||||
}
|
||||
|
||||
* {
|
||||
line-height: inherit
|
||||
}
|
||||
|
||||
a[x-apple-data-detectors=true] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important
|
||||
}
|
||||
|
||||
|
||||
table,
|
||||
td {
|
||||
color: #000000;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="clean-body u_body"
|
||||
style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #F7F8F9;color: #000000">
|
||||
<!--[if IE]><div class="ie-container"><![endif]-->
|
||||
<!--[if mso]><div class="mso-container"><![endif]-->
|
||||
<table role="presentation"
|
||||
style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #F7F8F9;width:100%"
|
||||
cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr style="vertical-align: top">
|
||||
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: #F7F8F9;"><![endif]-->
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 1px 0px 0px;background-color: #b10000">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 1px 0px 0px;background-color: #b10000;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="345" style="background-color: #b10000;width: 345px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-50"
|
||||
style="max-width: 320px;min-width: 345px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="background-color: #b10000;height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:15px 10px 10px 11px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<div>
|
||||
<h3 style="display: block;
|
||||
color: #ffffff;
|
||||
margin: 0;vertical-align:top;
|
||||
|
||||
font-size: 1.6em;
|
||||
margin-block-start: 0.67em;
|
||||
margin-block-end: 0.67em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
font-weight: bold; justify-content: space-between;
|
||||
unicode-bidi: isolate;">Daily Progress Report</h3>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]><td align="center" width="345" style="background-color: #b10000;width: 345px;padding: 15px 1px 1px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-50"
|
||||
style="max-width: 320px;min-width: 345px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="background-color: #b10000;height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 15px 1px 1px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:11px 10px 10px 27px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<div>
|
||||
<div class="project-info" style="color:#ffffff;text-align:right">
|
||||
<strong>Project:</strong> ANP ultimas wakad<br>
|
||||
<strong>Date:</strong> 17 September 2025
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="690" style="width: 690px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-100"
|
||||
style="max-width: 320px;min-width: 690px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<!--[if mso]><table role="presentation" width="100%"><tr><td><![endif]-->
|
||||
<h4
|
||||
style="margin: 0px; line-height: 140%; text-align: left; word-wrap: break-word; font-size: 12px; font-weight: 400;">
|
||||
<span>* Project Stats Reported as 18-Sep-25 03:30:03 UTC <br>* Report is based on Data
|
||||
submitted on Date 17-Sep-25</span>
|
||||
</h4>
|
||||
<!--[if mso]></td></tr></table><![endif]-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="230" style="width: 230px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-33p33"
|
||||
style="max-width: 320px;min-width: 230px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<div>
|
||||
<div class="card" style=" flex: 1;
|
||||
min-width: 200px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s
|
||||
ease, box-shadow 0.2s
|
||||
ease;
|
||||
border-top: 1px solid #e63946;">
|
||||
<h4 class="card-title" style=" font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
color: #6c757d;">Regularization Pending</h4>
|
||||
<p class="value tasks"
|
||||
style="font-size: 22px; font-weight: bold; color: rgb(0, 123, 255); line-height: inherit; margin: 0px;">
|
||||
28/32</p>
|
||||
<img src="https://cdn.marcoaiot.com/mailcontent/donut-chart.png">
|
||||
<p class="text-muted" style="line-height: inherit; margin: 0px;">Regularization
|
||||
Pending</p>
|
||||
<div class="legend" style=" margin-top: 10px;
|
||||
display: flex
|
||||
;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #555;">
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-green" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #28a745;"></span> Completed
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-blue" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #007bff;"></span> In Progress
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-gray" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #ccc;"></span> Pending
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]><td align="center" width="230" style="width: 230px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-33p33"
|
||||
style="max-width: 320px;min-width: 230px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<div>
|
||||
<div class="card" style=" flex: 1;
|
||||
min-width: 200px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s
|
||||
ease, box-shadow 0.2s
|
||||
ease;
|
||||
border-top: 1px solid #e63946;">
|
||||
<h4 class="card-title" style=" font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
color: #6c757d;">DAILY TASKS COMPLETED
|
||||
</h4>
|
||||
<p class="value tasks"
|
||||
style="font-size: 22px; font-weight: bold; color: rgb(0, 123, 255); line-height: inherit; margin: 0px;">
|
||||
28/32</p>
|
||||
<img src="https://cdn.marcoaiot.com/mailcontent/donut-chart.png">
|
||||
<p class="text-muted" style="line-height: inherit; margin: 0px;">Team members present
|
||||
on the site</p>
|
||||
<div class="legend" style=" margin-top: 10px;
|
||||
display: flex
|
||||
;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #555;">
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-green" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #28a745;"></span> Completed
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-blue" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #007bff;"></span> In Progress
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-gray" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #ccc;"></span> Pending
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]><td align="center" width="230" style="width: 230px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-33p33"
|
||||
style="max-width: 320px;min-width: 230px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<div>
|
||||
<div class="card" style=" flex: 1;
|
||||
min-width: 200px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s
|
||||
ease, box-shadow 0.2s
|
||||
ease;
|
||||
border-top: 1px solid #e63946;">
|
||||
<h4 class="card-title" style=" font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
color: #6c757d;">Project Completed</h4>
|
||||
<p class="value tasks"
|
||||
style="font-size: 22px; font-weight: bold; color: rgb(0, 123, 255); line-height: inherit; margin: 0px;">
|
||||
28/32</p>
|
||||
<img src="https://cdn.marcoaiot.com/mailcontent/donut-chart.png">
|
||||
<p class="text-muted" style="line-height: inherit; margin: 0px;">PROJECT COMPLETION
|
||||
STATUS</p>
|
||||
<div class="legend" style=" margin-top: 10px;
|
||||
display: flex
|
||||
;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #555;">
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-green" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #28a745;"></span> Completed
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-blue" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #007bff;"></span> In Progress
|
||||
</div>
|
||||
<div class="legend-item" style="display: flex
|
||||
;
|
||||
align-items: center;
|
||||
gap: 4px;"><span class="legend-color legend-gray" style="width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;background: #ccc;"></span> Pending
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="690" style="width: 690px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-100"
|
||||
style="max-width: 320px;min-width: 690px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<!--[if mso]><table role="presentation" width="100%"><tr><td><![endif]-->
|
||||
<h4
|
||||
style="margin: 0px; line-height: 140%; text-align: left; word-wrap: break-word; font-size: 16px; font-weight: 400;">
|
||||
<span>Activities (Tasks PErformed on 17-Sep-2025</span>
|
||||
</h4>
|
||||
<!--[if mso]></td></tr></table><![endif]-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="690" style="width: 690px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-100"
|
||||
style="max-width: 320px;min-width: 690px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<table
|
||||
style="width: 100%; border-collapse: collapse; table-layout: fixed; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #FFFFFF;">
|
||||
|
||||
<thead>
|
||||
|
||||
<tr>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
<p>Name</p>
|
||||
</th>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
<p>Job Role</p>
|
||||
</th>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
</th>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
|
||||
<tbody style="font-size: 14px;text-align: left;line-height: 140%;">
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
<p>Siddharth Badre</p>
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="690" style="width: 690px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-100"
|
||||
style="max-width: 320px;min-width: 690px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<table style="font-family:arial,helvetica,sans-serif;" role="presentation" cellpadding="0"
|
||||
cellspacing="0" width="100%" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td
|
||||
style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:arial,helvetica,sans-serif;"
|
||||
align="left">
|
||||
|
||||
<table
|
||||
style="width: 100%; border-collapse: collapse; table-layout: fixed; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #FFFFFF;">
|
||||
|
||||
<thead>
|
||||
|
||||
<tr>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
<p>Add header text</p>
|
||||
</th>
|
||||
|
||||
<th
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC; background-color: #DDDDDD; font-size: 14px; font-weight: 700; text-align: left;">
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
|
||||
<tbody style="font-size: 14px;text-align: left;line-height: 140%;">
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
<p>Add text</p>
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
<td
|
||||
style="padding: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: #CCC; border-left-width: 1px; border-left-style: solid; border-left-color: #CCC; border-right-width: 1px; border-right-style: solid; border-right-color: #CCC; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #CCC;">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="u-row-container" style="padding: 0px;background-color: transparent">
|
||||
<div class="u-row"
|
||||
style="margin: 0 auto;min-width: 320px;max-width: 690px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
|
||||
<div
|
||||
style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
|
||||
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" border="0" style="width:690px;"><tr style="background-color: transparent;"><![endif]-->
|
||||
|
||||
<!--[if (mso)|(IE)]><td align="center" width="690" style="width: 690px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top"><![endif]-->
|
||||
<div class="u-col u-col-100"
|
||||
style="max-width: 320px;min-width: 690px;display: table-cell;vertical-align: top;">
|
||||
<div
|
||||
style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
<div
|
||||
style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
|
||||
<!--<![endif]-->
|
||||
|
||||
<!--[if (!mso)&(!IE)]><!-->
|
||||
</div><!--<![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
<!--[if (mso)|(IE)]></td><![endif]-->
|
||||
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--[if mso]></div><![endif]-->
|
||||
<!--[if IE]></div><![endif]-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
89
python-email-sender/multipart-email.py
Normal file
89
python-email-sender/multipart-email.py
Normal file
@ -0,0 +1,89 @@
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.image import MIMEImage
|
||||
from email.mime.base import MIMEBase
|
||||
from email import encoders
|
||||
|
||||
# --- Email Configuration ---
|
||||
# Replace with your actual email and app password
|
||||
sender_password = "qrtq wfuj hwpp fhqr"
|
||||
recipient_email =["vikasnale@gmail.com", "vikas@marcoaiot.com", "umeshvdesai@outlook.com"]
|
||||
sender_email = "marcoioitsoft@gmail.com"
|
||||
receiver_emails = ["vikasnale@gmail.com", "vikas@marcoaiot.com"]
|
||||
password = "qrtq wfuj hwpp fhqr" # Use Gmail App Password here
|
||||
|
||||
# --- 1. Create the top-level container (multipart/related) ---
|
||||
# This container will hold the HTML body and the embedded images.
|
||||
msg_root = MIMEMultipart('related')
|
||||
msg_root['Subject'] = 'Python Email with Embedded Images and Attachment'
|
||||
msg_root['From'] = sender_email
|
||||
msg_root['To'] = recipient_email
|
||||
msg_root.preamble = 'This is a multi-part message in MIME format.'
|
||||
|
||||
# --- 2. Create the alternative container (multipart/alternative) ---
|
||||
# This part holds both the plain-text and HTML versions of the email content.
|
||||
msg_alternative = MIMEMultipart('alternative')
|
||||
msg_root.attach(msg_alternative)
|
||||
|
||||
# --- Define the plain text and HTML content ---
|
||||
plain_text_content = """\
|
||||
Hello,
|
||||
This is the plain text version of the email.
|
||||
The images are not visible here.
|
||||
Please view this email in a client that supports HTML to see the embedded images.
|
||||
"""
|
||||
|
||||
html_content = """\
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>This email contains two embedded images and one regular attachment.</p>
|
||||
<p>Here is the first image (CID):</p>
|
||||
<img src="cid:image1.jpg" alt="First Image">
|
||||
<p>And here is the second one (CID):</p>
|
||||
<img src="cid:logo.png" alt="Company Logo">
|
||||
<p>Please see the attached PDF for more information.</p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
# Attach the plain text and HTML versions to the alternative container
|
||||
msg_alternative.attach(MIMEText(plain_text_content, 'plain'))
|
||||
msg_alternative.attach(MIMEText(html_content, 'html'))
|
||||
|
||||
# --- 3. Attach the embedded images with Content-ID (CID) ---
|
||||
# The Content-ID is crucial for the HTML body to reference the image.
|
||||
# The 'inline' disposition makes sure the image is displayed within the email body.
|
||||
|
||||
# Attach 'image1.jpg'
|
||||
with open('image1.jpg', 'rb') as fp:
|
||||
msg_image1 = MIMEImage(fp.read(), _subtype="jpeg")
|
||||
msg_image1.add_header('Content-ID', '<image1.jpg>')
|
||||
msg_image1.add_header('Content-Disposition', 'inline')
|
||||
msg_root.attach(msg_image1)
|
||||
|
||||
# Attach 'logo.png'
|
||||
with open('logo.png', 'rb') as fp:
|
||||
msg_logo = MIMEImage(fp.read(), _subtype="png")
|
||||
msg_logo.add_header('Content-ID', '<logo.png>')
|
||||
msg_logo.add_header('Content-Disposition', 'inline')
|
||||
msg_root.attach(msg_logo)
|
||||
|
||||
# --- 4. Attach the regular attachment ---
|
||||
# This part is for the file that should be a standard attachment.
|
||||
with open('document.pdf', 'rb') as fp:
|
||||
part = MIMEBase('application', 'pdf')
|
||||
part.set_payload(fp.read())
|
||||
encoders.encode_base64(part)
|
||||
part.add_header('Content-Disposition', 'attachment', filename='document.pdf')
|
||||
msg_root.attach(part)
|
||||
|
||||
# --- 5. Send the email using SMTP ---
|
||||
try:
|
||||
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
|
||||
smtp.login(sender_email, sender_password)
|
||||
smtp.send_message(msg_root)
|
||||
print("Email sent successfully!")
|
||||
except Exception as e:
|
||||
print(f"Failed to send email: {e}")
|
||||
@ -5,11 +5,11 @@ import os
|
||||
|
||||
# Sender and receiver
|
||||
sender_email = "marcoioitsoft@gmail.com"
|
||||
receiver_emails = ["vikasnale@gmail.com", "vikas@marcoaiot.com"]
|
||||
receiver_emails = ["garu.vikas@gmail.com", "vikas@marcoaiot.com" ,"umeshvdesai@outlook.com"]
|
||||
password = "qrtq wfuj hwpp fhqr" # Use Gmail App Password here
|
||||
|
||||
# Read body from text file (e.g., body.txt in the same folder)
|
||||
file_path = os.path.join(os.path.dirname(__file__), "body.txt")
|
||||
file_path = os.path.join(os.path.dirname(__file__), "body.html")
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
body = f.read()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user