Skip to content

Commit

Permalink
Remove subscribed emails that have bounced from spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
blopker committed Nov 13, 2024
1 parent a3a23b5 commit 1333799
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 53 deletions.
39 changes: 22 additions & 17 deletions assets/js/components/avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import _Avatar from "@totem.org/solid-boring-avatars"
import { type JSXElement, Show } from "solid-js"
import { type JSXElement, Show, mergeProps } from "solid-js"
import { useTotemTip } from "./tooltip"

import type { ProfileAvatarTypeEnum } from "../client"

const defaults = {
size: 50,
name: "",
seed: "",
url: "",
type: "TD",
tooltip: false,
}

function Avatar(props: {
size?: number
name?: string
Expand All @@ -12,6 +22,8 @@ function Avatar(props: {
type?: ProfileAvatarTypeEnum
children?: JSXElement
}) {
const _props = mergeProps(defaults, props)

const setAnchor = () => {
if (props.tooltip) {
return useTotemTip({ content: props.name ?? "" })
Expand All @@ -22,38 +34,31 @@ function Avatar(props: {
<div
ref={setAnchor()}
class="max-h-full rounded-full bg-white [&>svg]:h-auto [&>svg]:max-w-full"
style={{ padding: `${props.size ?? 25 / 1000}rem` }}>
style={{ padding: `${_props.size / 1000}rem` }}>
<Show
when={props.type === "IM" && props.url}
when={_props.type === "IM" && _props.url}
fallback={
<_Avatar
size={props.size}
// title={props.name}
name={props.seed}
size={_props.size}
// title={_props.name}
name={_props.seed}
variant="marble"
/>
}>
<img
style={{
width: `${props.size}px`,
width: `${_props.size}px`,
}}
class="h-auto max-w-full rounded-full"
src={props.url}
alt={props.name}
src={_props.url}
alt={_props.name}
/>
</Show>
</div>
)
}

Avatar.tagName = "t-avatar"
Avatar.propsDefault = {
size: 50,
name: "",
seed: "",
url: "",
type: "TD",
tooltip: false,
}
Avatar.propsDefault = defaults

export default Avatar
11 changes: 8 additions & 3 deletions totem/circles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
notify_circle_starting,
notify_circle_tomorrow,
)
from totem.email.exceptions import EmailBounced
from totem.utils.hash import basic_hash, hmac
from totem.utils.md import MarkdownField, MarkdownMixin
from totem.utils.models import AdminURLMixin, SluggedModel
Expand Down Expand Up @@ -214,7 +215,7 @@ def add_attendee(self, user):
notify_circle_starting(self, user).send()
else:
# Otherwise, send the user the signed up email
notify_circle_signup(self, user).send(blocking=False)
notify_circle_signup(self, user).send()
if not self.circle.author == user:
notify_slack(f"✅ New session attendee: {self._get_slack_attendee_message(user)}")

Expand Down Expand Up @@ -284,7 +285,7 @@ def notify_missed(self, force=False):
if user == self.circle.author:
continue
if user not in self.joined.all():
missed_event_email(self, user).send(blocking=False)
missed_event_email(self, user).send()

def advertise(self, force=False):
# Notify users who are subscribed that a new event is available, if they aren't already attending.
Expand All @@ -294,7 +295,11 @@ def advertise(self, force=False):
self.save()
for user in self.circle.subscribed.all():
if self.can_attend(silent=True) and user not in self.attendees.all():
notify_circle_advertisement(self, user).send()
try:
notify_circle_advertisement(self, user).send()
except EmailBounced:
# If the email was blocked, remove the user from the circle
self.circle.unsubscribe(user)

def cal_link(self):
return full_url(self.get_absolute_url())
Expand Down
34 changes: 16 additions & 18 deletions totem/email/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
from django.template.loader import render_to_string
from pydantic import AnyHttpUrl, BaseModel, TypeAdapter

from totem.utils.pool import global_pool

from .models import EmailLog
from .utils import send_brevo_email, send_mail

Expand Down Expand Up @@ -49,22 +47,22 @@ def render_html(self) -> str:
def render_text(self) -> str:
return render_to_string(f"email/emails/{self.template}.txt", context=self.model_dump())

def send(self, blocking: bool = True):
if blocking:
send_mail(
subject=self.subject,
html_message=self.render_html(),
text_message=self.render_text(),
recipient_list=[self.recipient],
)
else:
global_pool.add_task(
send_mail,
subject=self.subject,
html_message=self.render_html(),
text_message=self.render_text(),
recipient_list=[self.recipient],
)
def send(self):
# if blocking:
send_mail(
subject=self.subject,
html_message=self.render_html(),
text_message=self.render_text(),
recipient_list=[self.recipient],
)
# else:
# global_pool.add_task(
# send_mail,
# subject=self.subject,
# html_message=self.render_html(),
# text_message=self.render_text(),
# recipient_list=[self.recipient],
# )
EmailLog.objects.create(
subject=self.subject,
template=self.template,
Expand Down
2 changes: 2 additions & 0 deletions totem/email/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class EmailBounced(Exception):
pass
11 changes: 8 additions & 3 deletions totem/email/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import requests
from anymail.exceptions import AnymailRecipientsRefused
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.mail import send_mail as django_send_mail
from pydantic import BaseModel

from totem.email.data import EMAIL_BLOCKLIST
from totem.email.exceptions import EmailBounced

session = requests.Session()

Expand All @@ -19,9 +21,12 @@ def send_mail(
) -> int:
# remove newlines from subject
subject = subject.replace("\n", " ")
return django_send_mail(
subject, text_message, from_email, recipient_list, fail_silently=fail_silently, html_message=html_message
)
try:
return django_send_mail(
subject, text_message, from_email, recipient_list, fail_silently=fail_silently, html_message=html_message
)
except AnymailRecipientsRefused:
raise EmailBounced(f"Email to {recipient_list} with subject {subject} was blocked.")


class Recipient(BaseModel):
Expand Down
12 changes: 0 additions & 12 deletions totem/email/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,6 @@ def template_view(request, name=None):
)


event_details = """
## Sexual Liberation
Sexual liberation is going to look different for each of us. For some, it may actually mean less sex—liberating your voice to say 'no' to your partner more often. For others, sexual liberation might involve buying your first solo toy or exploring a threesome. We are all on different journeys, and this space is dedicated to destigmatizing conversations about sex in a safe environment, identifying our personal boundaries, and discovering what sexual liberation means to each of us.
We will ask questions like:
* *What would sexual liberation look like in your life, and why would that be important?*
We hope that after this space, you feel emboldened in your desires and in your ability to voice them."""


def get_templates():
# files = Path(__file__).parent.joinpath("templates/email/emails").glob("*.mjml")
# return {file.stem: file.name for file in files}
Expand Down

0 comments on commit 1333799

Please sign in to comment.