modified
properties/models.py
@@ -4,6 +4,7 @@ import timeimport uuidimport requestsfrom django.conf import settingsfrom django.contrib.auth import get_user_modelfrom django.core.mail import EmailMessagefrom django.db import models, transaction
@@ -112,7 +113,8 @@ class AlertsMixin: def send_down_email(self): subject = f"Status: {self.name} is down!" message = render_to_string("emails/property_down.html", {"property": self}) context = {"property": self, "BASE_URL": settings.BASE_URL} message = render_to_string("emails/property_down.html", context) from_email = "noreply@bythewood.me" to_emails = [self.user.email] email = EmailMessage(subject, message, from_email, to_emails)
@@ -124,7 +126,8 @@ class AlertsMixin: def send_recovery_email(self): subject = f"Status: {self.name} is back up!" message = render_to_string("emails/property_recovery.html", {"property": self}) context = {"property": self, "BASE_URL": settings.BASE_URL} message = render_to_string("emails/property_recovery.html", context) from_email = "noreply@bythewood.me" to_emails = [self.user.email] email = EmailMessage(subject, message, from_email, to_emails)
modified
properties/templates/emails/property_email_base.html
@@ -1,157 +1,143 @@<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="x-apple-disable-message-reformatting"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="x-apple-disable-message-reformatting"> <meta name="color-scheme" content="dark"> <meta name="supported-color-schemes" content="dark"> <meta name="format-detection" content="telephone=no, date=no, address=no, email=no"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>{{ email_title }}</title> <style type="text/css"> body,table,td{font-family:Helvetica,Arial,sans-serif !important}.ExternalClass{width:100%}.ExternalClass,.ExternalClass p,.ExternalClass span,.ExternalClass font,.ExternalClass td,.ExternalClass div{line-height:150%}a{text-decoration:none}*{color:inherit}a[x-apple-data-detectors],u+#body a,#MessageViewBody a{color:inherit;text-decoration:none;font-size:inherit;font-family:inherit;font-weight:inherit;line-height:inherit}img{-ms-interpolation-mode:bicubic}table:not([class^=s-]){font-family:Helvetica,Arial,sans-serif;mso-table-lspace:0pt;mso-table-rspace:0pt;border-spacing:0px;border-collapse:collapse}table:not([class^=s-]) td{border-spacing:0px;border-collapse:collapse}@media screen and (max-width: 600px){.w-full,.w-full>tbody>tr>td{width:100% !important}.p-3:not(table),.p-3:not(.btn)>tbody>tr>td,.p-3.btn td a{padding:12px !important}*[class*=s-lg-]>tbody>tr>td{font-size:0 !important;line-height:0 !important;height:0 !important}.s-4>tbody>tr>td{font-size:16px !important;line-height:16px !important;height:16px !important}.s-10>tbody>tr>td{font-size:40px !important;line-height:40px !important;height:40px !important}} body { margin: 0 !important; padding: 0 !important; background: #0e0d0a !important; } table { border-collapse: collapse; } img { border: 0; display: block; } a { color: #7db88c; text-decoration: none; } a:hover { text-decoration: underline; } @media (max-width: 620px) { .shell { width: 100% !important; } .px-pad { padding-left: 22px !important; padding-right: 22px !important; } .kv-key { width: 100% !important; display: block !important; border-left: 0 !important; padding: 14px 0 0 0 !important; } .kv-val { width: 100% !important; display: block !important; border-left: 0 !important; padding: 4px 0 14px 0 !important; } } </style> </head> <body class="bg-light" style="outline: 0; width: 100%; min-width: 100%; height: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; font-family: Helvetica, Arial, sans-serif; line-height: 24px; font-weight: normal; font-size: 16px; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; color: #000000; margin: 0; padding: 0; border-width: 0;" bgcolor="#f7fafc"> <table class="bg-light body" valign="top" role="presentation" border="0" cellpadding="0" cellspacing="0" style="outline: 0; width: 100%; min-width: 100%; height: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; font-family: Helvetica, Arial, sans-serif; line-height: 24px; font-weight: normal; font-size: 16px; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; color: #000000; margin: 0; padding: 0; border-width: 0;" bgcolor="#f7fafc"> <tbody> <tr> <td valign="top" style="line-height: 24px; font-size: 16px; margin: 0;" align="left" bgcolor="#f7fafc"> <table class="container" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;"> <tbody> <tr> <td align="center" style="line-height: 24px; font-size: 16px; margin: 0; padding: 0 16px;"> <!--[if (gte mso 9)|(IE)]> <table align="center" role="presentation"> <tbody> <tr> <td width="600"> <![endif]--> <table align="center" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px; margin: 0 auto;"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; margin: 0;" align="left"> <table class="s-10 w-full" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;" width="100%"> <tbody> <tr> <td style="line-height: 40px; font-size: 40px; width: 100%; height: 40px; margin: 0;" align="left" width="100%" height="40">   </td> </tr> </tbody> </table> <table class="card rounded-none" role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-radius: 0px; border-collapse: separate !important; width: 100%; overflow: hidden; border: 1px solid #e2e8f0;" bgcolor="#ffffff"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; width: 100%; border-radius: 0px; margin: 0;" align="left" bgcolor="#ffffff"> <table class="card-body" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; width: 100%; margin: 0; padding: 20px;" align="left"> <h1 class="{% block header_class %}{% endblock %}" style="{% block header_style %}{% endblock %} padding-top: 0; padding-bottom: 0; font-weight: 500; vertical-align: baseline; font-size: 36px; line-height: 43.2px; margin: 0;" align="left"> <table class="p-3" role="presentation" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; margin: 0; padding: 12px;" align="left"> <strong class="h2" style="padding-top: 0; padding-bottom: 0; font-weight: 500; text-align: left; vertical-align: baseline; font-size: 32px; line-height: 38.4px; margin: 0;">{% block header_title %}{% endblock %}</strong> </td> </tr> </tbody> </table> </h1> <table class="s-4 w-full" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;" width="100%"> <tbody> <tr> <td style="line-height: 16px; font-size: 16px; width: 100%; height: 16px; margin: 0;" align="left" width="100%" height="16">   </td> </tr> </tbody> </table> <table class="alert {% block alert_class %}{% endblock %} rounded-none" role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate !important; width: 100%; border-radius: 0px; border-width: 0;"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; border-radius: 0px; {% block alert_style %}{% endblock %} margin: 0; padding: 12px 20px; border: 1px solid transparent;" align="left" bgcolor="{% block alert_bg %}{% endblock %}"> <div> {% block alert_message %}{% endblock %} </div> </td> </tr> </tbody> </table> <table class="s-4 w-full" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;" width="100%"> <tbody> <tr> <td style="line-height: 16px; font-size: 16px; width: 100%; height: 16px; margin: 0;" align="left" width="100%" height="16">   </td> </tr> </tbody> </table> <div class="space-y-3"> <table class="table" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 100%;"> <tbody> <tr> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top"> <strong>name</strong> </td> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top">{{ property.name }}</td> </tr> <tr> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top"> <strong>url</strong> </td> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top"> <a href="{{ property.url }}" target="_blank" style="color: #0d6efd;">{{ property.url }}</a> </td> </tr> <tr> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top"> <strong>status</strong> </td> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top">{{ property.current_status }}</td> </tr> <tr> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top"> <strong>avg. time</strong> </td> <td style="line-height: 24px; font-size: 16px; border-top-width: 1px; border-top-color: #e2e8f0; border-top-style: solid; margin: 0; padding: 12px;" align="left" valign="top">{{ property.avg_response_time }}</td> </tr> </tbody> </table> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <table class="s-10 w-full" role="presentation" border="0" cellpadding="0" cellspacing="0" style="width: 100%;" width="100%"> <tbody> <tr> <td style="line-height: 40px; font-size: 40px; width: 100%; height: 40px; margin: 0;" align="left" width="100%" height="40">   </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <!--[if (gte mso 9)|(IE)]> <body style="margin: 0; padding: 0; background-color: #0e0d0a; color: #ddd7cd; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 14px; line-height: 1.65;"> <div style="display: none; max-height: 0; overflow: hidden; mso-hide: all; font-size: 1px; line-height: 1px; color: #0e0d0a;">{{ preheader }}</div> <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #0e0d0a;"> <tr> <td align="center" style="padding: 40px 16px;"> <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px;"> <tr> <td class="px-pad" style="padding: 0 0 18px 0;"> <table role="presentation" cellpadding="0" cellspacing="0" border="0"> <tr> <td style="vertical-align: middle; padding-right: 10px; line-height: 0;"> <span style="display: inline-block; width: 8px; height: 8px; background-color: #6b9e78; border-radius: 50%; box-shadow: 0 0 0 3px rgba(107,158,120,0.18);"></span> </td> <td style="vertical-align: middle; color: #ede8e0; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700;"> // Status </td> </tr> </table> </td> </tr> </table> <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px; background-color: #13120e; border: 1px solid {{ accent_border }};"> <tr> <td style="height: 3px; background-color: {{ accent }}; line-height: 3px; font-size: 0;"> </td> </tr> <tr> <td class="px-pad" style="padding: 30px 32px 6px 32px;"> <table role="presentation" cellpadding="0" cellspacing="0" border="0"> <tr> <td style="vertical-align: middle; padding-right: 8px; line-height: 0;"> <span style="display: inline-block; width: 7px; height: 7px; background-color: {{ accent }}; border-radius: 50%;"></span> </td> <td style="vertical-align: middle; color: {{ accent_bright }}; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 700;"> {{ status_label }} </td> </tr> </table> </td> </tr> <tr> <td class="px-pad" style="padding: 14px 32px 4px 32px;"> <h1 style="margin: 0; color: #ede8e0; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 26px; line-height: 1.25; font-weight: 700; letter-spacing: -0.01em;"> {{ event_title }} </h1> </td> </tr> <tr> <td class="px-pad" style="padding: 14px 32px 26px 32px; color: #a09890; font-size: 14px; line-height: 1.75;"> {{ event_copy }} </td> </tr> <tr> <td class="px-pad" style="padding: 0 32px 6px 32px;"> <div style="font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: #c9a84c; padding: 0 0 10px 0; font-weight: 700;"> / Property </div> <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border: 1px solid rgba(107,158,120,0.12); background: rgba(9,8,6,0.5);"> <tr> <td class="kv-key" width="32%" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Name</td> <td class="kv-val" style="padding: 12px 14px; color: #ede8e0; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top; word-break: break-word;">{{ property.name }}</td> </tr> <tr> <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">URL</td> <td class="kv-val" style="padding: 12px 14px; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top; word-break: break-all;"> <a href="{{ property.url }}" style="color: #7db88c; text-decoration: none;">{{ property.url }}</a> </td> </tr> <tr> <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Status</td> <td class="kv-val" style="padding: 12px 14px; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top;"> <span style="display: inline-block; background-color: {{ accent_tint }}; color: {{ accent_bright }}; border: 1px solid {{ accent_border }}; padding: 3px 9px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700;">{{ property.current_status }}</span> </td> </tr> <tr> <td class="kv-key" style="padding: 12px 14px; color: #665f56; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; border-top: 1px solid rgba(107,158,120,0.08); vertical-align: top; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;">Avg time</td> <td class="kv-val" style="padding: 12px 14px; color: #ede8e0; font-size: 13px; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace; border-top: 1px solid rgba(107,158,120,0.08); border-left: 1px solid rgba(107,158,120,0.08); vertical-align: top;">{{ property.avg_response_time }} ms</td> </tr> </table> </td> </tr> <tr> <td class="px-pad" style="padding: 26px 32px 32px 32px;"> <table role="presentation" cellpadding="0" cellspacing="0" border="0"> <tr> <td style="background-color: {{ accent_tint }}; border: 1px solid {{ accent_border }};"> <a href="{{ BASE_URL }}/properties/{{ property.id }}/" style="display: inline-block; padding: 12px 22px; color: {{ accent_bright }}; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; text-decoration: none; font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, Consolas, monospace;"> View property → </a> </td> </tr> </tbody> </table> <![endif]--> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </table> <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="shell" width="560" style="width: 100%; max-width: 560px;"> <tr> <td class="px-pad" style="padding: 24px 0 0 0; color: #4a443c; font-size: 11px; line-height: 1.8; letter-spacing: 0.02em;"> Self-hosted monitoring · HTTP checks every three minutes<br> Alerts fire only on state transitions. Manage notifications from your <a href="{{ BASE_URL }}/accounts/profile/" style="color: #665f56; text-decoration: underline;">profile</a>. </td> </tr> </table> </td> </tr> </table> </body></html>