-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.py
More file actions
126 lines (107 loc) · 3.87 KB
/
utils.py
File metadata and controls
126 lines (107 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from functools import singledispatch
from typing import Dict, List, Union, Annotated
from procollab import settings
from .constants import MAILING_USERS_BATCH_SIZE
from .models import MailingSchema
from users.models import CustomUser
import django.db.models
from django.contrib.auth import get_user_model
from django.core import mail
from django.core.mail import EmailMultiAlternatives
from django.template import Context, Template
from .definitions import MailDataDict, EmailDataToPrepare
User = get_user_model()
@singledispatch
def prepare_mail_data(post_data):
users = post_data.getlist("users[]")
schema_id = post_data["schemas"]
subject = post_data["subject"]
mail_schema = MailingSchema.objects.get(pk=schema_id)
context = {}
for variable_name in mail_schema.schema:
key_in_post = "field-" + variable_name
if key_in_post in post_data:
context[variable_name] = post_data[key_in_post]
users_to_send = CustomUser.objects.filter(pk__in=users)
return {
"users_to_send": users_to_send,
"subject": subject,
"mail_schema_template": mail_schema.template,
"context": context,
}
@prepare_mail_data.register(EmailDataToPrepare)
def _(post_data: EmailDataToPrepare) -> MailDataDict:
schema_id = post_data.schema_id
subject = post_data.subject
mail_schema = MailingSchema.objects.get(pk=schema_id)
context = {}
for variable_name in mail_schema.schema:
if variable_name in post_data.context_data:
context[variable_name] = post_data.context_data[variable_name]
users_to_send = CustomUser.objects.filter(pk__in=post_data.users_ids)
return {
"users": users_to_send,
"subject": subject,
"template_string": mail_schema.template,
"template_context": context,
}
def create_message_groups(messages: list) -> list[list]:
grouped_messages: list[list] = [
messages[message : message + MAILING_USERS_BATCH_SIZE] # noqa: E203
for message in range(0, len(messages), MAILING_USERS_BATCH_SIZE)
]
return grouped_messages
def send_mail(
user: User,
subject: str,
template_string: str,
template_context: Union[
Dict,
List,
] = None,
connection=None,
):
return send_mass_mail([user], subject, template_string, template_context, connection)
def send_group_messages(messages: list) -> int:
connection = mail.get_connection()
num_sent = connection.send_messages(messages)
connection.close()
return num_sent
def send_mass_mail(
users: django.db.models.QuerySet | List[User],
subject: str,
template_string: str,
template_context: Union[
MailDataDict,
list,
] = None,
connection=None,
) -> Annotated[int, "Количество отосланных сообщений"]:
"""
Begin mailing to specified users, sending rendered template with template_text arg.
Throws an error if template render is unsuccessful.
Args:
users: - The list of users who should receive the email.
template_string: str of template_path
subject: Subject of mail.
template_context: Context for template render.
connection: Connection to mail backend
"""
if template_context is None:
template_context = {}
template = Template(template_string)
messages = []
for user in users:
template_context["user"] = user
html_msg = template.render(Context(template_context))
plain_msg = template.render(Context(template_context))
msg = EmailMultiAlternatives(
subject, plain_msg, settings.EMAIL_USER, [user.email]
)
msg.attach_alternative(html_msg, "text/html")
messages.append(msg)
grouped_messages = create_message_groups(messages)
num_sent: int = 0
for group in grouped_messages:
num_sent += send_group_messages(group)
return num_sent