Merge branch 'python-email-with-charts'

This commit is contained in:
Vikas Nale 2025-11-26 17:53:59 +05:30
commit 3564e14e80
16 changed files with 5824 additions and 0 deletions

View 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()

View 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": "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",
"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'"
}
}

View File

@ -0,0 +1 @@
https://wiki.marcoaiot.com/index.php/AWS_S3_Migration_Script

View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Donut Variants</title>
<style>
.donut {
--percentage: 65; /* Change this per chart */
--primary: #e63946; /* Fill color */
--track: #e9ecef; /* Background track */
--size: 120px; /* Default size */
--thickness: 20px; /* Default thickness */
width: var(--size);
height: var(--size);
border-radius: 50%;
background: conic-gradient(
var(--primary) calc(var(--percentage) * 1%),
var(--track) 0
);
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-weight: bold;
color: #333;
}
.donut::before {
content: "";
position: absolute;
width: calc(var(--size) - var(--thickness));
height: calc(var(--size) - var(--thickness));
border-radius: 50%;
background: #fff; /* Inner cut-out */
}
.donut span {
position: absolute;
font-size: calc(var(--size) / 6);
}
/* Variants */
.donut.thin {
--size: 80px;
--thickness: 12px;
}
.donut.medium {
--size: 120px;
--thickness: 25px;
}
.donut.large {
--size: 180px;
--thickness: 35px;
}
.progress {
width: 100%;
background-color: #e9ecef;
border-radius: 0.375rem;
overflow: hidden;
height: 0.51rem; /* Default height */
margin-bottom: 1rem;
font-family: Arial, sans-serif;
font-size: 0.375rem; /* Default size */
font-weight: 500;
}
.progress.thin {
height: 0.7rem;
font-size: 0.6rem;
}
.progress.medium {
height: 1rem;
font-size: 0.7rem;
}
.progress.large {
height: 1.5rem;
font-size: 1.2rem;
}
.progress-bar {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background-color: #0d6efd; /* default = Bootstrap primary */
transition: width 0.6s ease;
}
/* Color variants */
.progress-bar-success {
background-color: #198754;
}
.progress-bar-warning {
background-color: #ffc107;
color: #000;
}
.progress-bar-danger {
background-color: #dc3545;
}
</style>
</head>
<body style="display:block; gap:40px; align-items:center; justify-content:center; min-height:100vh;">
<div style="
display: flex;
vertical-align: middle;
">
<!-- Thin -->
<div class="donut thin" style="--percentage: 45;">
<span>45%</span>
</div>
<!-- Medium -->
<div class="donut medium" style="--percentage: 73;">
<span>73%</span>
</div>
<!-- Large -->
<div class="donut large" style="--percentage: 90;">
<span>90%</span>
</div>
</div>
<div style="
margin-top: 100px;
">
<div class="progress" style="width:200px">
<div class="progress-bar" style="width: 25%;">25%</div>
</div>
<div class="progress thin " style="width:200px">
<div class="progress-bar progress-bar-success" style="width: 50%;">50%</div>
</div>
<div class="progress medium" style="width:200px">
<div class="progress-bar progress-bar-warning" style="width: 75%;">75%</div>
</div>
<div class="progress large" style="width:50%">
<div class="progress-bar progress-bar-danger" style="width: 90%;">90%</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,598 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Daily Progress Report</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background: #f5f5f5;
color: #333;
}
.container {
max-width: 1100px;
margin: 20px auto;
background: #fff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.header {
background: #b10000;
color: #fff;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.header h1 {
font-size: 22px;
margin: 0;
}
.header .project-info {
font-size: 14px;
text-align: right;
}
.status-note {
font-size: 12px;
color: #555;
padding: 15px 20px 0 20px;
}
.status-cards {
display: flex;
justify-content: space-between;
gap: 15px;
padding: 20px;
flex-wrap: wrap;
}
.card {
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);
/* <-- added shadow */
transition: transform 0.2s ease, box-shadow 0.2s ease;
border-top: 1px solid #e63946;
}
.card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.card h3 {
font-size: 14px;
margin: 0 0 10px 0;
}
.card p {
margin: 5px 0;
}
.card .value {
font-size: 22px;
font-weight: bold;
}
.card-title {
font-size: 0.9rem;
text-transform: uppercase;
font-weight: 600;
color: #6c757d;
}
.attendance {
color: #b10000;
}
.tasks {
color: #007bff;
}
.completion {
color: #28a745;
}
.activities {
padding: 20px;
}
.activities h2 {
font-size: 18px;
margin-bottom: 10px;
}
.table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
.table th,
.table td {
border: 1px solid #ddd;
padding: 8px;
text-align: center;
}
.table th {
background: #f0f0f0;
}
.footer {
background: #b10000;
color: #fff;
text-align: center;
padding: 15px;
font-size: 12px;
}
.footer a {
color: #fff;
margin: 0 8px;
text-decoration: none;
}
/* Responsive */
@media (max-width: 600px) {
.header {
flex-direction: column;
text-align: center;
}
.header .project-info {
text-align: center;
margin-top: 10px;
}
.status-cards {
flex-direction: column;
}
}
.legend {
margin-top: 10px;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
font-size: 12px;
color: #555;
}
.legend-item {
display: flex;
align-items: center;
gap: 4px;
}
.legend-color {
width: 10px;
height: 10px;
border-radius: 2px;
display: inline-block;
}
.legend-red {
background: #b10000;
}
.legend-blue {
background: #007bff;
}
.legend-green {
background: #28a745;
}
.legend-gray {
background: #ccc;
}
.donut {
--percentage: 65;
/* Change this per chart */
--danger: #e63946;
--primary: #007bff;
--warning: #ffc107;
--success: #198754;
/* Fill color */
--track: #e9ecef;
/* Background track */
--size: 120px;
/* Default size */
--thickness: 20px;
/* Default thickness */
width: var(--size);
height: var(--size);
border-radius: 50%;
background: conic-gradient(var(--danger) calc(var(--percentage) * 1%),
var(--track) 0);
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-weight: bold;
color: #333;
}
.donut::before {
content: "";
position: absolute;
width: calc(var(--size) - var(--thickness));
height: calc(var(--size) - var(--thickness));
border-radius: 50%;
background: #fff;
/* Inner cut-out */
}
.donut span {
position: absolute;
font-size: calc(var(--size) / 6);
}
/* Variants */
.donut.thin {
--size: 80px;
--thickness: 12px;
}
.donut.medium {
--size: 120px;
--thickness: 25px;
}
.donut.large {
--size: 180px;
--thickness: 35px;
}
/* Color variants */
.donut-success {
background: conic-gradient(var(--success) calc(var(--percentage) * 1%),
var(--track) 0);
color: var(--success)
}
.donut-warning {
background: conic-gradient(var(--warning) calc(var(--percentage) * 1%),
var(--track) 0);
color: var(--warning)
}
.donut-danger {
background: conic-gradient(var(--danger) calc(var(--percentage) * 1%),
var(--track) 0);
color: var(--danger)
}
.donut-primary {
background: conic-gradient(var(--primary) calc(var(--percentage) * 1%),
var(--track) 0);
color: var(--primary)
}
</style>
</head>
<body>
<div class="container">
<!-- Header -->
<div class="header">
<h1>Daily Progress Report</h1>
<div class="project-info">
<strong>Project:</strong> ANP ultimas wakad<br>
<strong>Date:</strong> 17 September 2025
</div>
</div>
<!-- Status Note -->
<div class="status-note">
* Project Status Reported - Generated at 18-Sep-2025 03:30:03 UTC
</div>
<!-- Status Cards -->
<div class="status-cards">
<div class="card">
<h4 class="card-title">TODAY'S ATTENDANCE</h4>
<div style="display:flex; flex-wrap:wrap;">
<!-- Left Column -->
<div style="width:50%; box-sizing:border-box;display:flex; justify-content:center; align-items:center;">
<!-- Medium -->
<div class="donut thin" style="--percentage: 66;">
<span>20 / 30</span>
</div>
</div>
<!-- Right Column -->
<div class="legend" style="width:50%; padding:15px; box-sizing:border-box;">
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;">
<span class="legend-color legend-green"></span> Completed
</div>
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;; ">
<span class="legend-color legend-blue"></span> In Progress
</div>
<div class="legend-item"
style="margin-bottom:10px; text-align: left; display:left; justify-content:left; align-items:left!important;;">
<span class="legend-color legend-gray"></span> Pending
</div>
</div>
</div>
<div>
<div style="padding:10px; text-align:center;">
<p class="text-muted">Team members present on the site</p>
</div>
</div>
</div>
<div class="card">
<h4 class="card-title">DAILY TASKS COMPLETED</h4>
<div style="display:flex; flex-wrap:wrap;">
<!-- Left Column -->
<div style="width:50%; box-sizing:border-box;display:flex; justify-content:center; align-items:center;">
<!-- Medium -->
<div class="donut thin donut-primary" style="--percentage: 66;">
<span>20 / 30</span>
</div>
</div>
<!-- Right Column -->
<div class="legend" style="width:50%; padding:15px; box-sizing:border-box;">
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;">
<span class="legend-color legend-green"></span> Completed
</div>
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;; ">
<span class="legend-color legend-blue"></span> In Progress
</div>
<div class="legend-item"
style="margin-bottom:10px; text-align: left; display:left; justify-content:left; align-items:left!important;;">
<span class="legend-color legend-gray"></span> Pending
</div>
</div>
</div>
<div>
<div style="padding:10px; text-align:center;">
<p class="text-muted">Team members present on the site</p>
</div>
</div>
</div>
<div class="card">
<h4 class="card-title">DAILY TASKS COMPLETED</h4>
<p class="value tasks">20 / 30</p>
<p>Team member present</p>
<div class="legend">
<div class="legend-item"><span class="legend-color legend-blue"></span> Completed</div>
<div class="legend-item"><span class="legend-color legend-green"></span> In Progress</div>
<div class="legend-item"><span class="legend-color legend-gray"></span> Pending</div>
</div>
</div>
<div class="card">
<h4 class="card-title">PROJECT COMPLETION STATUS</h4>
<p class=" value completion">20 / 30</p>
<p>Team member present</p>
<div class="legend">
<div class="legend-item"><span class="legend-color legend-green"></span> Completed</div>
<div class="legend-item"><span class="legend-color legend-blue"></span> In Progress</div>
<div class="legend-item"><span class="legend-color legend-gray"></span> Pending</div>
</div>
</div>
<div class="card">
<h4 class="card-title">Regularization Pending</h4>
<p class="value tasks">28/32</p>
<p class="text-muted">Regularization Pending</p>
<div class="legend">
<div class="legend-item"><span class="legend-color legend-green"></span> Completed</div>
<div class="legend-item"><span class="legend-color legend-blue"></span> In Progress</div>
<div class="legend-item"><span class="legend-color legend-gray"></span> Pending</div>
</div>
</div>
<div class="card">
<!-- Row 1: Header -->
<div>
<h4 class="card-title">Checkout Pending</h4>
</div>
<!-- Row 2: Two Columns -->
<div style="display:flex; flex-wrap:wrap;">
<!-- Left Column -->
<div style="width:50%; box-sizing:border-box;display:flex; justify-content:center; align-items:center;">
<!-- Medium -->
<div class="donut thin donut-success" style="--percentage: 73;">
<span>73%</span>
</div>
</div>
<!-- Right Column -->
<div class="legend" style="width:50%; padding:15px; box-sizing:border-box;">
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;">
<span class="legend-color legend-green"></span> Completed
</div>
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;; ">
<span class="legend-color legend-blue"></span> In Progress
</div>
<div class="legend-item"
style="margin-bottom:10px; text-align: left; display:left; justify-content:left; align-items:left!important;;">
<span class="legend-color legend-gray"></span> Pending
</div>
</div>
</div>
<!-- Row 3: Full Width -->
<div>
<div style="padding:10px; text-align:center;">
<p class="text-muted">Team members present on the site</p>
</div>
</div>
</div>
<div class="card">
<div>
<h4 class="card-title">Activity Report Pending</h4>
</div>
<div style="display:flex; flex-wrap:wrap;">
<!-- 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: 0;">
<span>0%</span>
</div>
</div>
<!-- Right Column -->
<div class="legend" style="width:50%; padding:15px; box-sizing:border-box;">
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;">
<span class="legend-color legend-green"></span> Completed
</div>
<div class="legend-item"
style="margin-bottom:10px;text-align: left; display:left; justify-content:left; align-items:left!important;; ">
<span class="legend-color legend-blue"></span> In Progress
</div>
<div class="legend-item"
style="margin-bottom:10px; text-align: left; display:left; justify-content:left; align-items:left!important;;">
<span class="legend-color legend-gray"></span> Pending
</div>
</div>
</div>
<div>
<div style="padding:10px; text-align:center;">
<p class="text-muted">Team members present on the site</p>
</div>
</div>
</div>
<div class="card">
<!-- Row 1: Header -->
<div>
<h4 class="card-title">Team Strength on Site</h4>
</div>
<table style="width: 100%;">
<tr>
<td style="text-align: left;">Site Engineer</td>
<td style="text-align: right;">1</td>
</tr>
<tr>
<td style="text-align: left;">Weilder</td>
<td style="text-align: right;">15</td>
</tr>
<tr>
<td style="text-align: left;">Helper</td>
<td style="text-align: right;">2</td>
</tr>
<tr>
<td style="text-align: left;">Painter</td>
<td style="text-align: right;">1</td>
</tr>
</table>
</div>
</div>
<!-- Activities -->
<div class="activities">
<h2>Activities (Tasks) Performed 17-Sep-2025</h2>
<table class="table">
<thead>
<tr>
<th>NAME</th>
<th>JOB ROLE</th>
<th>CHECK IN</th>
<th>CHECK OUT</th>
</tr>
</thead>
<tbody>
<tr>
<td>Siddharth Barde</td>
<td>Site Engineer</td>
<td>17-Sep-2025 11:47 AM</td>
<td>-</td>
</tr>
<tr>
<td>Siddharth Barde</td>
<td>Site Engineer</td>
<td>17-Sep-2025 11:47 AM</td>
<td>-</td>
</tr>
<tr>
<td>Siddharth Barde</td>
<td>Site Engineer</td>
<td>17-Sep-2025 11:47 AM</td>
<td>-</td>
</tr>
</tbody>
</table>
</div>
<!-- Footer -->
<div class="footer" style="display:flex; flex-wrap:wrap;">
<div style="width: 50%;text-align: left;">
Contact Us: contact[at]marcoaiot.com<br>
Marco AIoT technologies Pvt. Ltd. ©2025 All Rights Reserved
</div>
<div style="width: 50%; text-align: right;">
<!-- <a href="#">Instagram</a> | -->
<a href="#"><img src="https://cdn.marcoaiot.com/icons/brands/google.png" style="height: 15px;" /></a> |
<a href="#"><img src="https://cdn.marcoaiot.com/icons/brands/twitter.png" style="height: 15px;" /></a> |
<a href="#"><img src="https://cdn.marcoaiot.com/icons/brands/facebook.png" style="height: 15px;" /></a> |
<a href="#"><img src="https://cdn.marcoaiot.com/icons/brands/instagram.png" style="height: 15px;" /></a>
<!-- <a href="#"><img src="https://cdn.marcoaiot.com/icons/brands/youtube.png" style="height: 15px;" /></a> | <a
href="#">LinkedIn</a> |
<a href="#">YouTube</a> -->
</div>
</div>
<div style="text-align: center;width: 100%;background-color: #fff;margin:10px;font-size: small;color: #6c757d ;">
You have received this email because it contains important information about your Marco PMS Account account.
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Donut Variants</title>
<style>
.donut {
--percentage: 65; /* Change this per chart */
--primary: #e63946; /* Fill color */
--track: #e9ecef; /* Background track */
--size: 120px; /* Default size */
--thickness: 20px; /* Default thickness */
width: var(--size);
height: var(--size);
border-radius: 50%;
background: conic-gradient(
var(--primary) calc(var(--percentage) * 1%),
var(--track) 0
);
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-weight: bold;
color: #333;
}
.donut::before {
content: "";
position: absolute;
width: calc(var(--size) - var(--thickness));
height: calc(var(--size) - var(--thickness));
border-radius: 50%;
background: #fff; /* Inner cut-out */
}
.donut span {
position: absolute;
font-size: calc(var(--size) / 6);
}
/* Variants */
.donut.thin {
--size: 80px;
--thickness: 12px;
}
.donut.medium {
--size: 120px;
--thickness: 25px;
}
.donut.large {
--size: 180px;
--thickness: 35px;
}
.progress {
width: 100%;
background-color: #e9ecef;
border-radius: 0.375rem;
overflow: hidden;
height: 0.51rem; /* Default height */
margin-bottom: 1rem;
font-family: Arial, sans-serif;
font-size: 0.375rem; /* Default size */
font-weight: 500;
}
.progress.thin {
height: 0.7rem;
font-size: 0.6rem;
}
.progress.medium {
height: 1rem;
font-size: 0.7rem;
}
.progress.large {
height: 1.5rem;
font-size: 1.2rem;
}
.progress-bar {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background-color: #0d6efd; /* default = Bootstrap primary */
transition: width 0.6s ease;
}
/* Color variants */
.progress-bar-success {
background-color: #198754;
}
.progress-bar-warning {
background-color: #ffc107;
color: #000;
}
.progress-bar-danger {
background-color: #dc3545;
}
</style>
</head>
<body style="display:block; gap:40px; align-items:center; justify-content:center; min-height:100vh;">
<div style="
display: flex;
vertical-align: middle;
">
<!-- Thin -->
<div class="donut thin" style="--percentage: 45;">
<span>45%</span>
</div>
<!-- Medium -->
<div class="donut medium" style="--percentage: 73;">
<span>73%</span>
</div>
<!-- Large -->
<div class="donut large" style="--percentage: 90;">
<span>90%</span>
</div>
</div>
<div style="
margin-top: 100px;
">
<div class="progress" style="width:200px">
<div class="progress-bar" style="width: 25%;">25%</div>
</div>
<div class="progress thin " style="width:200px">
<div class="progress-bar progress-bar-success" style="width: 50%;">50%</div>
</div>
<div class="progress medium" style="width:200px">
<div class="progress-bar progress-bar-warning" style="width: 75%;">75%</div>
</div>
<div class="progress large" style="width:50%">
<div class="progress-bar progress-bar-danger" style="width: 90%;">90%</div>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View 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>

View File

@ -0,0 +1,10 @@
{
"EMAIL_CONFIGURATION": {
"EMAIL_HOST": "mail.marcoaiot.com",
"EMAIL_PORT": 587,
"EMAIL_USER": "admin@marcoaiot.com",
"EMAIL_PASS": "xxx",
"EMAIL_SUBJECT": "Database backup process",
"EMAIL_RECEIVERS": "vikas@marcoaiot.com,umesh@marcoaiot.com"
}
}

View File

@ -0,0 +1,84 @@
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import os
import cairosvg
def generate_donut_svg(percentage, color="#0d6efd", size=120, thickness=4):
"""
Generate an inline SVG donut chart.
"""
svg = f"""
<svg width="{size}" height="{size}" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
<!-- Track -->
<path
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none"
stroke="#e9ecef"
stroke-width="{thickness}"
/>
<!-- Progress -->
<path
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none"
stroke="{color}"
stroke-width="{thickness}"
stroke-dasharray="{percentage}, 100"
/>
<!-- Label -->
<text x="18" y="20.35" fill="#333" font-size="5" text-anchor="middle">{percentage}%</text>
</svg>
"""
return svg
# Sender and receiver
sender_email = "marcoioitsoft@gmail.com"
receiver_emails = ["vikasnale@gmail.com", "vikas@marcoaiot.com", "umeshvdesai@outlook.com"]
password = "qrtq wfuj hwpp fhqr" # Use Gmail App Password here
# Read HTML body from file
file_path = os.path.join(os.path.dirname(__file__), "body.txt")
with open(file_path, "r", encoding="utf-8") as f:
body = f.read()
# Create the email
message = MIMEMultipart("related")
message["From"] = sender_email
message["To"] = ", ".join(receiver_emails)
message["Subject"] = "Test HTML Email with Donut Charts"
# Generate SVGs and convert to PNGs
donut_svgs = [
generate_donut_svg(45, "#e63946"),
generate_donut_svg(73, "#0d6efd"),
generate_donut_svg(90, "#198754")
]
# Attach donuts as inline images
for i, svg in enumerate(donut_svgs, start=1):
png_bytes = cairosvg.svg2png(bytestring=svg.encode("utf-8"))
img = MIMEImage(png_bytes, "png")
cid = f"donut{i}"
img.add_header("Content-ID", f"<{cid}>")
message.attach(img)
body += f'<br><img src="cid:{cid}" alt="Donut{i}">'
# Attach the final HTML body
message.attach(MIMEText(f"<html><body>{body}</body></html>", "html"))
# Send the email
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(sender_email, password)
server.sendmail(sender_email, receiver_emails, message.as_string())
print("✅ Email sent successfully with embedded donut PNGs!")
except Exception as e:
print("❌ Error:", e)
finally:
server.quit()

View 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}")

View File

@ -0,0 +1,35 @@
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
# Sender and receiver
sender_email = "marcoioitsoft@gmail.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.html")
with open(file_path, "r", encoding="utf-8") as f:
body = f.read()
# Create the email
message = MIMEMultipart()
message["From"] = sender_email
message["To"] =", ".join(receiver_emails)
message["Subject"] = "Test Email from Python"
# Attach body
message.attach(MIMEText(body, "html"))
try:
# Connect to Gmail SMTP server
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls() # Secure the connection
server.login(sender_email, password)
server.sendmail(sender_email, receiver_emails, message.as_string())
print("✅ Email sent successfully!")
except Exception as e:
print("❌ Error:", e)
finally:
server.quit()

View File

@ -0,0 +1,84 @@
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import os
import cairosvg
def generate_donut_svg(percentage, color="#0d6efd", size=120, thickness=4):
"""
Generate an inline SVG donut chart.
"""
svg = f"""
<svg width="{size}" height="{size}" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
<!-- Track -->
<path
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none"
stroke="#e9ecef"
stroke-width="{thickness}"
/>
<!-- Progress -->
<path
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none"
stroke="{color}"
stroke-width="{thickness}"
stroke-dasharray="{percentage}, 100"
/>
<!-- Label -->
<text x="18" y="20.35" fill="#333" font-size="5" text-anchor="middle">{percentage}%</text>
</svg>
"""
return svg
# Sender and receiver
sender_email = "marcoioitsoft@gmail.com"
receiver_emails = ["vikasnale@gmail.com", "vikas@marcoaiot.com", "umeshvdesai@outlook.com"]
password = "qrtq wfuj hwpp fhqr" # Use Gmail App Password here
# Read HTML body from file
file_path = os.path.join(os.path.dirname(__file__), "body.txt")
with open(file_path, "r", encoding="utf-8") as f:
body = f.read()
# Create the email
message = MIMEMultipart("related")
message["From"] = sender_email
message["To"] = ", ".join(receiver_emails)
message["Subject"] = "Test HTML Email with Donut Charts"
# Generate SVGs and convert to PNGs
donut_svgs = [
generate_donut_svg(45, "#e63946"),
generate_donut_svg(73, "#0d6efd"),
generate_donut_svg(90, "#198754")
]
# Attach donuts as inline images
for i, svg in enumerate(donut_svgs, start=1):
png_bytes = cairosvg.svg2png(bytestring=svg.encode("utf-8"))
img = MIMEImage(png_bytes, "png")
cid = f"donut{i}"
img.add_header("Content-ID", f"<{cid}>")
message.attach(img)
body += f'<br><img src="cid:{cid}" alt="Donut{i}">'
# Attach the final HTML body
message.attach(MIMEText(f"<html><body>{body}</body></html>", "html"))
# Send the email
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(sender_email, password)
server.sendmail(sender_email, receiver_emails, message.as_string())
print("✅ Email sent successfully with embedded donut PNGs!")
except Exception as e:
print("❌ Error:", e)
finally:
server.quit()

