Advertisement
Guest User

EOL Notification Script

a guest
May 15th, 2025
93
0
27 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.08 KB | Source Code | 0 0
  1. import requests
  2. import datetime
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.mime.multipart import MIMEMultipart
  6. import locale
  7.  
  8. #------------------------ [Var & Const def] -----------------------------------------------
  9. # Set the locale to French for date formatting
  10. locale.setlocale(locale.LC_TIME, "fr_FR.UTF-8")
  11.  
  12. # List of products to monitor
  13. PRODUCTS = [
  14. "ubuntu-server", "windows-server"
  15. ]
  16.  
  17. # Email sending settings
  18. SMTP_SERVER = "<your-smtp-server>" # Replace with your SMTP server
  19. SMTP_PORT = 25 # Using port 25 without authentication
  20. EMAIL_FROM = "<your-sender>" # Replace with your email
  21. EMAIL_TO = "<your-recipient>" # Replace with recipient's email
  22.  
  23. #------------------------------------- [Functions] ---------------------------------------
  24.  
  25. def get_end_of_life_info(product):
  26. """Fetches end-of-life information and the real product name."""
  27. print(f"Fetching data for product: {product}")
  28. url = f"https://endoflife.date/api/{product}.json"
  29. try:
  30. response = requests.get(url)
  31. if response.status_code == 200:
  32. data = response.json()
  33. if data:
  34. # Retrieve the real product name from the API
  35. product_name = data[0].get("name", product.capitalize())
  36. return product_name, data
  37. else:
  38. print(f"HTTP error {response.status_code} for {product}")
  39. return product.capitalize(), None
  40. except Exception as e:
  41. print(f"Error fetching data for {product}: {e}")
  42. return product.capitalize(), None
  43.  
  44.  
  45. def filter_supported_versions(data):
  46. """Filters versions whose end-of-life is in one year or less."""
  47. today = datetime.date.today()
  48. one_year_later = today + datetime.timedelta(days=365)
  49.  
  50. filtered_versions = []
  51. for entry in data:
  52. eol_date_str = entry.get("eol")
  53.  
  54. # Check if the date is valid and usable
  55. if isinstance(eol_date_str, str) and eol_date_str.lower() != "false":
  56. try:
  57. eol_date = datetime.datetime.strptime(eol_date_str, "%Y-%m-%d").date()
  58. if today <= eol_date <= one_year_later:
  59. formatted_date = eol_date.strftime("%d %B %Y") # E.g.: "26 March 2025"
  60. filtered_versions.append((entry.get("cycle", "Unknown"), eol_date, formatted_date, entry.get("latest")))
  61. except ValueError:
  62. print(f"Error parsing end-of-life date for {entry}: {eol_date_str}")
  63.  
  64. return filtered_versions
  65.  
  66.  
  67. def get_row_class(eol_date):
  68. """Returns the CSS class to apply to the row depending on support end date."""
  69. today = datetime.date.today()
  70. two_months_later = today + datetime.timedelta(days=60)
  71. six_months_later = today + datetime.timedelta(days=180)
  72.  
  73. if eol_date <= two_months_later:
  74. return "red"
  75. elif eol_date <= six_months_later:
  76. return "orange"
  77. else:
  78. return "green"
  79.  
  80.  
  81. def generate_html_table():
  82. """Generates an HTML table of soon-to-be unsupported versions, one table per product."""
  83. all_tables_html = ""
  84.  
  85. for product in PRODUCTS:
  86. product_name, data = get_end_of_life_info(product)
  87. if data:
  88. filtered_versions = filter_supported_versions(data)
  89. if filtered_versions:
  90. # Sort versions by end-of-life date (furthest first)
  91. filtered_versions.sort(key=lambda x: x[1], reverse=True)
  92.  
  93. # Use real name in the title
  94. table_html = f"""
  95. <h2>{product_name}</h2>
  96. <table>
  97. <tr>
  98. <th>Version</th>
  99. <th>Latest Version</th>
  100. <th>End of Support</th>
  101. </tr>
  102. """
  103.  
  104. for cycle, eol_date, formatted_date, latest in filtered_versions:
  105. row_class = get_row_class(eol_date)
  106. table_html += f"""
  107. <tr class="{row_class}">
  108. <td>{cycle}</td>
  109. <td>{latest}</td>
  110. <td>{formatted_date}</td>
  111. </tr>
  112. """
  113.  
  114. table_html += "</table>"
  115. all_tables_html += table_html
  116.  
  117. if not all_tables_html:
  118. return None
  119.  
  120. # Add CSS for table styling
  121. return f"""
  122. <html>
  123. <head>
  124. <style>
  125. body {{ font-family: Arial, sans-serif; }}
  126. h2 {{ font-size: 18px; margin-top: 20px; }}
  127. table {{ width: auto; border-collapse: collapse; margin-bottom: 20px; }}
  128. th, td {{ padding: 4px 8px; text-align: left; border: 1px solid #ddd; }}
  129. .red {{ background-color: #FF0000; }} /* Red */
  130. .orange {{ background-color: #FFA500; }} /* Orange */
  131. .green {{ background-color: #90EE90; }} /* Green */
  132. </style>
  133. </head>
  134. <body>
  135. {all_tables_html}
  136. </body>
  137. </html>
  138. """
  139.  
  140.  
  141. def send_email(table_html):
  142. """Sends an HTML email with the table of soon-to-be unsupported versions."""
  143. msg = MIMEMultipart()
  144. msg['From'] = EMAIL_FROM
  145. msg['To'] = EMAIL_TO
  146. msg['Subject'] = "Alert: End of Support for Software Versions"
  147.  
  148. body = f"""
  149. <html>
  150. <body>
  151. <p>Hello,</p>
  152. <p>Here is the list of versions whose end of support is within one year:</p>
  153. {table_html}
  154. <p>Best regards,<br>Your Monitoring System</p>
  155. </body>
  156. </html>
  157. """
  158.  
  159. msg.attach(MIMEText(body, 'html'))
  160.  
  161. try:
  162. print("Attempting to connect to SMTP server...")
  163. server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
  164. server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
  165. server.quit()
  166. print("Email sent successfully.")
  167. except smtplib.SMTPException as e:
  168. print(f"SMTP error when sending email: {e}")
  169. except Exception as e:
  170. print(f"General error when sending email: {e}")
  171.  
  172. # --------------------------- [Main] ------------------------------------
  173. if __name__ == "__main__":
  174. table_html = generate_html_table()
  175. if table_html:
  176. print("Table generated successfully")
  177. send_email(table_html)
  178. else:
  179. print("No product to display.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement