1 # Copyright (C) 2006-2019 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """Model for addresses."""
20 from email
.utils
import formataddr
21 from mailman
.database
.model
import Model
22 from mailman
.database
.types
import SAUnicode
23 from mailman
.interfaces
.address
import (
24 AddressVerificationEvent
, IAddress
, IEmailValidator
)
25 from mailman
.utilities
.datetime
import now
26 from public
import public
27 from sqlalchemy
import Column
, DateTime
, ForeignKey
, Integer
28 from sqlalchemy
.orm
import backref
, relationship
29 from zope
.component
import getUtility
30 from zope
.event
import notify
31 from zope
.interface
import implementer
35 @implementer(IAddress
)
39 __tablename__
= 'address'
41 id = Column(Integer
, primary_key
=True)
42 email
= Column(SAUnicode
, index
=True, unique
=True)
43 _original
= Column(SAUnicode
)
44 display_name
= Column(SAUnicode
)
45 _verified_on
= Column('verified_on', DateTime
)
46 registered_on
= Column(DateTime
)
48 user_id
= Column(Integer
, ForeignKey('user.id'), index
=True)
50 preferences_id
= Column(Integer
, ForeignKey('preferences.id'), index
=True)
51 preferences
= relationship(
52 'Preferences', backref
=backref('address', uselist
=False))
54 def __init__(self
, email
, display_name
):
56 getUtility(IEmailValidator
).validate(email
)
57 lower_case
= email
.lower()
58 self
.email
= lower_case
59 self
.display_name
= display_name
60 self
._original
= (None if lower_case
== email
else email
)
61 self
.registered_on
= now()
64 addr
= (self
.email
if self
._original
is None else self
._original
)
65 return formataddr((self
.display_name
, addr
))
68 verified
= ('verified' if self
.verified_on
else 'not verified')
69 address_str
= str(self
)
70 if self
._original
is None:
71 return '<Address: {} [{}] at {:#x}>'.format(
72 address_str
, verified
, id(self
))
74 return '<Address: {} [{}] key: {} at {:#x}>'.format(
75 address_str
, verified
, self
.email
, id(self
))
78 def verified_on(self
):
79 return self
._verified
_on
82 def verified_on(self
, timestamp
):
83 self
._verified
_on
= timestamp
84 notify(AddressVerificationEvent(self
))
87 def original_email(self
):
88 return (self
.email
if self
._original
is None else self
._original
)