1
0
Fork 1
mirror of https://github.com/coddingtonbear/django-mailbox.git synced 2026-07-09 22:38:19 +02:00

Merge pull request #215 from coddingtonbear/bump-django

Upgrade & drop Python & Django, upgrade TravisCI config
This commit is contained in:
Adam Dobrawy 2019-12-28 20:10:10 +01:00 committed by GitHub
commit 8b2493a32a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 228 additions and 349 deletions

View file

@ -1,42 +1,51 @@
version: ~> 1.0
os: linux
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:
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:
- secure: aswHU7pQroGM+GHoYlhXzzk2FYfqxXJORjqXPsbgoHAIu4Bssaj8+YAzIcdy3j9kSt4I8VBpjnn8H/wzQXki75JBZOosQrIeMK018+uR+ZMONBLqDYW/N7EJHLgZt9QXxQNKeZygrD4GN/Dc4gLHGvPQC/RfPuuHcnF0Liaahoo=
- secure: RZ6M6984P885GRoyx9n/WCCWGoFAzYpS8sZkXu3e/HK9oPXfaM2IEHjkq03jIC/FcWn/QMtFjOUBqQU94rnqdivFdFkeZHk1WUQgC0hztH3Qhh9zu2PNIrYUDpVD5dJqBpprWbSwFP8yNsJlP9A2RUubTlZblKHuaBhhiuNN+kU=
- secure: gsAAl/RaTodLJDHWOuHZWtooa9/psyXBONF7ElZOTki3WvH+KugtjuXn3pXBGbUhvGqd5qfgPqX7WQOFP9KTdkXBbkU20rCHLh3SV8V2vRkGFAFiGPBTFfSA83zFNMvmgEnTww4OzYsfs4wHTEyxBeQkggnB5bXEvqkFVrHBjuQ=
- secure: mMa7UUt+CQDB52fGM1T3oRL67OzQzRIc+BQCOqUEUhBV7p5g7Y1Hv6NTdVZTvK16x3DsP+5kFNd1v7rsTFw2qzP3hOxIv2BtMPuSzZdnN85Zd/nGwnztxzj/rqw7TMBaYvIdEZZbpRF/K0p0Xr6LJK2s9UkPXPUaLqly7kNi360=
- secure: aswHU7pQroGM+GHoYlhXzzk2FYfqxXJORjqXPsbgoHAIu4Bssaj8+YAzIcdy3j9kSt4I8VBpjnn8H/wzQXki75JBZOosQrIeMK018+uR+ZMONBLqDYW/N7EJHLgZt9QXxQNKeZygrD4GN/Dc4gLHGvPQC/RfPuuHcnF0Liaahoo=
- secure: RZ6M6984P885GRoyx9n/WCCWGoFAzYpS8sZkXu3e/HK9oPXfaM2IEHjkq03jIC/FcWn/QMtFjOUBqQU94rnqdivFdFkeZHk1WUQgC0hztH3Qhh9zu2PNIrYUDpVD5dJqBpprWbSwFP8yNsJlP9A2RUubTlZblKHuaBhhiuNN+kU=
- secure: gsAAl/RaTodLJDHWOuHZWtooa9/psyXBONF7ElZOTki3WvH+KugtjuXn3pXBGbUhvGqd5qfgPqX7WQOFP9KTdkXBbkU20rCHLh3SV8V2vRkGFAFiGPBTFfSA83zFNMvmgEnTww4OzYsfs4wHTEyxBeQkggnB5bXEvqkFVrHBjuQ=
- secure: mMa7UUt+CQDB52fGM1T3oRL67OzQzRIc+BQCOqUEUhBV7p5g7Y1Hv6NTdVZTvK16x3DsP+5kFNd1v7rsTFw2qzP3hOxIv2BtMPuSzZdnN85Zd/nGwnztxzj/rqw7TMBaYvIdEZZbpRF/K0p0Xr6LJK2s9UkPXPUaLqly7kNi360=
install:
- pip install tox
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
sudo: false

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Model configuration in application ``django_mailbox`` for administration
@ -10,7 +9,7 @@ import logging
from django.conf import settings
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.signals import message_received
@ -74,7 +73,7 @@ class MessageAdmin(admin.ModelAdmin):
def envelope_headers(self, msg):
email = msg.get_email_object()
return '\n'.join(
[('%s: %s' % (h, v)) for h, v in email.items()]
[('{}: {}'.format(h, v)) for h, v in email.items()]
)
inlines = [

View file

@ -1,5 +1,5 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class MailBoxConfig(AppConfig):

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django_mailbox.utils

View file

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.8 on 2016-08-15 22:39
from __future__ import unicode_literals
from django.db import migrations, models

View file

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-04-21 00:26
from __future__ import unicode_literals
from django.db import migrations

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Models declaration for application ``django_mailbox``.
@ -8,7 +7,9 @@ import gzip
from email.encoders import encode_base64
from email.message import Message as EmailMessage
from email.utils import formatdate, parseaddr
from urllib.parse import parse_qs, unquote, urlparse
from quopri import encode as encode_quopri
from io import BytesIO
import base64
import email
import logging
@ -18,17 +19,13 @@ import sys
import uuid
from tempfile import NamedTemporaryFile
import six
from six.moves.urllib.parse import parse_qs, unquote, urlparse
import django
from django.conf import settings as django_settings
from django.core.files.base import ContentFile, File
from django.core.mail.message import make_msgid
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.encoding import python_2_unicode_compatible
from django_mailbox import utils
from django_mailbox.signals import message_received
@ -41,20 +38,19 @@ logger = logging.getLogger(__name__)
class ActiveMailboxManager(models.Manager):
def get_queryset(self):
return super(ActiveMailboxManager, self).get_queryset().filter(
return super().get_queryset().filter(
active=True,
)
@python_2_unicode_compatible
class Mailbox(models.Model):
name = models.CharField(
_(u'Name'),
_('Name'),
max_length=255,
)
uri = models.CharField(
_(u'URI'),
_('URI'),
max_length=255,
help_text=(_(
"Example: imap+ssl://myusername:mypassword@someserver <br />"
@ -72,7 +68,7 @@ class Mailbox(models.Model):
)
from_email = models.CharField(
_(u'From email'),
_('From email'),
max_length=255,
help_text=(_(
"Example: MailBot &lt;mailbot@yourdomain.com&gt;<br />"
@ -89,7 +85,7 @@ class Mailbox(models.Model):
)
active = models.BooleanField(
_(u'Active'),
_('Active'),
help_text=(_(
"Check this e-mail inbox for new e-mail messages during polling "
"cycles. This checkbox does not have an effect upon whether "
@ -102,7 +98,7 @@ class Mailbox(models.Model):
)
last_polling = models.DateTimeField(
_(u"Last polling"),
_("Last polling"),
help_text=(_("The time of last successful polling for messages."
"It is blank for new mailboxes and is not set for "
"mailboxes that only receive messages via a pipe.")),
@ -294,7 +290,7 @@ class Mailbox(models.Model):
attachment.document.save(
uuid.uuid4().hex + extension,
ContentFile(
six.BytesIO(
BytesIO(
msg.get_payload(decode=True)
).getvalue()
)
@ -392,7 +388,7 @@ class Mailbox(models.Model):
with gzip.GzipFile(fileobj=fp_tmp, mode="w") as fp:
fp.write(message.as_string().encode('utf-8'))
msg.eml.save(
"%s.eml.gz" % (uuid.uuid4(), ),
"{}.eml.gz".format(uuid.uuid4()),
File(fp_tmp),
save=False
)
@ -430,41 +426,40 @@ class Mailbox(models.Model):
class IncomingMessageManager(models.Manager):
def get_queryset(self):
return super(IncomingMessageManager, self).get_queryset().filter(
return super().get_queryset().filter(
outgoing=False,
)
class OutgoingMessageManager(models.Manager):
def get_queryset(self):
return super(OutgoingMessageManager, self).get_queryset().filter(
return super().get_queryset().filter(
outgoing=True,
)
class UnreadMessageManager(models.Manager):
def get_queryset(self):
return super(UnreadMessageManager, self).get_queryset().filter(
return super().get_queryset().filter(
read=None
)
@python_2_unicode_compatible
class Message(models.Model):
mailbox = models.ForeignKey(
Mailbox,
related_name='messages',
verbose_name=_(u'Mailbox'),
verbose_name=_('Mailbox'),
on_delete=models.CASCADE
)
subject = models.CharField(
_(u'Subject'),
_('Subject'),
max_length=255
)
message_id = models.CharField(
_(u'Message ID'),
_('Message ID'),
max_length=255
)
@ -473,7 +468,7 @@ class Message(models.Model):
related_name='replies',
blank=True,
null=True,
verbose_name=_(u'In reply to'),
verbose_name=_('In reply to'),
on_delete=models.CASCADE
)
@ -483,21 +478,21 @@ class Message(models.Model):
)
to_header = models.TextField(
_(u'To header'),
_('To header'),
)
outgoing = models.BooleanField(
_(u'Outgoing'),
_('Outgoing'),
default=False,
blank=True,
)
body = models.TextField(
_(u'Body'),
_('Body'),
)
encoded = models.BooleanField(
_(u'Encoded'),
_('Encoded'),
default=False,
help_text=_('True if the e-mail body is Base64 encoded'),
)
@ -508,17 +503,17 @@ class Message(models.Model):
)
read = models.DateTimeField(
_(u'Read'),
_('Read'),
default=None,
blank=True,
null=True,
)
eml = models.FileField(
_(u'Raw message contents'),
_('Raw message contents'),
null=True,
upload_to="messages",
help_text=_(u'Original full content of message')
help_text=_('Original full content of message')
)
objects = models.Manager()
unread_messages = UnreadMessageManager()
@ -634,9 +629,9 @@ class Message(models.Model):
if encoding and encoding.lower() == 'quoted-printable':
# Cannot use `email.encoders.encode_quopri due to
# bug 14360: http://bugs.python.org/issue14360
output = six.BytesIO()
output = BytesIO()
encode_quopri(
six.BytesIO(
BytesIO(
attachment.document.read()
),
output,
@ -688,10 +683,8 @@ class Message(models.Model):
no fields existed for storing arbitrary bytes.
"""
if six.PY3:
body = body.encode('utf-8')
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):
"""Returns an `email.message.Message` instance representing the
@ -722,10 +715,7 @@ class Message(models.Model):
self.eml.close()
else:
body = self.get_body()
if six.PY3:
flat = email.message_from_bytes(body)
else:
flat = email.message_from_string(body)
flat = email.message_from_bytes(body)
self._email_object = self._rehydrate(flat)
return self._email_object
@ -734,7 +724,7 @@ class Message(models.Model):
for attachment in self.attachments.all():
# This attachment is attached only to this message.
attachment.delete()
return super(Message, self).delete(*args, **kwargs)
return super().delete(*args, **kwargs)
def __str__(self):
return self.subject
@ -744,7 +734,6 @@ class Message(models.Model):
verbose_name_plural = _('E-mail messages')
@python_2_unicode_compatible
class MessageAttachment(models.Model):
message = models.ForeignKey(
Message,
@ -756,30 +745,25 @@ class MessageAttachment(models.Model):
)
headers = models.TextField(
_(u'Headers'),
_('Headers'),
null=True,
blank=True,
)
document = models.FileField(
_(u'Document'),
_('Document'),
upload_to=utils.get_attachment_save_path,
)
def delete(self, *args, **kwargs):
"""Deletes the attachment."""
self.document.delete()
return super(MessageAttachment, self).delete(*args, **kwargs)
return super().delete(*args, **kwargs)
def _get_rehydrated_headers(self):
headers = self.headers
if headers is None:
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)
def _set_dehydrated_headers(self, email_object):
@ -798,7 +782,7 @@ class MessageAttachment(models.Model):
def get_filename(self):
"""Returns the original filename of this attachment."""
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)
if result is None:
return file_name

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
import email
from south.db import db

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
@ -9,33 +8,33 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# 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']),
keep_default=False)
def backwards(self, orm):
# Deleting field 'MessageAttachment.message'
db.delete_column(u'django_mailbox_messageattachment', 'message_id')
db.delete_column('django_mailbox_messageattachment', 'message_id')
models = {
u'django_mailbox.mailbox': {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
'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'},
'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', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'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']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'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': "orm['django_mailbox.Message']"}),
'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'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
u'django_mailbox.messageattachment': {
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
u'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']"})
'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': "orm['django_mailbox.Message']"})
}
}

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
@ -21,22 +20,22 @@ class Migration(SchemaMigration):
)
models = {
u'django_mailbox.mailbox': {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
'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'},
'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', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'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']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'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': "orm['django_mailbox.Message']"}),
'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'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
u'django_mailbox.messageattachment': {
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
u'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']"})
'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': "orm['django_mailbox.Message']"})
}
}

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
@ -12,40 +11,40 @@ class Migration(SchemaMigration):
db.delete_table('django_mailbox_message_attachments')
# 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),
keep_default=False)
def backwards(self, orm):
# 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)),
('message', models.ForeignKey(orm[u'django_mailbox.message'], null=False)),
('messageattachment', models.ForeignKey(orm[u'django_mailbox.messageattachment'], null=False))
('message', models.ForeignKey(orm['django_mailbox.message'], 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'
db.delete_column(u'django_mailbox_messageattachment', 'headers')
db.delete_column('django_mailbox_messageattachment', 'headers')
models = {
u'django_mailbox.mailbox': {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
'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'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'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']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'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': "orm['django_mailbox.Message']"}),
'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'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
u'django_mailbox.messageattachment': {
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
u'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']"})
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
}
}

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
@ -9,33 +8,33 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# 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),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Message.encoded'
db.delete_column(u'django_mailbox_message', 'encoded')
db.delete_column('django_mailbox_message', 'encoded')
models = {
u'django_mailbox.mailbox': {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
'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'},
'body': ('django.db.models.fields.TextField', [], {}),
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'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']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'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': "orm['django_mailbox.Message']"}),
'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'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
u'django_mailbox.messageattachment': {
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
u'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']"})
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
}
}

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
@ -9,34 +8,34 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# 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),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Message.eml'
db.delete_column(u'django_mailbox_message', 'eml')
db.delete_column('django_mailbox_message', 'eml')
models = {
u'django_mailbox.mailbox': {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
'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'},
'body': ('django.db.models.fields.TextField', [], {}),
'eml': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'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']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'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': "orm['django_mailbox.Message']"}),
'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'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
u'django_mailbox.messageattachment': {
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'headers': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
u'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']"})
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attachments'", 'null': 'True', 'to': "orm['django_mailbox.Message']"})
}
}

View file

@ -2,8 +2,6 @@ import email
import os.path
import time
import six
from django.conf import settings
from django.test import TestCase
@ -57,7 +55,7 @@ class EmailMessageTestCase(TestCase):
settings.EMAIL_HOST_USER = self.test_account
settings.EMAIL_HOST_PASSWORD = self.test_password
settings.EMAIL_USE_TLS = True
super(EmailMessageTestCase, self).setUp()
super().setUp()
def _get_new_messages(self, mailbox, condition=None):
start_time = time.time()
@ -70,8 +68,7 @@ class EmailMessageTestCase(TestCase):
# check if generator contains at least one element
message = next(messages)
yield message
for message in messages:
yield message
yield from messages
return
except StopIteration:
@ -92,10 +89,7 @@ class EmailMessageTestCase(TestCase):
def _get_email_object(self, name):
copy = self._get_email_as_text(name)
if six.PY3:
return email.message_from_bytes(copy)
else:
return email.message_from_string(copy)
return email.message_from_bytes(copy)
def _headers_identical(self, left, right, header=None):
""" Check if headers are (close enough to) identical.
@ -131,7 +125,7 @@ class EmailMessageTestCase(TestCase):
raise AssertionError("Extra header '%s'" % key)
if not self._headers_identical(right[key], value, header=key):
raise AssertionError(
"Header '%s' unequal:\n%s\n%s" % (
"Header '{}' unequal:\n{}\n{}".format(
key,
repr(value),
repr(right[key]),
@ -144,7 +138,7 @@ class EmailMessageTestCase(TestCase):
raise AssertionError("Extra header '%s'" % key)
if not self._headers_identical(left[key], value, header=key):
raise AssertionError(
"Header '%s' unequal:\n%s\n%s" % (
"Header '{}' unequal:\n{}\n{}".format(
key,
repr(value),
repr(right[key]),
@ -175,7 +169,7 @@ class EmailMessageTestCase(TestCase):
def _raise_mismatched(self, left, right):
raise AssertionError(
"Message payloads do not match:\n%s\n%s" % (
"Message payloads do not match:\n{}\n{}".format(
left.as_string(),
right.as_string()
)
@ -183,7 +177,7 @@ class EmailMessageTestCase(TestCase):
def assertEqual(self, left, right): # noqa: N802
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)
def tearDown(self):
@ -194,4 +188,4 @@ class EmailMessageTestCase(TestCase):
models.TEXT_STORED_MIMETYPES = self._TEXT_STORED_MIMETYPES
self.mailbox.delete()
super(EmailMessageTestCase, self).tearDown()
super().tearDown()

View file

@ -1,7 +1,6 @@
import os
import uuid
from six.moves.urllib import parse
from urllib import parse
from django.core.mail import EmailMultiAlternatives
@ -14,7 +13,7 @@ __all__ = ['TestImap']
class TestImap(EmailMessageTestCase):
def setUp(self):
super(TestImap, self).setUp()
super().setUp()
self.test_imap_server = (
os.environ.get('EMAIL_IMAP_SERVER')

View file

@ -1,6 +1,6 @@
import copy
import mock
from unittest import mock
from django_mailbox import models, utils
from django_mailbox.models import Message

View file

@ -3,8 +3,7 @@ import os.path
import sys
import copy
import mock
import six
from unittest import mock
from django_mailbox.models import Mailbox, Message
from django_mailbox.utils import convert_header_to_unicode
@ -54,18 +53,18 @@ class TestProcessEmail(EmailMessageTestCase):
attachments = msg.attachments.order_by('pk').all()
self.assertEqual(
u'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
u'\u043e\u0436\u0435\u043d\u0438\u0439 HSE Career Fair 8 \u0430'
u'\u043f\u0440\u0435\u043b\u044f 2016.pdf',
'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
'\u043e\u0436\u0435\u043d\u0438\u0439 HSE Career Fair 8 \u0430'
'\u043f\u0440\u0435\u043b\u044f 2016.pdf',
attachments[0].get_filename()
)
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()
)
self.assertEqual(
u'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
u'\u043e\u0436\u0435\u043d\u0438\u0439 2016.pptx',
'\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043b'
'\u043e\u0436\u0435\u043d\u0438\u0439 2016.pptx',
attachments[2].get_filename()
)
@ -89,33 +88,6 @@ class TestProcessEmail(EmailMessageTestCase):
'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):
""" Ensure that we properly handle UTF-8 encoded attachment
@ -138,13 +110,13 @@ class TestProcessEmail(EmailMessageTestCase):
attachment = msg.attachments.all()[0]
self.assertEqual(
attachment.get_filename(),
u'pi\u0142kochwyty.jpg'
'pi\u0142kochwyty.jpg'
)
attachment = msg.attachments.all()[1]
self.assertEqual(
attachment.get_filename(),
u'odpowied\u017a Burmistrza.jpg'
'odpowied\u017a Burmistrza.jpg'
)
def test_message_get_text_body(self):
@ -187,7 +159,7 @@ class TestProcessEmail(EmailMessageTestCase):
'messages/generic_message.eml'
)
) as f:
unicode_body = six.u(f.read())
unicode_body = f.read()
message = Message()
message.body = unicode_body
@ -281,10 +253,8 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(email_object)
expected_text = six.u(
'This message contains funny UTF16 characters like this one: '
'"\xc2\xa0" and this one "\xe2\x9c\xbf".'
)
expected_text = 'This message contains funny UTF16 characters ' + \
'like this one: "\xc2\xa0" and this one "\xe2\x9c\xbf".'
actual_text = msg.text
self.assertEqual(
@ -320,14 +290,12 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(email_object)
actual_text = msg.text
expected_body = six.u(
'\u042d\u0442\u043e '
'\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 '
'\u0438\u043c\u0435\u0435\u0442 '
'\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d'
'\u0443\u044e '
expected_body = '\u042d\u0442\u043e ' + \
'\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 ' + \
'\u0438\u043c\u0435\u0435\u0442 ' + \
'\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d' + \
'\u0443\u044e ' + \
'\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430.'
)
self.assertEqual(
actual_text,
@ -341,23 +309,15 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(email_object)
expected_subject = six.u(
'\u00D3\u00E7\u00ED\u00E0\u00E9 \u00EA\u00E0\u00EA '
'\u00E7\u00E0\u00F0\u00E0\u00E1\u00E0\u00F2\u00FB\u00E2'
'\u00E0\u00F2\u00FC \u00EE\u00F2 1000$ \u00E2 '
expected_subject = '\u00D3\u00E7\u00ED\u00E0\u00E9 \u00EA\u00E0\u00EA ' + \
'\u00E7\u00E0\u00F0\u00E0\u00E1\u00E0\u00F2\u00FB\u00E2' + \
'\u00E0\u00F2\u00FC \u00EE\u00F2 1000$ \u00E2 ' + \
'\u00ED\u00E5\u00E4\u00E5\u00EB\u00FE!'
)
actual_subject = msg.subject
self.assertEqual(actual_subject, expected_subject)
if sys.version_info >= (3, 3):
# 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>')
expected_from = 'test test <mr.test32@mail.ru>'
actual_from = msg.from_header
self.assertEqual(expected_from, actual_from)
def test_message_reply(self):
@ -426,15 +386,15 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(message)
actual_email_object = msg.get_email_object()
self.assertNotEquals(msg.eml, None)
self.assertTrue(msg.eml.name.endswith('.eml'))
with open(msg.eml.name, 'rb') as f:
self.assertEqual(f.read(),
self._get_email_as_text('generic_message.eml'))
self.assertEqual(
f.read(),
self._get_email_as_text('generic_message.eml')
)
def test_message_saving_ignored(self):
message = self._get_email_object('generic_message.eml')

View file

@ -1,5 +1,5 @@
from distutils.version import LooseVersion
import mock
from unittest import mock
from django.core.management import call_command, CommandError
from django.test import TestCase

View file

@ -1,5 +1,4 @@
import mock
import six
from unittest import mock
from django.test.utils import override_settings
@ -9,24 +8,22 @@ from django_mailbox.transports import ImapTransport, Pop3Transport
FAKE_UID_SEARCH_ANSWER = (
'OK',
[
six.b(
'18 19 20 21 22 23 24 25 26 27 28 29 '
'30 31 32 33 34 35 36 37 38 39 40 41 42 43 44'
)
b'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'
]
)
FAKE_UID_FETCH_SIZES = (
'OK',
[
six.b('1 (UID 18 RFC822.SIZE 58070000000)'),
six.b('2 (UID 19 RFC822.SIZE 2593)')
b'1 (UID 18 RFC822.SIZE 58070000000)',
b'2 (UID 19 RFC822.SIZE 2593)'
]
)
FAKE_UID_FETCH_MSG = (
'OK',
[
(
six.b('1 (UID 18 RFC822 {5807}'),
b'1 (UID 18 RFC822 {5807}',
get_email_as_text('generic_message.eml')
),
]
@ -34,13 +31,13 @@ FAKE_UID_FETCH_MSG = (
FAKE_UID_COPY_MSG = (
'OK',
[
six.b('[COPYUID 1 2 2] (Success)')
b'[COPYUID 1 2 2] (Success)'
]
)
FAKE_LIST_ARCHIVE_FOLDERS_ANSWERS = (
'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.uid = imap_server_uid_method
self.imap_server.list = imap_server_list_method
super(IMAPTestCase, self).setUp()
super().setUp()
class TestImapTransport(IMAPTestCase):
def setUp(self):
super(TestImapTransport, self).setUp()
super().setUp()
self.arbitrary_hostname = 'one.two.three'
self.arbitrary_port = 100
self.ssl = False
@ -92,7 +89,7 @@ class TestImapTransport(IMAPTestCase):
class TestImapArchivedTransport(TestImapTransport):
def setUp(self):
super(TestImapArchivedTransport, self).setUp()
super().setUp()
self.archive = 'Archive'
self.transport = ImapTransport(
self.arbitrary_hostname,
@ -107,7 +104,7 @@ class TestMaxSizeImapTransport(TestImapTransport):
@override_settings(DJANGO_MAILBOX_MAX_MESSAGE_SIZE=5807)
def setUp(self):
super(TestMaxSizeImapTransport, self).setUp()
super().setUp()
self.transport = ImapTransport(
self.arbitrary_hostname,
@ -142,7 +139,7 @@ class TestPop3Transport(EmailMessageTestCase):
self.ssl
)
self.transport.server = None
super(TestPop3Transport, self).setUp()
super().setUp()
def test_get_email_message(self):
with mock.patch.object(self.transport, 'server') as server:

View file

@ -1,19 +1,11 @@
import email
import six
# Do *not* remove this, we need to use this in subclasses of EmailTransport
if six.PY3:
from email.errors import MessageParseError # noqa: F401
else:
from email.Errors import MessageParseError # noqa: F401
from email.errors import MessageParseError # noqa: F401
class EmailTransport(object):
class EmailTransport:
def get_email_from_bytes(self, contents):
if six.PY3:
message = email.message_from_bytes(contents)
else:
message = email.message_from_string(contents)
message = email.message_from_bytes(contents)
return message

View file

@ -1,5 +1,4 @@
import sys
import six
from .base import EmailTransport
@ -9,13 +8,8 @@ class GenericFileMailbox(EmailTransport):
_path = None
def __init__(self, path):
super(GenericFileMailbox, self).__init__()
if six.PY2:
self._path = path.encode(
sys.getfilesystemencoding()
)
else:
self._path = path
super().__init__()
self._path = path
def get_instance(self):
return self._variant(self._path)

View file

@ -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,
access_token
)

View file

@ -88,7 +88,7 @@ class ImapTransport(EmailTransport):
safe_message_ids.append(uid)
except ValueError as e:
logger.warning(
"ValueError: %s working on %s" % (e, each_msg[0])
"ValueError: {} working on {}".format(e, each_msg[0])
)
pass
return safe_message_ids

View file

@ -1,5 +1,3 @@
import six
from poplib import POP3, POP3_SSL
from .base import EmailTransport, MessageParseError
@ -24,9 +22,7 @@ class Pop3Transport(EmailTransport):
self.server.pass_(password)
def get_message_body(self, message_lines):
if six.PY3:
return six.binary_type('\r\n', 'ascii').join(message_lines)
return '\r\n'.join(message_lines)
return bytes('\r\n', 'ascii').join(message_lines)
def get_message(self, condition=None):
message_count = len(self.server.list()[1])

View file

@ -3,8 +3,6 @@ import email.header
import logging
import os
import six
from django.conf import settings
@ -75,11 +73,8 @@ def get_settings():
def convert_header_to_unicode(header):
default_charset = get_settings()['default_charset']
if six.PY2 and isinstance(header, six.text_type):
return header
def _decode(value, encoding):
if isinstance(value, six.text_type):
if isinstance(value, str):
return value
if not encoding or encoding == 'unknown-8bit':
encoding = default_charset
@ -106,7 +101,7 @@ def get_body_from_message(message, maintype, subtype):
"""
Fetchs the body message matching main/sub content type.
"""
body = six.text_type('')
body = ''
for part in message.walk():
if part.get('content-disposition', '').startswith('attachment;'):
continue

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# django-mailbox documentation build configuration file, created by
# sphinx-quickstart on Tue Jan 22 20:29:12 2013.
@ -40,8 +39,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'django-mailbox'
copyright = u'2014, Adam Coddington'
project = 'django-mailbox'
copyright = '2014, Adam Coddington'
# The version info for the project you're documenting, acts as replacement for
# |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
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'django-mailbox.tex', u'django-mailbox Documentation',
u'Adam Coddington', 'manual'),
('index', 'django-mailbox.tex', 'django-mailbox Documentation',
'Adam Coddington', 'manual'),
]
# 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
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'django-mailbox', u'django-mailbox Documentation',
[u'Adam Coddington'], 1)
('index', 'django-mailbox', 'django-mailbox Documentation',
['Adam Coddington'], 1)
]
# If true, show URL addresses after external links.
@ -227,8 +226,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'django-mailbox', u'django-mailbox Documentation',
u'Adam Coddington', 'django-mailbox', 'One line description of project.',
('index', 'django-mailbox', 'django-mailbox Documentation',
'Adam Coddington', 'django-mailbox', 'One line description of project.',
'Miscellaneous'),
]
@ -275,18 +274,18 @@ def process_docstring(app, what, name, obj, options, lines):
if help_text:
# Add the model field to the end of the docstring as a param
# 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:
# Add the model field to the end of the docstring as a param
# 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
if isinstance(field, models.ForeignKey):
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:
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 lines

View file

@ -27,24 +27,25 @@ setup(
extras_require={
'gmail-oauth2': gmail_oauth2_require
},
python_requires=">=3",
classifiers=[
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Framework :: Django',
'Framework :: Django :: 1.7',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10',
'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 :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Communications :: Email',
'Topic :: Communications :: Email :: Post-Office',
'Topic :: Communications :: Email :: Post-Office :: IMAP',

28
tox.ini
View file

@ -2,29 +2,25 @@
# sort by django version, next by python version
envlist=
flake8
py{27,34}-django17
py{34,35}-django18
py{27,34,35}-django19
py{27,34,35}-django110
py{27,34,35,36}-django111
py{34,35,36}-django20
py{35,36}-django111
py{35,36}-django20
py{35,36,37}-django21
py{35,36,37}-django22
py{36,37,38}-django30
[testenv]
passenv=EMAIL_IMAP_SERVER EMAIL_ACCOUNT EMAIL_PASSWORD EMAIL_SMTP_SERVER
deps=
django17: django>=1.7,<1.8
django18: django>=1.8,<1.9
django19: django>=1.9,<1.10
django110: django>=1.10,<1.11
django111: django>=1.11,<2.0
django20: django>=2.0,<2.1
django111: django==1.11.*
django20: django==2.0.*
django21: django==2.0.*
django22: django==2.0.*
django30: django==3.0b1
-r{toxinidir}/test_requirements.txt
sitepackages=False
commands=
django110: python {toxinidir}/manage.py makemigrations --check --dry-run
django111: python {toxinidir}/manage.py makemigrations --check --dry-run
django20: python {toxinidir}/manage.py makemigrations --check --dry-run
python manage.py test -v2 {posargs}
python {toxinidir}/manage.py makemigrations --check --dry-run
python -Wd manage.py test -v2 {posargs}
[testenv:flake8]
deps=flake8