Commit 9afed753 authored by vaisakh.nair's avatar vaisakh.nair 🎯

Merge branch 'develop_vaisakh' into 'develop'

Develop vaisakh

See merge request !2
parents 6edc119e 64bb63c8
# MONGO_CLIENT=mongodb://localhost
# MONGO_PORT=2717
# MONGO_DATABASE=admin
# MONGO_COLLECTION=eventLogs
MONGO_CLIENT=mongodb://admin:iLens%241234@192.168.3.181:2717/admin?connectTimeoutMS=10000&authSource=admin&authMechanism=SCRAM-SHA-1
MONGO_PORT=2717
MONGO_DATABASE=ilens_ai
MONGO_COLLECTION=eventLogs
URL_WITH_ATTACH=https://cloud.ilens.io/sms-util/api/v1/eim/email/form/send
URL_WITHOUT_ATTACH=https://cloud.ilens.io/sms-util/api/v1/eim/email/send
AUTHORIZATION=Basic QWxsR29vZE5hbWVzUkdvbmU6Y29tQlJBTlNlQU50YW1hc0ViSUNhUGVD
FROM_ADDRESS=no-reply@ilens.io
MONGO_COLLECTION_EMAIL=email_ids
GATEWAY=priority
.idea/inspectionProfiles/profiles_settings.xml
.idea/inspectionProfiles/Project_Default.xml
.idea/jk_report.iml
.idea/misc.xml
*.xml
*.pb
# Default ignored files
/shelf/
/workspace.xml
# Use an official Python runtime as the base image
FROM python:3.8
# Set the working directory in the container
WORKDIR /app
# Copy the project files to the working directory
COPY . /app
# Install the project dependencies
RUN pip install -r requirements.txt
# Expose the port on which your application runs (if needed)
# EXPOSE <port_number>
# Define the command to run your application
CMD ["python", "app.py"]
\ No newline at end of file
import logging
from scripts.create_report_email_utility import DailyReportGenerator
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def generate_daily_report():
# Create an instance of DailyReportGenerator
report_generator = DailyReportGenerator()
# Generate the daily report
report_path = report_generator.create_excel_report()
# Send the email with the report
# please comment out if you are running the create_report.py file without a email method.
report_generator.send_email_from_ut(filepath=report_path)
return report_path
if __name__ == "__main__":
try:
report_path = generate_daily_report()
logger.info(f"Generated Daily Report: {report_path}")
except Exception as e:
logger.error("Error generating daily report:", exc_info=True)
template_file: D:\vision_utilities\vision_utilities\report_generator\templates\daily_report_jk_template.xlsx
folder_path: D:\vision_utilities\vision_utilities\report_generator\daily_reports
# logo_image: path/to/logo.png
cameras:
- camera_name: jk
packer_name: Packer 1
- camera_name: camera_42
packer_name: Packer 2
- camera_name: camera_44
packer_name: Packer 4
- camera_name: camera_45
packer_name: Packer 5
- camera_name: camera_46
packer_name: Packer 6
- camera_name: camera_47
packer_name: Packer 7
- camera_name: Packer 1
packer_name: Packer - 1
- camera_name: Packer 2
packer_name: Packer - 2
- camera_name: Packer 4
packer_name: Packer - 4
- camera_name: Packer 5
packer_name: Packer - 5
- camera_name: Packer 6
packer_name: Packer - 6
- camera_name: Packer 7
packer_name: Packer - 7
email:
subject: Daily Report
body: |
Dear Sir,
Please find attached the daily report for your review for yesterday's consignment.
Thanks and Regards.
import pandas as pd
from pymongo import MongoClient
from datetime import datetime, timedelta
import schedule
import time
import os
class DailyReportGenerator:
def __init__(self):
# Connect to MongoDB
client = MongoClient(os.environ["MONGO_CLIENT"])
db = client[os.environ["MONGO_DATABASE"]]
self.collection = db[os.environ["MONGO_COLLECTION"]]
def get_shift_name(self, timestamp):
hour = timestamp.hour
if 6 <= hour < 14:
return 'Shift A'
elif 14 <= hour < 22:
return 'Shift B'
else:
return 'Shift C'
def map_packer_name(self, camera_name):
packer_mapping = {
'camera_41': 'Packer 1',
'camera_42': 'Packer 2',
'camera_44': 'Packer 4',
'camera_45': 'Packer 5',
'camera_46': 'Packer 6',
'camera_47': 'Packer 7'
}
return packer_mapping.get(camera_name, 'Unknown')
def get_count(self, start_time, end_time, camera_name):
query = {
'timestamp': {'$gte': start_time, '$lte': end_time},
'cameraName': camera_name
}
documents = self.collection.find(query).sort('timestamp', 1)
first_document = None
last_document = None
for document in documents:
if first_document is None:
first_document = document
last_document = document
if first_document is None or last_document is None:
return 0
count_difference = int(last_document['cement_bag_count']) - int(first_document['cement_bag_count'])
return count_difference
def create_excel_report(self):
data = []
current_time = datetime.now()
start_time = datetime(current_time.year, current_time.month, current_time.day - 1, 6, 0, 0)
end_time = datetime(current_time.year, current_time.month, current_time.day, 6, 0, 0)
for camera_name in ['camera_41', 'camera_42', 'camera_44', 'camera_45', 'camera_46', 'camera_47']:
shift_name = self.get_shift_name(start_time)
packer_name = self.map_packer_name(camera_name)
count = self.get_count(start_time, end_time, camera_name)
data.append({
'Date': start_time.date(),
'Shift Name': shift_name,
'Packer Name': packer_name,
'Count': count
})
df = pd.DataFrame(data)
file_path = os.path.abspath('daily_report.xlsx')
writer = pd.ExcelWriter(file_path, engine='openpyxl')
df.to_excel(writer, index=False, sheet_name='Report')
writer.save()
print('file path ***************** ---------', file_path)
return file_path
def schedule_report_generation(self):
schedule.every().day.at('08:00').do(self.create_excel_report)
while True:
schedule.run_pending()
time.sleep(1)
# Create an instance of DailyReportGenerator and start scheduling report generation
report_generator = DailyReportGenerator()
report_generator.schedule_report_generation()
import pandas as pd
from pymongo import MongoClient
from datetime import datetime, timedelta
import os
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import yaml
from dotenv import load_dotenv
load_dotenv(dotenv_path='.env')
class DailyReportGenerator:
def __init__(self):
# Connect to MongoDB
client = MongoClient(os.environ["MONGO_CLIENT"])
db = client[os.environ["MONGO_DATABASE"]]
self.collection = db[os.environ["MONGO_COLLECTION"]]
# Load configuration from config.yml
with open('config.yml') as config_file:
config = yaml.safe_load(config_file)
self.template_file = config['template_file']
# self.logo_image = config['logo_image']
def get_shift_name(self, timestamp):
hour = timestamp.hour
if 6 <= hour < 14:
return 'Shift A'
elif 14 <= hour < 22:
return 'Shift B'
else:
return 'Shift C'
def map_packer_name(self, camera_name):
packer_mapping = {
'jk_4cebd0ec': 'Packer 1',
'camera_42': 'Packer 2',
'camera_44': 'Packer 4',
'camera_45': 'Packer 5',
'camera_46': 'Packer 6',
'camera_47': 'Packer 7'
}
return packer_mapping.get(camera_name, 'Unknown')
def get_count(self, start_time, end_time, camera_name):
query = {
'timestamp': {'$gte': start_time, '$lte': end_time},
'cameraName': camera_name
}
documents = self.collection.find(query).sort('timestamp', 1)
first_document = None
last_document = None
for document in documents:
if first_document is None:
first_document = document
last_document = document
if first_document is None or last_document is None:
return 0
count_difference = int(last_document['cement_bag_count']) - int(first_document['cement_bag_count'])
return count_difference
def create_excel_report(self):
report_file = 'daily_report.xlsx'
current_time = datetime.now()
report_date = current_time.strftime("%Y-%m-%d")
report_file = f"daily_report_{report_date}.xlsx"
start_time = datetime(current_time.year, current_time.month, current_time.day - 1, 6, 0, 0)
end_time = datetime(current_time.year, current_time.month, current_time.day, 23, 59, 0)
wb = load_workbook(self.template_file)
sheet = wb.active
# Add logos
# logo_image = Image(self.logo_image)
# sheet.add_image(logo_image, 'A1')
# sheet.merge_cells('A1:C3')
# Set report date
sheet['L6'] = report_date
serial_number = 1
# Start filling details from row 8
row = 8
for camera_name in ['jk_4cebd0ec', 'camera_42', 'camera_44', 'camera_45', 'camera_46', 'camera_47']:
shift_name = self.get_shift_name(start_time)
packer_name = self.map_packer_name(camera_name)
count = self.get_count(start_time, end_time, camera_name)
# Fill in the data in respective cells
sheet[f'A{row}'] = serial_number
sheet[f'B{row}'] = start_time.date()
sheet[f'C{row}'] = shift_name
sheet[f'D{row}'] = packer_name
sheet[f'E{row}'] = count
row += 1
serial_number += 1
# Save the report file
wb.save(report_file)
# Return the absolute path of the generated report file
file_path = os.path.abspath(report_file)
return file_path
# Create an instance of DailyReportGenerator
report_generator = DailyReportGenerator()
# Generate the daily report
report_path = report_generator.create_excel_report()
# Print the path of the generated report
print(f"Generated Daily Report: {report_path}")
import pandas as pd
from pymongo import MongoClient
from datetime import datetime, timedelta
import os
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import yaml
from dotenv import load_dotenv
from collections import defaultdict
load_dotenv(dotenv_path='.env')
class DailyReportGenerator:
def __init__(self):
# Connect to MongoDB
client = MongoClient(os.environ["MONGO_CLIENT"])
db = client[os.environ["MONGO_DATABASE"]]
self.collection = db[os.environ["MONGO_COLLECTION"]]
# Load configuration from config.yml
with open('config.yml') as config_file:
config = yaml.safe_load(config_file)
self.template_file = config['template_file']
# self.logo_image = config['logo_image']
def get_shift_name(self, timestamp):
hour = timestamp.hour
if 6 <= hour < 14:
return 'Shift A'
elif 14 <= hour < 22:
return 'Shift B'
else:
return 'Shift C'
def map_packer_name(self, camera_name):
packer_mapping = {
'camera_41': 'Packer 1',
'camera_42': 'Packer 2',
'camera_44': 'Packer 4',
'camera_45': 'Packer 5',
'camera_46': 'Packer 6',
'camera_47': 'Packer 7'
}
return packer_mapping.get(camera_name, 'Unknown')
def get_count(self, start_time, end_time, camera_name):
query = {
'timestamp': {'$gte': start_time, '$lte': end_time},
'cameraName': camera_name
}
documents = self.collection.find(query).sort('timestamp', 1)
count_difference = 0
first_count = 0
last_count = 0
for i, document in enumerate(documents):
if i == 0:
first_count = int(document['cement_bag_count'])
last_count = int(document['cement_bag_count'])
count_difference = last_count - first_count
return count_difference
def create_excel_report(self):
report_file = 'daily_report.xlsx'
current_time = datetime.now()
report_date = current_time.strftime("%Y-%m-%d")
report_file = f"daily_report_{report_date}.xlsx"
wb = load_workbook(self.template_file)
sheet = wb.active
# Set report date
sheet['L6'] = report_date
serial_number = 1
# Define the shifts and their respective time ranges
shifts = {
'Shift A': (datetime(current_time.year, current_time.month, current_time.day -1 , 6, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0)),
'Shift B': (datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 22, 0, 0)),
'Shift C': (datetime(current_time.year, current_time.month, current_time.day- 1, 22, 0, 0),
datetime(current_time.year, current_time.month, current_time.day, 6, 0, 0))
}
# Start filling details from row 8
row = 7
for camera_name in ['camera_41', 'camera_42', 'camera_44', 'camera_45', 'camera_46', 'camera_47']:
for shift, (start_time, end_time) in shifts.items():
packer_name = self.map_packer_name(camera_name)
count = self.get_count(start_time, end_time, camera_name)
# Fill in the data in respective cells
sheet[f'A{row}'] = serial_number
sheet[f'B{row}'] = end_time.date()
sheet[f'C{row}'] = shift
sheet[f'D{row}'] = packer_name
sheet[f'E{row}'] = count
row += 1
serial_number += 1
# Save the report file
wb.save(report_file)
# Return the absolute path of the generated report file
file_path = os.path.abspath(report_file)
return file_path
# Create an instance of DailyReportGenerator
report_generator = DailyReportGenerator()
# Generate the daily report
report_path = report_generator.create_excel_report()
# Print the path of the generated report
print(f"Generated Daily Report: {report_path}")
pandas==1.1.5
pymongo==3.11.4
PyYAML==6.0
openpyxl==3.1.2
requests==2.29.0
python-dotenv==1.0.0
pillow==9.5.0
\ No newline at end of file
......@@ -34,11 +34,11 @@ class DailyReportGenerator:
hour = timestamp.hour
if 6 <= hour < 14:
return 'Shift A'
return 'Shift - A'
elif 14 <= hour < 22:
return 'Shift B'
return 'Shift - B'
else:
return 'Shift C'
return 'Shift - C'
def get_packer_name(self, camera_name):
......@@ -73,25 +73,28 @@ class DailyReportGenerator:
current_time = datetime.now()
# Generate a unique identifier (e.g., timestamp)
unique_id = current_time.strftime("%Y%m%d%H%M%S%f")
# Calculate the previous day's date
previous_day = current_time - timedelta(days=1)
report_date = previous_day.strftime("%Y-%m-%d")
report_file = f"daily_report_{report_date}.xlsx"
report_file = f"daily_report_{report_date}_{unique_id}.xlsx"
wb = load_workbook(self.template_file)
sheet = wb.active
# Set report date
sheet['L6'] = report_date
sheet['F5'] = report_date
serial_number = 1
# Define the shifts and their respective time ranges
shifts = {
'Shift A': (datetime(current_time.year, current_time.month, current_time.day -1 , 6, 0, 0),
'Shift - A': (datetime(current_time.year, current_time.month, current_time.day -1 , 6, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0)),
'Shift B': (datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0),
'Shift - B': (datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 22, 0, 0)),
'Shift C': (datetime(current_time.year, current_time.month, current_time.day- 1, 22, 0, 0),
'Shift - C': (datetime(current_time.year, current_time.month, current_time.day- 1, 22, 0, 0),
datetime(current_time.year, current_time.month, current_time.day, 6, 0, 0))
}
......@@ -111,8 +114,8 @@ class DailyReportGenerator:
# Fill in the data in respective cells
sheet[f'A{row}'] = serial_number
sheet[f'B{row}'] = end_time.date()
sheet[f'C{row}'] = shift
sheet[f'D{row}'] = packer_name
sheet[f'C{row}'] = packer_name
sheet[f'D{row}'] = shift
sheet[f'E{row}'] = count
total_count += count # Accumulate the count
......@@ -122,27 +125,22 @@ class DailyReportGenerator:
serial_number += 1
# Fill the total count in cell E26
sheet['F26'] = total_count
sheet['F25'] = total_count
# Fill the packer counts in column L
for packer_name, count in packer_counts.items():
packer_row = 9 + packer_names.index(packer_name) * 3
print('packer_row ------------- ',packer_row , 'packer_names.index(packer_name)--------- ',packer_names.index(packer_name))
sheet[f'F{packer_row}'] = count
# Set print area to include all cells with data
max_row = sheet.max_row
max_column = sheet.max_column
print_area = f"A1:{openpyxl.utils.get_column_letter(max_column)}{max_row}"
sheet.print_area = print_area
# Save the report file
wb.save(report_file)
# Return the absolute path of the generated report file
file_path = os.path.abspath(report_file)
return file_path
# Create an instance of DailyReportGenerator
report_generator = DailyReportGenerator()
# Generate the daily report
report_path = report_generator.create_excel_report()
# Print the path of the generated report
print(f"Generated Daily Report: {report_path}")
......@@ -2,12 +2,15 @@ import pandas as pd
from pymongo import MongoClient
from datetime import datetime, timedelta
import os
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import yaml
from dotenv import load_dotenv
from collections import defaultdict
import smtplib
import requests
import logging
load_dotenv(dotenv_path='.env')
......@@ -32,20 +35,47 @@ class DailyReportGenerator:
def get_shift_name(self, timestamp):
"""
Maps the shift names to the desired timings.
Returns:
str: The shift names.
"""
hour = timestamp.hour
if 6 <= hour < 14:
return 'Shift A'
return 'Shift - A'
elif 14 <= hour < 22:
return 'Shift B'
return 'Shift - B'
else:
return 'Shift C'
return 'Shift - C'
def get_packer_name(self, camera_name):
"""
Fetches the camera mapping fromt he config file/any for of input file given.
Returns: The mappings
"""
return self.camera_mappings.get(camera_name, 'Unknown')
def get_count(self, start_time, end_time, camera_name):
"""
Fetches the count difference between the first and last document within the specified time range and camera name.
Args:
start_time (datetime): The start time of the time range.
end_time (datetime): The end time of the time range.
camera_name (str): The name of the camera.
Returns:
int: The count difference between the first and last document within the specified time range and camera name.
"""
query = {
'timestamp': {'$gte': start_time, '$lte': end_time},
'cameraName': camera_name
......@@ -67,69 +97,161 @@ class DailyReportGenerator:
def create_excel_report(self):
"""
Generates an Excel report based on the provided data and saves it in the specified folder.
Returns:
str: The absolute path of the generated report file.
"""
reports_folder = self.config['folder_path']
if not os.path.exists(reports_folder):
os.makedirs(reports_folder)
report_file = 'daily_report.xlsx'
current_time = datetime.now()
report_date = current_time.strftime("%Y-%m-%d")
report_file = f"daily_report_{report_date}.xlsx"
# Generate a unique identifier (e.g., timestamp)
unique_id = current_time.strftime("%Y%m%d%H%M%S%f")
# Calculate the previous day's date
previous_day = current_time - timedelta(days=1)
report_date = previous_day.strftime("%Y-%m-%d")
report_file = f"daily_report_{report_date}_{unique_id}.xlsx"
wb = load_workbook(self.template_file)
sheet = wb.active
# Set report date
sheet['L6'] = report_date
sheet['F5'] = report_date
serial_number = 1
# Define the shifts and their respective time ranges
shifts = {
'Shift A': (datetime(current_time.year, current_time.month, current_time.day -1 , 6, 0, 0),
'Shift - A': (datetime(current_time.year, current_time.month, current_time.day -1 , 6, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0)),
'Shift B': (datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0),
'Shift - B': (datetime(current_time.year, current_time.month, current_time.day -1, 14, 0, 0),
datetime(current_time.year, current_time.month, current_time.day -1, 22, 0, 0)),
'Shift C': (datetime(current_time.year, current_time.month, current_time.day- 1, 22, 0, 0),
'Shift - C': (datetime(current_time.year, current_time.month, current_time.day- 1, 22, 0, 0),
datetime(current_time.year, current_time.month, current_time.day, 6, 0, 0))
}
# Start filling details from row 8
row = 7
total_count = 0 # Initialize total count
packer_counts = defaultdict(int) # Initialize packer counts dictionary
# Get the camera_names from config.yml
# Get the camera_names and corresponding packer_names from config.yml
camera_names = [item['camera_name'] for item in self.config['cameras']]
packer_names = [item['packer_name'] for item in self.config['cameras']]
for camera_name in camera_names:
for camera_name, packer_name in zip(camera_names, packer_names):
for shift, (start_time, end_time) in shifts.items():
packer_name = self.get_packer_name(camera_name)
count = self.get_count(start_time, end_time, camera_name)
# Fill in the data in respective cells
sheet[f'A{row}'] = serial_number
sheet[f'B{row}'] = end_time.date()
sheet[f'C{row}'] = shift
sheet[f'D{row}'] = packer_name
sheet[f'C{row}'] = packer_name
sheet[f'D{row}'] = shift
sheet[f'E{row}'] = count
total_count += count # Accumulate the count
packer_counts[packer_name] += count # Accumulate the count for the packer
row += 1
serial_number += 1
# Fill the total count in cell E26
sheet['E26'] = total_count
sheet['F25'] = total_count
# Fill the packer counts in column L
for packer_name, count in packer_counts.items():
packer_row = 9 + packer_names.index(packer_name) * 3
sheet[f'F{packer_row}'] = count
# Set print area to include all cells with data
max_row = sheet.max_row
max_column = sheet.max_column
print_area = f"A1:{openpyxl.utils.get_column_letter(max_column)}{max_row}"
sheet.print_area = print_area
report_file = os.path.join(reports_folder, report_file)
# Save the report file
wb.save(report_file)
# Return the absolute path of the generated report file
file_path = os.path.abspath(report_file)
return file_path
# Create an instance of DailyReportGenerator
report_generator = DailyReportGenerator()
def get_receiver_emails(self):
"""
Retrieves the email addresses of receivers from the MongoDB collection.
# Generate the daily report
report_path = report_generator.create_excel_report()
Returns:
list: A list of email addresses of receivers.
# Print the path of the generated report
print(f"Generated Daily Report: {report_path}")
"""
# Connect to MongoDB and retrieve the email addresses from the collection
client = MongoClient(os.environ["MONGO_CLIENT"])
db = client[os.environ["MONGO_DATABASE"]]
collection = db[os.environ["MONGO_COLLECTION_EMAIL"]]
emails = []
documents = collection.find()
for document in documents:
emails.append(document["email"])
return emails
def send_email_from_ut(self,filename="daily_report.xlsx", filepath=None):
"""
Sends an email to the receiver list with the specified file attachment and payload.
Args:
filename (str, optional): The name of the file attachment. Defaults to "daily_report.xlsx".
filepath (str, optional): The file path of the attachment. Defaults to None.
Returns:
bool: True if the email was successfully sent, False otherwise.
"""
logging.info("Sending email to {}".format(self.get_receiver_emails()))
payload = dict()
payload['from_name'] = os.environ["FROM_ADDRESS"]
payload['receiver_list'] = self.get_receiver_emails()
payload['subject'] = self.config['email']['subject']
payload['content'] = self.config['email']['body']
payload['gateway_id'] = os.environ["GATEWAY"]
headers = {'authorization': os.environ["AUTHORIZATION"]}
count = 0
while count < 3:
try:
if filename and filepath:
files = [('attachments', (filename, open(filepath, 'rb'), 'application/html'))]
response = requests.request("POST", os.environ["URL_WITH_ATTACH"], data=payload,
headers=headers, files=files, timeout=10)
logging.info(f"Response status code for request is: {response.status_code}")
if response.status_code == 200:
return True
else:
response = requests.request("POST", os.environ["URL_WITHOUT_ATTACH"], json=payload,
headers=headers, timeout=10)
logging.info(f"Response status code for request is: {response.status_code}")
if response.status_code == 200:
return True
except Exception as e:
logging.error(e)
count += 1
return False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment