Aug-06-2024, 02:55 PM
I have written some code that takes screenshots of a dual-monitor setup. If it 'sees' images with a certain ratio of skin tone-colored pixels, if sends that image to an accountability partner. This was written to solve the problem of a porn addict on his work computer who does not have admin privileges and needed to be able to run something like a python script to help with accountability.
I am interested in any ways to improve the code because I am a novice when it comes to programming. Also, I am looking into ways to make the running of the code automatic and ways to keep from getting around it.
Currently, I have a .bat file that runs the python code at computer startup, but the trouble is that I haven't been able to get an automatic computer shutdown to occur when the user 'forgets' to shut down the machine.
I am interested in any ways to improve the code because I am a novice when it comes to programming. Also, I am looking into ways to make the running of the code automatic and ways to keep from getting around it.
Currently, I have a .bat file that runs the python code at computer startup, but the trouble is that I haven't been able to get an automatic computer shutdown to occur when the user 'forgets' to shut down the machine.
# This script takes a screenshot of both monitors and if a certain portion of the screen contains colors # that have skin tones, then an email will go to an accountability partner. import mss import mss.tools from datetime import datetime, timedelta import time import cv2 import matplotlib.pyplot as plt import os #using import numpy as np import smtplib #using from email.mime.text import MIMEText #using from email.mime.multipart import MIMEMultipart #using from email.mime.image import MIMEImage #using # Function to send email with file names and images # Arguments--Subject of email, message in text, email address to send to & image path def send_email(subject, message, to_email, image_path): # Gain access to email server smtp_server = 'smtp.office365.com' smtp_port = 587 smtp_username = 'username_goes_here' smtp_password = 'password_here_please' # Define variables for the email msg = MIMEMultipart() msg['From'] = smtp_username msg['To'] = to_email msg['Subject'] = subject msg.attach(MIMEText(message, 'plain')) if image_path: print(f'Image path: {image_path}') # os.path.isfile() method is used to check whether the specified path is an existing file or not if os.path.isfile(image_path): for img in skin_images: image_path = os.path.join(image_folder, img) with open(image_path, 'rb') as f: img_data = f.read() img_mime = MIMEImage(img_data, name=os.path.basename(image_path)) msg.attach(img_mime) else: print(f"Error: Image file '{image_path}' not found.") try: # Connect to Microsoft SMTP server server = smtplib.SMTP(smtp_server, smtp_port) server.starttls() # Secure the connection server.login(smtp_username, smtp_password) # Login to email server # Send email server.sendmail(smtp_username, to_email, msg.as_string()) print(f"Accountability Email to SomeOtherDude sent successfully to {to_email}!") server.quit() # Disconnect from server except smtplib.SMTPAuthenticationError as e: print(f"Failed to send email: SMTP Authentication Error - {e}") except smtplib.SMTPException as e: print(f"Failed to send email: SMTP Exception - {e}") except Exception as e: print(f"Failed to send email: {str(e)}") # Function to detect skin tones in images def detect_skin_tones(image_folder, skin_threshold_ratio=0.03): skin_images = [] # Iterate through images in the folder for filename in os.listdir(image_folder): if filename.endswith(".jpg") or filename.endswith(".png"): # Read image img_path = os.path.join(image_folder, filename) image = cv2.imread(img_path) # Convert image from BGR to HSV hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Define skin tone ranges in HSV color space lower_skin = np.array([0, 48, 80], dtype=np.uint8) upper_skin = np.array([20, 255, 255], dtype=np.uint8) # Create mask for skin tones mask = cv2.inRange(hsv_image, lower_skin, upper_skin) # Count skin tone pixels skin_pixel_count = cv2.countNonZero(mask) # Calculate total number of pixels in the image total_pixels = image.shape[0] * image.shape[1] # Calculate skin tone threshold based on image size skin_threshold = total_pixels * skin_threshold_ratio # Check if skin pixels exceed threshold if skin_pixel_count >= skin_threshold: skin_images.append(filename) return skin_images def capture_and_save_screenshot(monitor_index, filename_prefix): with mss.mss() as sct: mon = sct.monitors[monitor_index] monitor = { "top": mon["top"], "left": mon["left"], "width": mon["width"], "height": mon["height"], "mon": monitor_index, } current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") output = f"{filename_prefix}_{current_time}.png" sct_img = sct.grab(monitor) image = mss.tools.to_png(sct_img.rgb, sct_img.size, output=output) return output # Testing snippet. Comment out the Working snippet before using. Also comment out email send. #iteration_count = 0 #while iteration_count < 1: # iteration_count += 1 # capture_and_save_screenshot(1, "Monitor_1") # capture_and_save_screenshot(2, "Monitor_2") # time.sleep(1) # Working snippet. Un-comment out send email method call iteration_count = 0 while iteration_count < 72: iteration_count += 1 capture_and_save_screenshot(1, "Monitor_1") capture_and_save_screenshot(2, "Monitor_2") time.sleep(600) image_folder = 'C:\\Users\\blahblah\\Desktop\\+Loc_Ref_Files\\Screenshots' # skin_images is a list of file names that show skin tones skin_images = detect_skin_tones(image_folder, skin_threshold_ratio=0.03) #print(f'Skin images detected in image folder: {skin_images}') # Comment out the section below if testing, but if testing email section then don't. if skin_images: subject = 'Accountability for SomeDude' message = f'Ask SomeDude about these screenshots: {skin_images}' message2 = 'No explicit images were found today. Yay!' to_email = '[email protected]' # [email protected] if skin_images: image_path = os.path.join(image_folder, skin_images[0]) send_email(subject, message, to_email, image_path) else: send_email(subject, message2, to_email)