forked from mirror/django-mailbox
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]
|
||||
current_version = 4.8.2
|
||||
current_version = 4.9.0
|
||||
commit = True
|
||||
tag = True
|
||||
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
|
||||
*.sqlite3
|
||||
.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
|
||||
=========
|
||||
|
||||
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
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
include *.rst
|
||||
include .travis.yml
|
||||
include MANIFEST
|
||||
recursive-include django_mailbox *.eml
|
||||
recursive-include docs *.py
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
__version__ = '4.8.2'
|
||||
__version__ = '4.9.0'
|
||||
|
||||
default_app_config = 'django_mailbox.apps.MailBoxConfig'
|
||||
|
|
|
|||
|
|
@ -5,3 +5,5 @@ from django.utils.translation import gettext_lazy as _
|
|||
class MailBoxConfig(AppConfig):
|
||||
name = 'django_mailbox'
|
||||
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 mimetypes
|
||||
import os.path
|
||||
import sys
|
||||
import uuid
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ class MailboxQuerySet(models.QuerySet):
|
|||
for mailbox in self.all():
|
||||
logger.debug('Receiving mail for %s' % mailbox)
|
||||
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):
|
||||
|
|
@ -123,6 +122,13 @@ class Mailbox(models.Model):
|
|||
objects = MailboxManager()
|
||||
active_mailboxes = ActiveMailboxManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Mailbox')
|
||||
verbose_name_plural = _('Mailboxes')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def _protocol_info(self):
|
||||
return urlparse(self.uri)
|
||||
|
|
@ -292,7 +298,10 @@ class Mailbox(models.Model):
|
|||
settings = utils.get_settings()
|
||||
|
||||
new = EmailMessage()
|
||||
if msg.is_multipart():
|
||||
if (
|
||||
msg.is_multipart()
|
||||
and not 'attachment' in msg.get('Content-Disposition', '')
|
||||
):
|
||||
for header, value in msg.items():
|
||||
new[header] = value
|
||||
for part in msg.get_payload():
|
||||
|
|
@ -333,11 +342,21 @@ class Mailbox(models.Model):
|
|||
|
||||
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(
|
||||
uuid.uuid4().hex + extension,
|
||||
ContentFile(
|
||||
BytesIO(
|
||||
msg.get_payload(decode=True)
|
||||
attachment_payload
|
||||
).getvalue()
|
||||
)
|
||||
)
|
||||
|
|
@ -448,13 +467,12 @@ class Mailbox(models.Model):
|
|||
|
||||
def get_new_mail(self, condition=None):
|
||||
"""Connect to this transport and fetch new messages."""
|
||||
new_mail = []
|
||||
connection = self.get_connection()
|
||||
if not connection:
|
||||
return
|
||||
for message in connection.get_message(condition):
|
||||
msg = self.process_incoming_message(message)
|
||||
if not msg is None:
|
||||
if msg is not None:
|
||||
yield msg
|
||||
self.last_polling = now()
|
||||
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):
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(
|
||||
|
|
@ -579,6 +589,7 @@ class Message(models.Model):
|
|||
eml = models.FileField(
|
||||
_('Raw message contents'),
|
||||
null=True,
|
||||
blank=True,
|
||||
upload_to="messages",
|
||||
help_text=_('Original full content of message')
|
||||
)
|
||||
|
|
@ -677,7 +688,6 @@ class Message(models.Model):
|
|||
def _rehydrate(self, msg):
|
||||
new = EmailMessage()
|
||||
settings = utils.get_settings()
|
||||
|
||||
if msg.is_multipart():
|
||||
for header, value in msg.items():
|
||||
new[header] = value
|
||||
|
|
@ -696,24 +706,24 @@ class Message(models.Model):
|
|||
if encoding and encoding.lower() == 'quoted-printable':
|
||||
# Cannot use `email.encoders.encode_quopri due to
|
||||
# bug 14360: http://bugs.python.org/issue14360
|
||||
output = BytesIO()
|
||||
encode_quopri(
|
||||
BytesIO(
|
||||
attachment.document.read()
|
||||
),
|
||||
output,
|
||||
quotetabs=True,
|
||||
header=False,
|
||||
)
|
||||
new.set_payload(
|
||||
output.getvalue().decode().replace(' ', '=20')
|
||||
)
|
||||
with open(attachment.document.path, 'rb') as f:
|
||||
output = BytesIO()
|
||||
encode_quopri(
|
||||
BytesIO(
|
||||
f.read()
|
||||
),
|
||||
output,
|
||||
quotetabs=True,
|
||||
header=False,
|
||||
)
|
||||
new.set_payload(
|
||||
output.getvalue().decode().replace(' ', '=20')
|
||||
)
|
||||
del new['Content-Transfer-Encoding']
|
||||
new['Content-Transfer-Encoding'] = 'quoted-printable'
|
||||
else:
|
||||
new.set_payload(
|
||||
attachment.document.read()
|
||||
)
|
||||
with open(attachment.document.path, 'rb') as f:
|
||||
new.set_payload(f.read())
|
||||
del new['Content-Transfer-Encoding']
|
||||
encode_base64(new)
|
||||
except MessageAttachment.DoesNotExist:
|
||||
|
|
@ -757,7 +767,7 @@ class Message(models.Model):
|
|||
"""Returns an `email.message.EmailMessage` instance representing the
|
||||
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.
|
||||
|
||||
.. note::
|
||||
|
|
@ -777,9 +787,8 @@ class Message(models.Model):
|
|||
if self.eml.name.endswith('.gz'):
|
||||
body = gzip.GzipFile(fileobj=self.eml).read()
|
||||
else:
|
||||
self.eml.open()
|
||||
body = self.eml.file.read()
|
||||
self.eml.close()
|
||||
with self.eml.open():
|
||||
body = self.eml.file.read()
|
||||
else:
|
||||
body = self.get_body()
|
||||
flat = email.message_from_bytes(body)
|
||||
|
|
@ -834,6 +843,11 @@ class MessageAttachment(models.Model):
|
|||
return email.message_from_string(headers)
|
||||
|
||||
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()
|
||||
|
||||
def __delitem__(self, name):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
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 os.path
|
||||
import sys
|
||||
|
||||
import copy
|
||||
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 import utils
|
||||
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
|
||||
|
||||
__all__ = ['TestProcessEmail']
|
||||
|
|
@ -88,6 +87,23 @@ class TestProcessEmail(EmailMessageTestCase):
|
|||
'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):
|
||||
""" Ensure that we properly handle UTF-8 encoded attachment
|
||||
|
||||
|
|
@ -367,12 +383,12 @@ class TestProcessEmail(EmailMessageTestCase):
|
|||
email_object = self._get_email_object(
|
||||
'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)
|
||||
|
||||
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):
|
||||
message = self._get_email_object('generic_message.eml')
|
||||
|
|
@ -386,7 +402,7 @@ class TestProcessEmail(EmailMessageTestCase):
|
|||
|
||||
msg = self.mailbox.process_incoming_message(message)
|
||||
|
||||
self.assertNotEquals(msg.eml, None)
|
||||
self.assertNotEqual(msg.eml, None)
|
||||
|
||||
self.assertTrue(msg.eml.name.endswith('.eml'))
|
||||
|
||||
|
|
@ -408,7 +424,7 @@ class TestProcessEmail(EmailMessageTestCase):
|
|||
|
||||
msg = self.mailbox.process_incoming_message(message)
|
||||
|
||||
self.assertEquals(msg.eml, None)
|
||||
self.assertEqual(msg.eml, None)
|
||||
|
||||
def test_message_compressed(self):
|
||||
message = self._get_email_object('generic_message.eml')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
from distutils.version import LooseVersion
|
||||
from unittest import mock
|
||||
|
||||
from django.core.management import call_command, CommandError
|
||||
from django.test import TestCase
|
||||
import django
|
||||
|
||||
|
||||
class CommandsTestCase(TestCase):
|
||||
def test_processincomingmessage_no_args(self):
|
||||
|
|
@ -20,15 +19,7 @@ class CommandsTestCase(TestCase):
|
|||
args, kwargs = handle.call_args
|
||||
|
||||
# Make sure that we called with the right arguments
|
||||
try:
|
||||
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())
|
||||
|
||||
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
|
||||
|
||||
def test_processincomingmessage_with_arg(self):
|
||||
"""Check that processincomingmessage works with mailbox_name given"""
|
||||
|
|
@ -40,26 +31,11 @@ class CommandsTestCase(TestCase):
|
|||
|
||||
call_command('processincomingmessage', mailbox_name)
|
||||
args, kwargs = handle.call_args
|
||||
try:
|
||||
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)
|
||||
|
||||
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
|
||||
|
||||
def test_processincomingmessage_too_many_args(self):
|
||||
"""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):
|
||||
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
|
||||
|
||||
with self.assertRaises(CommandError):
|
||||
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
|
||||
|
|
|
|||
|
|
@ -9,4 +9,3 @@ class EmailTransport:
|
|||
message = email.message_from_bytes(contents)
|
||||
|
||||
return message
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import sys
|
||||
|
||||
|
||||
from .base import EmailTransport
|
||||
|
||||
|
|
|
|||
|
|
@ -63,4 +63,3 @@ class Office365Transport(EmailTransport):
|
|||
|
||||
o365message.delete()
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ def get_settings():
|
|||
),
|
||||
'default_charset': getattr(
|
||||
settings,
|
||||
'DJANGO_MAILBOX_default_charset',
|
||||
'DJANGO_MAILBOX_DEFAULT_CHARSET',
|
||||
'iso8859-1',
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ sys.path.insert(0, os.path.abspath('..'))
|
|||
import inspect
|
||||
import django
|
||||
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
|
||||
settings.configure(INSTALLED_APPS=['django_mailbox', ])
|
||||
django.setup()
|
||||
|
|
@ -265,11 +265,11 @@ def process_docstring(app, what, name, obj, options, lines):
|
|||
continue
|
||||
|
||||
# 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
|
||||
# any help text
|
||||
verbose_name = force_text(field.verbose_name).capitalize()
|
||||
verbose_name = force_str(field.verbose_name).capitalize()
|
||||
|
||||
if help_text:
|
||||
# Add the model field to the end of the docstring as a param
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
Django-mailbox
|
||||
==============
|
||||
|
||||
.. image:: https://travis-ci.org/coddingtonbear/django-mailbox.png?branch=master
|
||||
:target: https://travis-ci.org/coddingtonbear/django-mailbox
|
||||
.. image:: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml/badge.svg
|
||||
: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,
|
||||
or had to otherwise construct an application driven by e-mail?
|
||||
|
|
|
|||
|
|
@ -80,3 +80,9 @@ Settings
|
|||
* Default: ``False``
|
||||
* Type: ``boolean``
|
||||
* 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?
|
||||
---------------------
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
|
@ -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:
|
||||
|
||||
* Ensure that ``.github/workflows/main.yml`` file reflects support for new Python 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.
|
||||
* 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 TravisCI are correct.
|
||||
* Verify by pushing changes on a separate branch to see if the changes in Github Actions are correct.
|
||||
* 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.
|
||||
The O365_ library is used.
|
||||
The O365_ library is used and must be installed.
|
||||
|
||||
.. _O365: https://github.com/O365/python-o365
|
||||
.. _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.
|
||||
|
||||
|
|
|
|||
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
|
||||
:target: https://travis-ci.org/coddingtonbear/django-mailbox
|
||||
.. image:: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml/badge.svg
|
||||
:target: https://github.com/coddingtonbear/django-mailbox/actions/workflows/main.yml
|
||||
|
||||
.. image:: https://badge.fury.io/py/django-mailbox.png
|
||||
:target: http://badge.fury.io/py/django-mailbox
|
||||
|
||||
.. image:: https://pypip.in/d/django-mailbox/badge.png
|
||||
:target: https://pypi.python.org/pypi/django-mailbox
|
||||
:target: https://pypi.org/project/django-mailbox/
|
||||
|
||||
|
||||
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
|
||||
`Github <http://github.com/coddingtonbear/django-mailbox/issues>`_.
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
django>=3.1.1,<3.2
|
||||
django>=3.2,<4.0
|
||||
six
|
||||
|
|
|
|||
23
setup.py
23
setup.py
|
|
@ -32,25 +32,25 @@ setup(
|
|||
'gmail-oauth2': gmail_oauth2_require,
|
||||
'office365-oauth2': office365_oauth2_require
|
||||
},
|
||||
python_requires=">=3",
|
||||
python_requires=">=3.8",
|
||||
classifiers=[
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
'Framework :: Django',
|
||||
'Framework :: Django :: 1.11',
|
||||
'Framework :: Django :: 2.0',
|
||||
'Framework :: Django :: 2.1',
|
||||
'Framework :: Django :: 2.2',
|
||||
'Framework :: Django :: 3.0',
|
||||
'Framework :: Django :: 3.2',
|
||||
'Framework :: Django :: 4.0',
|
||||
'Framework :: Django :: 4.1',
|
||||
'Framework :: Django :: 4.2',
|
||||
'Framework :: Django :: 5.0',
|
||||
'Programming Language :: Python',
|
||||
'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.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
'Programming Language :: Python :: 3.11',
|
||||
'Programming Language :: Python :: 3.12',
|
||||
'Topic :: Communications :: Email',
|
||||
'Topic :: Communications :: Email :: Post-Office',
|
||||
'Topic :: Communications :: Email :: Post-Office :: IMAP',
|
||||
|
|
@ -59,7 +59,4 @@ setup(
|
|||
],
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'six>=1.6.1'
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
pytest==2.9.1
|
||||
pytest-django==2.9.1
|
||||
mock==2.0.0
|
||||
pytest
|
||||
pytest-django
|
||||
mock
|
||||
|
|
|
|||
34
tox.ini
34
tox.ini
|
|
@ -2,20 +2,32 @@
|
|||
# sort by django version, next by python version
|
||||
envlist=
|
||||
flake8
|
||||
py{35,36}-django111
|
||||
py{35,36}-django20
|
||||
py{35,36,37}-django21
|
||||
py{35,36,37}-django22
|
||||
py{36,37,38}-django30
|
||||
py{310,311,312}-django50
|
||||
py{38,39,310,311}-django42
|
||||
py{38,39,310,311}-django41
|
||||
py{38,39,310}-django40
|
||||
py{38,39,310}-django32
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.8: py38
|
||||
3.9: py39
|
||||
3.10: py310
|
||||
3.11: py311
|
||||
3.12: py312
|
||||
|
||||
[testenv]
|
||||
passenv=EMAIL_IMAP_SERVER EMAIL_ACCOUNT EMAIL_PASSWORD EMAIL_SMTP_SERVER
|
||||
passenv=
|
||||
EMAIL_IMAP_SERVER
|
||||
EMAIL_ACCOUNT
|
||||
EMAIL_PASSWORD
|
||||
EMAIL_SMTP_SERVER
|
||||
deps=
|
||||
django111: django==1.11.*
|
||||
django20: django==2.0.*
|
||||
django21: django==2.0.*
|
||||
django22: django==2.0.*
|
||||
django30: django==3.0b1
|
||||
django50: Django==5.0,<5.1
|
||||
django42: Django>=4.2,<5.0
|
||||
django41: Django>=4.1,<4.2
|
||||
django40: Django>=4.0,<4.1
|
||||
django32: Django>=3.2,<4.0
|
||||
-r{toxinidir}/test_requirements.txt
|
||||
sitepackages=False
|
||||
commands=
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue