示例#1
0
class ThreadedComment(Comment):
    title = models.TextField(_('Title'), blank=True)
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               default=None,
                               related_name='children',
                               verbose_name=_('Parent'))
    last_child = models.ForeignKey('self',
                                   null=True,
                                   blank=True,
                                   verbose_name=_('Last child'))
    tree_path = models.CharField(_('Tree path'),
                                 editable=False,
                                 db_index=True,
                                 max_length=255)
    rank = models.IntegerField(_('Rank'), null=True)

    objects = CommentManager()

    def _get_depth(self):
        return len(self.tree_path.split(PATH_SEPARATOR))

    depth = property(_get_depth)

    def _root_id(self):
        return int(self.tree_path.split(PATH_SEPARATOR)[0])

    root_id = property(_root_id)

    def _root_path(self):
        return ThreadedComment.objects.filter(
            pk__in=self.tree_path.split(PATH_SEPARATOR)[:-1])

    root_path = property(_root_path)

    def save(self, *args, **kwargs):
        skip_tree_path = kwargs.pop('skip_tree_path', False)
        super(ThreadedComment, self).save(*args, **kwargs)
        if skip_tree_path:
            return None

        tree_path = unicode(self.pk).zfill(PATH_DIGITS)
        if self.parent:
            tree_path = PATH_SEPARATOR.join((self.parent.tree_path, tree_path))

            self.parent.last_child = self
            ThreadedComment.objects.filter(pk=self.parent_id).update(
                last_child=self)

        self.tree_path = tree_path
        ThreadedComment.objects.filter(pk=self.pk).update(
            tree_path=self.tree_path)

    class Meta(object):
        ordering = ('tree_path', 'rank')
        db_table = 'threadedcomments_comment'
        verbose_name = _('Threaded comment')
        verbose_name_plural = _('Threaded comments')
示例#2
0
class CustomComment(DatasetMixin, Comment):
    _dataset = CommentDataset

    date_updated = models.DateTimeField(default=lambda *args: timezone.now())

    objects = CommentManager()

    @classmethod
    def load_comments(cls, app, model, pk, offset=0, size=10):
        return

    @classmethod
    def post_comment(cls, app, model, pk, content):
        return
class ThreadedComment(MPTTModel, Comment):
    """
    Threaded comments with MPTT
    """

    parent = TreeForeignKey(
        'self',
        related_name='children',
        null=True, blank=True,
        verbose_name=_('reply in comment'))

    objects = CommentManager()
    tree = TreeManager()

    class MPTTMeta:
        """
        Comment MPTT's meta informations.
        """
        order_insertion_by = ['submit_date']
示例#4
0
class CustomComment(ThreadedComment):

    subscribe = models.BooleanField(default=False)

    objects = CommentManager()

    def save(self, send_notifications=True, *args, **kwargs):
        created = not self.pk
        super(CustomComment, self).save(*args, **kwargs)
        if created and notification_enabled() and send_notifications:
            self.send_admin_notifications()
            if not moderation_enabled():
                self.send_subscriptors_notifications()

    def send_admin_notifications(self):
        subject = _("New comment posted on '%s'") % self.content_object
        message = self.get_as_text()
        if moderation_enabled():
            url = "http://%s%s" % (self.site.domain,
                                   reverse('comments-approve',
                                           args=(self.id, )))
            managers_message = _("This comment is moderated!\nYou may approve it " \
                                 "on the following url: %s\n\n") % url + message
        else:
            managers_message = message
        mail_managers(subject, managers_message, fail_silently=True)

    # Send mail to suscribed users of the tree path
    def send_subscriptors_notifications(self):
        subject = _("New comment posted on '%s'") % self.content_object
        message = self.get_as_text()
        comments = CustomComment.objects.filter(id=self.root_path,
                                                subscribe=True)
        if comments:
            messages = [(subject, message, settings.DEFAULT_FROM_EMAIL,
                         [comment.userinfo["email"]]) for comment in comments]
            send_mass_mail(messages, fail_silently=True)

    class Meta:
        verbose_name = _("comment")
        verbose_name_plural = _("comments")
示例#5
0
class Comment(BaseCommentAbstractModel):
    """
    A user comment about some object.
    """

    # Who posted this comment? If ``user`` is set then it was an authenticated
    # user; otherwise at least user_name should have been set and the comment
    # was posted by a non-authenticated user.
    user = models.ForeignKey(User,
                             verbose_name=_('user'),
                             blank=True,
                             null=True,
                             related_name="%(class)s_comments")
    user_name = models.CharField(_("user's name"), max_length=50, blank=True)
    user_email = models.EmailField(_("user's email address"), blank=True)
    user_url = models.URLField(_("user's URL"), blank=True)

    comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH)

    # Metadata about the comment
    submit_date = models.DateTimeField(_('date/time submitted'), default=None)
    ip_address = models.IPAddressField(_('IP address'), blank=True, null=True)
    is_public   = models.BooleanField(_('is public'), default=True,
                    help_text=_('Uncheck this box to make the comment effectively ' \
                                'disappear from the site.'))
    is_removed  = models.BooleanField(_('is removed'), default=False,
                    help_text=_('Check this box if the comment is inappropriate. ' \
                                'A "This comment has been removed" message will ' \
                                'be displayed instead.'))

    # Manager
    objects = CommentManager()

    class Meta:
        db_table = "django_comments"
        ordering = ('submit_date', )
        permissions = [("can_moderate", "Can moderate comments")]
        verbose_name = _('comment')
        verbose_name_plural = _('comments')

    def __unicode__(self):
        return "%s: %s..." % (self.name, self.comment[:50])

    def save(self, *args, **kwargs):
        if self.submit_date is None:
            self.submit_date = timezone.now()
        super(Comment, self).save(*args, **kwargs)

    def _get_userinfo(self):
        """
        Get a dictionary that pulls together information about the poster
        safely for both authenticated and non-authenticated comments.

        This dict will have ``name``, ``email``, and ``url`` fields.
        """
        if not hasattr(self, "_userinfo"):
            self._userinfo = {
                "name": self.user_name,
                "email": self.user_email,
                "url": self.user_url
            }
            if self.user_id:
                u = self.user
                if u.email:
                    self._userinfo["email"] = u.email

                # If the user has a full name, use that for the user name.
                # However, a given user_name overrides the raw user.username,
                # so only use that if this comment has no associated name.
                if u.get_full_name():
                    self._userinfo["name"] = self.user.get_full_name()
                elif not self.user_name:
                    self._userinfo["name"] = u.username
        return self._userinfo

    userinfo = property(_get_userinfo, doc=_get_userinfo.__doc__)

    def _get_name(self):
        return self.userinfo["name"]

    def _set_name(self, val):
        if self.user_id:
            raise AttributeError(_("This comment was posted by an authenticated "\
                                   "user and thus the name is read-only."))
        self.user_name = val

    name = property(_get_name,
                    _set_name,
                    doc="The name of the user who posted this comment")

    def _get_email(self):
        return self.userinfo["email"]

    def _set_email(self, val):
        if self.user_id:
            raise AttributeError(_("This comment was posted by an authenticated "\
                                   "user and thus the email is read-only."))
        self.user_email = val

    email = property(_get_email,
                     _set_email,
                     doc="The email of the user who posted this comment")

    def _get_url(self):
        return self.userinfo["url"]

    def _set_url(self, val):
        self.user_url = val

    url = property(_get_url,
                   _set_url,
                   doc="The URL given by the user who posted this comment")

    def get_absolute_url(self, anchor_pattern="#c%(id)s"):
        return self.get_content_object_url() + (anchor_pattern % self.__dict__)

    def get_as_text(self):
        """
        Return this comment as plain text.  Useful for emails.
        """
        d = {
            'user': self.user or self.name,
            'date': self.submit_date,
            'comment': self.comment,
            'domain': self.site.domain,
            'url': self.get_absolute_url()
        }
        return _(
            'Posted by %(user)s at %(date)s\n\n%(comment)s\n\nhttp://%(domain)s%(url)s'
        ) % d
