1
0
Fork 0

Merge branch 'coddingtonbear:master' into master

This commit is contained in:
Pietro 2023-12-23 21:03:09 +01:00 committed by GitHub
commit d04d4d56da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 468 additions and 1037 deletions

View file

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 4.8.2 current_version = 4.9.0
commit = True commit = True
tag = True tag = True
tag_name = {new_version} tag_name = {new_version}

40
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: CI
on:
push:
branches:
- master
pull_request:
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
tests:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-22.04
strategy:
matrix:
python-version:
- '3.8'
- '3.9'
- '3.10'
- '3.11'
- '3.12'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade 'tox>=4.0.0rc3'
- name: Run tox targets for ${{ matrix.python-version }}
run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .)

1
.gitignore vendored
View file

@ -14,3 +14,4 @@ dummy_project/*
messages messages
*.sqlite3 *.sqlite3
.idea/ .idea/
venv/

View file

@ -1,46 +0,0 @@
version: ~> 1.0
os: linux
language: python
jobs:
- env: TOX_ENV=docs
python: 3.8
# 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 INTEGRATION=1
python: 3.8
install:
- pip install tox
script:
- tox -e $TOX_ENV

View file

@ -1,6 +1,15 @@
Changelog Changelog
========= =========
4.9.0
-----
* Add Django 3.2, 4.0, 4.1, 4.2, 5.0 support
* Remove support for deprecated Django versions
* Add Python 3.8, 3.9, 3.10, 3.11, 3.12 support
* Remove support for deprecated Python versions
4.8.1 4.8.1
----- -----

View file

@ -1,5 +1,4 @@
include *.rst include *.rst
include .travis.yml
include MANIFEST include MANIFEST
recursive-include django_mailbox *.eml recursive-include django_mailbox *.eml
recursive-include docs *.py recursive-include docs *.py

View file

@ -1,3 +1,3 @@
__version__ = '4.8.2' __version__ = '4.9.0'
default_app_config = 'django_mailbox.apps.MailBoxConfig' default_app_config = 'django_mailbox.apps.MailBoxConfig'

View file

@ -5,3 +5,5 @@ from django.utils.translation import gettext_lazy as _
class MailBoxConfig(AppConfig): class MailBoxConfig(AppConfig):
name = 'django_mailbox' name = 'django_mailbox'
verbose_name = _("Mail Box") verbose_name = _("Mail Box")
default_auto_field = "django.db.models.AutoField"

Binary file not shown.

View file

@ -0,0 +1,190 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-12 18:01+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: django_mailbox/admin.py:26
msgid "Get new mail"
msgstr "Изтегли новата поща"
#: django_mailbox/admin.py:36
msgid "Re-send message received signal"
msgstr "Изпрати отново сигнал за прието съобщение"
#: django_mailbox/admin.py:66
msgid "Attachment count"
msgstr "Брой приложения"
#: django_mailbox/apps.py:7
msgid "Mail Box"
msgstr "Пощенска кутия"
#: django_mailbox/models.py:62
msgid "Name"
msgstr "Име"
#: django_mailbox/models.py:67
msgid "URI"
msgstr "URI"
#: django_mailbox/models.py:70
msgid ""
"Example: imap+ssl://myusername:mypassword@someserver <br /><br />Internet "
"transports include 'imap' and 'pop3'; common local file transports include "
"'maildir', 'mbox', and less commonly 'babyl', 'mh', and 'mmdf'. <br /><br /"
">Be sure to urlencode your username and password should they contain illegal "
"characters (like @, :, etc)."
msgstr ""
"Пример: imap+ssl://myusername:mypassword@someserver <br /><br />Интернет "
"протоколите за обмен на поща включват 'imap' and 'pop3'; стандартните протоколи за обмен чрез локални файлове включват "
"'maildir', 'mbox' и по-рядко 'babyl', 'mh', and 'mmdf'. <br /><br /"
">Моля, не забравяйте да използвате urlencode за вашето потребителско име и парола, ако съдържат забранени "
"символи (като @, : и т.н.)."
#: django_mailbox/models.py:85
msgid "From email"
msgstr "От имейл адрес"
#: django_mailbox/models.py:88
msgid ""
"Example: MailBot &lt;mailbot@yourdomain.com&gt;<br />'From' header to set "
"for outgoing email.<br /><br />If you do not use this e-mail inbox for "
"outgoing mail, this setting is unnecessary.<br />If you send e-mail without "
"setting this, your 'From' header will'be set to match the setting "
"`DEFAULT_FROM_EMAIL`."
msgstr ""
"Example: MailBot &lt;mailbot@yourdomain.com&gt;<br />'От' хедър за изходяща "
"поща.<br /><br />Ако не използвате тази пощенска кутия за "
"изходяща поща, тази настройка не е необходима.<br />Ако изпращате поща без "
"да сте настроили горното, вашият 'От' хедър ще бъде настроен да отговаря на настройката "
"`DEFAULT_FROM_EMAIL`."
#: django_mailbox/models.py:102
msgid "Active"
msgstr "Активна"
#: django_mailbox/models.py:104
msgid ""
"Check this e-mail inbox for new e-mail messages during polling cycles. This "
"checkbox does not have an effect upon whether mail is collected here when "
"this mailbox receives mail from a pipe, and does not affect whether e-mail "
"messages can be dispatched from this mailbox. "
msgstr ""
"Проверявай тази пощенска кутия за нови съобщения, когато се извършва събиране на поща. Тази "
"настройка не се прилага, когато пощата се събира чрез "
"pipe и няма ефект върху това дали могат да се изпращат "
"съобщения чрез тази пощенска кутия. "
#: django_mailbox/models.py:115
msgid "Last polling"
msgstr "Последна проверка"
#: django_mailbox/models.py:116
msgid ""
"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."
msgstr ""
"Времето на последната успешна проверка за нови съобщения. Празно за нови "
"пощенски кутии и не се обновява за пощенски кутии, които събират поща само чрез pipe."
#: django_mailbox/models.py:490 django_mailbox/models.py:519
msgid "Mailbox"
msgstr "Пощенска кутия"
#: django_mailbox/models.py:491
msgid "Mailboxes"
msgstr "Пощенски кутии"
#: django_mailbox/models.py:524
msgid "Subject"
msgstr "Тема"
#: django_mailbox/models.py:529
msgid "Message ID"
msgstr "ID на съобщението"
#: django_mailbox/models.py:538
msgid "In reply to"
msgstr "В отговор на"
#: django_mailbox/models.py:543
msgid "From header"
msgstr "От хедър"
#: django_mailbox/models.py:548
msgid "To header"
msgstr "До хедър"
#: django_mailbox/models.py:552
msgid "Outgoing"
msgstr "Изходяща"
#: django_mailbox/models.py:558
msgid "Body"
msgstr "Тяло"
#: django_mailbox/models.py:562
msgid "Encoded"
msgstr "Енкоднато"
#: django_mailbox/models.py:564
msgid "True if the e-mail body is Base64 encoded"
msgstr "Да ако тялото на съобщението е енкоднато в Base64"
#: django_mailbox/models.py:568
msgid "Processed"
msgstr "Обработено"
#: django_mailbox/models.py:573
msgid "Read"
msgstr "Прочетено"
#: django_mailbox/models.py:580
msgid "Raw message contents"
msgstr "Сурово съдържание на съобщението"
#: django_mailbox/models.py:583
msgid "Original full content of message"
msgstr "Оригинално пълно съдържание на съобщението"
#: django_mailbox/models.py:800
msgid "E-mail message"
msgstr "Имейл съобщение"
#: django_mailbox/models.py:801
msgid "E-mail messages"
msgstr "Имейл съобщения"
#: django_mailbox/models.py:810
msgid "Message"
msgstr "Съобщение"
#: django_mailbox/models.py:815
msgid "Headers"
msgstr "Хедъри"
#: django_mailbox/models.py:821
msgid "Document"
msgstr "Документ"
#: django_mailbox/models.py:873
msgid "Message attachment"
msgstr "Приложение към съобщението"
#: django_mailbox/models.py:874
msgid "Message attachments"
msgstr "Приложения към съобщението"

View file

@ -0,0 +1,18 @@
# Generated by Django 3.2.23 on 2023-12-16 23:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('django_mailbox', '0008_auto_20190219_1553'),
]
operations = [
migrations.AlterField(
model_name='message',
name='eml',
field=models.FileField(blank=True, help_text='Original full content of message', null=True, upload_to='messages', verbose_name='Raw message contents'),
),
]

View file

@ -15,7 +15,6 @@ import email
import logging import logging
import mimetypes import mimetypes
import os.path import os.path
import sys
import uuid import uuid
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
@ -42,7 +41,7 @@ class MailboxQuerySet(models.QuerySet):
for mailbox in self.all(): for mailbox in self.all():
logger.debug('Receiving mail for %s' % mailbox) logger.debug('Receiving mail for %s' % mailbox)
count += sum(1 for i in mailbox.get_new_mail()) count += sum(1 for i in mailbox.get_new_mail())
logger.debug('Received %d %s.', count, 'mails' if count != 1 else 'mail') logger.debug('Received %d %s.', count, 'mail(s)')
class MailboxManager(models.Manager): class MailboxManager(models.Manager):
@ -123,6 +122,13 @@ class Mailbox(models.Model):
objects = MailboxManager() objects = MailboxManager()
active_mailboxes = ActiveMailboxManager() active_mailboxes = ActiveMailboxManager()
class Meta:
verbose_name = _('Mailbox')
verbose_name_plural = _('Mailboxes')
def __str__(self):
return self.name
@property @property
def _protocol_info(self): def _protocol_info(self):
return urlparse(self.uri) return urlparse(self.uri)
@ -292,7 +298,10 @@ class Mailbox(models.Model):
settings = utils.get_settings() settings = utils.get_settings()
new = EmailMessage() new = EmailMessage()
if msg.is_multipart(): if (
msg.is_multipart()
and not 'attachment' in msg.get('Content-Disposition', '')
):
for header, value in msg.items(): for header, value in msg.items():
new[header] = value new[header] = value
for part in msg.get_payload(): for part in msg.get_payload():
@ -333,11 +342,21 @@ class Mailbox(models.Model):
attachment = MessageAttachment() attachment = MessageAttachment()
if msg.get_content_type() == 'message/rfc822':
attachment_payloads = msg.get_payload()
if len(attachment_payloads) != 1:
raise AssertionError(
"Attachment of type 'message/rfc822' "
'must have exactly 1 payload.'
)
attachment_payload = attachment_payloads[0].as_bytes()
else:
attachment_payload = msg.get_payload(decode=True)
attachment.document.save( attachment.document.save(
uuid.uuid4().hex + extension, uuid.uuid4().hex + extension,
ContentFile( ContentFile(
BytesIO( BytesIO(
msg.get_payload(decode=True) attachment_payload
).getvalue() ).getvalue()
) )
) )
@ -448,13 +467,12 @@ class Mailbox(models.Model):
def get_new_mail(self, condition=None): def get_new_mail(self, condition=None):
"""Connect to this transport and fetch new messages.""" """Connect to this transport and fetch new messages."""
new_mail = []
connection = self.get_connection() connection = self.get_connection()
if not connection: if not connection:
return return
for message in connection.get_message(condition): for message in connection.get_message(condition):
msg = self.process_incoming_message(message) msg = self.process_incoming_message(message)
if not msg is None: if msg is not None:
yield msg yield msg
self.last_polling = now() self.last_polling = now()
if django.VERSION >= (1, 5): # Django 1.5 introduces update_fields if django.VERSION >= (1, 5): # Django 1.5 introduces update_fields
@ -483,14 +501,6 @@ class Mailbox(models.Model):
) )
def __str__(self):
return self.name
class Meta:
verbose_name = _('Mailbox')
verbose_name_plural = _('Mailboxes')
class IncomingMessageManager(models.Manager): class IncomingMessageManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter( return super().get_queryset().filter(
@ -579,6 +589,7 @@ class Message(models.Model):
eml = models.FileField( eml = models.FileField(
_('Raw message contents'), _('Raw message contents'),
null=True, null=True,
blank=True,
upload_to="messages", upload_to="messages",
help_text=_('Original full content of message') help_text=_('Original full content of message')
) )
@ -677,7 +688,6 @@ class Message(models.Model):
def _rehydrate(self, msg): def _rehydrate(self, msg):
new = EmailMessage() new = EmailMessage()
settings = utils.get_settings() settings = utils.get_settings()
if msg.is_multipart(): if msg.is_multipart():
for header, value in msg.items(): for header, value in msg.items():
new[header] = value new[header] = value
@ -696,24 +706,24 @@ 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 = BytesIO() with open(attachment.document.path, 'rb') as f:
encode_quopri( output = BytesIO()
BytesIO( encode_quopri(
attachment.document.read() BytesIO(
), f.read()
output, ),
quotetabs=True, output,
header=False, quotetabs=True,
) header=False,
new.set_payload( )
output.getvalue().decode().replace(' ', '=20') new.set_payload(
) output.getvalue().decode().replace(' ', '=20')
)
del new['Content-Transfer-Encoding'] del new['Content-Transfer-Encoding']
new['Content-Transfer-Encoding'] = 'quoted-printable' new['Content-Transfer-Encoding'] = 'quoted-printable'
else: else:
new.set_payload( with open(attachment.document.path, 'rb') as f:
attachment.document.read() new.set_payload(f.read())
)
del new['Content-Transfer-Encoding'] del new['Content-Transfer-Encoding']
encode_base64(new) encode_base64(new)
except MessageAttachment.DoesNotExist: except MessageAttachment.DoesNotExist:
@ -757,7 +767,7 @@ class Message(models.Model):
"""Returns an `email.message.EmailMessage` instance representing the """Returns an `email.message.EmailMessage` instance representing the
contents of this message and all attachments. contents of this message and all attachments.
See [email.message.EmailMessage]_ for more information as to what methods See [email.message.EmailMessage]_ for more information like what methods
and properties are available on `email.message.EmailMessage` instances. and properties are available on `email.message.EmailMessage` instances.
.. note:: .. note::
@ -777,9 +787,8 @@ class Message(models.Model):
if self.eml.name.endswith('.gz'): if self.eml.name.endswith('.gz'):
body = gzip.GzipFile(fileobj=self.eml).read() body = gzip.GzipFile(fileobj=self.eml).read()
else: else:
self.eml.open() with self.eml.open():
body = self.eml.file.read() body = self.eml.file.read()
self.eml.close()
else: else:
body = self.get_body() body = self.get_body()
flat = email.message_from_bytes(body) flat = email.message_from_bytes(body)
@ -834,6 +843,11 @@ class MessageAttachment(models.Model):
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):
if email_object._payload is None:
# otherwise it breaks in
# lib/python3.x/email/generator.py:_handle_message,
# line: "self._fp.write(payload)"
email_object._payload = ""
self.headers = email_object.as_string() self.headers = email_object.as_string()
def __delitem__(self, name): def __delitem__(self, name):

View file

@ -1,3 +1,3 @@
from django.dispatch.dispatcher import Signal from django.dispatch.dispatcher import Signal
message_received = Signal(providing_args=['message']) message_received = Signal() # providing_args=['message']

View file

@ -1,58 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Mailbox'
db.create_table('django_mailbox_mailbox', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('uri', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal('django_mailbox', ['Mailbox'])
# Adding model 'Message'
db.create_table('django_mailbox_message', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('mailbox', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['django_mailbox.Mailbox'])),
('subject', self.gf('django.db.models.fields.CharField')(max_length=255)),
('message_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
('from_address', self.gf('django.db.models.fields.CharField')(max_length=255)),
('body', self.gf('django.db.models.fields.TextField')()),
('received', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal('django_mailbox', ['Message'])
def backwards(self, orm):
# Deleting model 'Mailbox'
db.delete_table('django_mailbox_mailbox')
# Deleting model 'Message'
db.delete_table('django_mailbox_message')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'uri': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['django_mailbox.Mailbox']"}),
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,38 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Mailbox.uri'
db.alter_column('django_mailbox_mailbox', 'uri', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
def backwards(self, orm):
# User chose to not deal with backwards NULL issues for 'Mailbox.uri'
raise RuntimeError("Cannot reverse this migration. 'Mailbox.uri' and its values cannot be restored.")
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'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'}),
'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,41 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Mailbox.active'
db.add_column('django_mailbox_mailbox', 'active',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Mailbox.active'
db.delete_column('django_mailbox_mailbox', 'active')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'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'}),
'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,42 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Message.outgoing'
db.add_column('django_mailbox_message', 'outgoing',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Message.outgoing'
db.delete_column('django_mailbox_message', 'outgoing')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'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'}),
'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,38 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
db.rename_column('django_mailbox_message', 'from_address', 'address')
db.rename_column('django_mailbox_message', 'received', 'processed')
def backwards(self, orm):
db.rename_column('django_mailbox_message', 'address', 'from_address')
db.rename_column('django_mailbox_message', 'processed', 'received')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'body': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'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'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,55 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Message.in_reply_to'
db.add_column('django_mailbox_message', 'in_reply_to',
self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='replies', null=True, to=orm['django_mailbox.Message']),
keep_default=False)
# Adding M2M table for field references on 'Message'
db.create_table('django_mailbox_message_references', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('from_message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('to_message', models.ForeignKey(orm['django_mailbox.message'], null=False))
))
db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id'])
def backwards(self, orm):
# Deleting field 'Message.in_reply_to'
db.delete_column('django_mailbox_message', 'in_reply_to_id')
# Removing M2M table for field references on 'Message'
db.delete_table('django_mailbox_message_references')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'body': ('django.db.models.fields.TextField', [], {}),
'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'}),
'references': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'referenced_by'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['django_mailbox.Message']"}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,59 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting field 'Message.address'
db.delete_column('django_mailbox_message', 'address')
# Adding field 'Message.from_header'
db.add_column('django_mailbox_message', 'from_header',
self.gf('django.db.models.fields.CharField')(default='', max_length=255),
keep_default=False)
# Adding field 'Message.to_header'
db.add_column('django_mailbox_message', 'to_header',
self.gf('django.db.models.fields.TextField')(default=''),
keep_default=False)
def backwards(self, orm):
# User chose to not deal with backwards NULL issues for 'Message.address'
raise RuntimeError("Cannot reverse this migration. 'Message.address' and its values cannot be restored.")
# Deleting field 'Message.from_header'
db.delete_column('django_mailbox_message', 'from_header')
# Deleting field 'Message.to_header'
db.delete_column('django_mailbox_message', 'to_header')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'references': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'referenced_by'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['django_mailbox.Message']"}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,46 +0,0 @@
import datetime
import email
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
for message in orm['django_mailbox.message'].objects.all():
msg_object = email.message_from_string(
message.body
)
message.from_header = msg_object['from']
message.to_header = msg_object['to']
message.save()
def backwards(self, orm):
raise RuntimeError('Cannot reverse this migration.')
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'references': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'referenced_by'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['django_mailbox.Message']"}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
}
}
complete_apps = ['django_mailbox']
symmetrical = True

View file

@ -1,47 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing M2M table for field references on 'Message'
db.delete_table('django_mailbox_message_references')
def backwards(self, orm):
# Adding M2M table for field references on 'Message'
db.create_table('django_mailbox_message_references', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('from_message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('to_message', models.ForeignKey(orm['django_mailbox.message'], null=False))
))
db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id'])
models = {
'django_mailbox.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': '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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,45 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Mailbox.from_email'
db.add_column('django_mailbox_mailbox', 'from_email',
self.gf('django.db.models.fields.CharField')(default=None, max_length=255, null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Mailbox.from_email'
db.delete_column('django_mailbox_mailbox', 'from_email')
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,46 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Message.read'
db.add_column('django_mailbox_message', 'read',
self.gf('django.db.models.fields.DateTimeField')(default=None, null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Message.read'
db.delete_column('django_mailbox_message', 'read')
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,66 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'MessageAttachment'
db.create_table('django_mailbox_messageattachment', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('document', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
))
db.send_create_signal('django_mailbox', ['MessageAttachment'])
# Adding M2M table for field attachments on 'Message'
db.create_table('django_mailbox_message_attachments', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False))
))
db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])
def backwards(self, orm):
# Deleting model 'MessageAttachment'
db.delete_table('django_mailbox_messageattachment')
# Removing M2M table for field attachments on 'Message'
db.delete_table('django_mailbox_message_attachments')
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'attachments': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['django_mailbox.MessageAttachment']", 'symmetrical': 'False'}),
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,53 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field '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('django_mailbox_messageattachment', 'message_id')
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'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'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'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']"})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,54 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
no_dry_run = True
def forwards(self, orm):
for message in orm['django_mailbox.Message'].objects.all():
for attachment in message.attachments.all():
attachment.message = message
attachment.save()
def backwards(self, orm):
for attachment in orm['django_mailbox.MessageAttachment'].objects.all():
if attachment.message:
attachment.message.attachments.add(
attachment
)
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'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'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'django_mailbox.messageattachment': {
'Meta': {'object_name': 'MessageAttachment'},
'document': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'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']"})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,64 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing M2M table for field attachments on 'Message'
db.delete_table('django_mailbox_message_attachments')
# Adding field '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('django_mailbox_message_attachments', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False))
))
db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])
# Deleting field 'MessageAttachment.headers'
db.delete_column('django_mailbox_messageattachment', 'headers')
models = {
'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'}),
'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'})
},
'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'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'}),
'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']"})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,54 +0,0 @@
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field '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('django_mailbox_message', 'encoded')
models = {
'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'}),
'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'})
},
'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'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'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'}),
'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']"})
}
}
complete_apps = ['django_mailbox']

View file

@ -1,55 +0,0 @@
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field '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('django_mailbox_message', 'eml')
models = {
'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'}),
'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'})
},
'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'}),
'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'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
},
'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'}),
'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']"})
}
}
complete_apps = ['django_mailbox']

View file

@ -0,0 +1,62 @@
From: Adam Coddington <test@adamcoddington.net>
To: Adam Coddington <test@adamcoddington.net>
Subject: Email with RFC 822 attachment
Date: Fri, 15 May 2020 11:15:00 +0000
Message-ID: <ce1f843c1a2d4de7a0c7c78c84a50f8d@adamcoddington.net>
Content-Type: multipart/mixed;
boundary="_004_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_"
Return-Path: test@adamcoddington.net
MIME-Version: 1.0
--_004_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_
Content-Type: multipart/alternative;
boundary="_000_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_"
--_000_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Dear Sir or Madam,
I am sending you an email message as an attachment.
--_000_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<html xmlns=3D"http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
1">
</head>
<body>
<div>
<p>Dear Sir or Madam,</p>
<p>I am sending you an email message as an attachment.</p>
</div>
</body>
</html>
--_000_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_--
--_004_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_
Content-Type: message/rfc822
Content-Disposition: attachment;
creation-date="Fri, 15 May 2020 11:10:00 GMT";
modification-date="Fri, 15 May 2020 11:10:00 GMT"
From: Adam Coddington <test@adamcoddington.net>
To: Adam Coddington <test@adamcoddington.net>
Subject: Attached email
Date: Fri, 15 May 2020 09:00:00 +0000
Message-ID: <ujURpHHC.xh4Qpg28.RLQSSkBK.cQSyhEG5.PmxCEEdV@127.0.0.1>
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Hello!
This is the attached email.
--_004_ce1f843c1a2d4de7a0c7c78c84a50f8dadamcoddington.net_--

View file

@ -1,6 +1,5 @@
import gzip import gzip
import os.path import os.path
import sys
import copy import copy
from unittest import mock from unittest import mock
@ -9,7 +8,7 @@ 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
from django_mailbox import utils from django_mailbox import utils
from django_mailbox.tests.base import EmailMessageTestCase from django_mailbox.tests.base import EmailMessageTestCase
from django.utils.encoding import force_text from django.utils.encoding import force_str
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
__all__ = ['TestProcessEmail'] __all__ = ['TestProcessEmail']
@ -88,6 +87,23 @@ class TestProcessEmail(EmailMessageTestCase):
'heart.png', 'heart.png',
) )
def test_message_with_rfc822_attachment(self):
message = self._get_email_object('message_with_rfc822_attachment.eml')
mailbox = Mailbox.objects.create()
msg = mailbox.process_incoming_message(message)
expected_count = 1
actual_count = msg.attachments.count()
self.assertEqual(
expected_count,
actual_count,
)
attachment = msg.attachments.all()[0]
self.assertIsNone(attachment.get_filename())
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
@ -367,12 +383,12 @@ class TestProcessEmail(EmailMessageTestCase):
email_object = self._get_email_object( email_object = self._get_email_object(
'message_with_long_content.eml', 'message_with_long_content.eml',
) )
size = len(force_text(email_object.as_string())) size = len(force_str(email_object.as_string()))
msg = self.mailbox.process_incoming_message(email_object) msg = self.mailbox.process_incoming_message(email_object)
self.assertEqual(size, self.assertEqual(size,
len(force_text(msg.get_email_object().as_string()))) len(force_str(msg.get_email_object().as_string())))
def test_message_saved(self): def test_message_saved(self):
message = self._get_email_object('generic_message.eml') message = self._get_email_object('generic_message.eml')
@ -386,7 +402,7 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(message) msg = self.mailbox.process_incoming_message(message)
self.assertNotEquals(msg.eml, None) self.assertNotEqual(msg.eml, None)
self.assertTrue(msg.eml.name.endswith('.eml')) self.assertTrue(msg.eml.name.endswith('.eml'))
@ -408,7 +424,7 @@ class TestProcessEmail(EmailMessageTestCase):
msg = self.mailbox.process_incoming_message(message) msg = self.mailbox.process_incoming_message(message)
self.assertEquals(msg.eml, None) self.assertEqual(msg.eml, None)
def test_message_compressed(self): def test_message_compressed(self):
message = self._get_email_object('generic_message.eml') message = self._get_email_object('generic_message.eml')

View file

@ -1,34 +1,25 @@
from distutils.version import LooseVersion
from unittest 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
import django
class CommandsTestCase(TestCase): class CommandsTestCase(TestCase):
def test_processincomingmessage_no_args(self): def test_processincomingmessage_no_args(self):
"""Check that processincomingmessage works with no args""" """Check that processincomingmessage works with no args"""
mailbox_name = None mailbox_name = None
# Mock handle so that the test doesn't hang waiting for input. Note that we are only testing # Mock handle so that the test doesn't hang waiting for input. Note that we are only testing
# the argument parsing here -- functionality should be tested elsewhere # the argument parsing here -- functionality should be tested elsewhere
with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle: with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle:
# Don't care about the return value # Don't care about the return value
handle.return_value = None handle.return_value = None
call_command('processincomingmessage') call_command('processincomingmessage')
args, kwargs = handle.call_args args, kwargs = handle.call_args
# Make sure that we called with the right arguments # Make sure that we called with the right arguments
try: self.assertEqual(kwargs['mailbox_name'], mailbox_name)
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
except KeyError:
# Handle Django 1.7
# It uses optparse instead of argparse, so instead of being
# set to None, mailbox_name is simply left out altogether
# Thus we expect an empty tuple here
self.assertEqual(args, tuple())
def test_processincomingmessage_with_arg(self): def test_processincomingmessage_with_arg(self):
"""Check that processincomingmessage works with mailbox_name given""" """Check that processincomingmessage works with mailbox_name given"""
@ -37,29 +28,14 @@ class CommandsTestCase(TestCase):
with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle: with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle:
handle.return_value = None handle.return_value = None
call_command('processincomingmessage', mailbox_name) call_command('processincomingmessage', mailbox_name)
args, kwargs = handle.call_args args, kwargs = handle.call_args
try:
self.assertEqual(kwargs['mailbox_name'], mailbox_name) self.assertEqual(kwargs['mailbox_name'], mailbox_name)
except (AssertionError, KeyError):
# Handle Django 1.7
# It uses optparse instead of argparse, so instead of being
# in kwargs, mailbox_name is in args
self.assertEqual(args[0], mailbox_name)
def test_processincomingmessage_too_many_args(self): def test_processincomingmessage_too_many_args(self):
"""Check that processincomingmessage raises an error if too many args""" """Check that processincomingmessage raises an error if too many args"""
# Only perform this test for Django versions greater than 1.7.*. This
# is because, with optparse, too many arguments doesn't result in an with self.assertRaises(CommandError):
# error, which means this test is worthless anyway call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
# For the "compatibility" versions, unexpected arguments aren't handled
# very well, and result in a TypeError
if (LooseVersion(django.get_version()) >= LooseVersion('1.8') and
LooseVersion(django.get_version()) < LooseVersion('1.10')):
with self.assertRaises(TypeError):
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
# In 1.10 and later a proper CommandError should be raised
elif LooseVersion(django.get_version()) >= LooseVersion('1.10'):
with self.assertRaises(CommandError):
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')

View file

@ -8,7 +8,7 @@ from django_mailbox.transports import ImapTransport, Pop3Transport
FAKE_UID_SEARCH_ANSWER = ( FAKE_UID_SEARCH_ANSWER = (
'OK', 'OK',
[ [
b'18 19 20 21 22 23 24 25 26 27 28 29 ' + 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' b'30 31 32 33 34 35 36 37 38 39 40 41 42 43 44'
] ]
) )

View file

@ -9,4 +9,3 @@ class EmailTransport:
message = email.message_from_bytes(contents) message = email.message_from_bytes(contents)
return message return message

View file

@ -1,4 +1,4 @@
import sys
from .base import EmailTransport from .base import EmailTransport

View file

@ -63,4 +63,3 @@ class Office365Transport(EmailTransport):
o365message.delete() o365message.delete()
return return

View file

@ -64,7 +64,7 @@ def get_settings():
), ),
'default_charset': getattr( 'default_charset': getattr(
settings, settings,
'DJANGO_MAILBOX_default_charset', 'DJANGO_MAILBOX_DEFAULT_CHARSET',
'iso8859-1', 'iso8859-1',
) )
} }

View file

@ -244,7 +244,7 @@ sys.path.insert(0, os.path.abspath('..'))
import inspect import inspect
import django import django
from django.utils.html import strip_tags from django.utils.html import strip_tags
from django.utils.encoding import force_text from django.utils.encoding import force_str
from django.conf import settings from django.conf import settings
settings.configure(INSTALLED_APPS=['django_mailbox', ]) settings.configure(INSTALLED_APPS=['django_mailbox', ])
django.setup() django.setup()
@ -265,11 +265,11 @@ def process_docstring(app, what, name, obj, options, lines):
continue continue
# Decode and strip any html out of the field's help text # Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text)) help_text = strip_tags(force_str(field.help_text))
# Decode and capitalize the verbose name, for use if there isn't # Decode and capitalize the verbose name, for use if there isn't
# any help text # any help text
verbose_name = force_text(field.verbose_name).capitalize() verbose_name = force_str(field.verbose_name).capitalize()
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

View file

@ -6,8 +6,8 @@
Django-mailbox Django-mailbox
============== ==============
.. image:: https://travis-ci.org/coddingtonbear/django-mailbox.png?branch=master .. image:: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml/badge.svg
:target: https://travis-ci.org/coddingtonbear/django-mailbox :target: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml
How many times have you had to consume some sort of POP3, IMAP, or local mailbox for incoming content, How many times have you had to consume some sort of POP3, IMAP, or local mailbox for incoming content,
or had to otherwise construct an application driven by e-mail? or had to otherwise construct an application driven by e-mail?

View file

@ -80,3 +80,9 @@ Settings
* Default: ``False`` * Default: ``False``
* Type: ``boolean`` * Type: ``boolean``
* Controls whether or not we store original messages in ``eml`` field * Controls whether or not we store original messages in ``eml`` field
* ``DJANGO_MAILBOX_DEFAULT_CHARSET``
* Default: ``iso8859-1``
* Type: ``string``
* Controls which charset is used if the charset is not specified in the header.

View file

@ -8,7 +8,7 @@ make it simple.
How to file a ticket? How to file a ticket?
--------------------- ---------------------
Just go to https://github.com/coddingtonbear/django-mailbox and create new Just go to https://github.com/coddingtonbear/django-mailbox/issues and create new
one. one.
@ -50,10 +50,8 @@ Changes are only necessary for new minor or major Django versions.
To add support for a new version perform the following task: To add support for a new version perform the following task:
* Ensure that ``.github/workflows/main.yml`` file reflects support for new Python release.
* Ensure that ``tox.ini`` file reflects support for new Django release. * Ensure that ``tox.ini`` file reflects support for new Django release.
* Verify in tox that the code is executed correctly on all versions of the Python interpreter. * Verify in tox that the code is executed correctly on all versions of the Python interpreter.
* Ensure that ``.travis.yml`` file reflects support for new Django release. Note the excluded versions of the Python interpreter. * Verify by pushing changes on a separate branch to see if the changes in Github Actions are correct.
* Verify by pushing changes on a separate branch to see if the changes in TravisCI are correct.
* Proceed to the standard procedure for a new package release (see `How to do a new release?`_ ). * Proceed to the standard procedure for a new package release (see `How to do a new release?`_ ).
A `spreadsheet with generator is available <https://docs.google.com/spreadsheets/d/1YsVPDeOAgf_c_7XOXh6SZUO2ebMNoFXysxfj4r1tFiM/edit?usp=sharing>`_ that can assist this process.

View file

@ -121,12 +121,15 @@ Office 365 API
------------------------------------- -------------------------------------
Office 365 allows through the API to read a mailbox with Oauth. Office 365 allows through the API to read a mailbox with Oauth.
The O365_ library is used. The O365_ library is used and must be installed.
.. _O365: https://github.com/O365/python-o365 .. _O365: https://github.com/O365/python-o365
.. _configuration: https://github.com/O365/python-o365#authentication .. _configuration: https://github.com/O365/python-o365#authentication
For the configuration_ you need to register an application and get a client_id, client_secret and tenant_id. For the Oauth configuration you need to follow the instructions on the O365 configuration_ page.
You need to register an application and get a client_id, client_secret and tenant_id.
client_secret is equivalent to the app secret value and not the ID.
This implementation uses the client credentials grant flow and the password you specify will be ignored. This implementation uses the client credentials grant flow and the password you specify will be ignored.

0
manage.py Normal file → Executable file
View file

View file

@ -1,11 +1,8 @@
.. image:: https://travis-ci.org/coddingtonbear/django-mailbox.png?branch=master .. image:: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml/badge.svg
:target: https://travis-ci.org/coddingtonbear/django-mailbox :target: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml
.. image:: https://badge.fury.io/py/django-mailbox.png .. image:: https://badge.fury.io/py/django-mailbox.png
:target: http://badge.fury.io/py/django-mailbox :target: https://pypi.org/project/django-mailbox/
.. image:: https://pypip.in/d/django-mailbox/badge.png
:target: https://pypi.python.org/pypi/django-mailbox
Easily ingest messages from POP3, IMAP, Office365 API or local mailboxes into your Django application. Easily ingest messages from POP3, IMAP, Office365 API or local mailboxes into your Django application.
@ -21,7 +18,7 @@ or -- if you're in a hurry -- by using a signal receiver.
- Please post issues on - Please post issues on
`Github <http://github.com/coddingtonbear/django-mailbox/issues>`_. `Github <http://github.com/coddingtonbear/django-mailbox/issues>`_.
- Test status available on - Test status available on
`Travis-CI <https://travis-ci.org/coddingtonbear/django-mailbox>`_. `Github-Actions <https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml>`_.
.. image:: https://badges.gitter.im/Join%20Chat.svg .. image:: https://badges.gitter.im/Join%20Chat.svg

View file

@ -1,2 +1,2 @@
django>=3.1.1,<3.2 django>=3.2,<4.0
six six

View file

@ -32,25 +32,25 @@ setup(
'gmail-oauth2': gmail_oauth2_require, 'gmail-oauth2': gmail_oauth2_require,
'office365-oauth2': office365_oauth2_require 'office365-oauth2': office365_oauth2_require
}, },
python_requires=">=3", python_requires=">=3.8",
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.11', 'Framework :: Django :: 3.2',
'Framework :: Django :: 2.0', 'Framework :: Django :: 4.0',
'Framework :: Django :: 2.1', 'Framework :: Django :: 4.1',
'Framework :: Django :: 2.2', 'Framework :: Django :: 4.2',
'Framework :: Django :: 3.0', 'Framework :: Django :: 5.0',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 3', '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', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'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',
@ -59,7 +59,4 @@ setup(
], ],
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
install_requires=[
'six>=1.6.1'
]
) )

View file

@ -1,3 +1,3 @@
pytest==2.9.1 pytest
pytest-django==2.9.1 pytest-django
mock==2.0.0 mock

34
tox.ini
View file

@ -2,20 +2,32 @@
# sort by django version, next by python version # sort by django version, next by python version
envlist= envlist=
flake8 flake8
py{35,36}-django111 py{310,311,312}-django50
py{35,36}-django20 py{38,39,310,311}-django42
py{35,36,37}-django21 py{38,39,310,311}-django41
py{35,36,37}-django22 py{38,39,310}-django40
py{36,37,38}-django30 py{38,39,310}-django32
[gh-actions]
python =
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
[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=
django111: django==1.11.* django50: Django==5.0,<5.1
django20: django==2.0.* django42: Django>=4.2,<5.0
django21: django==2.0.* django41: Django>=4.1,<4.2
django22: django==2.0.* django40: Django>=4.0,<4.1
django30: django==3.0b1 django32: Django>=3.2,<4.0
-r{toxinidir}/test_requirements.txt -r{toxinidir}/test_requirements.txt
sitepackages=False sitepackages=False
commands= commands=