← Back to team overview

launchpad-reviewers team mailing list archive

Re: [Merge] ~pappacena/launchpad:comment-editing-model into launchpad:master

 

Pushed the requested changes. This should be good to go now.

Diff comments:

> diff --git a/lib/lp/services/messages/interfaces/messagerevision.py b/lib/lp/services/messages/interfaces/messagerevision.py
> new file mode 100644
> index 0000000..3b72673
> --- /dev/null
> +++ b/lib/lp/services/messages/interfaces/messagerevision.py
> @@ -0,0 +1,69 @@
> +# Copyright 2019-2021 Canonical Ltd.  This software is licensed under the
> +# GNU Affero General Public License version 3 (see the file LICENSE).
> +
> +"""Message revision history."""
> +
> +from __future__ import absolute_import, print_function, unicode_literals
> +
> +__all__ = [
> +    'IMessageRevision',
> +    'IMessageRevisionChunk',
> +    ]
> +
> +from lazr.restful.fields import Reference
> +from zope.interface import (
> +    Attribute,
> +    Interface,
> +    )
> +from zope.schema import (
> +    Datetime,
> +    Int,
> +    Text,
> +    )
> +
> +from lp import _
> +from lp.services.messages.interfaces.message import IMessage
> +
> +
> +class IMessageRevisionView(Interface):
> +    """IMessageRevision readable attributes."""
> +    id = Int(title=_("ID"), required=True, readonly=True)
> +
> +    revision = Int(title=_("Revision number"), required=True, readonly=True)
> +
> +    content = Text(
> +        title=_("The message at the given revision"),
> +        required=False, readonly=True)

:facepalm:
Fixing it.

> +
> +    message = Reference(
> +        title=_('The current message of this revision.'),
> +        schema=IMessage, required=True, readonly=True)
> +
> +    date_created = Datetime(
> +        title=_("The time when this message revision was created."),
> +        required=True, readonly=True)
> +
> +    date_deleted = Datetime(
> +        title=_("The time when this message revision was created."),
> +        required=False, readonly=True)
> +
> +    chunks = Attribute(_('Message pieces'))
> +
> +
> +class IMessageRevisionEdit(Interface):
> +    """IMessageRevision editable attributes."""
> +
> +    def deleteContent():
> +        """Logically deletes this MessageRevision."""
> +
> +
> +class IMessageRevision(IMessageRevisionView, IMessageRevisionEdit):
> +    """A historical revision of a IMessage."""
> +
> +
> +class IMessageRevisionChunk(Interface):
> +    id = Int(title=_('ID'), required=True, readonly=True)
> +    messagerevision = Int(
> +        title=_('MessageRevision'), required=True, readonly=True)
> +    sequence = Int(title=_('Sequence order'), required=True, readonly=True)
> +    content = Text(title=_('Text content'), required=False, readonly=True)
> diff --git a/lib/lp/services/messages/model/message.py b/lib/lp/services/messages/model/message.py
> index e592daa..b73e212 100644
> --- a/lib/lp/services/messages/model/message.py
> +++ b/lib/lp/services/messages/model/message.py
> @@ -164,6 +176,63 @@ class Message(SQLBase):
>          """See `IMessage`."""
>          return None
>  
> +    @cachedproperty
> +    def revisions(self):
> +        """See `IMessage`."""
> +        return list(Store.of(self).find(
> +            MessageRevision,
> +            MessageRevision.message == self
> +        ).order_by(Desc(MessageRevision.revision)))
> +
> +    def editContent(self, new_content):
> +        """See `IMessage`."""
> +        store = Store.of(self)
> +
> +        # Move the old content to a new revision.
> +        date_created = (
> +            self.date_last_edited if self.date_last_edited is not None
> +            else self.datecreated)
> +        current_rev_num = store.find(
> +            Max(MessageRevision.revision),
> +            MessageRevision.message == self).one()
> +        rev_num = (current_rev_num or 0) + 1
> +        rev = MessageRevision(
> +            message=self, revision=rev_num, date_created=date_created)
> +        self.date_last_edited = utc_now()
> +        store.add(rev)
> +
> +        # Move the current text content to the recently created revision.
> +        for chunk in self._chunks:
> +            if chunk.blob is None:
> +                revision_chunk = MessageRevisionChunk(
> +                    rev, chunk.sequence, chunk.content)
> +                store.add(revision_chunk)
> +                store.remove(chunk)
> +
> +        # Create the new content.
> +        new_chunk = MessageChunk(message=self, sequence=1, content=new_content)

Ok! I'll try to fill eventual gaps instead of jumping directly into max_seq + 1.

> +        store.add(new_chunk)
> +
> +        store.flush()
> +
> +        # Clean up caches.
> +        del get_property_cache(self).text_contents
> +        del get_property_cache(self).chunks
> +        del get_property_cache(self).revisions
> +        return rev
> +
> +    def deleteContent(self):
> +        """See `IMessage`."""
> +        store = Store.of(self)
> +        store.find(MessageChunk, MessageChunk.message == self).remove()
> +        for rev in self.revisions:
> +            store.find(MessageRevisionChunk, message_revision=rev).remove()
> +        store.find(MessageRevision, MessageRevision.message == self).remove()
> +        del get_property_cache(self).text_contents
> +        del get_property_cache(self).chunks
> +        del get_property_cache(self).revisions
> +        self.date_deleted = utc_now()
> +
>  
>  def get_parent_msgids(parsed_message):
>      """Returns a list of message ids the mail was a reply to.


-- 
https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401894
Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:comment-editing-model.


References