plain.email 0.15.0__tar.gz → 0.15.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plain_email-0.15.0 → plain_email-0.15.2}/.gitignore +1 -1
- {plain_email-0.15.0 → plain_email-0.15.2}/PKG-INFO +21 -40
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/CHANGELOG.md +21 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/README.md +20 -39
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/backends/base.py +2 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/message.py +0 -5
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/utils.py +0 -2
- {plain_email-0.15.0 → plain_email-0.15.2}/pyproject.toml +1 -1
- {plain_email-0.15.0 → plain_email-0.15.2}/LICENSE +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/README.md +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/__init__.py +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/backends/__init__.py +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/backends/console.py +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/backends/filebased.py +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/backends/smtp.py +0 -0
- {plain_email-0.15.0 → plain_email-0.15.2}/plain/email/default_settings.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plain.email
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.2
|
|
4
4
|
Summary: Everything you need to send email in Plain.
|
|
5
5
|
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -18,8 +18,7 @@ Description-Content-Type: text/markdown
|
|
|
18
18
|
- [Sending HTML emails](#sending-html-emails)
|
|
19
19
|
- [Template-based emails](#template-based-emails)
|
|
20
20
|
- [Attachments](#attachments)
|
|
21
|
-
- [
|
|
22
|
-
- [SMTP settings](#smtp-settings)
|
|
21
|
+
- [Settings](#settings)
|
|
23
22
|
- [Email backends](#email-backends)
|
|
24
23
|
- [SMTP backend](#smtp-backend)
|
|
25
24
|
- [Console backend](#console-backend)
|
|
@@ -131,43 +130,25 @@ email.attach_file("/path/to/report.pdf")
|
|
|
131
130
|
email.send()
|
|
132
131
|
```
|
|
133
132
|
|
|
134
|
-
##
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
When using the SMTP backend, configure your mail server:
|
|
154
|
-
|
|
155
|
-
```python
|
|
156
|
-
# settings.py
|
|
157
|
-
|
|
158
|
-
EMAIL_HOST = "smtp.example.com"
|
|
159
|
-
EMAIL_PORT = 587
|
|
160
|
-
EMAIL_HOST_USER = "your-username"
|
|
161
|
-
EMAIL_HOST_PASSWORD = "your-password"
|
|
162
|
-
EMAIL_USE_TLS = True # Use STARTTLS
|
|
163
|
-
EMAIL_USE_SSL = False # Use implicit SSL (mutually exclusive with TLS)
|
|
164
|
-
|
|
165
|
-
# Optional settings
|
|
166
|
-
EMAIL_TIMEOUT = 10 # Connection timeout in seconds
|
|
167
|
-
EMAIL_SSL_CERTFILE = None # Path to SSL certificate file
|
|
168
|
-
EMAIL_SSL_KEYFILE = None # Path to SSL key file
|
|
169
|
-
EMAIL_USE_LOCALTIME = False # Use local time in Date header (default: UTC)
|
|
170
|
-
```
|
|
133
|
+
## Settings
|
|
134
|
+
|
|
135
|
+
| Setting | Default | Env var |
|
|
136
|
+
| ------------------------ | ------------- | ------------------------------ |
|
|
137
|
+
| `EMAIL_BACKEND` | Required | `PLAIN_EMAIL_BACKEND` |
|
|
138
|
+
| `EMAIL_DEFAULT_FROM` | Required | `PLAIN_EMAIL_DEFAULT_FROM` |
|
|
139
|
+
| `EMAIL_DEFAULT_REPLY_TO` | `None` | `PLAIN_EMAIL_DEFAULT_REPLY_TO` |
|
|
140
|
+
| `EMAIL_HOST` | `"localhost"` | `PLAIN_EMAIL_HOST` |
|
|
141
|
+
| `EMAIL_PORT` | `587` | `PLAIN_EMAIL_PORT` |
|
|
142
|
+
| `EMAIL_HOST_USER` | `""` | `PLAIN_EMAIL_HOST_USER` |
|
|
143
|
+
| `EMAIL_HOST_PASSWORD` | `""` | `PLAIN_EMAIL_HOST_PASSWORD` |
|
|
144
|
+
| `EMAIL_USE_TLS` | `True` | `PLAIN_EMAIL_USE_TLS` |
|
|
145
|
+
| `EMAIL_USE_SSL` | `False` | `PLAIN_EMAIL_USE_SSL` |
|
|
146
|
+
| `EMAIL_TIMEOUT` | `None` | `PLAIN_EMAIL_TIMEOUT` |
|
|
147
|
+
| `EMAIL_SSL_CERTFILE` | `None` | `PLAIN_EMAIL_SSL_CERTFILE` |
|
|
148
|
+
| `EMAIL_SSL_KEYFILE` | `None` | `PLAIN_EMAIL_SSL_KEYFILE` |
|
|
149
|
+
| `EMAIL_USE_LOCALTIME` | `False` | `PLAIN_EMAIL_USE_LOCALTIME` |
|
|
150
|
+
|
|
151
|
+
See [`default_settings.py`](./default_settings.py) for more details.
|
|
171
152
|
|
|
172
153
|
## Email backends
|
|
173
154
|
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# plain-email changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.2](https://github.com/dropseed/plain/releases/plain-email@0.15.2) (2026-02-04)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- Added `__all__` export to `backends/base` module ([e7164d3891b2](https://github.com/dropseed/plain/commit/e7164d3891b2))
|
|
8
|
+
- Removed `@internalcode` decorator from internal MIME helper classes ([e7164d3891b2](https://github.com/dropseed/plain/commit/e7164d3891b2))
|
|
9
|
+
|
|
10
|
+
### Upgrade instructions
|
|
11
|
+
|
|
12
|
+
- No changes required.
|
|
13
|
+
|
|
14
|
+
## [0.15.1](https://github.com/dropseed/plain/releases/plain-email@0.15.1) (2026-01-28)
|
|
15
|
+
|
|
16
|
+
### What's changed
|
|
17
|
+
|
|
18
|
+
- Added Settings section to README ([803fee1ad5](https://github.com/dropseed/plain/commit/803fee1ad5))
|
|
19
|
+
|
|
20
|
+
### Upgrade instructions
|
|
21
|
+
|
|
22
|
+
- No changes required.
|
|
23
|
+
|
|
3
24
|
## [0.15.0](https://github.com/dropseed/plain/releases/plain-email@0.15.0) (2026-01-15)
|
|
4
25
|
|
|
5
26
|
### What's changed
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
- [Sending HTML emails](#sending-html-emails)
|
|
8
8
|
- [Template-based emails](#template-based-emails)
|
|
9
9
|
- [Attachments](#attachments)
|
|
10
|
-
- [
|
|
11
|
-
- [SMTP settings](#smtp-settings)
|
|
10
|
+
- [Settings](#settings)
|
|
12
11
|
- [Email backends](#email-backends)
|
|
13
12
|
- [SMTP backend](#smtp-backend)
|
|
14
13
|
- [Console backend](#console-backend)
|
|
@@ -120,43 +119,25 @@ email.attach_file("/path/to/report.pdf")
|
|
|
120
119
|
email.send()
|
|
121
120
|
```
|
|
122
121
|
|
|
123
|
-
##
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
When using the SMTP backend, configure your mail server:
|
|
143
|
-
|
|
144
|
-
```python
|
|
145
|
-
# settings.py
|
|
146
|
-
|
|
147
|
-
EMAIL_HOST = "smtp.example.com"
|
|
148
|
-
EMAIL_PORT = 587
|
|
149
|
-
EMAIL_HOST_USER = "your-username"
|
|
150
|
-
EMAIL_HOST_PASSWORD = "your-password"
|
|
151
|
-
EMAIL_USE_TLS = True # Use STARTTLS
|
|
152
|
-
EMAIL_USE_SSL = False # Use implicit SSL (mutually exclusive with TLS)
|
|
153
|
-
|
|
154
|
-
# Optional settings
|
|
155
|
-
EMAIL_TIMEOUT = 10 # Connection timeout in seconds
|
|
156
|
-
EMAIL_SSL_CERTFILE = None # Path to SSL certificate file
|
|
157
|
-
EMAIL_SSL_KEYFILE = None # Path to SSL key file
|
|
158
|
-
EMAIL_USE_LOCALTIME = False # Use local time in Date header (default: UTC)
|
|
159
|
-
```
|
|
122
|
+
## Settings
|
|
123
|
+
|
|
124
|
+
| Setting | Default | Env var |
|
|
125
|
+
| ------------------------ | ------------- | ------------------------------ |
|
|
126
|
+
| `EMAIL_BACKEND` | Required | `PLAIN_EMAIL_BACKEND` |
|
|
127
|
+
| `EMAIL_DEFAULT_FROM` | Required | `PLAIN_EMAIL_DEFAULT_FROM` |
|
|
128
|
+
| `EMAIL_DEFAULT_REPLY_TO` | `None` | `PLAIN_EMAIL_DEFAULT_REPLY_TO` |
|
|
129
|
+
| `EMAIL_HOST` | `"localhost"` | `PLAIN_EMAIL_HOST` |
|
|
130
|
+
| `EMAIL_PORT` | `587` | `PLAIN_EMAIL_PORT` |
|
|
131
|
+
| `EMAIL_HOST_USER` | `""` | `PLAIN_EMAIL_HOST_USER` |
|
|
132
|
+
| `EMAIL_HOST_PASSWORD` | `""` | `PLAIN_EMAIL_HOST_PASSWORD` |
|
|
133
|
+
| `EMAIL_USE_TLS` | `True` | `PLAIN_EMAIL_USE_TLS` |
|
|
134
|
+
| `EMAIL_USE_SSL` | `False` | `PLAIN_EMAIL_USE_SSL` |
|
|
135
|
+
| `EMAIL_TIMEOUT` | `None` | `PLAIN_EMAIL_TIMEOUT` |
|
|
136
|
+
| `EMAIL_SSL_CERTFILE` | `None` | `PLAIN_EMAIL_SSL_CERTFILE` |
|
|
137
|
+
| `EMAIL_SSL_KEYFILE` | `None` | `PLAIN_EMAIL_SSL_KEYFILE` |
|
|
138
|
+
| `EMAIL_USE_LOCALTIME` | `False` | `PLAIN_EMAIL_USE_LOCALTIME` |
|
|
139
|
+
|
|
140
|
+
See [`default_settings.py`](./default_settings.py) for more details.
|
|
160
141
|
|
|
161
142
|
## Email backends
|
|
162
143
|
|
|
@@ -20,7 +20,6 @@ from io import BytesIO, StringIO
|
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
from typing import TYPE_CHECKING, Any
|
|
22
22
|
|
|
23
|
-
from plain.internal import internalcode
|
|
24
23
|
from plain.runtime import settings
|
|
25
24
|
from plain.templates import Template, TemplateFileMissing
|
|
26
25
|
from plain.utils.encoding import force_str, punycode
|
|
@@ -136,7 +135,6 @@ def _sanitize_address(addr: str | tuple[str, str], encoding: str) -> str:
|
|
|
136
135
|
return formataddr((nm, parsed_address.addr_spec))
|
|
137
136
|
|
|
138
137
|
|
|
139
|
-
@internalcode
|
|
140
138
|
class MIMEMixin:
|
|
141
139
|
def as_string(self, unixfrom: bool = False, linesep: str = "\n") -> str:
|
|
142
140
|
"""Return the entire formatted message as a string.
|
|
@@ -165,7 +163,6 @@ class MIMEMixin:
|
|
|
165
163
|
return fp.getvalue()
|
|
166
164
|
|
|
167
165
|
|
|
168
|
-
@internalcode
|
|
169
166
|
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
|
170
167
|
def __setitem__(self, name: str, val: str) -> None:
|
|
171
168
|
# message/rfc822 attachments must be ASCII
|
|
@@ -173,7 +170,6 @@ class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
|
|
173
170
|
MIMEMessage.__setitem__(self, name, val)
|
|
174
171
|
|
|
175
172
|
|
|
176
|
-
@internalcode
|
|
177
173
|
class SafeMIMEText(MIMEMixin, MIMEText):
|
|
178
174
|
def __init__(
|
|
179
175
|
self, _text: str, _subtype: str = "plain", _charset: str | None = None
|
|
@@ -199,7 +195,6 @@ class SafeMIMEText(MIMEMixin, MIMEText):
|
|
|
199
195
|
MIMEText.set_payload(self, payload, charset=charset)
|
|
200
196
|
|
|
201
197
|
|
|
202
|
-
@internalcode
|
|
203
198
|
class SafeMIMEMultipart(MIMEMixin, MIMEMultipart):
|
|
204
199
|
def __init__(
|
|
205
200
|
self,
|
|
@@ -6,13 +6,11 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import socket
|
|
8
8
|
|
|
9
|
-
from plain.internal import internalcode
|
|
10
9
|
from plain.utils.encoding import punycode
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
# Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of
|
|
14
13
|
# seconds, which slows down the restart of the server.
|
|
15
|
-
@internalcode
|
|
16
14
|
class CachedDnsName:
|
|
17
15
|
def __str__(self) -> str:
|
|
18
16
|
return self.get_fqdn()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|