View File

@ -0,0 +1,11 @@
# Services & Containers
SERVICES=nginx,rocketchat,mongod,mysql
CONTAINERS=redmine-app,mediawiki-app,sonarqube,postgres-sonar,ecc269bb3ba3
# Mail settings
SENDER_EMAIL=marcoioitsoft@gmail.com
RECEIVER_EMAIL=umesh@marcoaiot.com,vikas@marcoaiot.com
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=marcoioitsoft@gmail.com
SMTP_PASSWORD=qrtq wfuj hwpp fhqr

View File

@ -0,0 +1,114 @@
#!/usr/bin/env python3
import subprocess
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from dotenv import load_dotenv
load_dotenv()
# ----------------- CONFIG -----------------
services = os.getenv("SERVICES", "").split(",")
containers = os.getenv("CONTAINERS", "").split(",") # update with your container names
sender_email = os.getenv("SENDER_EMAIL", "")
receiver_email =os.getenv("RECEIVER_EMAIL", "").split(",")
smtp_server = os.getenv("SMTP_SERVER", "")
smtp_port = os.getenv("SMTP_PORT", "")
smtp_user = os.getenv("SMTP_USER", "")
smtp_password = os.getenv("SMTP_PASSWORD", "")
# ------------------------------------------
def run_cmd(cmd):
return subprocess.getoutput(cmd)
def check_service(service):
status = subprocess.run(["systemctl", "is-active", service], capture_output=True, text=True)
if status.returncode == 0:
return True, ""
else:
for attempt in range(2):
print("Attempting to start: " + service)
subprocess.run(["systemctl", "restart", service])
status = subprocess.run(["systemctl", "is-active", service], capture_output=True, text=True)
if status.returncode == 0:
return True, ""
logs = run_cmd(f"journalctl -u {service} -n 20 --no-pager")
return False, logs
def check_container(container):
status = run_cmd(f"docker inspect -f '{{{{.State.Running}}}}' {container}")
if status.strip() == "true":
return True, ""
else:
for attempt in range(2):
run_cmd(f"docker restart {container}")
status = run_cmd(f"docker inspect -f '{{{{.State.Running}}}}' {container}")
if status.strip() == "true":
return True, ""
logs = run_cmd(f"docker logs --tail 20 {container}")
return False, logs
def send_email(failures):
if not failures:
return
msg = MIMEMultipart("alternative")
msg["From"] = sender_email
msg["To"] = ", ".join(receiver_email)
msg["Subject"] = "Service/Container Failure Report"
# HTML Email Body
html = """
<html>
<body style="font-family: Arial, sans-serif; background-color: #f8f9fa; padding: 20px;">
<h2 style="color: #dc3545;"> Failure Report</h2>
<p>The following services/containers failed even after restart attempts:</p>
<hr>
"""
for name, logs in failures.items():
html += f"""
<div style="margin-bottom: 20px; padding: 10px; background-color: #fff3cd; border-left: 5px solid #dc3545;">
<h3 style="margin: 0; color: #721c24;"> {name} Failed</h3>
<p><b>Last 20 log lines:</b></p>
<pre style="background-color: #f1f1f1; padding: 10px; border-radius: 5px; max-height: 300px; overflow-y: auto; font-size: 12px; color: #212529;">{logs}</pre>
</div>
"""
html += """
<hr>
<p style="color: #6c757d;">This is an automated alert. Please check the server immediately.</p>
</body>
</html>
"""
msg.attach(MIMEText(html, "html"))
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(smtp_user, smtp_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
if __name__ == "__main__":
failures = {}
print("inside __main__")
for service in services:
print("looping services: " + service)
ok, logs = check_service(service)
print(ok)
print(logs)
if not ok:
failures[service] = logs
for container in containers:
ok, logs = check_container(container)
print("looping containers: " + container)
print(ok)
print(logs)
if not ok:
failures[f"Docker: {container}"] = logs
print(failures)
send_email(failures)