# Path: archive_chan/models.py
# class Board(models.Model):
#     name = models.CharField(max_length=255, primary_key = True)
#     active = models.BooleanField(
#         default=True,
#         help_text='Should this board be updated with new posts?'
#     )
#     store_threads_for = models.IntegerField(
#         default=48,
#         help_text='[hours] After that much time passes from the last reply in a NOT SAVED thread it will be deleted. Set to 0 to preserve threads forever.'
#     )
#     replies_threshold = models.IntegerField(
#         default=20,
#         help_text='Store threads after they reach that many replies.'
#     )
# 
#     class Meta:
#         ordering = ['name']
# 
#     def __str__(self):
#         return format("/%s/" % self.name)
# 
#     def get_absolute_url(self):
#         return reverse('archive_chan:board', args=[self.name])
# 
# class Thread(models.Model):
#     board = models.ForeignKey('Board')
#     number = models.IntegerField()
#     saved = models.BooleanField(default=False) # Threads which are not saved will get deleted after some time.
#     auto_saved = models.BooleanField(default=False) # Was this thread saved automatically by a trigger?
#     tags = models.ManyToManyField('Tag', through='TagToThread')
# 
#     replies = models.IntegerField(default=0)
#     images = models.IntegerField(default=0)
#     first_reply = models.DateTimeField(null=True, default=None)
#     last_reply = models.DateTimeField(null=True, default=None)
# 
#     # Used by scraper.
#     def last_reply_time(self):
#         last = self.post_set.last()
#         if last is None:
#             return None
#         else:
#             return last.time
# 
#     # Used by scraper.
#     def count_replies(self):
#         return self.post_set.count() - 1
# 
#     # Used by board template. Can't figure out a query which wouldd fetch everything in one go.
#     def first_post(self):
#         return self.post_set.select_related('image').first()
# 
#     class Meta:
#         unique_together = ('board', 'number')
# 
#     def __str__(self):
#         return format("#%s" % (self.number))
# 
#     def get_absolute_url(self):
#         return reverse('archive_chan:thread', args=[self.board.name, self.number])
# 
# class Post(models.Model):
#     thread = models.ForeignKey('Thread')
# 
#     number = models.IntegerField()
#     time = models.DateTimeField()
# 
#     name = models.CharField(max_length=255, blank=True)
#     trip = models.CharField(max_length=255, blank=True)
#     email = models.CharField(max_length=255, blank=True)
#     country = models.CharField(max_length=2, blank=True)
# 
#     subject = models.TextField(blank=True)
#     comment = models.TextField(blank=True)
# 
#     save_time = models.DateTimeField(auto_now_add = True)
# 
#     def is_main(self):
#         return (self.number == self.thread.number)
# 
#     class Meta:
#         ordering = ['number']
# 
#     def __str__(self):
#         return format("#%s" % (self.number))
# 
#     def get_absolute_url(self):
#         return '%s#post-%s' % (self.thread.get_absolute_url(), self.number)
# 
# @receiver(post_delete, sender=Post)
# def post_post_delete(sender, instance, **kwargs):
#     """Update replies, images, last_reply, first_reply."""
#     thread = instance.thread
# 
#     # Replies
#     thread.replies -= 1
# 
#     # Images.
#     try:
#         if instance.image:
#             thread.images -= 1
# 
#     except:
#         pass
# 
#     # First and last reply.
#     if thread.first_reply == instance.time or thread.last_reply == instance.time:
#         thread_recount = Thread.objects.annotate(
#             min_post=Min('post__time'),
#             max_post=Max('post__time')
#         ).get(pk=instance.thread.pk)
#         
#         thread.first_reply=thread_recount.min_post
#         thread.last_reply=thread_recount.max_post
# 
#     thread.save()


import datetime
from django.core.management.base import BaseCommand
from django.db.models import Max
from django.utils.timezone import utc
from django.core.signals import Signal
from archive_chan.models import Board, Thread, Post, post_post_delete
from django.db.models.signals import post_delete



class Command(BaseCommand):
    args = ''
    help = 'Remove old, unsaved threads. This command should be run periodically to clean the database.'

    def handle(self, *args, **options):
        boards = Board.objects.filter(store_threads_for__gt=0)

        for board in boards:
            processing_start = datetime.datetime.now()

            # Get the posts older than the amount specified in the board settings.
            time_threshold = datetime.datetime.now().replace(tzinfo=utc) - datetime.timedelta(hours=board.store_threads_for)
            queryset = Thread.objects.filter(board=board, last_reply__lt=time_threshold, saved=False)

            # Count for stats and delete.
            amount = queryset.count()

            post_delete.disconnect(receiver=post_post_delete, sender=Post)

            try:
                queryset.delete()

            except Exception as e:
                sys.stderr.write('%s\m' % (e))

            finally:

# Path: archive_chan/models.py
# class Board(models.Model):
#     name = models.CharField(max_length=255, primary_key = True)
#     active = models.BooleanField(
#         default=True,
#         help_text='Should this board be updated with new posts?'
#     )
#     store_threads_for = models.IntegerField(
#         default=48,
#         help_text='[hours] After that much time passes from the last reply in a NOT SAVED thread it will be deleted. Set to 0 to preserve threads forever.'
#     )
#     replies_threshold = models.IntegerField(
#         default=20,
#         help_text='Store threads after they reach that many replies.'
#     )
# 
#     class Meta:
#         ordering = ['name']
# 
#     def __str__(self):
#         return format("/%s/" % self.name)
# 
#     def get_absolute_url(self):
#         return reverse('archive_chan:board', args=[self.name])
# 
# class Thread(models.Model):
#     board = models.ForeignKey('Board')
#     number = models.IntegerField()
#     saved = models.BooleanField(default=False) # Threads which are not saved will get deleted after some time.
#     auto_saved = models.BooleanField(default=False) # Was this thread saved automatically by a trigger?
#     tags = models.ManyToManyField('Tag', through='TagToThread')
# 
#     replies = models.IntegerField(default=0)
#     images = models.IntegerField(default=0)
#     first_reply = models.DateTimeField(null=True, default=None)
#     last_reply = models.DateTimeField(null=True, default=None)
# 
#     # Used by scraper.
#     def last_reply_time(self):
#         last = self.post_set.last()
#         if last is None:
#             return None
#         else:
#             return last.time
# 
#     # Used by scraper.
#     def count_replies(self):
#         return self.post_set.count() - 1
# 
#     # Used by board template. Can't figure out a query which wouldd fetch everything in one go.
#     def first_post(self):
#         return self.post_set.select_related('image').first()
# 
#     class Meta:
#         unique_together = ('board', 'number')
# 
#     def __str__(self):
#         return format("#%s" % (self.number))
# 
#     def get_absolute_url(self):
#         return reverse('archive_chan:thread', args=[self.board.name, self.number])
# 
# class Post(models.Model):
#     thread = models.ForeignKey('Thread')
# 
#     number = models.IntegerField()
#     time = models.DateTimeField()
# 
#     name = models.CharField(max_length=255, blank=True)
#     trip = models.CharField(max_length=255, blank=True)
#     email = models.CharField(max_length=255, blank=True)
#     country = models.CharField(max_length=2, blank=True)
# 
#     subject = models.TextField(blank=True)
#     comment = models.TextField(blank=True)
# 
#     save_time = models.DateTimeField(auto_now_add = True)
# 
#     def is_main(self):
#         return (self.number == self.thread.number)
# 
#     class Meta:
#         ordering = ['number']
# 
#     def __str__(self):
#         return format("#%s" % (self.number))
# 
#     def get_absolute_url(self):
#         return '%s#post-%s' % (self.thread.get_absolute_url(), self.number)
# 
# @receiver(post_delete, sender=Post)
# def post_post_delete(sender, instance, **kwargs):
#     """Update replies, images, last_reply, first_reply."""
#     thread = instance.thread
# 
#     # Replies
#     thread.replies -= 1
# 
#     # Images.
#     try:
#         if instance.image:
#             thread.images -= 1
# 
#     except:
#         pass
# 
#     # First and last reply.
#     if thread.first_reply == instance.time or thread.last_reply == instance.time:
#         thread_recount = Thread.objects.annotate(
#             min_post=Min('post__time'),
#             max_post=Max('post__time')
#         ).get(pk=instance.thread.pk)
#         
#         thread.first_reply=thread_recount.min_post
#         thread.last_reply=thread_recount.max_post
# 
#     thread.save()


# Path: archive_chan/management/commands/archive_chan_remove_old_threads.py
import datetime
from django.core.management.base import BaseCommand
from django.db.models import Max
from django.utils.timezone import utc
from django.core.signals import Signal
from archive_chan.models import Board, Thread, Post, post_post_delete
from django.db.models.signals import post_delete




class Command(BaseCommand):
    args = ''
    help = 'Remove old, unsaved threads. This command should be run periodically to clean the database.'

    def handle(self, *args, **options):
        boards = Board.objects.filter(store_threads_for__gt=0)

        for board in boards:
            processing_start = datetime.datetime.now()

            # Get the posts older than the amount specified in the board settings.
            time_threshold = datetime.datetime.now().replace(tzinfo=utc) - datetime.timedelta(hours=board.store_threads_for)
            queryset = Thread.objects.filter(board=board, last_reply__lt=time_threshold, saved=False)

            # Count for stats and delete.
            amount = queryset.count()

            post_delete.disconnect(receiver=post_post_delete, sender=Post)

            try:
                queryset.delete()

            except Exception as e:
                sys.stderr.write('%s\m' % (e))

            finally:

                post_delete.connect(post_post_delete, sender=Post)