from django.db import models
from config.settings import common
from django.utils.text import slugify
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from treebeard.mp_tree import MP_Node
import datetime

class Thread(models.Model):
    """
    Thread model:
    Used for conversations.
    """
    title = models.CharField(max_length=30, blank=False,
                             verbose_name=_('Subject'))
    slug = models.SlugField(max_length=250, db_index=True, unique=True)
    description = models.TextField(max_length=1000, blank=False,
                                   verbose_name=_('Message'))
    date = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(common.AUTH_USER_MODEL)

    def __unicode__(self):
        return self.description

    def save(self, *args, **kwargs):
        title = self.title
        self.slug = original_slug = slugify(title)
        count = 0
        while Thread.objects.filter(slug=self.slug).exists():
            count += 1
            self.slug = "%s-%i" % (original_slug, count)

        super(Thread, self).save(*args, **kwargs)

    def get_absolute_url(self):
        kwargs = {
            'slug': self.slug,
        }

        return reverse('threads:detail', kwargs=kwargs)


class ThreadUserVote(models.Model):
    """
    ThreadUserVote Model:
    Stores votes from users to Threads
    """
    user = models.ForeignKey(common.AUTH_USER_MODEL)
    thread = models.ForeignKey(Thread)
    value = models.IntegerField(default=1)


class Comment(MP_Node):
    """
    Comment Model:
    Comments under Threads and other comments
    """
    content = models.TextField(max_length=30, blank=False,
                               verbose_name=_('Comment'))
    thread = models.OneToOneField(Thread, null=True, blank=True)
    user = models.ForeignKey(common.AUTH_USER_MODEL)
    date = models.DateTimeField(default=datetime.datetime.now)
    points = models.IntegerField(default=0)

    node_order_by = ['date']

    def __unicode__(self):
        return self.content


class CommentUserVote(models.Model):
    """
    CommentUserVote Model:
    Stores votes from users to Comments
    """
    user = models.ForeignKey(common.AUTH_USER_MODEL)
    comment = models.ForeignKey(Comment)
    value = models.IntegerField(default=1)

@@ -237,24 +237,76 @@
 Node
-%0Aimport datetime
+, MP_NodeManager%0Aimport datetime%0Afrom collections import OrderedDict
 %0A%0Acl
@@ -1598,24 +1598,1591 @@
 efault=1)%0A%0A%0A
+class CommentManager(MP_NodeManager):%0A    %22%22%22%0A    Manager for the comment model.%0A    Allows custom operation on the tree.%0A    %22%22%22%0A    def build_tree(self, parent=None, order_by=None):%0A        if parent is None:%0A            tree = Comment.get_tree()%0A            parent_depth = 1%0A        else:%0A            tree = Comment.get_tree(parent=parent)%0A            parent_depth = parent.depth%0A%0A        if order_by is not None:%0A            tree = tree.order_by(order_by)%0A%0A        output_tree = OrderedDict()%0A%0A        leafs = list(tree)%0A        depth = parent_depth - 1%0A        traversed_path = %5B%5D%0A%0A        def get_chunks(path, steplen):%0A            output=%5B%5D%0A            for chunk in range(0,len(path)/steplen):%0A                output.append(path%5Bchunk*steplen:(chunk+1)*steplen%5D)%0A            return output%0A%0A        while len(leafs)%3E0:%0A            depth+= 1%0A            moved = %5B%5D%0A            for key, leaf in enumerate(leafs):%0A                if leaf.depth == depth:%0A                    parent_path = get_chunks(leaf.path%5B(parent_depth-1)*Comment.steplen:%5D, Comment.steplen)%0A                    path = output_tree%0A%0A                    for chunk in range(0,(len(parent_path))-1):%0A                        path = path%5Bparent_path%5Bchunk%5D%5D%5B1%5D%0A                    path%5Bparent_path%5B-1%5D%5D = %5B%7B'content':leaf.content, 'user': leaf.user.pk,%7D, OrderedDict()%5D%0A                    moved.append(key)%0A                    %0A            for to_delete in reversed(moved):%0A                del(leafs%5Bto_delete%5D)%0A            if depth %3E 50:%0A                raise Exception%0A        return output_tree%0A%0A
 class Commen
@@ -3615,16 +3615,47 @@
 fault=0)
+%0A    objects = CommentManager()
 %0A%0A    no

Add helper method to build a tree