core.models package

eonvelope.models package containing all models for the Eonvelope database.

class core.models.Account(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('account'), DirtyFieldsMixin, URLMixin, DownloadMixin, FavoriteModelMixin, TimestampModelMixin, HealthModelMixin, Model

Database model for the account data of a mail account.

BASENAME = 'account'
DELETE_NOTICE = 'This will delete the records of this account and all mailboxes, emails and attachments found in it!'
DELETE_NOTICE_PLURAL = 'This will delete the records of these accounts and all mailboxes, emails and attachments found in them!'
MAX_MAIL_HOST_PORT = 65535
mail_address

The username of the account. Unique together with user. Named mail_address for continuity.

password

The password to log into the account.

mail_host

The url of the mail server where the account is located.

mail_host_port

The port of the mail server. Can be null if the default port of the protocol is used.

protocol

The mail protocol of the mail server.

timeout

The timeout parameter for the connection to the host, defaults to 10s.

allow_insecure_connection

Whether to allow insecure connections to the host, defaults to False.

user

The user this account belongs to. Deletion of that user deletes this correspondent.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the account, using mail_address and protocol.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Account>
created

The datetime the model instance was created. Is set automatically.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
get_protocol_display(*, field=<django.db.models.fields.CharField: protocol>)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_favorite

Flags favorite accounts. False by default.

is_healthy

Flags whether the model instance is subject to errors. None by default.

last_error

The latest error in connection with the model instance.

last_error_occurred_at

The time of occurrence of the latest error.

mailboxes

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

objects = <django.db.models.manager.Manager object>
save(*args, **kwargs)[source]

Extended to auto-update mailboxes when the account is saved for the first time.

Return type:

None

Parameters:
updated

The datetime the model instance entry was last updated. Is set automatically.

user_id
clean()[source]

Validation for the unique together constraint on mail_account. Validate the account data by testing if one of the relevant fields is dirty.

Required to allow correct validation of the create form.

Raises:

ValidationError – If the instance violates the constraint or testing fails.

Return type:

None

get_fetcher_class()[source]

Returns the fetcher class from core.utils.fetchers corresponding to protocol.

Return type:

type[BaseFetcher]

Returns:

The fetcher class for the account.

Raises:

ValueError – If the protocol doesn’t match any fetcher class. Marks the account as unhealthy in this case.

get_fetcher()[source]

Instantiates the fetcher from core.utils.fetchers corresponding to protocol.

Handles possible errors instantiating the fetcher.

Return type:

BaseFetcher

Returns:

A fetcher instance for the account.

Raises:
  • ValueError – If the protocol doesn’t match any fetcher class. Marks the account as unhealthy in this case.

  • MailAccountError – If the fetcher fails to initialize. Marks the account as unhealthy in this case.

test()[source]

Tests whether the data in the model is correct.

Tests connecting and logging in to the mailhost and account. The core.models.Account.is_healthy flag is set accordingly. Relies on the test method of the core.utils.fetchers classes.

Raises:

MailAccountError – If the test is fails.

Return type:

None

update_mailboxes()[source]

Scans the given mailaccount for unknown mailboxes, parses and inserts them into the database.

If successful, marks this account as healthy, otherwise unhealthy.

Raises:

MailAccountError – If scanning for mailboxes failed.

Return type:

None

add_daemons()[source]

Adds a default set of daemons to the in- and sent mailboxes of this account.

Return type:

None

property complete_mail_address: str

The complete mail address of the account. If the username (mail_address) is not valid a valid address, constructs one with mail_host. If there is no username, guess it from the Eonvelope users name.

Returns:

A valid mail address for the account.

property mail_host_address: str

The mail_host address with port specified for the hostname.

Returns:

The complete host address.

property available_download_formats: list[tuple[str, StrOrPromise]]

Get all formats that emails in this account can be downloaded in.

Returns:

A list of download formats and format names.

property has_download: bool

Checks whether a download is possible for the instance.

class core.models.Attachment(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('attachment'), DownloadMixin, ThumbnailMixin, URLMixin, FavoriteModelMixin, FilePathModelMixin, TimestampModelMixin, Model

Database model for an attachment file in a mail.

BASENAME = 'attachment'
DELETE_NOTICE = 'This will only delete the record of this attachment, not of the email.'
DELETE_NOTICE_PLURAL = 'This will only delete the records of these attachments, not of their emails.'
file_name

The filename of the attachment.

content_disposition

The disposition of the file. Typically ‘attachment’, ‘inline’ or ‘’.

content_id

The MIME subtype of the file.

content_maintype

The MIME maintype of the file.

content_subtype

The MIME subtype of the file.

datasize

The filesize of the attachment.

email: ForeignKey

The mail that the attachment was found in. Deletion of that email deletes this attachment.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the attachment, using file_name and email.

save(*args, **kwargs)[source]

Extended :django:django.models.Model.save() method.

Saves the data to storage if configured.

Return type:

None

Parameters:
_get_storage_file_name()[source]

Create the filename for the stored attachment.

Return type:

str

share_to_paperless()[source]

Sends this attachment to the Paperless server of its user.

Return type:

str

Returns:

The uuid string of the Paperless consumer task for the document.

Raises:
exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Attachment>
created

The datetime the model instance was created. Is set automatically.

email_id
file_path

The relative path in the storage where the file is stored. Can be null if no file has been saved (null does not collide with the unique constraint.).

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_favorite

Flags favorite accounts. False by default.

objects = <django.db.models.manager.Manager object>
share_to_immich()[source]

Sends this attachment to the Immich server of its user.

Return type:

str

Returns:

The response by Immich with the id string of the stored immich image.

Raises:
updated

The datetime the model instance entry was last updated. Is set automatically.

property has_thumbnail: bool

Whether the attachment has a mimetype that can be embedded into html.

References

https://stackoverflow.com/questions/51107683/which-mime-types-can-be-displayed-in-browser

property thumbnail: str[source]

Builds the html thumbnail for the attachment.

Returns:

The html for the thumbnail. The empty string if the attachment has no thumbnail.

property content_type: str

Reconstructs the full MIME content type of the attachment.

Returns:

The attachments content type if known, else “”.

property is_shareable_to_paperless: bool

Whether the attachment has a mimetype that can be processed by a paperless server.

References

https://docs.paperless-ngx.com/faq/#what-file-types-does-paperless-ngx-support

property is_shareable_to_immich: bool

Whether the attachment has a mimetype that can be processed by a Immich server.

References

https://immich.app/docs/features/supported-formats/

classmethod create_from_email_message(email_message, email)[source]

Creates :class:`core.models.Attachment`s from an email message.

Parameters:
  • email_message (EmailMessage) – The email_message to get and create all attachments from.

  • email (Email) – The email model created from the email_message.

Return type:

list[Attachment]

Returns:

A list of core.models.Attachment in the email message.

static queryset_as_file(queryset)[source]

Processes the files of the emails in the queryset into a temporary file.

Parameters:

queryset (QuerySet) – The email queryset to compile into a file.

Return type:

_TemporaryFileWrapper

Returns:

The temporary file wrapper.

Raises:

Attachment.DoesNotExist – If the queryset is empty.

class core.models.Correspondent(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('correspondent'), DownloadMixin, URLMixin, FavoriteModelMixin, TimestampModelMixin, Model

Database model for the correspondent data found in a mail.

BASENAME = 'correspondent'
DELETE_NOTICE = 'This will only delete the record of this correspondent, not of its emails.'
DELETE_NOTICE_PLURAL = 'This will only delete the records of these correspondents, not of their emails.'
email_address

The mail address of the correspondent. Unique.

email_name

The mailer name. Can be blank if none has been found.

real_name

The real name. Can be blank if the user doesn’t set one.

user

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

list_id

The List-ID header of the mailinglist. Unique together with correspondent.

list_owner

The List-Owner header of the mailinglist. Can be blank.

list_subscribe

The List-Subscribe header of the mailinglist. Can be blank.

list_unsubscribe

The List-Unsubscribe header of the mailinglist. Can be blank.

list_unsubscribe_post

The List-Unsubscribe-Post header of the mailinglist. Can be blank.

list_post

The List-Post header of the mailinglist. Can be blank.

list_help

The List-Help header of the mailinglist. Can be blank.

list_archive

The List-Archive header of the mailinglist. Can be blank.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Correspondent>
correspondentemails

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

created

The datetime the model instance was created. Is set automatically.

emails

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_favorite

Flags favorite accounts. False by default.

objects = <django.db.models.manager.Manager object>
updated

The datetime the model instance entry was last updated. Is set automatically.

user_id
__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the correspondent, using email_address.

share_to_nextcloud()[source]

Sends this attachment to the Nextcloud server of its user.

Note

Nextcloud returns 201 on success.

Raises:
  • RuntimeError – If the users Nextcloud URL is not or improperly set.

  • ConnectionError – If connecting to Nextcloud failed.

  • PermissionError – If authentication to Nextcloud failed.

  • ValueError – If uploading the file to Nextcloud resulted in a bad response.

Return type:

None

property is_mailinglist: bool

Whether the correspondent is a mailinglist.

Returns:

Whether the correspondent has any list_ attributes.

property list_unsubscribe_post_name: str

Gets the name of the list unsubscribe method from list_unsubscribe.

Returns:

The name of the list unsubscribe method.

property list_archive_href: str

Parses the href for subscribing to the correspondents list.

Returns:

The correspondents subscribe hyperref. The empty string if list_unsubscribe is empty.

property list_help_href: str

Parses the href for subscribing to the correspondents list.

Returns:

The correspondents subscribe hyperref. The empty string if list_unsubscribe is empty.

property list_post_href: str

Parses the href for subscribing to the correspondents list.

Returns:

The correspondents subscribe hyperref. The empty string if list_unsubscribe is empty.

property list_subscribe_href: str

Parses the href for subscribing to the correspondents list.

Returns:

The correspondents subscribe hyperref. The empty string if list_unsubscribe is empty.

property list_unsubscribe_href: str

Parses the href for unsubscribing from the correspondents list.

Returns:

The correspondents unsubscribe hyperref. The empty string if list_unsubscribe is empty.

property name: str

Gets the best available name for the correspondent, if necessary from the mailaddress.

Returns:

The most accurate available name of the correspondent.

property has_download: bool

Correspondent can always be downloaded.

classmethod create_from_correspondent_tuple(correspondent_tuple, user)[source]

Creates a core.models.Correspondent from email header data.

Parameters:
  • correspondent_tuple (tuple[str, str]) – The tuple of correspondent data to create a model from.

  • user (User) – The user the correspondent shall belong to.

Return type:

Correspondent | None

Returns:

The core.models.Correspondent with the data from the header. If the correspondent already exists in the db returns that version. None if there is no address in correspondent_tuple.

static queryset_as_file(queryset)[source]

Parse the correspondents in the queryset into a vcard object bytestream.

Parameters:

queryset (QuerySet) – The correspondent queryset to compile into a file.

Return type:

BytesIO

Returns:

The vcard object bytestream.

Raises:

Correspondent.DoesNotExist – If the queryset is empty.

class core.models.Daemon(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('routine'), DirtyFieldsMixin, URLMixin, HealthModelMixin, TimestampModelMixin, Model

Database model for the daemon fetching a mailbox.

Note

The internal name of this object is daemon, the external name for the user interface is routine.

BASENAME = 'daemon'
DELETE_NOTICE = 'This will only delete this routine, not its mailbox.'
DELETE_NOTICE_PLURAL = 'This will only delete these routine, not their mailboxes.'
uuid

The uuid of this daemon. Used to create a unique logfile.

mailbox: ForeignKey

The mailbox this daemon fetches. Unique. Deletion of that mailbox deletes this daemon.

fetching_criterion

The fetching criterion for this mailbox. eonvelope.constants.EmailFetchingCriterionChoices.ALL by default.

fetching_criterion_arg

Additional fetching criterion argument for this mailbox. “” by default.

celery_task: OneToOneField

The periodic celery task wrapped by this daemon.

interval: ForeignKey

The period with which the daemon is running.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Daemon>
celery_task_id
created

The datetime the model instance was created. Is set automatically.

get_fetching_criterion_display(*, field=<django.db.models.fields.CharField: fetching_criterion>)
get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

interval_id
is_healthy

Flags whether the model instance is subject to errors. None by default.

last_error

The latest error in connection with the model instance.

last_error_occurred_at

The time of occurrence of the latest error.

mailbox_id
objects = <django.db.models.manager.Manager object>
updated

The datetime the model instance entry was last updated. Is set automatically.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the daemon, using uuid and mailbox.

save(*args, **kwargs)[source]

Extended :django:django.models.Model.save() method.

Return type:

None

Parameters:
delete(*args, **kwargs)[source]
Return type:

tuple[int, dict[str, int]]

Parameters:
clean()[source]

Validates that fetching_criterion is available for the mailbox.account.

Return type:

None

test()[source]

Tests whether the data in the model is correct and the daemons task can be run.

Tests the entire task, including fetching and the celery backend. The core.models.Daemon.is_healthy flag is set accordingly by the task itself.

Raises:

Exception – Any exception raised by the task.

Return type:

None

start()[source]

Start the daemons celery_task.

Return type:

bool

Returns:

Whether the start operation was successful.

stop()[source]

Stops the daemons celery_task.

Return type:

bool

Returns:

Whether the stop operation was successful.

class core.models.Email(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('email'), DownloadMixin, ThumbnailMixin, URLMixin, FavoriteModelMixin, FilePathModelMixin, TimestampModelMixin, Model

Database model for an email.

BASENAME = 'email'
DELETE_NOTICE = 'This will delete the records of this email and all its attachments but not its correspondents.'
DELETE_NOTICE_PLURAL = 'This will delete the records of these emails and all their attachments but not their correspondents.'
message_id

The messageID header of the mail. Unique together with mailbox.

datetime

The Date header of the mail.

subject

The subject header of the mail.

plain_bodytext

The plain bodytext of the mail. Can be blank.

html_bodytext

The html bodytext of the mail. Can be blank.

in_reply_to: models.ManyToManyField[Email, Email]

The mails that this mail is a response to. Technically just a single mail, but as a mail can exist in multiple mailboxes, this needs to be able to reference multiples.

references: models.ManyToManyField[Email, Email]

The mails that this email references.

datasize

The bytes size of the mail.

correspondents: models.ManyToManyField[Correspondent, Correspondent]

The correspondents that are mentioned in this mail. Bridges through core.models.EmailCorrespondent.

mailbox: models.ForeignKey[Mailbox]

The mailbox that this mail has been found in. Unique together with message_id. Deletion of that mailbox deletes this mail.

headers

All other header fields of the mail. Can be null.

x_spam_flag

The x_spam header of this mail. Can be null.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the email, using message_id, datetime and mailbox.

save(*args, **kwargs)[source]

Extended :django:django.models.Model.save() method.

Saves the data to eml if configured.

Return type:

None

Parameters:
_get_storage_file_name()[source]

Create the filename for the stored eml.

Return type:

str

fill_from_email_bytes(email_bytes)[source]

Fills the core.models.Email with data from an email in bytes form.

Parameters:

email_bytes (bytes) – The email bytes data.

Return type:

Email

Returns:

The core.models.Email instance with data from the bytes.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Email>
add_correspondents()[source]

Adds the correspondents from the headerfields to the model.

Return type:

None

attachments

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

created

The datetime the model instance was created. Is set automatically.

emailcorrespondents

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

file_path

The relative path in the storage where the file is stored. Can be null if no file has been saved (null does not collide with the unique constraint.).

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_datetime(*, field=<django.db.models.fields.DateTimeField: datetime>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_datetime(*, field=<django.db.models.fields.DateTimeField: datetime>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_favorite

Flags favorite accounts. False by default.

mailbox_id
objects = <django.db.models.manager.Manager object>
referenced_by

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

replies

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

updated

The datetime the model instance entry was last updated. Is set automatically.

add_in_reply_to()[source]

Adds the in-reply-to emails from the headerfields to the model.

Return type:

None

add_references()[source]

Adds the references from the headerfields to the model.

Return type:

None

reprocess()[source]

Reprocesses the mails connections to other emails in the database.

Return type:

None

restore_to_mailbox()[source]

Restores the email to its mailbox.

Raises:
Return type:

None

property conversation: QuerySet[source]

Recursively gets all emails that are part of this emails conversation, connected through references or in_reply_to.

Returns:

Queryset of all mails in the conversation.

property has_thumbnail: bool

Checks whether a thumbnail download is possible for the instance.

property can_be_restored: bool

Checks if the email can be restored to its mailbox.

Returns:

Whether the email can be restored.

property html_version: str[source]

Renders a html version of this email.

Uses the template and css from constance settings.

Returns:

The emails html version.

property is_spam: bool

Checks the spam headers to decide whether the mail is spam.

Returns:

Whether the mail is considered spam.

classmethod create_from_email_bytes(email_bytes, mailbox)[source]

Creates an core.models.Email from an email in bytes form.

Parameters:
  • email_bytes (bytes) – The email bytes to parse the emaildata from.

  • mailbox (Mailbox) – The mailbox the email is in.

Return type:

Email | None

Returns:

The core.models.Email instance with data from the bytes. None if there is no Message-ID header in email_message, if the mail already exists in the db or if the mail is spam and is supposed to be thrown out.

static _queryset_as_zip_eml(queryset)[source]

Parses a queryset of emails into a zip of eml files.

Note

Does not validate args! This has to be done beforehand.

Return type:

_TemporaryFileWrapper

Parameters:

queryset (QuerySet)

static _queryset_as_mailbox_file(queryset, file_format)[source]

Parses a queryset of emails into a mailbox file.

Note

Does not validate args! This has to be done beforehand.

Return type:

_TemporaryFileWrapper

Parameters:
static _queryset_as_mailbox_zip(queryset, file_format)[source]

Parses a queryset of emails into a zipped mailbox dir.

Note

Does not validate args! This has to be done beforehand.

Return type:

_TemporaryFileWrapper

Parameters:
static queryset_as_file(queryset, file_format)[source]

Processes the files of the emails in the queryset into a temporary file.

Parameters:
Return type:

_TemporaryFileWrapper

Returns:

The temporary file wrapper.

Raises:
class core.models.EmailCorrespondent(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('email_correspondent'), URLMixin, TimestampModelMixin, Model

Database model for connecting emails and their correspondents.

BASENAME = 'email'

Direct user to email endpoints.

DELETE_NOTICE = 'This will delete the records of this email and all its attachments but not its correspondents.'
DELETE_NOTICE_PLURAL = 'This will delete the records of these emails and all their attachments but not their correspondents.'
email

The email correspondent was mentioned in. Unique together with correspondent and mention.

correspondent

The correspondent mentioned in email. Unique together with email and mention.

mention

The mention of correspondent in email. Unique together with email and correspondent.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for EmailCorrespondent>
correspondent_id
created

The datetime the model instance was created. Is set automatically.

email_id
get_mention_display(*, field=<django.db.models.fields.CharField: mention>)
get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
updated

The datetime the model instance entry was last updated. Is set automatically.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the emailcorrespondent, using email, correspondent and mention.

classmethod create_from_header(header, header_name, email)[source]

Prepares a list core.models.EmailCorrespondent from an email header.

Parameters:
  • header (str) – The header to parse the malinglistdata from.

  • header_name (str) – The name of the header, the mention type of the correspondent.

  • email (Email) – The email for the new emailcorrespondent.

Return type:

set[EmailCorrespondent] | None

Returns:

The list of core.models.EmailCorrespondent instances with data from the header. If the correspondent already exists in the db. None if the correspondent could not be parsed.

Raises:

ValueError – If the email argument is not in the db.

class core.models.Mailbox(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('mailbox'), DirtyFieldsMixin, URLMixin, UploadMixin, DownloadMixin, FavoriteModelMixin, HealthModelMixin, TimestampModelMixin, Model

Database model for a mailbox in a mail account.

BASENAME = 'mailbox'
DELETE_NOTICE = 'This will delete the record of this mailbox and all emails and attachments found in it!'
DELETE_NOTICE_PLURAL = 'This will delete the records of these mailboxes and all emails and attachments found in them!'
name

The mailaccount internal name of the mailbox. Unique together with account.

type

The mailaccount internal role or distinguished id of the mailbox.

account: models.ForeignKey[Account]

The mailaccount this mailbox was found in. Unique together with name. Deletion of that account deletes this mailbox.

save_attachments

Whether to save attachments of the mails found in this mailbox. constance.get_config('DEFAULT_SAVE_ATTACHMENTS') by default.

save_to_eml

Whether to save the mails found in this mailbox as .eml files. constance.get_config('DEFAULT_SAVE_TO_EML') by default.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the mailbox, using name and account.

test()[source]

Tests whether the data in the model is correct.

Tests connecting and logging in to the mailhost and account. The core.models.Mailbox.is_healthy flag is set accordingly. Relies on the test method of the core.utils.fetchers classes.

Raises:
  • MailAccountError – If the test is fails due to an issue with the account.

  • MailboxError – If the test is fails due to an issue with the mailbox.

Return type:

None

fetch(criterion)[source]

Fetches emails from this mailbox based on criterion and adds them to the db.

If successful, marks this mailbox as healthy, otherwise unhealthy.

Parameters:

criterion (FetchingCriterion) – The criterion used to fetch emails from the mailbox.

Raises:
  • MailboxError – Reraised if fetching failed due to a MailboxError.

  • MailAccountError – Reraised if fetching failed due to a MailAccountError.

Return type:

None

_add_email_from_eml(file)[source]

Reads emails from a zipped mailbox dir.

Return type:

None

Parameters:

file (BinaryIO)

_add_emails_from_zip_eml(file)[source]

Reads emails from a zip of eml files.

Return type:

None

Parameters:

file (BinaryIO)

_add_emails_from_mailbox_file(file, file_format)[source]

Reads emails from a mailbox file.

Note

Does not validate file_format! This has to be done beforehand.

Return type:

None

Parameters:
_add_emails_from_mailbox_zip(file, file_format)[source]

Reads emails from a zipped mailbox dir.

Note

Does not validate file_format! This has to be done beforehand.

Return type:

None

Parameters:
add_emails_from_file(file, file_format)[source]

Adds emails from a file to the db.

Parameters:
  • file (BinaryIO) – The mailbox file.

  • file_format (str) – The format of the mailbox file. Case-insensitive.

Raises:

ValueError – If the file format is not implemented or the file failed to open.

Return type:

None

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for Mailbox>
account_id
created

The datetime the model instance was created. Is set automatically.

daemons

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

emails

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
get_type_display(*, field=<django.db.models.fields.CharField: type>)
property has_download: bool

Checks whether a download is possible for the instance.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_favorite

Flags favorite accounts. False by default.

is_healthy

Flags whether the model instance is subject to errors. None by default.

last_error

The latest error in connection with the model instance.

last_error_occurred_at

The time of occurrence of the latest error.

objects = <django.db.models.manager.Manager object>
updated

The datetime the model instance entry was last updated. Is set automatically.

property available_fetching_criteria: tuple[str, ...]

Gets the available fetching criteria based on the mail protocol of this mailbox.

Returns:

A tuple of all available fetching criteria for this mailbox.

Raises:

ValueError – If the account has an unimplemented protocol.

property available_no_arg_fetching_criteria: tuple[str, ...]

Gets the available fetching criteria that do not require an argument based on the mail protocol of this mailbox.

Returns:

A tuple of all available fetching criteria that do not require an argument for this mailbox.

Raises:

ValueError – If the account has an unimplemented protocol.

property available_fetching_criterion_choices: list[tuple[str, StrOrPromise]]

Gets the available fetching criterion choices based on the mail protocol of this mailbox.

Returns:

A choices-type tuple of all available fetching criteria for this mailbox.

Raises:

ValueError – If the account has an unimplemented protocol.

property available_no_arg_fetching_criterion_choices: list[tuple[str, StrOrPromise]]

Gets the available fetching criterion choices that do not require an argumentbased on the mail protocol of this mailbox.

Returns:

A choices-type tuple of all available fetching criteria that do not require an argument for this mailbox.

Raises:

ValueError – If the account has an unimplemented protocol.

property available_download_formats: list[tuple[str, StrOrPromise]]

Get all formats that emails in this mailbox can be downloaded in.

Returns:

A list of download formats and format names.

classmethod create_from_data(mailbox_name, mailbox_type, account)[source]

Creates a core.models.Mailbox from the mailboxdata.

Note

Mailbox created from data is considered healthy by default.

Parameters:
  • mailbox_name (str) – The name of the mailbox.

  • mailbox_type (str) – The type of the mailbox.

  • account (Account) – The account the mailbox is in.

Return type:

Mailbox | None

Returns:

The core.models.Mailbox instance with data from the bytes. None if the mailbox name is ignored.

Raises:

ValueError – If the given account is not in the db.

static queryset_as_file(queryset, file_format)[source]

Processes the files of the emails in the mailboxes in the queryset into a temporary file.

Parameters:
Return type:

_TemporaryFileWrapper

Returns:

The temporary file wrapper.

Raises:
class core.models.StorageShard(*args, **kwargs)[source]

Bases: ExportModelOperationsMixin('storage_shard'), TimestampModelMixin, Model

A database model to keep track of and manage the sharded storage’s status and structure.

Important

Use the custom methods to create new instances, never use create()!

shard_directory_name

The name of the directory tracked by this entry. Unique.

file_count

The number of files in this directory. 0 by default. Managed to not exceed constance.get_config('STORAGE_MAX_FILES_PER_DIR').

current

Flags whether this directory is the one where new data is being stored. False by default. There must only be one entry where this is set to True.

__str__()[source]

Returns a string representation of the model data.

Return type:

str

Returns:

The string representation of the storage directory, using path and the state of the directory.

save(*args, **kwargs)[source]

Extended :django:django.models.Model.save() method.

Safely creates the new directory tracked by the instance in the storage.

Return type:

None

Parameters:
exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

_meta = <Options for StorageShard>
created

The datetime the model instance was created. Is set automatically.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_updated(*, field=<django.db.models.fields.DateTimeField: updated>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

increment_file_count()[source]

Increments the file_count within the limits of constance.get_config('STORAGE_MAX_FILES_PER_DIR').

If the result exceeds this limit, creates a new storage directory via _add_shard().

Return type:

None

objects = <django.db.models.manager.Manager object>
updated

The datetime the model instance entry was last updated. Is set automatically.

decrement_file_count()[source]

Decrements the file_count but never below 0.

Return type:

None

classmethod get_current_storage()[source]

Gets the current storage instance.

Creates one if none is found.

Returns:

The currently used storage directory shard.

Return type:

StorageShard

classmethod _add_shard()[source]

Adds a new current storage directory.

Return type:

StorageShard

classmethod healthcheck()[source]

Provides a healthcheck for the storage.

Return type:

bool

Returns:

True if storage is healthy, False if there is no unique current storage directory or the count of files for one of the directories is wrong.

Submodules