Merge pull request #4553 from FinnStutzenstein/removeMotionLogs

Remove motion logs
This commit is contained in:
Finn Stutzenstein 2019-04-02 12:12:31 +02:00 committed by GitHub
commit 2f10fad375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 160 deletions

View File

@ -0,0 +1,14 @@
# Generated by Django 2.1.7 on 2019-04-01 06:58
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("motions", "0022_auto_20190320_0840")]
operations = [
migrations.RemoveField(model_name="motionlog", name="motion"),
migrations.RemoveField(model_name="motionlog", name="person"),
migrations.DeleteModel(name="MotionLog"),
]

View File

@ -6,7 +6,6 @@ from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import IntegrityError, models, transaction
from django.db.models import Max
from django.utils import formats, timezone
from jsonfield import JSONField
from openslides.agenda.models import Item
@ -81,7 +80,6 @@ class MotionManager(models.Manager):
"comments__section",
"comments__section__read_groups",
"agenda_items",
"log_messages",
"polls",
"attachments",
"tags",
@ -540,17 +538,6 @@ class Motion(RESTModelMixin, models.Model):
"""
return self.agenda_item.pk
def write_log(self, message_list, person=None, skip_autoupdate=False):
"""
Write a log message.
The message should be in English.
"""
if person and not person.is_authenticated:
person = None
motion_log = MotionLog(motion=self, message_list=message_list, person=person)
motion_log.save(skip_autoupdate=skip_autoupdate)
def is_amendment(self):
"""
Returns True if the motion is an amendment.
@ -903,50 +890,6 @@ class MotionBlock(RESTModelMixin, models.Model):
return {"title": self.title}
class MotionLog(RESTModelMixin, models.Model):
"""Save a logmessage for a motion."""
motion = models.ForeignKey(
Motion, on_delete=models.CASCADE, related_name="log_messages"
)
"""The motion to witch the object belongs."""
message_list = JSONField()
"""
The log message. It should be a list of strings in English.
"""
person = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=SET_NULL_AND_AUTOUPDATE, null=True
)
"""A user object, who created the log message. Optional."""
time = models.DateTimeField(auto_now=True)
"""The Time, when the loged action was performed."""
class Meta:
default_permissions = ()
ordering = ["-time"]
def __str__(self):
"""
Return a string, representing the log message.
"""
localtime = timezone.localtime(self.time)
time = formats.date_format(localtime, "DATETIME_FORMAT")
message_list = "".join(self.message_list)
time_and_messages = f"{time} {message_list}"
if self.person is not None:
return f"{time_and_messages} by {self.person}"
return time_and_messages
def get_root_rest_element(self):
"""
Returns the motion to this instance which is the root REST element.
"""
return self.motion
class MotionVote(RESTModelMixin, BaseVote):
"""Saves the votes for a MotionPoll.

View File

@ -25,7 +25,6 @@ from .models import (
MotionChangeRecommendation,
MotionComment,
MotionCommentSection,
MotionLog,
MotionPoll,
State,
StatuteParagraph,
@ -171,24 +170,6 @@ class AmendmentParagraphsJSONSerializerField(Field):
return data
class MotionLogSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionLog objects.
"""
message = SerializerMethodField()
class Meta:
model = MotionLog
fields = ("message_list", "person", "time", "message")
def get_message(self, obj):
"""
Concats the message parts to one string. Useful for smart template code.
"""
return str(obj)
class MotionPollSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionPoll objects.
@ -385,7 +366,6 @@ class MotionSerializer(ModelSerializer):
"""
comments = MotionCommentSerializer(many=True, read_only=True)
log_messages = MotionLogSerializer(many=True, read_only=True)
polls = MotionPollSerializer(many=True, read_only=True)
modified_final_version = CharField(allow_blank=True, required=False)
reason = CharField(allow_blank=True, required=False)
@ -435,7 +415,6 @@ class MotionSerializer(ModelSerializer):
"agenda_item_id",
"agenda_type",
"agenda_parent_id",
"log_messages",
"sort_parent",
"weight",
"created",

View File

@ -223,9 +223,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
for submitter in submitters:
Submitter.objects.add(submitter, motion)
# Write the log message and initiate response.
motion.write_log(["Motion created"], request.user)
# Send new submitters and supporters via autoupdate because users
# without permission to see users may not have them but can get it now.
# TODO: Skip history.
@ -298,16 +295,13 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
serializer.is_valid(raise_exception=True)
updated_motion = serializer.save()
# Write the log message, check removal of supporters and initiate response.
# TODO: Log if a motion was updated.
updated_motion.write_log(["Motion updated"], request.user)
# Check removal of supporters and initiate response.
if (
config["motions_remove_supporters"]
and updated_motion.state.allow_support
and not has_perm(request.user, "motions.can_manage")
):
updated_motion.supporters.clear()
updated_motion.write_log(["All supporters removed"], request.user)
# Send new supporters via autoupdate because users
# without permission to see users may not have them but can get it now.
@ -390,19 +384,15 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
comment.comment = comment_value
comment.save()
# write log
motion.write_log([f"Comment {section.name} updated"], request.user)
message = ["Comment {arg1} updated", section.name]
else: # DELETE
try:
comment = MotionComment.objects.get(motion=motion, section=section)
except MotionComment.DoesNotExist:
# Be silent about not existing comments, but do not create a log entry.
# Be silent about not existing comments.
pass
else:
comment.delete()
motion.write_log([f"Comment {section.name} deleted"], request.user)
message = ["Comment {arg1} deleted", section.name]
# Fire autoupdate again to save information to OpenSlides history.
@ -512,7 +502,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
):
raise ValidationError({"detail": "You can not support this motion."})
motion.supporters.add(request.user)
motion.write_log(["Motion supported"], request.user)
# Send new supporter via autoupdate because users without permission
# to see users may not have it but can get it now.
# TODO: Skip history.
@ -524,7 +513,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
if not motion.state.allow_support or not motion.is_supporter(request.user):
raise ValidationError({"detail": "You can not unsupport this motion."})
motion.supporters.remove(request.user)
motion.write_log(["Motion unsupported"], request.user)
message = "You have unsupported this motion successfully."
# Fire autoupdate again to save information to OpenSlides history.
@ -580,13 +568,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
)
message = f"The state of the motion was set to {motion.state.name}."
# Write the log message and initiate response.
motion.write_log(
message_list=[f"State set to {motion.state.name}"],
person=request.user,
skip_autoupdate=True,
)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
motion,
@ -661,13 +642,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
skip_autoupdate=True,
)
# Write the log message.
motion.write_log(
message_list=["State set to", " ", motion.state.name],
person=request.user,
skip_autoupdate=True,
)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
motion,
@ -731,13 +705,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
)
message = f"The recommendation of the motion was set to {label}."
# Write the log message and initiate response.
motion.write_log(
message_list=["Recommendation set to", " ", label],
person=request.user,
skip_autoupdate=True,
)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
motion,
@ -820,13 +787,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
else "None"
)
# Write the log message.
motion.write_log(
message_list=["Recommendation set to", " ", label],
person=request.user,
skip_autoupdate=True,
)
# Fire autoupdate and save information to OpenSlides history.
inform_changed_data(
motion,
@ -850,7 +810,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
motion.follow_recommendation()
# Save and write log.
motion.save(
update_fields=[
"state",
@ -861,11 +820,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
],
skip_autoupdate=True,
)
motion.write_log(
message_list=["State set to", " ", motion.state.name],
person=request.user,
skip_autoupdate=True,
)
# Now send all changes to the clients.
inform_changed_data(
@ -891,7 +845,6 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
poll = motion.create_poll(skip_autoupdate=True)
except WorkflowError as err:
raise ValidationError({"detail": err})
motion.write_log(["Vote created"], request.user, skip_autoupdate=True)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
@ -989,7 +942,6 @@ class MotionPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
"""
response = super().update(*args, **kwargs)
poll = self.get_object()
poll.motion.write_log(["Vote updated"], self.request.user)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
@ -1004,7 +956,6 @@ class MotionPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
"""
poll = self.get_object()
result = super().destroy(*args, **kwargs)
poll.motion.write_log(["Vote deleted"], self.request.user)
# Fire autoupdate again to save information to OpenSlides history.
inform_changed_data(
@ -1362,12 +1313,6 @@ class MotionBlockViewSet(ModelViewSet):
# Follow recommendation.
motion.follow_recommendation()
motion.save(skip_autoupdate=True)
# Write the log message.
motion.write_log(
message_list=["State set to", " ", motion.state.name],
person=request.user,
skip_autoupdate=True,
)
# Fire autoupdate and save information to OpenSlides history.
inform_changed_data(
motion,

View File

@ -15,7 +15,6 @@ from openslides.motions.models import (
MotionChangeRecommendation,
MotionComment,
MotionCommentSection,
MotionLog,
State,
StatuteParagraph,
Submitter,
@ -44,7 +43,6 @@ def test_motion_db_queries():
* 1 request for all motion comment sections required for the comments
* 1 request for all users required for the read_groups of the sections
* 1 request to get the agenda item,
* 1 request to get the motion log,
* 1 request to get the polls,
* 1 request to get the attachments,
* 1 request to get the tags,
@ -71,7 +69,7 @@ def test_motion_db_queries():
)
# TODO: Create some polls etc.
assert count_queries(Motion.get_elements) == 13
assert count_queries(Motion.get_elements) == 12
@pytest.mark.django_db(transaction=False)
@ -914,12 +912,6 @@ class ManageComments(TestCase):
comment = MotionComment.objects.get()
self.assertEqual(comment.comment, "test_comment_fk3jrnfwsdg%fj=feijf")
# Check for a log entry
motion_logs = MotionLog.objects.filter(motion=self.motion)
self.assertEqual(motion_logs.count(), 1)
comment_log = motion_logs.get()
self.assertTrue(self.section_read_write.name in comment_log.message_list[0])
def test_update_comment(self):
comment = MotionComment(
motion=self.motion,
@ -940,12 +932,6 @@ class ManageComments(TestCase):
comment = MotionComment.objects.get()
self.assertEqual(comment.comment, "test_comment_fk3jrnfwsdg%fj=feijf")
# Check for a log entry
motion_logs = MotionLog.objects.filter(motion=self.motion)
self.assertEqual(motion_logs.count(), 1)
comment_log = motion_logs.get()
self.assertTrue(self.section_read_write.name in comment_log.message_list[0])
def test_delete_comment(self):
comment = MotionComment(
motion=self.motion,
@ -962,12 +948,6 @@ class ManageComments(TestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(MotionComment.objects.count(), 0)
# Check for a log entry
motion_logs = MotionLog.objects.filter(motion=self.motion)
self.assertEqual(motion_logs.count(), 1)
comment_log = motion_logs.get()
self.assertTrue(self.section_read_write.name in comment_log.message_list[0])
def test_delete_not_existing_comment(self):
"""
This should fail silently; no error, if the user wants to delete
@ -981,10 +961,6 @@ class ManageComments(TestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(MotionComment.objects.count(), 0)
# Check that no log entry was created
motion_logs = MotionLog.objects.filter(motion=self.motion)
self.assertEqual(motion_logs.count(), 0)
def test_create_comment_no_write_permission(self):
response = self.client.post(
reverse("motion-manage-comments", args=[self.motion.pk]),