Merge pull request #190 from SibrenVasse/sender_format
Add more From: sender formatting options
This commit is contained in:
commit
78ff15912e
|
@ -206,31 +206,30 @@
|
|||
<div class="card-body">
|
||||
<div class="card-title">Sender address format</div>
|
||||
<div class="mt-1 mb-3">
|
||||
When your alias receives an email, says from <b>John Wick <john@wick.com></b>,
|
||||
When your alias receives an email, it says from: <b>John Wick <john@wick.com></b>,
|
||||
SimpleLogin forwards it to your mailbox. <br>
|
||||
|
||||
Due to some email constraints, SimpleLogin cannot keep the sender email address
|
||||
in the original form and needs to <b>transform</b> it to one of the 2 below formats.
|
||||
in the original form and needs to <b>transform</b> it to one of the formats below.
|
||||
</div>
|
||||
|
||||
<form method="post" action="#sender-format">
|
||||
<input type="hidden" name="form-name" value="change-sender-format">
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="sender-format" id="exampleRadios1" value="1"
|
||||
{% if current_user.use_via_format_for_sender %} checked {% endif %}>
|
||||
<label class="form-check-label" for="exampleRadios1">
|
||||
<b>john@wick.com via SimpleLogin</b>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="sender-format" id="exampleRadios2" value="0"
|
||||
{% if not current_user.use_via_format_for_sender %} checked {% endif %}>
|
||||
<label class="form-check-label" for="exampleRadios2">
|
||||
<b>John Wick - john at wick.com</b>
|
||||
</label>
|
||||
</div>
|
||||
<select class="form-control mr-sm-2" name="sender-format">
|
||||
<option value="{{ SenderFormatEnum.VIA.value }}"
|
||||
{% if current_user.sender_format == SenderFormatEnum.VIA.value %} selected {% endif %}>
|
||||
john@wick.com via SimpleLogin</option>
|
||||
<option value="{{ SenderFormatEnum.AT.value }}"
|
||||
{% if current_user.sender_format == SenderFormatEnum.AT.value %} selected {% endif %}>
|
||||
John Wick - john at wick.com</option>
|
||||
<option value="{{ SenderFormatEnum.A.value }}"
|
||||
{% if current_user.sender_format == SenderFormatEnum.A.value %} selected {% endif %}>
|
||||
John Wick - john(a)wick.com</option>
|
||||
<option value="{{ SenderFormatEnum.FULL.value }}"
|
||||
{% if current_user.sender_format == SenderFormatEnum.FULL.value %} selected {% endif %}>
|
||||
John Wick - john@wick.com</option>
|
||||
</select>
|
||||
|
||||
<button class="btn btn-outline-primary mt-3">Update</button>
|
||||
</form>
|
||||
|
|
|
@ -30,6 +30,7 @@ from app.models import (
|
|||
Client,
|
||||
AliasGeneratorEnum,
|
||||
ManualSubscription,
|
||||
SenderFormatEnum,
|
||||
)
|
||||
from app.utils import random_string
|
||||
|
||||
|
@ -161,12 +162,11 @@ def setting():
|
|||
return redirect(url_for("dashboard.setting"))
|
||||
elif request.form.get("form-name") == "change-sender-format":
|
||||
sender_format = int(request.form.get("sender-format"))
|
||||
if sender_format == 0:
|
||||
current_user.use_via_format_for_sender = False
|
||||
else:
|
||||
current_user.use_via_format_for_sender = True
|
||||
if SenderFormatEnum.has_value(sender_format):
|
||||
current_user.sender_format = sender_format
|
||||
db.session.commit()
|
||||
flash("Your sender format preference has been updated", "success")
|
||||
db.session.commit()
|
||||
flash("Your sender format preference has been updated", "success")
|
||||
return redirect(url_for("dashboard.setting"))
|
||||
|
||||
elif request.form.get("form-name") == "export-data":
|
||||
|
@ -200,6 +200,7 @@ def setting():
|
|||
"dashboard/setting.html",
|
||||
form=form,
|
||||
PlanEnum=PlanEnum,
|
||||
SenderFormatEnum=SenderFormatEnum,
|
||||
promo_form=promo_form,
|
||||
change_email_form=change_email_form,
|
||||
pending_email=pending_email,
|
||||
|
|
|
@ -96,19 +96,29 @@ class File(db.Model, ModelMixin):
|
|||
return s3.get_url(self.path, expires_in)
|
||||
|
||||
|
||||
class PlanEnum(enum.Enum):
|
||||
class EnumE(enum.Enum):
|
||||
@classmethod
|
||||
def has_value(cls, value: int) -> bool:
|
||||
return value in set(item.value for item in cls)
|
||||
|
||||
|
||||
class PlanEnum(EnumE):
|
||||
monthly = 2
|
||||
yearly = 3
|
||||
|
||||
|
||||
class AliasGeneratorEnum(enum.Enum):
|
||||
# Specify the format for sender address
|
||||
class SenderFormatEnum(EnumE):
|
||||
AT = 0 # John Wick - john at wick.com
|
||||
VIA = 1 # john@wick.com via SimpleLogin
|
||||
A = 2 # John Wick - john(a)wick.com
|
||||
FULL = 3 # John Wick - john@wick.com
|
||||
|
||||
|
||||
class AliasGeneratorEnum(EnumE):
|
||||
word = 1 # aliases are generated based on random words
|
||||
uuid = 2 # aliases are generated based on uuid
|
||||
|
||||
@classmethod
|
||||
def has_value(cls, value: int) -> bool:
|
||||
return value in set(item.value for item in cls)
|
||||
|
||||
|
||||
class User(db.Model, ModelMixin, UserMixin):
|
||||
__tablename__ = "users"
|
||||
|
@ -172,10 +182,13 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
|
||||
profile_picture = db.relationship(File, foreign_keys=[profile_picture_id])
|
||||
|
||||
# Use the "via" format for sender address, i.e. "name@example.com via SimpleLogin"
|
||||
# If False, use the format "Name - name at example.com"
|
||||
use_via_format_for_sender = db.Column(
|
||||
db.Boolean, default=True, nullable=False, server_default="1"
|
||||
# Specify the format for sender address
|
||||
# John Wick - john at wick.com -> 0
|
||||
# john@wick.com via SimpleLogin -> 1
|
||||
# John Wick - john@wick.com -> 2
|
||||
# John Wick - john@wick.com -> 3
|
||||
sender_format = db.Column(
|
||||
db.Integer, default="1", nullable=False, server_default="1"
|
||||
)
|
||||
|
||||
referral_id = db.Column(
|
||||
|
@ -868,21 +881,35 @@ class Contact(db.Model, ModelMixin):
|
|||
|
||||
def new_addr(self):
|
||||
"""
|
||||
Replace original email by reply_email. 2 possible formats:
|
||||
- first@example.com by SimpleLogin <reply_email> OR
|
||||
- First Last - first at example.com <reply_email>
|
||||
Replace original email by reply_email. Possible formats:
|
||||
- first@example.com via SimpleLogin <reply_email> OR
|
||||
- First Last - first at example.com <reply_email> OR
|
||||
- First Last - first(a)example.com <reply_email> OR
|
||||
- First Last - first@example.com <reply_email> OR
|
||||
And return new address with RFC 2047 format
|
||||
|
||||
`new_email` is a special reply address
|
||||
"""
|
||||
user = self.user
|
||||
if user and user.use_via_format_for_sender:
|
||||
if (
|
||||
not user
|
||||
or not SenderFormatEnum.has_value(user.sender_format)
|
||||
or user.sender_format == SenderFormatEnum.VIA.value
|
||||
):
|
||||
new_name = f"{self.website_email} via SimpleLogin"
|
||||
else:
|
||||
elif user.sender_format == SenderFormatEnum.AT.value:
|
||||
name = self.name or ""
|
||||
new_name = (
|
||||
name + (" - " if name else "") + self.website_email.replace("@", " at ")
|
||||
).strip()
|
||||
elif user.sender_format == SenderFormatEnum.A.value:
|
||||
name = self.name or ""
|
||||
new_name = (
|
||||
name + (" - " if name else "") + self.website_email.replace("@", "(a)")
|
||||
).strip()
|
||||
elif user.sender_format == SenderFormatEnum.FULL.value:
|
||||
name = self.name or ""
|
||||
new_name = (name + (" - " if name else "") + self.website_email).strip()
|
||||
|
||||
new_addr = formataddr((new_name, self.reply_email)).strip()
|
||||
return new_addr.strip()
|
||||
|
|
45
migrations/versions/2020_051515_5cad8fa84386_.py
Normal file
45
migrations/versions/2020_051515_5cad8fa84386_.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 5cad8fa84386
|
||||
Revises: a5e3c6693dc6
|
||||
Create Date: 2020-05-15 15:10:00.096349
|
||||
|
||||
"""
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "5cad8fa84386"
|
||||
down_revision = "a5e3c6693dc6"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column("users", "use_via_format_for_sender", server_default=None)
|
||||
op.alter_column(
|
||||
"users",
|
||||
"use_via_format_for_sender",
|
||||
new_column_name="sender_format",
|
||||
type_=sa.Integer(),
|
||||
postgresql_using="use_via_format_for_sender::integer",
|
||||
)
|
||||
op.alter_column("users", "sender_format", server_default="1")
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column("users", "sender_format", server_default=None)
|
||||
op.alter_column(
|
||||
"users",
|
||||
"sender_format",
|
||||
new_column_name="use_via_format_for_sender",
|
||||
type_=sa.Boolean(),
|
||||
postgresql_using="sender_format::boolean",
|
||||
)
|
||||
op.alter_column("users", "use_via_format_for_sender", server_default="1")
|
||||
# ### end Alembic commands ###
|
|
@ -1,11 +1,18 @@
|
|||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from uuid import UUID
|
||||
|
||||
from app.config import EMAIL_DOMAIN, MAX_NB_EMAIL_FREE_PLAN
|
||||
from app.email_utils import parseaddr_unicode
|
||||
from app.extensions import db
|
||||
from app.models import generate_email, User, Alias, Contact, Mailbox, AliasMailbox
|
||||
from app.models import (
|
||||
generate_email,
|
||||
User,
|
||||
Alias,
|
||||
Contact,
|
||||
Mailbox,
|
||||
AliasMailbox,
|
||||
SenderFormatEnum,
|
||||
)
|
||||
|
||||
|
||||
def test_generate_email(flask_client):
|
||||
|
@ -104,7 +111,7 @@ def test_new_addr(flask_client):
|
|||
alias = Alias.create_new_random(user)
|
||||
db.session.commit()
|
||||
|
||||
# use_via_format_for_sender is by default
|
||||
# default sender_format is 'via'
|
||||
c1 = Contact.create(
|
||||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
|
@ -115,8 +122,8 @@ def test_new_addr(flask_client):
|
|||
db.session.commit()
|
||||
assert c1.new_addr() == '"abcd@example.com via SimpleLogin" <rep@SL>'
|
||||
|
||||
# use_via_format_for_sender = False
|
||||
user.use_via_format_for_sender = False
|
||||
# set sender_format = AT
|
||||
user.sender_format = SenderFormatEnum.AT.value
|
||||
db.session.commit()
|
||||
assert c1.new_addr() == '"First Last - abcd at example.com" <rep@SL>'
|
||||
|
||||
|
|
Loading…
Reference in a new issue