PageRenderTime 93ms CodeModel.GetById 69ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/django/contrib/comments/models.py

https://code.google.com/p/mango-py/
Python | 191 lines | 136 code | 22 blank | 33 comment | 10 complexity | a7aae5402c82b1b483028f2fbb680a2a MD5 | raw file
  1import datetime
  2from django.contrib.auth.models import User
  3from django.contrib.comments.managers import CommentManager
  4from django.contrib.contenttypes import generic
  5from django.contrib.contenttypes.models import ContentType
  6from django.contrib.sites.models import Site
  7from django.db import models
  8from django.core import urlresolvers
  9from django.utils.translation import ugettext_lazy as _
 10from django.conf import settings
 11
 12COMMENT_MAX_LENGTH = getattr(settings,'COMMENT_MAX_LENGTH',3000)
 13
 14class BaseCommentAbstractModel(models.Model):
 15    """
 16    An abstract base class that any custom comment models probably should
 17    subclass.
 18    """
 19
 20    # Content-object field
 21    content_type   = models.ForeignKey(ContentType,
 22            verbose_name=_('content type'),
 23            related_name="content_type_set_for_%(class)s")
 24    object_pk      = models.TextField(_('object ID'))
 25    content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
 26
 27    # Metadata about the comment
 28    site        = models.ForeignKey(Site)
 29
 30    class Meta:
 31        abstract = True
 32
 33    def get_content_object_url(self):
 34        """
 35        Get a URL suitable for redirecting to the content object.
 36        """
 37        return urlresolvers.reverse(
 38            "comments-url-redirect",
 39            args=(self.content_type_id, self.object_pk)
 40        )
 41
 42class Comment(BaseCommentAbstractModel):
 43    """
 44    A user comment about some object.
 45    """
 46
 47    # Who posted this comment? If ``user`` is set then it was an authenticated
 48    # user; otherwise at least user_name should have been set and the comment
 49    # was posted by a non-authenticated user.
 50    user        = models.ForeignKey(User, verbose_name=_('user'),
 51                    blank=True, null=True, related_name="%(class)s_comments")
 52    user_name   = models.CharField(_("user's name"), max_length=50, blank=True)
 53    user_email  = models.EmailField(_("user's email address"), blank=True)
 54    user_url    = models.URLField(_("user's URL"), blank=True)
 55
 56    comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH)
 57
 58    # Metadata about the comment
 59    submit_date = models.DateTimeField(_('date/time submitted'), default=None)
 60    ip_address  = models.IPAddressField(_('IP address'), blank=True, null=True)
 61    is_public   = models.BooleanField(_('is public'), default=True,
 62                    help_text=_('Uncheck this box to make the comment effectively ' \
 63                                'disappear from the site.'))
 64    is_removed  = models.BooleanField(_('is removed'), default=False,
 65                    help_text=_('Check this box if the comment is inappropriate. ' \
 66                                'A "This comment has been removed" message will ' \
 67                                'be displayed instead.'))
 68
 69    # Manager
 70    objects = CommentManager()
 71
 72    class Meta:
 73        db_table = "django_comments"
 74        ordering = ('submit_date',)
 75        permissions = [("can_moderate", "Can moderate comments")]
 76        verbose_name = _('comment')
 77        verbose_name_plural = _('comments')
 78
 79    def __unicode__(self):
 80        return "%s: %s..." % (self.name, self.comment[:50])
 81
 82    def save(self, *args, **kwargs):
 83        if self.submit_date is None:
 84            self.submit_date = datetime.datetime.now()
 85        super(Comment, self).save(*args, **kwargs)
 86
 87    def _get_userinfo(self):
 88        """
 89        Get a dictionary that pulls together information about the poster
 90        safely for both authenticated and non-authenticated comments.
 91
 92        This dict will have ``name``, ``email``, and ``url`` fields.
 93        """
 94        if not hasattr(self, "_userinfo"):
 95            self._userinfo = {
 96                "name"  : self.user_name,
 97                "email" : self.user_email,
 98                "url"   : self.user_url
 99            }
100            if self.user_id:
101                u = self.user
102                if u.email:
103                    self._userinfo["email"] = u.email
104
105                # If the user has a full name, use that for the user name.
106                # However, a given user_name overrides the raw user.username,
107                # so only use that if this comment has no associated name.
108                if u.get_full_name():
109                    self._userinfo["name"] = self.user.get_full_name()
110                elif not self.user_name:
111                    self._userinfo["name"] = u.username
112        return self._userinfo
113    userinfo = property(_get_userinfo, doc=_get_userinfo.__doc__)
114
115    def _get_name(self):
116        return self.userinfo["name"]
117    def _set_name(self, val):
118        if self.user_id:
119            raise AttributeError(_("This comment was posted by an authenticated "\
120                                   "user and thus the name is read-only."))
121        self.user_name = val
122    name = property(_get_name, _set_name, doc="The name of the user who posted this comment")
123
124    def _get_email(self):
125        return self.userinfo["email"]
126    def _set_email(self, val):
127        if self.user_id:
128            raise AttributeError(_("This comment was posted by an authenticated "\
129                                   "user and thus the email is read-only."))
130        self.user_email = val
131    email = property(_get_email, _set_email, doc="The email of the user who posted this comment")
132
133    def _get_url(self):
134        return self.userinfo["url"]
135    def _set_url(self, val):
136        self.user_url = val
137    url = property(_get_url, _set_url, doc="The URL given by the user who posted this comment")
138
139    def get_absolute_url(self, anchor_pattern="#c%(id)s"):
140        return self.get_content_object_url() + (anchor_pattern % self.__dict__)
141
142    def get_as_text(self):
143        """
144        Return this comment as plain text.  Useful for emails.
145        """
146        d = {
147            'user': self.user or self.name,
148            'date': self.submit_date,
149            'comment': self.comment,
150            'domain': self.site.domain,
151            'url': self.get_absolute_url()
152        }
153        return _('Posted by %(user)s at %(date)s\n\n%(comment)s\n\nhttp://%(domain)s%(url)s') % d
154
155class CommentFlag(models.Model):
156    """
157    Records a flag on a comment. This is intentionally flexible; right now, a
158    flag could be:
159
160        * A "removal suggestion" -- where a user suggests a comment for (potential) removal.
161
162        * A "moderator deletion" -- used when a moderator deletes a comment.
163
164    You can (ab)use this model to add other flags, if needed. However, by
165    design users are only allowed to flag a comment with a given flag once;
166    if you want rating look elsewhere.
167    """
168    user      = models.ForeignKey(User, verbose_name=_('user'), related_name="comment_flags")
169    comment   = models.ForeignKey(Comment, verbose_name=_('comment'), related_name="flags")
170    flag      = models.CharField(_('flag'), max_length=30, db_index=True)
171    flag_date = models.DateTimeField(_('date'), default=None)
172
173    # Constants for flag types
174    SUGGEST_REMOVAL = "removal suggestion"
175    MODERATOR_DELETION = "moderator deletion"
176    MODERATOR_APPROVAL = "moderator approval"
177
178    class Meta:
179        db_table = 'django_comment_flags'
180        unique_together = [('user', 'comment', 'flag')]
181        verbose_name = _('comment flag')
182        verbose_name_plural = _('comment flags')
183
184    def __unicode__(self):
185        return "%s flag of comment ID %s by %s" % \
186            (self.flag, self.comment_id, self.user.username)
187
188    def save(self, *args, **kwargs):
189        if self.flag_date is None:
190            self.flag_date = datetime.datetime.now()
191        super(CommentFlag, self).save(*args, **kwargs)