示例#6
0
class ThreadedComment(MPTTModel, BaseCommentAbstractModel):

    # Copied from comments.Comment
    user = models.ForeignKey(User,
                             verbose_name=_('user'),
                             blank=True,
                             null=True,
                             related_name="%(class)s_comments")
    comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH)
    submit_date = models.DateTimeField(_('date/time submitted'), default=None)
    ip_address = models.IPAddressField(_('IP address'), blank=True, null=True)
    is_public = models.BooleanField(
        _('is public'),
        default=True,
        help_text=_('Uncheck this box to make the comment effectively '
                    'disappear from the site.'))
    is_removed = models.BooleanField(
        _('is removed'),
        default=False,
        help_text=_('Check this box if the comment is inappropriate. '
                    'A "This comment has been removed" message will '
                    'be displayed instead.'))
    objects = CommentManager()

    class Meta:
        ordering = (
            'tree_id',
            'submit_date',
        )

    def __unicode__(self):
        if self.is_removed:
            return u"a deleted comment"
        try:
            name = self.user.username
        except Exception:
            name = None
        return u"%s: %s..." % (name, self.comment[:50])

    def save(self, *args, **kwargs):
        if self.submit_date is None:
            self.submit_date = timezone.now()

        # Forbid more than 2 levels
        if self.parent_id is not None:
            while self.parent.get_level() > 0:
                self.parent = self.parent.parent

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

    def get_absolute_url(self, anchor_pattern="#comment-{id}"):
        url_base = self.get_content_object_url()
        return url_base + anchor_pattern.format(**self.__dict__)

    def get_reply_url(self, anchor_pattern="#reply-comment-{id}"):
        url_base = self.get_content_object_url()
        return url_base + anchor_pattern.format(**self.__dict__)

    def get_toplevel(self):
        if self.get_level() == 0:
            return self
        return self.parent.get_toplevel()

    # My stuff
    parent = TreeForeignKey('self',
                            null=True,
                            blank=True,
                            related_name='children')
    post_to_facebook = models.BooleanField(default=False)

    class MPTTMeta:
        # comments on one level will be ordered by date of creation
        order_insertion_by = ['submit_date']
示例#7
0
from openPLM.plmapp.models.document import *
from openPLM.plmapp.models.history import *
from openPLM.plmapp.models.link import *

# monkey patch Comment models to select related fields
from django.contrib.comments.models import Comment
from django.contrib.comments.managers import CommentManager


class CommentManager(CommentManager):
    def get_query_set(self):
        return (super(CommentManager, self).get_query_set().select_related(
            'user', 'user__profile'))


Comment.add_to_class('objects', CommentManager())

# import_models should be the last function


def import_models(force_reload=False):
    u"""
    Imports recursively all modules in directory *plmapp/customized_models*
    """

    MODELS_DIR = "customized_models"
    IMPORT_ROOT = "openPLM.plmapp.%s" % MODELS_DIR
    if __name__ != "openPLM.plmapp.models":
        # this avoids to import models twice
        return
    if force_reload or not hasattr(import_models, "done"):
 def filter(self, *args, **kwargs):
     "small optimization"
     return CommentManager.filter(self, *args, **kwargs).select_related("user")
示例#9
0
class ThreadedComment(Comment):
    title = models.TextField(_('Title'), blank=True)
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               default=None,
                               related_name='children',
                               verbose_name=_('Parent'))
    last_child = models.ForeignKey('self',
                                   null=True,
                                   blank=True,
                                   verbose_name=_('Last child'))
    tree_path = models.TextField(_('Tree path'), editable=False)
    #db_index=True)

    objects = CommentManager()

    __like = None
    __like_users = None
    __nolike = None
    __nolike_users = None

    def _get_depth(self):
        return len(self.tree_path.split(PATH_SEPARATOR))

    depth = property(_get_depth)

    def _root_id(self):
        return int(self.tree_path.split(PATH_SEPARATOR)[0])

    root_id = property(_root_id)

    def _root_path(self):
        return ThreadedComment.objects.filter(
            pk__in=self.tree_path.split(PATH_SEPARATOR)[:-1])

    root_path = property(_root_path)

    def save(self, *args, **kwargs):
        skip_tree_path = kwargs.pop('skip_tree_path', False)
        super(ThreadedComment, self).save(*args, **kwargs)
        if skip_tree_path:
            return None

        tree_path = unicode(self.pk).zfill(PATH_DIGITS)
        if self.parent:
            tree_path = PATH_SEPARATOR.join((self.parent.tree_path, tree_path))

            self.parent.last_child = self
            ThreadedComment.objects.filter(pk=self.parent_id).update(
                last_child=self)

        self.tree_path = tree_path
        ThreadedComment.objects.filter(pk=self.pk).update(
            tree_path=self.tree_path)

    def __get_relate(self):
        relate_list = self.relate.select_related().all()
        self.__like = []
        self.__nolike = []
        for r in relate_list:
            if r.relate == '+':
                self.__like.append(r)
            elif r.relate == '-':
                self.__nolike.append(r)

    def __get_like(self):
        if self.__like is None:
            self.__get_relate()
        return self.__like

    like = property(__get_like)

    def __get_like_users(self):
        if self.__like_users is None:
            self.__like_users = [l.user for l in self.like]
        return self.__like_users

    like_users = property(__get_like_users)

    def __get_nolike(self):
        if self.__nolike is None:
            self.__get_relate()
        return self.__nolike

    nolike = property(__get_nolike)

    def __get_nolike_users(self):
        if self.__nolike_users is None:
            self.__nolike_users = [l.user for l in self.nolike]
        return self.__nolike_users

    nolike_users = property(__get_nolike_users)

    class Meta(object):
        ordering = ('tree_path', )
        db_table = 'threadedcomments_comment'
        verbose_name = _('Threaded comment')
        verbose_name_plural = _('Threaded comments')
class ThreadedComment(Comment):
    title = models.TextField(_('Title'), blank=True)
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               default=None,
                               related_name='children',
                               verbose_name=_('Parent'))
    last_child = models.ForeignKey('self',
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL,
                                   verbose_name=_('Last child'))
    tree_path = models.TextField(_('Tree path'), editable=False, db_index=True)

    objects = CommentManager()

    @property
    def depth(self):
        return len(self.tree_path.split(PATH_SEPARATOR))

    @property
    def root_id(self):
        return int(self.tree_path.split(PATH_SEPARATOR)[0])

    @property
    def root_path(self):
        return ThreadedComment.objects.filter(
            pk__in=self.tree_path.split(PATH_SEPARATOR)[:-1])

    def save(self, *args, **kwargs):
        skip_tree_path = kwargs.pop('skip_tree_path', False)
        super(ThreadedComment, self).save(*args, **kwargs)
        if skip_tree_path:
            return None

        tree_path = unicode(self.pk).zfill(PATH_DIGITS)
        if self.parent:
            tree_path = PATH_SEPARATOR.join((self.parent.tree_path, tree_path))

            self.parent.last_child = self
            ThreadedComment.objects.filter(pk=self.parent_id).update(
                last_child=self)

        self.tree_path = tree_path
        ThreadedComment.objects.filter(pk=self.pk).update(
            tree_path=self.tree_path)

    def delete(self, *args, **kwargs):
        # Fix last child on deletion.
        if self.parent_id:
            try:
                prev_child_id = ThreadedComment.objects \
                                .filter(parent=self.parent_id) \
                                .exclude(pk=self.pk) \
                                .order_by('-submit_date') \
                                .values_list('pk', flat=True)[0]
            except IndexError:
                prev_child_id = None
            ThreadedComment.objects.filter(pk=self.parent_id).update(
                last_child=prev_child_id)
        super(ThreadedComment, self).delete(*args, **kwargs)

    class Meta(object):
        ordering = ('tree_path', )
        db_table = 'threadedcomments_comment'
        verbose_name = _('Threaded comment')
        verbose_name_plural = _('Threaded comments')
示例#11
0
class CommentWithRating(Comment):
    rating = models.IntegerField()

    objects = CommentManager()