2016-10-25 19:51:31 +02:00
|
|
|
from __future__ import absolute_import
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
from datetime import timedelta
|
2017-05-14 21:14:26 +02:00
|
|
|
|
|
|
|
from django.db import connection, transaction
|
|
|
|
from django.forms.models import model_to_dict
|
2017-04-15 04:03:56 +02:00
|
|
|
from django.utils.timezone import now as timezone_now
|
2017-05-14 21:14:26 +02:00
|
|
|
from zerver.models import Realm, Message, UserMessage, ArchivedMessage, ArchivedUserMessage, \
|
|
|
|
Attachment, ArchivedAttachment
|
2016-10-25 19:51:31 +02:00
|
|
|
|
2017-03-03 19:01:52 +01:00
|
|
|
from typing import Any, Dict, Optional, Generator
|
2016-10-25 19:51:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_realm_expired_messages(realm):
|
|
|
|
# type: (Any) -> Optional[Dict[str, Any]]
|
2017-04-15 04:03:56 +02:00
|
|
|
expired_date = timezone_now() - timedelta(days=realm.message_retention_days)
|
2016-10-25 19:51:31 +02:00
|
|
|
expired_messages = Message.objects.order_by('id').filter(sender__realm=realm,
|
|
|
|
pub_date__lt=expired_date)
|
|
|
|
if not expired_messages.exists():
|
|
|
|
return None
|
2016-11-30 21:55:59 +01:00
|
|
|
return {'realm_id': realm.id, 'expired_messages': expired_messages}
|
2016-10-25 19:51:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_expired_messages():
|
|
|
|
# type: () -> Generator[Any, None, None]
|
|
|
|
# Get all expired messages by Realm.
|
2017-03-14 01:20:25 +01:00
|
|
|
realms = Realm.objects.order_by('string_id').filter(
|
|
|
|
deactivated=False, message_retention_days__isnull=False)
|
2016-10-25 19:51:31 +02:00
|
|
|
for realm in realms:
|
|
|
|
realm_expired_messages = get_realm_expired_messages(realm)
|
|
|
|
if realm_expired_messages:
|
|
|
|
yield realm_expired_messages
|
2017-05-14 21:14:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
def move_attachment_message_to_archive_by_message(message_id):
|
|
|
|
# type: (int) -> None
|
|
|
|
# Move attachments messages relation table data to archive.
|
|
|
|
query = """
|
|
|
|
INSERT INTO zerver_archivedattachment_messages (id, archivedattachment_id,
|
|
|
|
archivedmessage_id)
|
|
|
|
SELECT zerver_attachment_messages.id, zerver_attachment_messages.attachment_id,
|
|
|
|
zerver_attachment_messages.message_id
|
|
|
|
FROM zerver_attachment_messages
|
|
|
|
LEFT JOIN zerver_archivedattachment_messages
|
|
|
|
ON zerver_archivedattachment_messages.id = zerver_attachment_messages.id
|
|
|
|
WHERE zerver_attachment_messages.message_id = {message_id}
|
|
|
|
AND zerver_archivedattachment_messages.id IS NULL
|
|
|
|
"""
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
cursor.execute(query.format(message_id=message_id))
|
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
def move_message_to_archive(message_id):
|
|
|
|
# type: (int) -> None
|
|
|
|
msg = list(Message.objects.filter(id=message_id).values())
|
|
|
|
if not msg:
|
|
|
|
raise Message.DoesNotExist
|
|
|
|
arc_message = ArchivedMessage(**msg[0])
|
|
|
|
arc_message.save()
|
|
|
|
|
|
|
|
# Move user_messages to the archive.
|
|
|
|
user_messages = UserMessage.objects.filter(
|
|
|
|
message_id=message_id).exclude(id__in=ArchivedUserMessage.objects.all())
|
|
|
|
archiving_messages = []
|
|
|
|
for user_message in user_messages.values():
|
|
|
|
archiving_messages.append(ArchivedUserMessage(**user_message))
|
|
|
|
ArchivedUserMessage.objects.bulk_create(archiving_messages)
|
|
|
|
|
|
|
|
# Move attachments to archive
|
|
|
|
attachments = Attachment.objects.filter(messages__id=message_id).exclude(
|
|
|
|
id__in=ArchivedAttachment.objects.all())
|
|
|
|
archiving_attachments = []
|
|
|
|
for attachment in attachments.values():
|
|
|
|
archiving_attachments.append(ArchivedAttachment(**attachment))
|
|
|
|
ArchivedAttachment.objects.bulk_create(archiving_attachments)
|
|
|
|
move_attachment_message_to_archive_by_message(message_id)
|
|
|
|
|
|
|
|
# Remove data from main tables
|
|
|
|
Message.objects.get(id=message_id).delete()
|
|
|
|
user_messages.filter(id__in=ArchivedUserMessage.objects.all(),
|
|
|
|
message_id__isnull=True).delete()
|
|
|
|
archived_attachments = ArchivedAttachment.objects.filter(messages__id=message_id)
|
|
|
|
Attachment.objects.filter(messages__isnull=True, id__in=archived_attachments).delete()
|