prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [v18] J'ai perdu mes sujets suivis
  Version : 18
  OS Windows
  Navigateur Firefox
  
  Alors qu'une synchro a été faite entre la prod et la beta, je ne retrouve plus mes sujets suivis dans la page https://beta.zestedesavoir.com/forums/ comme on peut le voir sur la capture ci-dessous (il ne me reste plus qu'un sujet suivis au lieu de beaucoup plus)
  
  ![suivis](https://cloud.githubusercontent.com/assets/6066015/14254805/a75c8ac6-fa91-11e5-9852-d5dc2d60547b.PNG)
  
  
  </issue>
  <code>
  [start of zds/notification/management/commands/migrate_subscriptions.py]
  1 # coding: utf-8
  2 from django.core.management import BaseCommand
  3 from django.db.models import F, Q
  4 from zds.forum.models import TopicRead
  5 from zds.member.models import Profile
  6 from zds.mp.models import PrivateTopicRead, PrivateTopic
  7 from zds.notification.models import TopicFollowed, TopicAnswerSubscription, ContentReactionAnswerSubscription, \
  8     PrivateTopicAnswerSubscription
  9 from zds.tutorialv2.models.models_database import ContentReaction, ContentRead
  10 
  11 
  12 class Command(BaseCommand):
  13     help = 'Migrate old subscriptions and notifications for new models.'
  14 
  15     def handle(self, *args, **options):
  16         for profile in Profile.objects.all():
  17             self.stdout.write(u'Migrate all notifications of {}...'.format(profile.user.username))
  18             # Forums.
  19             self.stdout.write(u'Starting migration with topics...')
  20             topics_followed = TopicFollowed.objects.filter(user=profile.user).values("topic").distinct().all()
  21             topics_never_read = TopicRead.objects\
  22                 .filter(user=profile.user)\
  23                 .filter(topic__in=topics_followed)\
  24                 .select_related("topic")\
  25                 .exclude(post=F('topic__last_message')).all()
  26 
  27             for topic_never_read in topics_never_read:
  28                 content = topic_never_read.topic.first_unread_post(profile.user)
  29                 if content is None:
  30                     content = topic_never_read.topic.last_message
  31 
  32                 # Migrate subscriptions.
  33                 content_object = topic_never_read.topic
  34                 subscription = TopicAnswerSubscription.objects.get_or_create_active(
  35                     user=profile.user, content_object=content_object)
  36 
  37                 # Migrate notifications.
  38                 subscription.send_notification(content=content, sender=content.author)
  39                 notification = TopicAnswerSubscription.objects\
  40                     .get_existing(profile.user, content_object, is_active=True).last_notification
  41                 notification.pubdate = content.pubdate
  42                 notification.save()
  43 
  44                 self.stdout.write(u'Migration about « {} » [OK]'.format(topic_never_read.topic.title))
  45 
  46             # Private messages.
  47             self.stdout.write(u'Starting migration with private topics...')
  48             topics_never_read = list(PrivateTopicRead.objects
  49                                      .filter(user=profile.user)
  50                                      .filter(privatepost=F('privatetopic__last_message')).all())
  51 
  52             tnrs = []
  53             for tnr in topics_never_read:
  54                 tnrs.append(tnr.privatetopic.pk)
  55 
  56             private_topics_unread = PrivateTopic.objects \
  57                 .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \
  58                 .exclude(pk__in=tnrs) \
  59                 .order_by("-pubdate") \
  60                 .distinct()
  61 
  62             for private_topic_unread in private_topics_unread:
  63                 answer = private_topic_unread.last_read_post(profile.user)
  64                 if answer is None:
  65                     answer = private_topic_unread.get_last_answer()
  66 
  67                 # Migrate subscriptions.
  68                 subscription = PrivateTopicAnswerSubscription.objects.get_or_create_active(
  69                     user=profile.user, content_object=private_topic_unread)
  70 
  71                 # Migrate notifications.
  72                 subscription.send_notification(content=answer, sender=answer.author, send_email=False)
  73                 notification = PrivateTopicAnswerSubscription.objects\
  74                     .get_existing(profile.user, private_topic_unread, is_active=True).last_notification
  75                 notification.pubdate = answer.pubdate
  76                 notification.save()
  77 
  78                 self.stdout.write(u'Migration about « {} » [OK]'.format(private_topic_unread.title))
  79 
  80             # Contents.
  81             self.stdout.write(u'Starting migration with contents...')
  82             content_followed_pk = ContentReaction.objects\
  83                 .filter(author=profile.user, related_content__public_version__isnull=False)\
  84                 .values_list('related_content__pk', flat=True)
  85 
  86             content_to_read = ContentRead.objects\
  87                 .select_related('note')\
  88                 .select_related('note__author')\
  89                 .select_related('content')\
  90                 .select_related('note__related_content__public_version')\
  91                 .filter(user=profile.user)\
  92                 .exclude(note__pk=F('content__last_note__pk')).all()
  93 
  94             for content_read in content_to_read:
  95                 content = content_read.content
  96                 if content.pk not in content_followed_pk and profile.user not in content.authors.all():
  97                     continue
  98                 reaction = content.first_unread_note(user=profile.user)
  99                 if reaction is None:
  100                     reaction = content.first_note()
  101                 if reaction is None:
  102                     continue
  103 
  104                 # Migrate subscriptions.
  105                 content_object = reaction.related_content
  106                 subscription = ContentReactionAnswerSubscription.objects.get_or_create_active(
  107                     user=profile.user, content_object=content_object)
  108 
  109                 # Migrate notifications.
  110                 subscription.send_notification(content=reaction, sender=reaction.author)
  111                 notification = ContentReactionAnswerSubscription.objects\
  112                     .get_existing(profile.user, content_object, is_active=True).last_notification
  113                 notification.pubdate = reaction.pubdate
  114                 notification.save()
  115 
  116                 self.stdout.write(u'Migration about « {} » [OK]'.format(content.title))
  117
  [end of zds/notification/management/commands/migrate_subscriptions.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/zds/notification/management/commands/migrate_subscriptions.py b/zds/notification/management/commands/migrate_subscriptions.py
  --- a/zds/notification/management/commands/migrate_subscriptions.py
  +++ b/zds/notification/management/commands/migrate_subscriptions.py
  @@ -1,12 +1,12 @@
   # coding: utf-8
   from django.core.management import BaseCommand
   from django.db.models import F, Q
  -from zds.forum.models import TopicRead
  +from zds.forum.models import TopicRead, Topic
   from zds.member.models import Profile
   from zds.mp.models import PrivateTopicRead, PrivateTopic
   from zds.notification.models import TopicFollowed, TopicAnswerSubscription, ContentReactionAnswerSubscription, \
       PrivateTopicAnswerSubscription
  -from zds.tutorialv2.models.models_database import ContentReaction, ContentRead
  +from zds.tutorialv2.models.models_database import ContentReaction, ContentRead, PublishableContent
   
   
   class Command(BaseCommand):
  @@ -24,12 +24,17 @@
                   .select_related("topic")\
                   .exclude(post=F('topic__last_message')).all()
   
  +            # Migrate subscriptions.
  +            for topic_followed in TopicFollowed.objects \
  +                    .filter(user=profile.user).values_list('topic', flat=True).distinct().all():
  +                content_object = Topic.objects.get(id=topic_followed)
  +                TopicAnswerSubscription.objects.get_or_create_active(user=profile.user, content_object=content_object)
  +
               for topic_never_read in topics_never_read:
                   content = topic_never_read.topic.first_unread_post(profile.user)
                   if content is None:
                       content = topic_never_read.topic.last_message
   
  -                # Migrate subscriptions.
                   content_object = topic_never_read.topic
                   subscription = TopicAnswerSubscription.objects.get_or_create_active(
                       user=profile.user, content_object=content_object)
  @@ -53,6 +58,16 @@
               for tnr in topics_never_read:
                   tnrs.append(tnr.privatetopic.pk)
   
  +            # Migrate subscriptions.
  +            private_topics = PrivateTopic.objects \
  +                .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \
  +                .order_by("-pubdate") \
  +                .distinct()
  +
  +            for private_topic in private_topics:
  +                PrivateTopicAnswerSubscription.objects.get_or_create_active(
  +                    user=profile.user, content_object=private_topic)
  +
               private_topics_unread = PrivateTopic.objects \
                   .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \
                   .exclude(pk__in=tnrs) \
  @@ -64,7 +79,6 @@
                   if answer is None:
                       answer = private_topic_unread.get_last_answer()
   
  -                # Migrate subscriptions.
                   subscription = PrivateTopicAnswerSubscription.objects.get_or_create_active(
                       user=profile.user, content_object=private_topic_unread)
   
  @@ -79,6 +93,16 @@
   
               # Contents.
               self.stdout.write(u'Starting migration with contents...')
  +            # Migrate subscriptions.
  +            contents_followed = ContentReaction.objects \
  +                .filter(author=profile.user, related_content__public_version__isnull=False) \
  +                .values_list('related_content', flat=True)
  +
  +            for content_followed in contents_followed:
  +                content_object = PublishableContent.objects.get(id=content_followed)
  +                ContentReactionAnswerSubscription.objects.get_or_create_active(
  +                    user=profile.user, content_object=content_object)
  +
               content_followed_pk = ContentReaction.objects\
                   .filter(author=profile.user, related_content__public_version__isnull=False)\
                   .values_list('related_content__pk', flat=True)
  @@ -101,7 +125,6 @@
                   if reaction is None:
                       continue
   
  -                # Migrate subscriptions.
                   content_object = reaction.related_content
                   subscription = ContentReactionAnswerSubscription.objects.get_or_create_active(
                       user=profile.user, content_object=content_object)
  
verification_info: {"golden_diff": "diff --git a/zds/notification/management/commands/migrate_subscriptions.py b/zds/notification/management/commands/migrate_subscriptions.py\n--- a/zds/notification/management/commands/migrate_subscriptions.py\n+++ b/zds/notification/management/commands/migrate_subscriptions.py\n@@ -1,12 +1,12 @@\n # coding: utf-8\n from django.core.management import BaseCommand\n from django.db.models import F, Q\n-from zds.forum.models import TopicRead\n+from zds.forum.models import TopicRead, Topic\n from zds.member.models import Profile\n from zds.mp.models import PrivateTopicRead, PrivateTopic\n from zds.notification.models import TopicFollowed, TopicAnswerSubscription, ContentReactionAnswerSubscription, \\\n     PrivateTopicAnswerSubscription\n-from zds.tutorialv2.models.models_database import ContentReaction, ContentRead\n+from zds.tutorialv2.models.models_database import ContentReaction, ContentRead, PublishableContent\n \n \n class Command(BaseCommand):\n@@ -24,12 +24,17 @@\n                 .select_related(\"topic\")\\\n                 .exclude(post=F('topic__last_message')).all()\n \n+            # Migrate subscriptions.\n+            for topic_followed in TopicFollowed.objects \\\n+                    .filter(user=profile.user).values_list('topic', flat=True).distinct().all():\n+                content_object = Topic.objects.get(id=topic_followed)\n+                TopicAnswerSubscription.objects.get_or_create_active(user=profile.user, content_object=content_object)\n+\n             for topic_never_read in topics_never_read:\n                 content = topic_never_read.topic.first_unread_post(profile.user)\n                 if content is None:\n                     content = topic_never_read.topic.last_message\n \n-                # Migrate subscriptions.\n                 content_object = topic_never_read.topic\n                 subscription = TopicAnswerSubscription.objects.get_or_create_active(\n                     user=profile.user, content_object=content_object)\n@@ -53,6 +58,16 @@\n             for tnr in topics_never_read:\n                 tnrs.append(tnr.privatetopic.pk)\n \n+            # Migrate subscriptions.\n+            private_topics = PrivateTopic.objects \\\n+                .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \\\n+                .order_by(\"-pubdate\") \\\n+                .distinct()\n+\n+            for private_topic in private_topics:\n+                PrivateTopicAnswerSubscription.objects.get_or_create_active(\n+                    user=profile.user, content_object=private_topic)\n+\n             private_topics_unread = PrivateTopic.objects \\\n                 .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \\\n                 .exclude(pk__in=tnrs) \\\n@@ -64,7 +79,6 @@\n                 if answer is None:\n                     answer = private_topic_unread.get_last_answer()\n \n-                # Migrate subscriptions.\n                 subscription = PrivateTopicAnswerSubscription.objects.get_or_create_active(\n                     user=profile.user, content_object=private_topic_unread)\n \n@@ -79,6 +93,16 @@\n \n             # Contents.\n             self.stdout.write(u'Starting migration with contents...')\n+            # Migrate subscriptions.\n+            contents_followed = ContentReaction.objects \\\n+                .filter(author=profile.user, related_content__public_version__isnull=False) \\\n+                .values_list('related_content', flat=True)\n+\n+            for content_followed in contents_followed:\n+                content_object = PublishableContent.objects.get(id=content_followed)\n+                ContentReactionAnswerSubscription.objects.get_or_create_active(\n+                    user=profile.user, content_object=content_object)\n+\n             content_followed_pk = ContentReaction.objects\\\n                 .filter(author=profile.user, related_content__public_version__isnull=False)\\\n                 .values_list('related_content__pk', flat=True)\n@@ -101,7 +125,6 @@\n                 if reaction is None:\n                     continue\n \n-                # Migrate subscriptions.\n                 content_object = reaction.related_content\n                 subscription = ContentReactionAnswerSubscription.objects.get_or_create_active(\n                     user=profile.user, content_object=content_object)\n", "issue": "[v18] J'ai perdu mes sujets suivis\nVersion : 18\nOS Windows\nNavigateur Firefox\n\nAlors qu'une synchro a \u00e9t\u00e9 faite entre la prod et la beta, je ne retrouve plus mes sujets suivis dans la page https://beta.zestedesavoir.com/forums/ comme on peut le voir sur la capture ci-dessous (il ne me reste plus qu'un sujet suivis au lieu de beaucoup plus)\n\n![suivis](https://cloud.githubusercontent.com/assets/6066015/14254805/a75c8ac6-fa91-11e5-9852-d5dc2d60547b.PNG)\n\n", "before_files": [{"content": "# coding: utf-8\nfrom django.core.management import BaseCommand\nfrom django.db.models import F, Q\nfrom zds.forum.models import TopicRead\nfrom zds.member.models import Profile\nfrom zds.mp.models import PrivateTopicRead, PrivateTopic\nfrom zds.notification.models import TopicFollowed, TopicAnswerSubscription, ContentReactionAnswerSubscription, \\\n    PrivateTopicAnswerSubscription\nfrom zds.tutorialv2.models.models_database import ContentReaction, ContentRead\n\n\nclass Command(BaseCommand):\n    help = 'Migrate old subscriptions and notifications for new models.'\n\n    def handle(self, *args, **options):\n        for profile in Profile.objects.all():\n            self.stdout.write(u'Migrate all notifications of {}...'.format(profile.user.username))\n            # Forums.\n            self.stdout.write(u'Starting migration with topics...')\n            topics_followed = TopicFollowed.objects.filter(user=profile.user).values(\"topic\").distinct().all()\n            topics_never_read = TopicRead.objects\\\n                .filter(user=profile.user)\\\n                .filter(topic__in=topics_followed)\\\n                .select_related(\"topic\")\\\n                .exclude(post=F('topic__last_message')).all()\n\n            for topic_never_read in topics_never_read:\n                content = topic_never_read.topic.first_unread_post(profile.user)\n                if content is None:\n                    content = topic_never_read.topic.last_message\n\n                # Migrate subscriptions.\n                content_object = topic_never_read.topic\n                subscription = TopicAnswerSubscription.objects.get_or_create_active(\n                    user=profile.user, content_object=content_object)\n\n                # Migrate notifications.\n                subscription.send_notification(content=content, sender=content.author)\n                notification = TopicAnswerSubscription.objects\\\n                    .get_existing(profile.user, content_object, is_active=True).last_notification\n                notification.pubdate = content.pubdate\n                notification.save()\n\n                self.stdout.write(u'Migration about \u00ab {} \u00bb [OK]'.format(topic_never_read.topic.title))\n\n            # Private messages.\n            self.stdout.write(u'Starting migration with private topics...')\n            topics_never_read = list(PrivateTopicRead.objects\n                                     .filter(user=profile.user)\n                                     .filter(privatepost=F('privatetopic__last_message')).all())\n\n            tnrs = []\n            for tnr in topics_never_read:\n                tnrs.append(tnr.privatetopic.pk)\n\n            private_topics_unread = PrivateTopic.objects \\\n                .filter(Q(author=profile.user) | Q(participants__in=[profile.user])) \\\n                .exclude(pk__in=tnrs) \\\n                .order_by(\"-pubdate\") \\\n                .distinct()\n\n            for private_topic_unread in private_topics_unread:\n                answer = private_topic_unread.last_read_post(profile.user)\n                if answer is None:\n                    answer = private_topic_unread.get_last_answer()\n\n                # Migrate subscriptions.\n                subscription = PrivateTopicAnswerSubscription.objects.get_or_create_active(\n                    user=profile.user, content_object=private_topic_unread)\n\n                # Migrate notifications.\n                subscription.send_notification(content=answer, sender=answer.author, send_email=False)\n                notification = PrivateTopicAnswerSubscription.objects\\\n                    .get_existing(profile.user, private_topic_unread, is_active=True).last_notification\n                notification.pubdate = answer.pubdate\n                notification.save()\n\n                self.stdout.write(u'Migration about \u00ab {} \u00bb [OK]'.format(private_topic_unread.title))\n\n            # Contents.\n            self.stdout.write(u'Starting migration with contents...')\n            content_followed_pk = ContentReaction.objects\\\n                .filter(author=profile.user, related_content__public_version__isnull=False)\\\n                .values_list('related_content__pk', flat=True)\n\n            content_to_read = ContentRead.objects\\\n                .select_related('note')\\\n                .select_related('note__author')\\\n                .select_related('content')\\\n                .select_related('note__related_content__public_version')\\\n                .filter(user=profile.user)\\\n                .exclude(note__pk=F('content__last_note__pk')).all()\n\n            for content_read in content_to_read:\n                content = content_read.content\n                if content.pk not in content_followed_pk and profile.user not in content.authors.all():\n                    continue\n                reaction = content.first_unread_note(user=profile.user)\n                if reaction is None:\n                    reaction = content.first_note()\n                if reaction is None:\n                    continue\n\n                # Migrate subscriptions.\n                content_object = reaction.related_content\n                subscription = ContentReactionAnswerSubscription.objects.get_or_create_active(\n                    user=profile.user, content_object=content_object)\n\n                # Migrate notifications.\n                subscription.send_notification(content=reaction, sender=reaction.author)\n                notification = ContentReactionAnswerSubscription.objects\\\n                    .get_existing(profile.user, content_object, is_active=True).last_notification\n                notification.pubdate = reaction.pubdate\n                notification.save()\n\n                self.stdout.write(u'Migration about \u00ab {} \u00bb [OK]'.format(content.title))\n", "path": "zds/notification/management/commands/migrate_subscriptions.py"}]}