will9512

email_random_photo_from_album

Jul 8th, 2024 (edited)
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.79 KB | None | 0 0
  1. import os
  2. import requests
  3. import smtplib
  4. from email.mime.multipart import MIMEMultipart
  5. from email.mime.text import MIMEText
  6. from email.mime.base import MIMEBase
  7. from email import encoders
  8. import logging
  9. from datetime import datetime, timedelta
  10. import random
  11. import json
  12. import uuid
  13. from PIL import Image
  14.  
  15. # Configure logging
  16. logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
  17.  
  18. # Load sensitive data from environment variables
  19. SERVER_URL = "http://default.server.url"
  20. PASSWORD = "default_password" #immich password
  21. SMTP_PASSWORD = "default_smtp_password"
  22. TRACKED_IMAGES_FILE = 'tracked_images.txt' # file to keep track of whats been sent
  23. PERSON_ID = 'default_person_id'
  24.  
  25. recipient_emails = [
  26. ]
  27.  
  28. def compress_image(file_path, quality=85, output_folder='compressed_images'):
  29.     original_size = os.path.getsize(file_path)
  30.     max_size = 25 * 1024 * 1024  # 25 MB
  31.  
  32.     if original_size > max_size:
  33.         os.makedirs(output_folder, exist_ok=True)
  34.         image = Image.open(file_path)
  35.         original_basename = os.path.basename(file_path)
  36.         new_file_path = os.path.join(output_folder, f"compressed_{original_basename}")
  37.  
  38.         image.save(new_file_path, format='JPEG', quality=quality)
  39.  
  40.         if os.path.exists(new_file_path):
  41.             os.remove(file_path)
  42.             return new_file_path
  43.         else:
  44.             return file_path
  45.     else:
  46.         return file_path
  47.  
  48. def download_asset(server_url, photo_id, token, query_key=None):
  49.     file_path = f'{photo_id}.jpg'
  50.     if not os.path.exists(file_path):
  51.         logging.info(f"Downloading image: {photo_id}")
  52.         download_url = f"{server_url}/api/assets/{photo_id}/original"
  53.         headers = {'Authorization': f'Bearer {token}', 'Accept': 'application/octet-stream'}
  54.         params = {'key': query_key} if query_key else {}
  55.  
  56.         try:
  57.             response = requests.get(download_url, headers=headers, params=params)
  58.             if response.status_code == 200:
  59.                 content_type = response.headers.get('Content-Type')
  60.                 extension = content_type.split('/')[-1]
  61.                 file_path = f"{photo_id}.{extension}"
  62.                
  63.                 with open(file_path, 'wb') as f:
  64.                     for chunk in response.iter_content(chunk_size=8192):
  65.                         f.write(chunk)
  66.                 logging.info(f"Image downloaded: {photo_id}")
  67.             else:
  68.                 logging.error(f"Failed to download image. Status code: {response.status_code}")
  69.                 return None
  70.         except requests.exceptions.RequestException as e:
  71.             logging.error(f"Error during image download: {e}")
  72.             return None
  73.     else:
  74.         logging.info(f"Image already exists: {photo_id}")
  75.  
  76.     file_path = compress_image(file_path) if 'image' in content_type else file_path
  77.     return file_path
  78.  
  79. def login_to_api(server_url, email, password):
  80.     logging.info("Attempting to log in...")
  81.     login_url = f"{server_url}/api/auth/login"
  82.     login_payload = json.dumps({"email": email, "password": password})
  83.     login_headers = {'Content-Type': 'application/json'}
  84.  
  85.     try:
  86.         response = requests.post(login_url, headers=login_headers, data=login_payload)
  87.         if response.status_code in [200, 201]:
  88.             logging.info("Login successful")
  89.             return response.json()
  90.         else:
  91.             logging.error(f"Failed to login. Status code: {response.status_code}")
  92.             return None
  93.     except requests.exceptions.RequestException as e:
  94.         logging.error(f"Error during login: {e}")
  95.         return None
  96.  
  97. def validate_token(server_url, token):
  98.     url = f"{server_url}/api/auth/validateToken"
  99.     headers = {'Authorization': f'Bearer {token}', 'Accept': 'application/json'}
  100.  
  101.     try:
  102.         response = requests.post(url, headers=headers)
  103.         if response.status_code == 200:
  104.             return response.json().get('authStatus', False)
  105.         else:
  106.             logging.error(f"Failed to validate token. Status code: {response.status_code}")
  107.             return False
  108.     except requests.exceptions.RequestException as e:
  109.         logging.error(f"Error during token validation: {e}")
  110.         return False
  111.  
  112. def get_time_buckets(server_url, token, user_id, size='MONTH'):
  113.     logging.info("Fetching time buckets...")
  114.     url = f"{server_url}/api/timeline/buckets"
  115.     headers = {'Authorization': f'Bearer {token}', 'Accept': 'application/json'}
  116.     params = {'userId': user_id, 'size': size}
  117.  
  118.     try:
  119.         response = requests.get(url, headers=headers, params=params)
  120.         if response.status_code == 200:
  121.             logging.info("Time buckets fetched successfully.")
  122.             return response.json()
  123.         else:
  124.             logging.error(f"Failed to fetch time buckets. Status code: {response.status_code}")
  125.             return []
  126.     except requests.exceptions.RequestException as e:
  127.         logging.error(f"Error fetching time buckets: {e}")
  128.         return []
  129.  
  130. def fetch_assets(server_url, token, person_id):
  131.     logging.info("Fetching assets...")
  132.     url = f"{server_url}/api/people/{person_id}/assets"
  133.     headers = {'Authorization': f'Bearer {token}', 'Accept': 'application/json'}
  134.  
  135.     try:
  136.         response = requests.get(url, headers=headers)
  137.         if response.status_code == 200:
  138.             logging.info("Assets fetched successfully")
  139.             assets = response.json()
  140.             last_month_date = datetime.now() - timedelta(days=30)
  141.             format_str = '%Y-%m-%dT%H:%M:%S.%fZ'
  142.             recent_assets = [
  143.                 asset for asset in assets
  144.                 if datetime.strptime(asset['fileCreatedAt'], format_str) >= last_month_date
  145.             ]
  146.             return recent_assets
  147.         else:
  148.             logging.error(f"Failed to fetch assets. Status code: {response.status_code}")
  149.             return []
  150.     except requests.exceptions.RequestException as e:
  151.         logging.error(f"Error fetching assets: {e}")
  152.         return []
  153.  
  154. def record_downloaded_image(image_id):
  155.     with open(TRACKED_IMAGES_FILE, 'a') as file:
  156.         file.write(f"{image_id}\n")
  157.     logging.info(f"Recorded image {image_id} as downloaded")
  158.  
  159. def has_image_been_downloaded(image_id):
  160.     if os.path.exists(TRACKED_IMAGES_FILE):
  161.         with open(TRACKED_IMAGES_FILE, 'r') as file):
  162.             downloaded_images = {line.strip() for line in file}
  163.         return image_id in downloaded_images
  164.     return False
  165.  
  166. def send_email_with_attachment(subject, body, recipient_emails, attachment_path):
  167.     msg = MIMEMultipart()
  168.     msg['From'] = EMAIL
  169.     msg['To'] = ', '.join(recipient_emails)
  170.     msg['Subject'] = subject
  171.     msg.attach(MIMEText(body, 'plain'))
  172.  
  173.     with open(attachment_path, 'rb') as file:
  174.         part = MIMEBase('application', 'octet-stream')
  175.         part.set_payload(file.read())
  176.         encoders.encode_base64(part)
  177.         part.add_header('Content-Disposition', f"attachment; filename= {os.path.basename(attachment_path)}")
  178.         msg.attach(part)
  179.  
  180.     try:
  181.         with smtplib.SMTP('smtp.gmail.com', 587) as server:
  182.             server.starttls()
  183.             server.login(EMAIL, SMTP_PASSWORD)
  184.             server.send_message(msg)
  185.             logging.info(f"Email sent to {', '.join(recipient_emails)}")
  186.     except smtplib.SMTPException as e:
  187.         logging.error(f"Error sending email: {e}")
  188.  
  189. def cleanup_file(file_path):
  190.     os.remove(file_path)
  191.     logging.info(f"Deleted file {file_path}")
  192.  
  193. # Example usage
  194. if __name__ == "__main__":
  195.     login_data = login_to_api(SERVER_URL, EMAIL, PASSWORD)
  196.     if login_data:
  197.         token = login_data.get('accessToken')
  198.         user_id = login_data.get('userId')
  199.         buckets = get_time_buckets(SERVER_URL, token, user_id)
  200.         if buckets:
  201.             latest_bucket = max(buckets, key=lambda b: b['timeBucket'])
  202.             assets = fetch_assets(SERVER_URL, token, PERSON_ID)
  203.             logging.info(f"Assets fetched successfully. Number of assets: {len(assets)}")
  204.  
  205.         if assets:
  206.             selected_asset = random.choice(assets)
  207.             if not has_image_been_downloaded(selected_asset['id']):
  208.                 file_path = download_asset(SERVER_URL, selected_asset['id'], token)
  209.                 if file_path:
  210.                     send_email_with_attachment("Random Photo", "Here's a random photo.", recipient_emails, file_path)
  211.                     cleanup_file(file_path)
  212.                     record_downloaded_image(selected_asset['id'])
  213.                 else:
  214.                     logging.error("Failed to process the image due to download issues")
  215.     else:
  216.         logging.error("Unable to login and perform operations")
  217.  
Add Comment
Please, Sign In to add comment