mirror of
https://github.com/coddingtonbear/django-mailbox.git
synced 2026-07-09 22:38:19 +02:00
Merge branch 'coddingtonbear:master' into master
This commit is contained in:
commit
d04d4d56da
50 changed files with 468 additions and 1037 deletions
|
|
@ -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
40
.github/workflows/main.yml
vendored
Normal 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
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@ dummy_project/*
|
||||||
messages
|
messages
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
.idea/
|
.idea/
|
||||||
|
venv/
|
||||||
46
.travis.yml
46
.travis.yml
|
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
BIN
django_mailbox/locale/bg/LC_MESSAGES/django.mo
Normal file
BIN
django_mailbox/locale/bg/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
190
django_mailbox/locale/bg/LC_MESSAGES/django.po
Normal file
190
django_mailbox/locale/bg/LC_MESSAGES/django.po
Normal 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 <mailbot@yourdomain.com><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 <mailbot@yourdomain.com><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 "Приложения към съобщението"
|
||||||
18
django_mailbox/migrations/0009_alter_message_eml.py
Normal file
18
django_mailbox/migrations/0009_alter_message_eml.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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,10 +706,11 @@ 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
|
||||||
|
with open(attachment.document.path, 'rb') as f:
|
||||||
output = BytesIO()
|
output = BytesIO()
|
||||||
encode_quopri(
|
encode_quopri(
|
||||||
BytesIO(
|
BytesIO(
|
||||||
attachment.document.read()
|
f.read()
|
||||||
),
|
),
|
||||||
output,
|
output,
|
||||||
quotetabs=True,
|
quotetabs=True,
|
||||||
|
|
@ -711,9 +722,8 @@ class Message(models.Model):
|
||||||
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):
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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']
|
|
||||||
|
|
@ -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_--
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
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):
|
||||||
|
|
@ -20,15 +19,7 @@ class CommandsTestCase(TestCase):
|
||||||
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"""
|
||||||
|
|
@ -40,26 +31,11 @@ class CommandsTestCase(TestCase):
|
||||||
|
|
||||||
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
|
|
||||||
# error, which means this test is worthless anyway
|
|
||||||
# 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):
|
with self.assertRaises(CommandError):
|
||||||
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
|
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,3 @@ class EmailTransport:
|
||||||
message = email.message_from_bytes(contents)
|
message = email.message_from_bytes(contents)
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
from .base import EmailTransport
|
from .base import EmailTransport
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,4 +63,3 @@ class Office365Transport(EmailTransport):
|
||||||
|
|
||||||
o365message.delete()
|
o365message.delete()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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?
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
|
||||||
|
|
@ -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
0
manage.py
Normal file → Executable file
11
readme.rst
11
readme.rst
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
django>=3.1.1,<3.2
|
django>=3.2,<4.0
|
||||||
six
|
six
|
||||||
|
|
|
||||||
23
setup.py
23
setup.py
|
|
@ -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'
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
pytest==2.9.1
|
pytest
|
||||||
pytest-django==2.9.1
|
pytest-django
|
||||||
mock==2.0.0
|
mock
|
||||||
|
|
|
||||||
34
tox.ini
34
tox.ini
|
|
@ -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=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue