forked from mirror/django-mailbox
Modernize syntax, drop Python EOL, drop drop Django<1.11, upgrade TravisCI config to v1, add Python 3.8 & Django 3.x
This commit is contained in:
parent
f9b0a27e5f
commit
2b2b7d6392
43 changed files with 228 additions and 349 deletions
65
.travis.yml
65
.travis.yml
|
|
@ -1,30 +1,43 @@
|
||||||
|
version: ~> 1.0
|
||||||
|
os: linux
|
||||||
language: python
|
language: python
|
||||||
python: '3.5'
|
|
||||||
|
jobs:
|
||||||
|
# sort by django version, next to by python version
|
||||||
|
# Django 1.11 support all supported Python interpreter
|
||||||
|
- env: TOX_ENV=django111-py35
|
||||||
|
python: 3.5
|
||||||
|
- env: TOX_ENV=django111-py36
|
||||||
|
python: 3.6
|
||||||
|
# Django 2.0 support 3.5, 3.6
|
||||||
|
- env: TOX_ENV=django20-py35
|
||||||
|
python: 3.5
|
||||||
|
- env: TOX_ENV=django20-py36
|
||||||
|
python: 3.6
|
||||||
|
|
||||||
|
# Django 2.1 support Python 3.5, 3.6, 3.7
|
||||||
|
- env: TOX_ENV=django21-py35
|
||||||
|
python: 3.5
|
||||||
|
- env: TOX_ENV=django21-py36
|
||||||
|
python: 3.6
|
||||||
|
- env: TOX_ENV=django21-py37
|
||||||
|
python: 3.7
|
||||||
|
# Django 2.2 support Python 3.5, 3.6, 3.7
|
||||||
|
- env: TOX_ENV=django22-py35
|
||||||
|
python: 3.5
|
||||||
|
- env: TOX_ENV=django22-py36
|
||||||
|
python: 3.6
|
||||||
|
- env: TOX_ENV=django22-py37
|
||||||
|
python: 3.7
|
||||||
|
# Django 3.0 (beta) support Python 3.6, 3.7, 3.8
|
||||||
|
- env: TOX_ENV=django30-py36
|
||||||
|
python: 3.6
|
||||||
|
- env: TOX_ENV=django30-py37
|
||||||
|
python: 3.7
|
||||||
|
- env: TOX_ENV=django30-py38
|
||||||
|
python: 3.8
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
|
||||||
# sort by django version, next to by python version
|
|
||||||
# Django 1.7 support Python 2.7, 3.4
|
|
||||||
- TOX_ENV=django17-py27
|
|
||||||
- TOX_ENV=django17-py34
|
|
||||||
# Django 1.8 support Python 2.7, 3.4, 3.5
|
|
||||||
- TOX_ENV=django18-py27
|
|
||||||
- TOX_ENV=django18-py34
|
|
||||||
- TOX_ENV=django18-py35
|
|
||||||
# Django 1.9 support Python 2.7, 3.4, 3.5
|
|
||||||
- TOX_ENV=django19-py27
|
|
||||||
- TOX_ENV=django19-py34
|
|
||||||
- TOX_ENV=django19-py35
|
|
||||||
# Django 1.10 support Python 2.7, 3.4, 3.5
|
|
||||||
- TOX_ENV=django110-py27
|
|
||||||
- TOX_ENV=django110-py34
|
|
||||||
- TOX_ENV=django110-py35
|
|
||||||
# Django 1.11 support all supported Python interpreter
|
|
||||||
# Django 2.0 support Python 3.4, 3.5, 3.6
|
|
||||||
- TOX_ENV=django111-py34
|
|
||||||
- TOX_ENV=django111-py35
|
|
||||||
- TOX_ENV=django111-py36
|
|
||||||
|
|
||||||
global:
|
global:
|
||||||
- secure: aswHU7pQroGM+GHoYlhXzzk2FYfqxXJORjqXPsbgoHAIu4Bssaj8+YAzIcdy3j9kSt4I8VBpjnn8H/wzQXki75JBZOosQrIeMK018+uR+ZMONBLqDYW/N7EJHLgZt9QXxQNKeZygrD4GN/Dc4gLHGvPQC/RfPuuHcnF0Liaahoo=
|
- secure: aswHU7pQroGM+GHoYlhXzzk2FYfqxXJORjqXPsbgoHAIu4Bssaj8+YAzIcdy3j9kSt4I8VBpjnn8H/wzQXki75JBZOosQrIeMK018+uR+ZMONBLqDYW/N7EJHLgZt9QXxQNKeZygrD4GN/Dc4gLHGvPQC/RfPuuHcnF0Liaahoo=
|
||||||
- secure: RZ6M6984P885GRoyx9n/WCCWGoFAzYpS8sZkXu3e/HK9oPXfaM2IEHjkq03jIC/FcWn/QMtFjOUBqQU94rnqdivFdFkeZHk1WUQgC0hztH3Qhh9zu2PNIrYUDpVD5dJqBpprWbSwFP8yNsJlP9A2RUubTlZblKHuaBhhiuNN+kU=
|
- secure: RZ6M6984P885GRoyx9n/WCCWGoFAzYpS8sZkXu3e/HK9oPXfaM2IEHjkq03jIC/FcWn/QMtFjOUBqQU94rnqdivFdFkeZHk1WUQgC0hztH3Qhh9zu2PNIrYUDpVD5dJqBpprWbSwFP8yNsJlP9A2RUubTlZblKHuaBhhiuNN+kU=
|
||||||
|
|
@ -35,8 +48,4 @@ install:
|
||||||
- pip install tox
|
- pip install tox
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# Update Python 3.6 path - see bug https://github.com/travis-ci/travis-ci/issues/4990
|
|
||||||
- if [[ $TOX_ENV = *"py36"* ]]; then echo "Activated PY3.6"; source ~/virtualenv/python3.6/bin/activate; pip install tox; fi
|
|
||||||
- tox -e $TOX_ENV
|
- tox -e $TOX_ENV
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Model configuration in application ``django_mailbox`` for administration
|
Model configuration in application ``django_mailbox`` for administration
|
||||||
|
|
@ -10,7 +9,7 @@ import logging
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from django_mailbox.models import MessageAttachment, Message, Mailbox
|
from django_mailbox.models import MessageAttachment, Message, Mailbox
|
||||||
from django_mailbox.signals import message_received
|
from django_mailbox.signals import message_received
|
||||||
|
|
@ -74,7 +73,7 @@ class MessageAdmin(admin.ModelAdmin):
|
||||||
def envelope_headers(self, msg):
|
def envelope_headers(self, msg):
|
||||||
email = msg.get_email_object()
|
email = msg.get_email_object()
|
||||||
return '\n'.join(
|
return '\n'.join(
|
||||||
[('%s: %s' % (h, v)) for h, v in email.items()]
|
[('{}: {}'.format(h, v)) for h, v in email.items()]
|
||||||
)
|
)
|
||||||
|
|
||||||
inlines = [
|
inlines = [
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class MailBoxConfig(AppConfig):
|
class MailBoxConfig(AppConfig):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django_mailbox.utils
|
import django_mailbox.utils
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.9.8 on 2016-08-15 22:39
|
# Generated by Django 1.9.8 on 2016-08-15 22:39
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.10.7 on 2018-04-21 00:26
|
# Generated by Django 1.10.7 on 2018-04-21 00:26
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Models declaration for application ``django_mailbox``.
|
Models declaration for application ``django_mailbox``.
|
||||||
|
|
@ -8,7 +7,9 @@ import gzip
|
||||||
from email.encoders import encode_base64
|
from email.encoders import encode_base64
|
||||||
from email.message import Message as EmailMessage
|
from email.message import Message as EmailMessage
|
||||||
from email.utils import formatdate, parseaddr
|
from email.utils import formatdate, parseaddr
|
||||||
|
from urllib.parse import parse_qs, unquote, urlparse
|
||||||
from quopri import encode as encode_quopri
|
from quopri import encode as encode_quopri
|
||||||
|
from io import BytesIO
|
||||||
import base64
|
import base64
|
||||||
import email
|
import email
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -18,17 +19,13 @@ import sys
|
||||||
import uuid
|
import uuid
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
import six
|
|
||||||
from six.moves.urllib.parse import parse_qs, unquote, urlparse
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django.conf import settings as django_settings
|
from django.conf import settings as django_settings
|
||||||
from django.core.files.base import ContentFile, File
|
from django.core.files.base import ContentFile, File
|
||||||
from django.core.mail.message import make_msgid
|
from django.core.mail.message import make_msgid
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
from django_mailbox import utils
|
from django_mailbox import utils
|
||||||
from django_mailbox.signals import message_received
|
from django_mailbox.signals import message_received
|
||||||
|
|
@ -41,20 +38,19 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class ActiveMailboxManager(models.Manager):
|
class ActiveMailboxManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super(ActiveMailboxManager, self).get_queryset().filter(
|
return super().get_queryset().filter(
|
||||||
active=True,
|
active=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Mailbox(models.Model):
|
class Mailbox(models.Model):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
_(u'Name'),
|
_('Name'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
)
|
)
|
||||||
|
|
||||||
uri = models.CharField(
|
uri = models.CharField(
|
||||||
_(u'URI'),
|
_('URI'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
help_text=(_(
|
help_text=(_(
|
||||||
"Example: imap+ssl://myusername:mypassword@someserver <br />"
|
"Example: imap+ssl://myusername:mypassword@someserver <br />"
|
||||||
|
|
@ -72,7 +68,7 @@ class Mailbox(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
from_email = models.CharField(
|
from_email = models.CharField(
|
||||||
_(u'From email'),
|
_('From email'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
help_text=(_(
|
help_text=(_(
|
||||||
"Example: MailBot <mailbot@yourdomain.com><br />"
|
"Example: MailBot <mailbot@yourdomain.com><br />"
|
||||||
|
|
@ -89,7 +85,7 @@ class Mailbox(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
active = models.BooleanField(
|
active = models.BooleanField(
|
||||||
_(u'Active'),
|
_('Active'),
|
||||||
help_text=(_(
|
help_text=(_(
|
||||||
"Check this e-mail inbox for new e-mail messages during polling "
|
"Check this e-mail inbox for new e-mail messages during polling "
|
||||||
"cycles. This checkbox does not have an effect upon whether "
|
"cycles. This checkbox does not have an effect upon whether "
|
||||||
|
|
@ -102,7 +98,7 @@ class Mailbox(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
last_polling = models.DateTimeField(
|
last_polling = models.DateTimeField(
|
||||||
_(u"Last polling"),
|
_("Last polling"),
|
||||||
help_text=(_("The time of last successful polling for messages."
|
help_text=(_("The time of last successful polling for messages."
|
||||||
"It is blank for new mailboxes and is not set for "
|
"It is blank for new mailboxes and is not set for "
|
||||||
"mailboxes that only receive messages via a pipe.")),
|
"mailboxes that only receive messages via a pipe.")),
|
||||||
|
|
@ -294,7 +290,7 @@ class Mailbox(models.Model):
|
||||||
attachment.document.save(
|
attachment.document.save(
|
||||||
uuid.uuid4().hex + extension,
|
uuid.uuid4().hex + extension,
|
||||||
ContentFile(
|
ContentFile(
|
||||||
six.BytesIO(
|
BytesIO(
|
||||||
msg.get_payload(decode=True)
|
msg.get_payload(decode=True)
|
||||||
).getvalue()
|
).getvalue()
|
||||||
)
|
)
|
||||||
|
|
@ -392,7 +388,7 @@ class Mailbox(models.Model):
|
||||||
with gzip.GzipFile(fileobj=fp_tmp, mode="w") as fp:
|
with gzip.GzipFile(fileobj=fp_tmp, mode="w") as fp:
|
||||||
fp.write(message.as_string().encode('utf-8'))
|
fp.write(message.as_string().encode('utf-8'))
|
||||||
msg.eml.save(
|
msg.eml.save(
|
||||||
"%s.eml.gz" % (uuid.uuid4(), ),
|
"{}.eml.gz".format(uuid.uuid4()),
|
||||||
File(fp_tmp),
|
File(fp_tmp),
|
||||||
save=False
|
save=False
|
||||||
)
|
)
|
||||||
|
|
@ -430,41 +426,40 @@ class Mailbox(models.Model):
|
||||||
|
|
||||||
class IncomingMessageManager(models.Manager):
|
class IncomingMessageManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super(IncomingMessageManager, self).get_queryset().filter(
|
return super().get_queryset().filter(
|
||||||
outgoing=False,
|
outgoing=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OutgoingMessageManager(models.Manager):
|
class OutgoingMessageManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super(OutgoingMessageManager, self).get_queryset().filter(
|
return super().get_queryset().filter(
|
||||||
outgoing=True,
|
outgoing=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class UnreadMessageManager(models.Manager):
|
class UnreadMessageManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super(UnreadMessageManager, self).get_queryset().filter(
|
return super().get_queryset().filter(
|
||||||
read=None
|
read=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Message(models.Model):
|
class Message(models.Model):
|
||||||
mailbox = models.ForeignKey(
|
mailbox = models.ForeignKey(
|
||||||
Mailbox,
|
Mailbox,
|
||||||
related_name='messages',
|
related_name='messages',
|
||||||
verbose_name=_(u'Mailbox'),
|
verbose_name=_('Mailbox'),
|
||||||
on_delete=models.CASCADE
|
on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
|
|
||||||
subject = models.CharField(
|
subject = models.CharField(
|
||||||
_(u'Subject'),
|
_('Subject'),
|
||||||
max_length=255
|
max_length=255
|
||||||
)
|
)
|
||||||
|
|
||||||
message_id = models.CharField(
|
message_id = models.CharField(
|
||||||
_(u'Message ID'),
|
_('Message ID'),
|
||||||
max_length=255
|
max_length=255
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -473,7 +468,7 @@ class Message(models.Model):
|
||||||
related_name='replies',
|
related_name='replies',
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name=_(u'In reply to'),
|
verbose_name=_('In reply to'),
|
||||||
on_delete=models.CASCADE
|
on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -483,21 +478,21 @@ class Message(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
to_header = models.TextField(
|
to_header = models.TextField(
|
||||||
_(u'To header'),
|
_('To header'),
|
||||||
)
|
)
|
||||||
|
|
||||||
outgoing = models.BooleanField(
|
outgoing = models.BooleanField(
|
||||||
_(u'Outgoing'),
|
_('Outgoing'),
|
||||||
default=False,
|
default=False,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
body = models.TextField(
|
body = models.TextField(
|
||||||
_(u'Body'),
|
_('Body'),
|
||||||
)
|
)
|
||||||
|
|
||||||
encoded = models.BooleanField(
|
encoded = models.BooleanField(
|
||||||
_(u'Encoded'),
|
_('Encoded'),
|
||||||
default=False,
|
default=False,
|
||||||
help_text=_('True if the e-mail body is Base64 encoded'),
|
help_text=_('True if the e-mail body is Base64 encoded'),
|
||||||
)
|
)
|
||||||
|
|
@ -508,17 +503,17 @@ class Message(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
read = models.DateTimeField(
|
read = models.DateTimeField(
|
||||||
_(u'Read'),
|
_('Read'),
|
||||||
default=None,
|
default=None,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
eml = models.FileField(
|
eml = models.FileField(
|
||||||
_(u'Raw message contents'),
|
_('Raw message contents'),
|
||||||
null=True,
|
null=True,
|
||||||
upload_to="messages",
|
upload_to="messages",
|
||||||
help_text=_(u'Original full content of message')
|
help_text=_('Original full content of message')
|
||||||
)
|
)
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
unread_messages = UnreadMessageManager()
|
unread_messages = UnreadMessageManager()
|
||||||
|
|
@ -634,9 +629,9 @@ class Message(models.Model):
|
||||||
if encoding and encoding.lower() == 'quoted-printable':
|
if encoding and encoding.lower() == 'quoted-printable':
|
||||||
# Cannot use `email.encoders.encode_quopri due to
|
# Cannot use `email.encoders.encode_quopri due to
|
||||||
# bug 14360: http://bugs.python.org/issue14360
|
# bug 14360: http://bugs.python.org/issue14360
|
||||||
output = six.BytesIO()
|
output = BytesIO()
|
||||||
encode_quopri(
|
encode_quopri(
|
||||||
six.BytesIO(
|
BytesIO(
|
||||||
attachment.document.read()
|
attachment.document.read()
|
||||||
),
|
),
|
||||||
output,
|
output,
|
||||||
|
|
@ -688,10 +683,8 @@ class Message(models.Model):
|
||||||
no fields existed for storing arbitrary bytes.
|
no fields existed for storing arbitrary bytes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if six.PY3:
|
|
||||||
body = body.encode('utf-8')
|
|
||||||
self.encoded = True
|
self.encoded = True
|
||||||
self.body = base64.b64encode(body).decode('ascii')
|
self.body = base64.b64encode(body.encode('utf-8')).decode('ascii')
|
||||||
|
|
||||||
def get_email_object(self):
|
def get_email_object(self):
|
||||||
"""Returns an `email.message.Message` instance representing the
|
"""Returns an `email.message.Message` instance representing the
|
||||||
|
|
@ -722,10 +715,7 @@ class Message(models.Model):
|
||||||
self.eml.close()
|
self.eml.close()
|
||||||
else:
|
else:
|
||||||
body = self.get_body()
|
body = self.get_body()
|
||||||
if six.PY3:
|
|
||||||
flat = email.message_from_bytes(body)
|
flat = email.message_from_bytes(body)
|
||||||
else:
|
|
||||||
flat = email.message_from_string(body)
|
|
||||||
self._email_object = self._rehydrate(flat)
|
self._email_object = self._rehydrate(flat)
|
||||||
return self._email_object
|
return self._email_object
|
||||||
|
|
||||||
|
|
@ -734,7 +724,7 @@ class Message(models.Model):
|
||||||
for attachment in self.attachments.all():
|
for attachment in self.attachments.all():
|
||||||
# This attachment is attached only to this message.
|
# This attachment is attached only to this message.
|
||||||
attachment.delete()
|
attachment.delete()
|
||||||
return super(Message, self).delete(*args, **kwargs)
|
return super().delete(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.subject
|
return self.subject
|
||||||
|
|
@ -744,7 +734,6 @@ class Message(models.Model):
|
||||||
verbose_name_plural = _('E-mail messages')
|
verbose_name_plural = _('E-mail messages')
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class MessageAttachment(models.Model):
|
class MessageAttachment(models.Model):
|
||||||
message = models.ForeignKey(
|
message = models.ForeignKey(
|
||||||
Message,
|
Message,
|
||||||
|
|
@ -756,30 +745,25 @@ class MessageAttachment(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
headers = models.TextField(
|
headers = models.TextField(
|
||||||
_(u'Headers'),
|
_('Headers'),
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
document = models.FileField(
|
document = models.FileField(
|
||||||
_(u'Document'),
|
_('Document'),
|
||||||
upload_to=utils.get_attachment_save_path,
|
upload_to=utils.get_attachment_save_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
"""Deletes the attachment."""
|
"""Deletes the attachment."""
|
||||||
self.document.delete()
|
self.document.delete()
|
||||||
return super(MessageAttachment, self).delete(*args, **kwargs)
|
return super().delete(*args, **kwargs)
|
||||||
|
|
||||||
def _get_rehydrated_headers(self):
|
def _get_rehydrated_headers(self):
|
||||||
headers = self.headers
|
headers = self.headers
|
||||||
if headers is None:
|
if headers is None:
|
||||||
return EmailMessage()
|
return EmailMessage()
|
||||||
if sys.version_info < (3, 0):
|
|
||||||
try:
|
|
||||||
headers = headers.encode('utf-8')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
headers = headers.decode('utf-8').encode('utf-8')
|
|
||||||
return email.message_from_string(headers)
|
return email.message_from_string(headers)
|
||||||
|
|
||||||
def _set_dehydrated_headers(self, email_object):
|
def _set_dehydrated_headers(self, email_object):
|
||||||
|
|
@ -798,7 +782,7 @@ class MessageAttachment(models.Model):
|
||||||
def get_filename(self):
|
def get_filename(self):
|
||||||
"""Returns the original filename of this attachment."""
|
"""Returns the original filename of this attachment."""
|
||||||
file_name = self._get_rehydrated_headers().get_filename()
|
file_name = self._get_rehydrated_headers().get_filename()
|
||||||
if isinstance(file_name, six.string_types):
|
if isinstance(file_name, str):
|
||||||
result = utils.convert_header_to_unicode(file_name)
|
result = utils.convert_header_to_unicode(file_name)
|
||||||
if result is None:
|
if result is None:
|
||||||
return file_name
|
return file_name
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
import email
|
import email
|
||||||
from south.db import db
|
from south.db import db
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# encoding: utf-8
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
@ -9,33 +8,33 @@ class Migration(SchemaMigration):
|
||||||
|
|
||||||
def forwards(self, orm):
|
def forwards(self, orm):
|
||||||
# Adding field 'MessageAttachment.message'
|
# Adding field 'MessageAttachment.message'
|
||||||
db.add_column(u'django_mailbox_messageattachment', 'message',
|
db.add_column('django_mailbox_messageattachment', 'message',
|
||||||
self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='attachments', null=True, to=orm['django_mailbox.Message']),
|
self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='attachments', null=True, to=orm['django_mailbox.Message']),
|
||||||
keep_default=False)
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
def backwards(self, orm):
|
||||||
# Deleting field 'MessageAttachment.message'
|
# Deleting field 'MessageAttachment.message'
|
||||||
db.delete_column(u'django_mailbox_messageattachment', 'message_id')
|
db.delete_column('django_mailbox_messageattachment', 'message_id')
|
||||||
|
|
||||||
|
|
||||||
models = {
|
models = {
|
||||||
u'django_mailbox.mailbox': {
|
'django_mailbox.mailbox': {
|
||||||
'Meta': {'object_name': 'Mailbox'},
|
'Meta': {'object_name': 'Mailbox'},
|
||||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
||||||
},
|
},
|
||||||
u'django_mailbox.message': {
|
'django_mailbox.message': {
|
||||||
'Meta': {'object_name': 'Message'},
|
'Meta': {'object_name': 'Message'},
|
||||||
'attachments': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'messages_old'", 'blank': 'True', 'to': u"orm['django_mailbox.MessageAttachment']"}),
|
'attachments': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'messages_old'", 'blank': 'True', 'to': "orm['django_mailbox.MessageAttachment']"}),
|
||||||
'body': ('django.db.models.fields.TextField', [], {}),
|
'body': ('django.db.models.fields.TextField', [], {}),
|
||||||
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
|
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}),
|
||||||
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
|
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}),
|
||||||
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
|
@ -43,11 +42,11 @@ class Migration(SchemaMigration):
|
||||||
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'to_header': ('django.db.models.fields.TextField', [], {})
|
'to_header': ('django.db.models.fields.TextField', [], {})
|
||||||
},
|
},
|
||||||
u'django_mailbox.messageattachment': {
|
'django_mailbox.messageattachment': {
|
||||||
'Meta': {'object_name': 'MessageAttachment'},
|
'Meta': {'object_name': 'MessageAttachment'},
|
||||||
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments_new'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"})
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments_new'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
@ -21,22 +20,22 @@ class Migration(SchemaMigration):
|
||||||
)
|
)
|
||||||
|
|
||||||
models = {
|
models = {
|
||||||
u'django_mailbox.mailbox': {
|
'django_mailbox.mailbox': {
|
||||||
'Meta': {'object_name': 'Mailbox'},
|
'Meta': {'object_name': 'Mailbox'},
|
||||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
||||||
},
|
},
|
||||||
u'django_mailbox.message': {
|
'django_mailbox.message': {
|
||||||
'Meta': {'object_name': 'Message'},
|
'Meta': {'object_name': 'Message'},
|
||||||
'attachments': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'messages_old'", 'blank': 'True', 'to': u"orm['django_mailbox.MessageAttachment']"}),
|
'attachments': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'messages_old'", 'blank': 'True', 'to': "orm['django_mailbox.MessageAttachment']"}),
|
||||||
'body': ('django.db.models.fields.TextField', [], {}),
|
'body': ('django.db.models.fields.TextField', [], {}),
|
||||||
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
|
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}),
|
||||||
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
|
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}),
|
||||||
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
|
@ -44,11 +43,11 @@ class Migration(SchemaMigration):
|
||||||
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'to_header': ('django.db.models.fields.TextField', [], {})
|
'to_header': ('django.db.models.fields.TextField', [], {})
|
||||||
},
|
},
|
||||||
u'django_mailbox.messageattachment': {
|
'django_mailbox.messageattachment': {
|
||||||
'Meta': {'object_name': 'MessageAttachment'},
|
'Meta': {'object_name': 'MessageAttachment'},
|
||||||
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments_new'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"})
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments_new'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
@ -12,40 +11,40 @@ class Migration(SchemaMigration):
|
||||||
db.delete_table('django_mailbox_message_attachments')
|
db.delete_table('django_mailbox_message_attachments')
|
||||||
|
|
||||||
# Adding field 'MessageAttachment.headers'
|
# Adding field 'MessageAttachment.headers'
|
||||||
db.add_column(u'django_mailbox_messageattachment', 'headers',
|
db.add_column('django_mailbox_messageattachment', 'headers',
|
||||||
self.gf('django.db.models.fields.TextField')(null=True, blank=True),
|
self.gf('django.db.models.fields.TextField')(null=True, blank=True),
|
||||||
keep_default=False)
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
def backwards(self, orm):
|
||||||
# Adding M2M table for field attachments on 'Message'
|
# Adding M2M table for field attachments on 'Message'
|
||||||
db.create_table(u'django_mailbox_message_attachments', (
|
db.create_table('django_mailbox_message_attachments', (
|
||||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||||
('message', models.ForeignKey(orm[u'django_mailbox.message'], null=False)),
|
('message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
|
||||||
('messageattachment', models.ForeignKey(orm[u'django_mailbox.messageattachment'], null=False))
|
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False))
|
||||||
))
|
))
|
||||||
db.create_unique(u'django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])
|
db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])
|
||||||
|
|
||||||
# Deleting field 'MessageAttachment.headers'
|
# Deleting field 'MessageAttachment.headers'
|
||||||
db.delete_column(u'django_mailbox_messageattachment', 'headers')
|
db.delete_column('django_mailbox_messageattachment', 'headers')
|
||||||
|
|
||||||
|
|
||||||
models = {
|
models = {
|
||||||
u'django_mailbox.mailbox': {
|
'django_mailbox.mailbox': {
|
||||||
'Meta': {'object_name': 'Mailbox'},
|
'Meta': {'object_name': 'Mailbox'},
|
||||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
||||||
},
|
},
|
||||||
u'django_mailbox.message': {
|
'django_mailbox.message': {
|
||||||
'Meta': {'object_name': 'Message'},
|
'Meta': {'object_name': 'Message'},
|
||||||
'body': ('django.db.models.fields.TextField', [], {}),
|
'body': ('django.db.models.fields.TextField', [], {}),
|
||||||
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
|
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}),
|
||||||
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
|
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}),
|
||||||
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
|
@ -53,12 +52,12 @@ class Migration(SchemaMigration):
|
||||||
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'to_header': ('django.db.models.fields.TextField', [], {})
|
'to_header': ('django.db.models.fields.TextField', [], {})
|
||||||
},
|
},
|
||||||
u'django_mailbox.messageattachment': {
|
'django_mailbox.messageattachment': {
|
||||||
'Meta': {'object_name': 'MessageAttachment'},
|
'Meta': {'object_name': 'MessageAttachment'},
|
||||||
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||||
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"})
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import datetime
|
import datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
@ -9,33 +8,33 @@ class Migration(SchemaMigration):
|
||||||
|
|
||||||
def forwards(self, orm):
|
def forwards(self, orm):
|
||||||
# Adding field 'Message.encoded'
|
# Adding field 'Message.encoded'
|
||||||
db.add_column(u'django_mailbox_message', 'encoded',
|
db.add_column('django_mailbox_message', 'encoded',
|
||||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||||
keep_default=False)
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
def backwards(self, orm):
|
||||||
# Deleting field 'Message.encoded'
|
# Deleting field 'Message.encoded'
|
||||||
db.delete_column(u'django_mailbox_message', 'encoded')
|
db.delete_column('django_mailbox_message', 'encoded')
|
||||||
|
|
||||||
|
|
||||||
models = {
|
models = {
|
||||||
u'django_mailbox.mailbox': {
|
'django_mailbox.mailbox': {
|
||||||
'Meta': {'object_name': 'Mailbox'},
|
'Meta': {'object_name': 'Mailbox'},
|
||||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
||||||
},
|
},
|
||||||
u'django_mailbox.message': {
|
'django_mailbox.message': {
|
||||||
'Meta': {'object_name': 'Message'},
|
'Meta': {'object_name': 'Message'},
|
||||||
'body': ('django.db.models.fields.TextField', [], {}),
|
'body': ('django.db.models.fields.TextField', [], {}),
|
||||||
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
|
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}),
|
||||||
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
|
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}),
|
||||||
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
|
@ -43,12 +42,12 @@ class Migration(SchemaMigration):
|
||||||
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'to_header': ('django.db.models.fields.TextField', [], {})
|
'to_header': ('django.db.models.fields.TextField', [], {})
|
||||||
},
|
},
|
||||||
u'django_mailbox.messageattachment': {
|
'django_mailbox.messageattachment': {
|
||||||
'Meta': {'object_name': 'MessageAttachment'},
|
'Meta': {'object_name': 'MessageAttachment'},
|
||||||
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||||
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"})
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from south.utils import datetime_utils as datetime
|
from south.utils import datetime_utils as datetime
|
||||||
from south.db import db
|
from south.db import db
|
||||||
from south.v2 import SchemaMigration
|
from south.v2 import SchemaMigration
|
||||||
|
|
@ -9,34 +8,34 @@ class Migration(SchemaMigration):
|
||||||
|
|
||||||
def forwards(self, orm):
|
def forwards(self, orm):
|
||||||
# Adding field 'Message.eml'
|
# Adding field 'Message.eml'
|
||||||
db.add_column(u'django_mailbox_message', 'eml',
|
db.add_column('django_mailbox_message', 'eml',
|
||||||
self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True),
|
self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True),
|
||||||
keep_default=False)
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
def backwards(self, orm):
|
||||||
# Deleting field 'Message.eml'
|
# Deleting field 'Message.eml'
|
||||||
db.delete_column(u'django_mailbox_message', 'eml')
|
db.delete_column('django_mailbox_message', 'eml')
|
||||||
|
|
||||||
|
|
||||||
models = {
|
models = {
|
||||||
u'django_mailbox.mailbox': {
|
'django_mailbox.mailbox': {
|
||||||
'Meta': {'object_name': 'Mailbox'},
|
'Meta': {'object_name': 'Mailbox'},
|
||||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
'from_email': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'})
|
||||||
},
|
},
|
||||||
u'django_mailbox.message': {
|
'django_mailbox.message': {
|
||||||
'Meta': {'object_name': 'Message'},
|
'Meta': {'object_name': 'Message'},
|
||||||
'body': ('django.db.models.fields.TextField', [], {}),
|
'body': ('django.db.models.fields.TextField', [], {}),
|
||||||
'eml': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
|
'eml': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
|
||||||
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
|
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}),
|
||||||
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
|
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}),
|
||||||
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
|
@ -44,12 +43,12 @@ class Migration(SchemaMigration):
|
||||||
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
'to_header': ('django.db.models.fields.TextField', [], {})
|
'to_header': ('django.db.models.fields.TextField', [], {})
|
||||||
},
|
},
|
||||||
u'django_mailbox.messageattachment': {
|
'django_mailbox.messageattachment': {
|
||||||
'Meta': {'object_name': 'MessageAttachment'},
|
'Meta': {'object_name': 'MessageAttachment'},
|
||||||
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||||
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"})
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import email
|
||||||
import os.path
|
import os.path
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
@ -57,7 +55,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
settings.EMAIL_HOST_USER = self.test_account
|
settings.EMAIL_HOST_USER = self.test_account
|
||||||
settings.EMAIL_HOST_PASSWORD = self.test_password
|
settings.EMAIL_HOST_PASSWORD = self.test_password
|
||||||
settings.EMAIL_USE_TLS = True
|
settings.EMAIL_USE_TLS = True
|
||||||
super(EmailMessageTestCase, self).setUp()
|
super().setUp()
|
||||||
|
|
||||||
def _get_new_messages(self, mailbox, condition=None):
|
def _get_new_messages(self, mailbox, condition=None):
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
@ -70,8 +68,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
# check if generator contains at least one element
|
# check if generator contains at least one element
|
||||||
message = next(messages)
|
message = next(messages)
|
||||||
yield message
|
yield message
|
||||||
for message in messages:
|
yield from messages
|
||||||
yield message
|
|
||||||
return
|
return
|
||||||
|
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|
@ -92,10 +89,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
|
|
||||||
def _get_email_object(self, name):
|
def _get_email_object(self, name):
|
||||||
copy = self._get_email_as_text(name)
|
copy = self._get_email_as_text(name)
|
||||||
if six.PY3:
|
|
||||||
return email.message_from_bytes(copy)
|
return email.message_from_bytes(copy)
|
||||||
else:
|
|
||||||
return email.message_from_string(copy)
|
|
||||||
|
|
||||||
def _headers_identical(self, left, right, header=None):
|
def _headers_identical(self, left, right, header=None):
|
||||||
""" Check if headers are (close enough to) identical.
|
""" Check if headers are (close enough to) identical.
|
||||||
|
|
@ -131,7 +125,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
raise AssertionError("Extra header '%s'" % key)
|
raise AssertionError("Extra header '%s'" % key)
|
||||||
if not self._headers_identical(right[key], value, header=key):
|
if not self._headers_identical(right[key], value, header=key):
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
"Header '%s' unequal:\n%s\n%s" % (
|
"Header '{}' unequal:\n{}\n{}".format(
|
||||||
key,
|
key,
|
||||||
repr(value),
|
repr(value),
|
||||||
repr(right[key]),
|
repr(right[key]),
|
||||||
|
|
@ -144,7 +138,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
raise AssertionError("Extra header '%s'" % key)
|
raise AssertionError("Extra header '%s'" % key)
|
||||||
if not self._headers_identical(left[key], value, header=key):
|
if not self._headers_identical(left[key], value, header=key):
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
"Header '%s' unequal:\n%s\n%s" % (
|
"Header '{}' unequal:\n{}\n{}".format(
|
||||||
key,
|
key,
|
||||||
repr(value),
|
repr(value),
|
||||||
repr(right[key]),
|
repr(right[key]),
|
||||||
|
|
@ -175,7 +169,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
|
|
||||||
def _raise_mismatched(self, left, right):
|
def _raise_mismatched(self, left, right):
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
"Message payloads do not match:\n%s\n%s" % (
|
"Message payloads do not match:\n{}\n{}".format(
|
||||||
left.as_string(),
|
left.as_string(),
|
||||||
right.as_string()
|
right.as_string()
|
||||||
)
|
)
|
||||||
|
|
@ -183,7 +177,7 @@ class EmailMessageTestCase(TestCase):
|
||||||
|
|
||||||
def assertEqual(self, left, right): # noqa: N802
|
def assertEqual(self, left, right): # noqa: N802
|
||||||
if not isinstance(left, email.message.Message):
|
if not isinstance(left, email.message.Message):
|
||||||
return super(EmailMessageTestCase, self).assertEqual(left, right)
|
return super().assertEqual(left, right)
|
||||||
return self.compare_email_objects(left, right)
|
return self.compare_email_objects(left, right)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
@ -194,4 +188,4 @@ class EmailMessageTestCase(TestCase):
|
||||||
models.TEXT_STORED_MIMETYPES = self._TEXT_STORED_MIMETYPES
|
models.TEXT_STORED_MIMETYPES = self._TEXT_STORED_MIMETYPES
|
||||||
|
|
||||||
self.mailbox.delete()
|
self.mailbox.delete()
|
||||||
super(EmailMessageTestCase, self).tearDown()
|
super().tearDown()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
from urllib import parse
|
||||||
from six.moves.urllib import parse
|
|
||||||
|
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives
|
||||||
|
|
||||||
|
|
@ -14,7 +13,7 @@ __all__ = ['TestImap']
|
||||||
|
|
||||||
class TestImap(EmailMessageTestCase):
|
class TestImap(EmailMessageTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestImap, self).setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.test_imap_server = (
|
self.test_imap_server = (
|
||||||
os.environ.get('EMAIL_IMAP_SERVER')
|
os.environ.get('EMAIL_IMAP_SERVER')
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import mock
|
from unittest import mock
|
||||||
|
|
||||||
from django_mailbox import models, utils
|
from django_mailbox import models, utils
|
||||||
from django_mailbox.models import Message
|
from django_mailbox.models import Message
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ import os.path
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import mock
|
from unittest import mock
|
||||||
import six
|
|
||||||
|
|
||||||
from django_mailbox.models import Mailbox, Message
|
from django_mailbox.models import Mailbox, Message
|
||||||
from django_mailbox.utils import convert_header_to_unicode
|
from django_mailbox.utils import convert_header_to_unicode
|
||||||
|
|
@ -54,18 +53,18 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
|
|
||||||
attachments = msg.attachments.order_by('pk').all()
|
attachments = msg.attachments.order_by('pk').all()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
u'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
|
'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
|
||||||
u'\u043e\u0436\u0435\u043d\u0438\u0439 HSE Career Fair 8 \u0430'
|
'\u043e\u0436\u0435\u043d\u0438\u0439 HSE Career Fair 8 \u0430'
|
||||||
u'\u043f\u0440\u0435\u043b\u044f 2016.pdf',
|
'\u043f\u0440\u0435\u043b\u044f 2016.pdf',
|
||||||
attachments[0].get_filename()
|
attachments[0].get_filename()
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
u'\u0412\u0435\u0434\u043e\u043c\u043e\u0441\u0442\u0438.pdf',
|
'\u0412\u0435\u0434\u043e\u043c\u043e\u0441\u0442\u0438.pdf',
|
||||||
attachments[1].get_filename()
|
attachments[1].get_filename()
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
u'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
|
'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
|
||||||
u'\u043e\u0436\u0435\u043d\u0438\u0439 2016.pptx',
|
'\u043e\u0436\u0435\u043d\u0438\u0439 2016.pptx',
|
||||||
attachments[2].get_filename()
|
attachments[2].get_filename()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -89,33 +88,6 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
'heart.png',
|
'heart.png',
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_message_with_not_decoded_attachment_header(self):
|
|
||||||
if sys.version_info > (3, 0):
|
|
||||||
self.skipTest(
|
|
||||||
"This test is only relevant on Python 2.x."
|
|
||||||
)
|
|
||||||
|
|
||||||
email_object = self._get_email_object(
|
|
||||||
'message_with_not_decoded_attachment_header.eml',
|
|
||||||
)
|
|
||||||
|
|
||||||
mailbox = Mailbox.objects.create()
|
|
||||||
msg = mailbox.process_incoming_message(email_object)
|
|
||||||
|
|
||||||
expected_count = 1
|
|
||||||
actual_count = msg.attachments.count()
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
expected_count,
|
|
||||||
actual_count,
|
|
||||||
)
|
|
||||||
|
|
||||||
attachment = msg.attachments.all()[0]
|
|
||||||
self.assertEqual(
|
|
||||||
attachment.get_filename(),
|
|
||||||
u'\xc3\xb0\xcc\x9eo\xce\xb2\xcc\x9ele.png',
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_message_with_utf8_attachment_header(self):
|
def test_message_with_utf8_attachment_header(self):
|
||||||
""" Ensure that we properly handle UTF-8 encoded attachment
|
""" Ensure that we properly handle UTF-8 encoded attachment
|
||||||
|
|
||||||
|
|
@ -138,13 +110,13 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
attachment = msg.attachments.all()[0]
|
attachment = msg.attachments.all()[0]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
attachment.get_filename(),
|
attachment.get_filename(),
|
||||||
u'pi\u0142kochwyty.jpg'
|
'pi\u0142kochwyty.jpg'
|
||||||
)
|
)
|
||||||
|
|
||||||
attachment = msg.attachments.all()[1]
|
attachment = msg.attachments.all()[1]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
attachment.get_filename(),
|
attachment.get_filename(),
|
||||||
u'odpowied\u017a Burmistrza.jpg'
|
'odpowied\u017a Burmistrza.jpg'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_message_get_text_body(self):
|
def test_message_get_text_body(self):
|
||||||
|
|
@ -187,7 +159,7 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
'messages/generic_message.eml'
|
'messages/generic_message.eml'
|
||||||
)
|
)
|
||||||
) as f:
|
) as f:
|
||||||
unicode_body = six.u(f.read())
|
unicode_body = f.read()
|
||||||
|
|
||||||
message = Message()
|
message = Message()
|
||||||
message.body = unicode_body
|
message.body = unicode_body
|
||||||
|
|
@ -281,10 +253,8 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
|
|
||||||
msg = self.mailbox.process_incoming_message(email_object)
|
msg = self.mailbox.process_incoming_message(email_object)
|
||||||
|
|
||||||
expected_text = six.u(
|
expected_text = 'This message contains funny UTF16 characters ' + \
|
||||||
'This message contains funny UTF16 characters like this one: '
|
'like this one: "\xc2\xa0" and this one "\xe2\x9c\xbf".'
|
||||||
'"\xc2\xa0" and this one "\xe2\x9c\xbf".'
|
|
||||||
)
|
|
||||||
actual_text = msg.text
|
actual_text = msg.text
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
@ -320,14 +290,12 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
msg = self.mailbox.process_incoming_message(email_object)
|
msg = self.mailbox.process_incoming_message(email_object)
|
||||||
|
|
||||||
actual_text = msg.text
|
actual_text = msg.text
|
||||||
expected_body = six.u(
|
expected_body = '\u042d\u0442\u043e ' + \
|
||||||
'\u042d\u0442\u043e '
|
'\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 ' + \
|
||||||
'\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 '
|
'\u0438\u043c\u0435\u0435\u0442 ' + \
|
||||||
'\u0438\u043c\u0435\u0435\u0442 '
|
'\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d' + \
|
||||||
'\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d'
|
'\u0443\u044e ' + \
|
||||||
'\u0443\u044e '
|
|
||||||
'\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430.'
|
'\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430.'
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
actual_text,
|
actual_text,
|
||||||
|
|
@ -341,23 +309,15 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
|
|
||||||
msg = self.mailbox.process_incoming_message(email_object)
|
msg = self.mailbox.process_incoming_message(email_object)
|
||||||
|
|
||||||
expected_subject = six.u(
|
expected_subject = '\u00D3\u00E7\u00ED\u00E0\u00E9 \u00EA\u00E0\u00EA ' + \
|
||||||
'\u00D3\u00E7\u00ED\u00E0\u00E9 \u00EA\u00E0\u00EA '
|
'\u00E7\u00E0\u00F0\u00E0\u00E1\u00E0\u00F2\u00FB\u00E2' + \
|
||||||
'\u00E7\u00E0\u00F0\u00E0\u00E1\u00E0\u00F2\u00FB\u00E2'
|
'\u00E0\u00F2\u00FC \u00EE\u00F2 1000$ \u00E2 ' + \
|
||||||
'\u00E0\u00F2\u00FC \u00EE\u00F2 1000$ \u00E2 '
|
|
||||||
'\u00ED\u00E5\u00E4\u00E5\u00EB\u00FE!'
|
'\u00ED\u00E5\u00E4\u00E5\u00EB\u00FE!'
|
||||||
)
|
|
||||||
actual_subject = msg.subject
|
actual_subject = msg.subject
|
||||||
self.assertEqual(actual_subject, expected_subject)
|
self.assertEqual(actual_subject, expected_subject)
|
||||||
|
|
||||||
if sys.version_info >= (3, 3):
|
expected_from = 'test test <mr.test32@mail.ru>'
|
||||||
# There were various bugfixes in Py3k's email module,
|
|
||||||
# this is apparently one of them.
|
|
||||||
expected_from = six.u('test test <mr.test32@mail.ru>')
|
|
||||||
else:
|
|
||||||
expected_from = six.u('test test<mr.test32@mail.ru>')
|
|
||||||
actual_from = msg.from_header
|
actual_from = msg.from_header
|
||||||
|
|
||||||
self.assertEqual(expected_from, actual_from)
|
self.assertEqual(expected_from, actual_from)
|
||||||
|
|
||||||
def test_message_reply(self):
|
def test_message_reply(self):
|
||||||
|
|
@ -426,15 +386,15 @@ class TestProcessEmail(EmailMessageTestCase):
|
||||||
|
|
||||||
msg = self.mailbox.process_incoming_message(message)
|
msg = self.mailbox.process_incoming_message(message)
|
||||||
|
|
||||||
actual_email_object = msg.get_email_object()
|
|
||||||
|
|
||||||
self.assertNotEquals(msg.eml, None)
|
self.assertNotEquals(msg.eml, None)
|
||||||
|
|
||||||
self.assertTrue(msg.eml.name.endswith('.eml'))
|
self.assertTrue(msg.eml.name.endswith('.eml'))
|
||||||
|
|
||||||
with open(msg.eml.name, 'rb') as f:
|
with open(msg.eml.name, 'rb') as f:
|
||||||
self.assertEqual(f.read(),
|
self.assertEqual(
|
||||||
self._get_email_as_text('generic_message.eml'))
|
f.read(),
|
||||||
|
self._get_email_as_text('generic_message.eml')
|
||||||
|
)
|
||||||
|
|
||||||
def test_message_saving_ignored(self):
|
def test_message_saving_ignored(self):
|
||||||
message = self._get_email_object('generic_message.eml')
|
message = self._get_email_object('generic_message.eml')
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
import mock
|
from unittest import mock
|
||||||
|
|
||||||
from django.core.management import call_command, CommandError
|
from django.core.management import call_command, CommandError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import mock
|
from unittest import mock
|
||||||
import six
|
|
||||||
|
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
|
@ -9,24 +8,22 @@ from django_mailbox.transports import ImapTransport, Pop3Transport
|
||||||
FAKE_UID_SEARCH_ANSWER = (
|
FAKE_UID_SEARCH_ANSWER = (
|
||||||
'OK',
|
'OK',
|
||||||
[
|
[
|
||||||
six.b(
|
b'18 19 20 21 22 23 24 25 26 27 28 29 ' +
|
||||||
'18 19 20 21 22 23 24 25 26 27 28 29 '
|
b'30 31 32 33 34 35 36 37 38 39 40 41 42 43 44'
|
||||||
'30 31 32 33 34 35 36 37 38 39 40 41 42 43 44'
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
FAKE_UID_FETCH_SIZES = (
|
FAKE_UID_FETCH_SIZES = (
|
||||||
'OK',
|
'OK',
|
||||||
[
|
[
|
||||||
six.b('1 (UID 18 RFC822.SIZE 58070000000)'),
|
b'1 (UID 18 RFC822.SIZE 58070000000)',
|
||||||
six.b('2 (UID 19 RFC822.SIZE 2593)')
|
b'2 (UID 19 RFC822.SIZE 2593)'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
FAKE_UID_FETCH_MSG = (
|
FAKE_UID_FETCH_MSG = (
|
||||||
'OK',
|
'OK',
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
six.b('1 (UID 18 RFC822 {5807}'),
|
b'1 (UID 18 RFC822 {5807}',
|
||||||
get_email_as_text('generic_message.eml')
|
get_email_as_text('generic_message.eml')
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
@ -34,13 +31,13 @@ FAKE_UID_FETCH_MSG = (
|
||||||
FAKE_UID_COPY_MSG = (
|
FAKE_UID_COPY_MSG = (
|
||||||
'OK',
|
'OK',
|
||||||
[
|
[
|
||||||
six.b('[COPYUID 1 2 2] (Success)')
|
b'[COPYUID 1 2 2] (Success)'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
FAKE_LIST_ARCHIVE_FOLDERS_ANSWERS = (
|
FAKE_LIST_ARCHIVE_FOLDERS_ANSWERS = (
|
||||||
'OK',
|
'OK',
|
||||||
[
|
[
|
||||||
six.b('(\\HasNoChildren \\All) "/" "[Gmail]/All Mail"')
|
b'(\\HasNoChildren \\All) "/" "[Gmail]/All Mail"'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -66,12 +63,12 @@ class IMAPTestCase(EmailMessageTestCase):
|
||||||
self.imap_server = mock.Mock()
|
self.imap_server = mock.Mock()
|
||||||
self.imap_server.uid = imap_server_uid_method
|
self.imap_server.uid = imap_server_uid_method
|
||||||
self.imap_server.list = imap_server_list_method
|
self.imap_server.list = imap_server_list_method
|
||||||
super(IMAPTestCase, self).setUp()
|
super().setUp()
|
||||||
|
|
||||||
|
|
||||||
class TestImapTransport(IMAPTestCase):
|
class TestImapTransport(IMAPTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestImapTransport, self).setUp()
|
super().setUp()
|
||||||
self.arbitrary_hostname = 'one.two.three'
|
self.arbitrary_hostname = 'one.two.three'
|
||||||
self.arbitrary_port = 100
|
self.arbitrary_port = 100
|
||||||
self.ssl = False
|
self.ssl = False
|
||||||
|
|
@ -92,7 +89,7 @@ class TestImapTransport(IMAPTestCase):
|
||||||
|
|
||||||
class TestImapArchivedTransport(TestImapTransport):
|
class TestImapArchivedTransport(TestImapTransport):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestImapArchivedTransport, self).setUp()
|
super().setUp()
|
||||||
self.archive = 'Archive'
|
self.archive = 'Archive'
|
||||||
self.transport = ImapTransport(
|
self.transport = ImapTransport(
|
||||||
self.arbitrary_hostname,
|
self.arbitrary_hostname,
|
||||||
|
|
@ -107,7 +104,7 @@ class TestMaxSizeImapTransport(TestImapTransport):
|
||||||
|
|
||||||
@override_settings(DJANGO_MAILBOX_MAX_MESSAGE_SIZE=5807)
|
@override_settings(DJANGO_MAILBOX_MAX_MESSAGE_SIZE=5807)
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestMaxSizeImapTransport, self).setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.transport = ImapTransport(
|
self.transport = ImapTransport(
|
||||||
self.arbitrary_hostname,
|
self.arbitrary_hostname,
|
||||||
|
|
@ -142,7 +139,7 @@ class TestPop3Transport(EmailMessageTestCase):
|
||||||
self.ssl
|
self.ssl
|
||||||
)
|
)
|
||||||
self.transport.server = None
|
self.transport.server = None
|
||||||
super(TestPop3Transport, self).setUp()
|
super().setUp()
|
||||||
|
|
||||||
def test_get_email_message(self):
|
def test_get_email_message(self):
|
||||||
with mock.patch.object(self.transport, 'server') as server:
|
with mock.patch.object(self.transport, 'server') as server:
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,11 @@
|
||||||
import email
|
import email
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
# Do *not* remove this, we need to use this in subclasses of EmailTransport
|
# Do *not* remove this, we need to use this in subclasses of EmailTransport
|
||||||
if six.PY3:
|
from email.errors import MessageParseError # noqa: F401
|
||||||
from email.errors import MessageParseError # noqa: F401
|
|
||||||
else:
|
|
||||||
from email.Errors import MessageParseError # noqa: F401
|
|
||||||
|
|
||||||
|
|
||||||
class EmailTransport(object):
|
class EmailTransport:
|
||||||
def get_email_from_bytes(self, contents):
|
def get_email_from_bytes(self, contents):
|
||||||
if six.PY3:
|
|
||||||
message = email.message_from_bytes(contents)
|
message = email.message_from_bytes(contents)
|
||||||
else:
|
|
||||||
message = email.message_from_string(contents)
|
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import sys
|
import sys
|
||||||
import six
|
|
||||||
|
|
||||||
from .base import EmailTransport
|
from .base import EmailTransport
|
||||||
|
|
||||||
|
|
@ -9,12 +8,7 @@ class GenericFileMailbox(EmailTransport):
|
||||||
_path = None
|
_path = None
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
super(GenericFileMailbox, self).__init__()
|
super().__init__()
|
||||||
if six.PY2:
|
|
||||||
self._path = path.encode(
|
|
||||||
sys.getfilesystemencoding()
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self._path = path
|
self._path = path
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class GmailImapTransport(ImapTransport):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
auth_string = 'user=%s\1auth=Bearer %s\1\1' % (
|
auth_string = 'user={}\1auth=Bearer {}\1\1'.format(
|
||||||
google_email_address,
|
google_email_address,
|
||||||
access_token
|
access_token
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class ImapTransport(EmailTransport):
|
||||||
safe_message_ids.append(uid)
|
safe_message_ids.append(uid)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"ValueError: %s working on %s" % (e, each_msg[0])
|
"ValueError: {} working on {}".format(e, each_msg[0])
|
||||||
)
|
)
|
||||||
pass
|
pass
|
||||||
return safe_message_ids
|
return safe_message_ids
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import six
|
|
||||||
|
|
||||||
from poplib import POP3, POP3_SSL
|
from poplib import POP3, POP3_SSL
|
||||||
|
|
||||||
from .base import EmailTransport, MessageParseError
|
from .base import EmailTransport, MessageParseError
|
||||||
|
|
@ -24,9 +22,7 @@ class Pop3Transport(EmailTransport):
|
||||||
self.server.pass_(password)
|
self.server.pass_(password)
|
||||||
|
|
||||||
def get_message_body(self, message_lines):
|
def get_message_body(self, message_lines):
|
||||||
if six.PY3:
|
return bytes('\r\n', 'ascii').join(message_lines)
|
||||||
return six.binary_type('\r\n', 'ascii').join(message_lines)
|
|
||||||
return '\r\n'.join(message_lines)
|
|
||||||
|
|
||||||
def get_message(self, condition=None):
|
def get_message(self, condition=None):
|
||||||
message_count = len(self.server.list()[1])
|
message_count = len(self.server.list()[1])
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ import email.header
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -75,11 +73,8 @@ def get_settings():
|
||||||
def convert_header_to_unicode(header):
|
def convert_header_to_unicode(header):
|
||||||
default_charset = get_settings()['default_charset']
|
default_charset = get_settings()['default_charset']
|
||||||
|
|
||||||
if six.PY2 and isinstance(header, six.text_type):
|
|
||||||
return header
|
|
||||||
|
|
||||||
def _decode(value, encoding):
|
def _decode(value, encoding):
|
||||||
if isinstance(value, six.text_type):
|
if isinstance(value, str):
|
||||||
return value
|
return value
|
||||||
if not encoding or encoding == 'unknown-8bit':
|
if not encoding or encoding == 'unknown-8bit':
|
||||||
encoding = default_charset
|
encoding = default_charset
|
||||||
|
|
@ -106,7 +101,7 @@ def get_body_from_message(message, maintype, subtype):
|
||||||
"""
|
"""
|
||||||
Fetchs the body message matching main/sub content type.
|
Fetchs the body message matching main/sub content type.
|
||||||
"""
|
"""
|
||||||
body = six.text_type('')
|
body = ''
|
||||||
for part in message.walk():
|
for part in message.walk():
|
||||||
if part.get('content-disposition', '').startswith('attachment;'):
|
if part.get('content-disposition', '').startswith('attachment;'):
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
25
docs/conf.py
25
docs/conf.py
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
#
|
||||||
# django-mailbox documentation build configuration file, created by
|
# django-mailbox documentation build configuration file, created by
|
||||||
# sphinx-quickstart on Tue Jan 22 20:29:12 2013.
|
# sphinx-quickstart on Tue Jan 22 20:29:12 2013.
|
||||||
|
|
@ -40,8 +39,8 @@ source_suffix = '.rst'
|
||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'django-mailbox'
|
project = 'django-mailbox'
|
||||||
copyright = u'2014, Adam Coddington'
|
copyright = '2014, Adam Coddington'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
|
@ -183,8 +182,8 @@ latex_elements = {
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('index', 'django-mailbox.tex', u'django-mailbox Documentation',
|
('index', 'django-mailbox.tex', 'django-mailbox Documentation',
|
||||||
u'Adam Coddington', 'manual'),
|
'Adam Coddington', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
|
@ -213,8 +212,8 @@ latex_documents = [
|
||||||
# One entry per manual page. List of tuples
|
# One entry per manual page. List of tuples
|
||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [
|
||||||
('index', 'django-mailbox', u'django-mailbox Documentation',
|
('index', 'django-mailbox', 'django-mailbox Documentation',
|
||||||
[u'Adam Coddington'], 1)
|
['Adam Coddington'], 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
|
|
@ -227,8 +226,8 @@ man_pages = [
|
||||||
# (source start file, target name, title, author,
|
# (source start file, target name, title, author,
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
('index', 'django-mailbox', u'django-mailbox Documentation',
|
('index', 'django-mailbox', 'django-mailbox Documentation',
|
||||||
u'Adam Coddington', 'django-mailbox', 'One line description of project.',
|
'Adam Coddington', 'django-mailbox', 'One line description of project.',
|
||||||
'Miscellaneous'),
|
'Miscellaneous'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -275,18 +274,18 @@ def process_docstring(app, what, name, obj, options, lines):
|
||||||
if help_text:
|
if help_text:
|
||||||
# Add the model field to the end of the docstring as a param
|
# Add the model field to the end of the docstring as a param
|
||||||
# using the help text as the description
|
# using the help text as the description
|
||||||
lines.append(u':param %s: %s' % (field.attname, help_text))
|
lines.append(':param {}: {}'.format(field.attname, help_text))
|
||||||
else:
|
else:
|
||||||
# Add the model field to the end of the docstring as a param
|
# Add the model field to the end of the docstring as a param
|
||||||
# using the verbose name as the description
|
# using the verbose name as the description
|
||||||
lines.append(u':param %s: %s' % (field.attname, verbose_name))
|
lines.append(':param {}: {}'.format(field.attname, verbose_name))
|
||||||
|
|
||||||
# Add the field's type to the docstring
|
# Add the field's type to the docstring
|
||||||
if isinstance(field, models.ForeignKey):
|
if isinstance(field, models.ForeignKey):
|
||||||
to = field.rel.to
|
to = field.rel.to
|
||||||
lines.append(u':type %s: %s to :class:`~%s.%s`' % (field.attname, type(field).__name__, to.__module__, to.__name__))
|
lines.append(':type {}: {} to :class:`~{}.{}`'.format(field.attname, type(field).__name__, to.__module__, to.__name__))
|
||||||
else:
|
else:
|
||||||
lines.append(u':type %s: %s' % (field.attname, type(field).__name__))
|
lines.append(':type {}: {}'.format(field.attname, type(field).__name__))
|
||||||
|
|
||||||
# Return the extended docstring
|
# Return the extended docstring
|
||||||
return lines
|
return lines
|
||||||
|
|
|
||||||
13
setup.py
13
setup.py
|
|
@ -27,24 +27,25 @@ setup(
|
||||||
extras_require={
|
extras_require={
|
||||||
'gmail-oauth2': gmail_oauth2_require
|
'gmail-oauth2': gmail_oauth2_require
|
||||||
},
|
},
|
||||||
|
python_requires=">=3",
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Framework :: Django',
|
'Framework :: Django',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Framework :: Django',
|
'Framework :: Django',
|
||||||
'Framework :: Django :: 1.7',
|
|
||||||
'Framework :: Django :: 1.8',
|
|
||||||
'Framework :: Django :: 1.9',
|
|
||||||
'Framework :: Django :: 1.10',
|
|
||||||
'Framework :: Django :: 1.11',
|
'Framework :: Django :: 1.11',
|
||||||
|
'Framework :: Django :: 2.0',
|
||||||
|
'Framework :: Django :: 2.1',
|
||||||
|
'Framework :: Django :: 2.2',
|
||||||
|
'Framework :: Django :: 3.0',
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2.6',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
'Topic :: Communications :: Email',
|
'Topic :: Communications :: Email',
|
||||||
'Topic :: Communications :: Email :: Post-Office',
|
'Topic :: Communications :: Email :: Post-Office',
|
||||||
'Topic :: Communications :: Email :: Post-Office :: IMAP',
|
'Topic :: Communications :: Email :: Post-Office :: IMAP',
|
||||||
|
|
|
||||||
28
tox.ini
28
tox.ini
|
|
@ -2,29 +2,25 @@
|
||||||
# sort by django version, next by python version
|
# sort by django version, next by python version
|
||||||
envlist=
|
envlist=
|
||||||
flake8
|
flake8
|
||||||
py{27,34}-django17
|
py{35,36}-django111
|
||||||
py{34,35}-django18
|
py{35,36}-django20
|
||||||
py{27,34,35}-django19
|
py{35,36,37}-django21
|
||||||
py{27,34,35}-django110
|
py{35,36,37}-django22
|
||||||
py{27,34,35,36}-django111
|
py{36,37,38}-django30
|
||||||
py{34,35,36}-django20
|
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
passenv=EMAIL_IMAP_SERVER EMAIL_ACCOUNT EMAIL_PASSWORD EMAIL_SMTP_SERVER
|
passenv=EMAIL_IMAP_SERVER EMAIL_ACCOUNT EMAIL_PASSWORD EMAIL_SMTP_SERVER
|
||||||
deps=
|
deps=
|
||||||
django17: django>=1.7,<1.8
|
django111: django==1.11.*
|
||||||
django18: django>=1.8,<1.9
|
django20: django==2.0.*
|
||||||
django19: django>=1.9,<1.10
|
django21: django==2.0.*
|
||||||
django110: django>=1.10,<1.11
|
django22: django==2.0.*
|
||||||
django111: django>=1.11,<2.0
|
django30: django==3.0b1
|
||||||
django20: django>=2.0,<2.1
|
|
||||||
-r{toxinidir}/test_requirements.txt
|
-r{toxinidir}/test_requirements.txt
|
||||||
sitepackages=False
|
sitepackages=False
|
||||||
commands=
|
commands=
|
||||||
django110: python {toxinidir}/manage.py makemigrations --check --dry-run
|
python {toxinidir}/manage.py makemigrations --check --dry-run
|
||||||
django111: python {toxinidir}/manage.py makemigrations --check --dry-run
|
python -Wd manage.py test -v2 {posargs}
|
||||||
django20: python {toxinidir}/manage.py makemigrations --check --dry-run
|
|
||||||
python manage.py test -v2 {posargs}
|
|
||||||
|
|
||||||
[testenv:flake8]
|
[testenv:flake8]
|
||||||
deps=flake8
|
deps=flake8
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue