def _limiter(last, seconds): limit = timedelta(seconds=seconds) since = (now() - last) if since < limit: raise APIException( _("please wait %(duration)s before making another post") % {"duration": timesince(now() - limit + since)})
def _limiter(last, seconds): limit = timedelta(seconds=seconds) since = (now() - last) if since < limit: raise APIException( _("please wait %(duration)s before making another post") % { "duration": timesince(now() - limit + since)})
def setUp(self): redisbayes.RedisBayes().flush() settings.OWS_LIMIT_VOTES = () settings.OWS_LIMIT_THREAD = -1 settings.OWS_LIMIT_COMMENT = -1 settings.OWS_LIMIT_MSG_DAY = 999999 self.create_users() self.article = db.Article(author=self.red_user, published=utils.now(), title='article title', slug='article-slug', content='exciting article content') self.article.save() comment_list = api.comment_new(user=self.blue_user, article_slug=self.article.slug, parent_id=0, content=random_words(20)) self.comment = db.Comment.objects.get(id=comment_list[0]['id']) # add a second comment api.comment_new(user=self.blue_user, article_slug=self.article.slug, parent_id=0, content=random_words(20)) self.carousel = db.Carousel() self.carousel.save() self.photo = db.Photo(carousel=self.carousel, caption='hello, world') self.photo.save()
def message_send(user, to_username, content, **kwargs): """Send a private message""" if not (user and user.id): raise APIException(_("you're not logged in")) content = content.strip() if len(content) < 3: raise APIException(_("message too short")) try: to_user = db.User.objects.get(username=to_username, is_active=True) except db.User.DoesNotExist: raise APIException(_('user not found')) if user == to_user: raise APIException(_("you can't message yourself")) if not user.is_staff: hours24 = now() - timedelta(hours=24) rec = db.Message.objects.filter(from_user=user, published__gt=hours24) sentusers = set(m.to_user.username for m in rec) if len(sentusers) > settings.OWS_LIMIT_MSG_DAY: raise APIException( _("you can't send more than %(limit)s messages per day") % { "limit": settings.OWS_LIMIT_MSG_DAY}) msg = db.Message.objects.create(from_user=user, to_user=to_user, content=content) db.Notification.send( to_user, user.get_absolute_url(), _("%(username)s sent you a message" % {"username": user.username})) html = render_to_string('occupywallst/message.html', {'message': msg}) return [msg.as_dict({'html': html})]
def items(self): return (db.Article.objects .filter(is_deleted=False, is_forum=True, is_visible=True, published__lt=utils.now() - self.delay) .order_by('-published'))[:25]
def comment_vote(user, comment, vote, **kwargs): """Increases comment karma by one If a user is logged in, we track their votes in the database. If a user is not logged in, we still allow them to vote but to prevent them from clicking the downvote arrow repeatedly we only allow an IP to vote once. We track these votes in a non-persistant cache because we don't want to log IP addresses. """ if not (user and user.id): raise APIException(_("not logged in")) if not isinstance(comment, db.Comment): try: comment = db.Comment.objects.get(id=comment, is_deleted=False) except db.Comment.DoesNotExist: raise APIException(_("comment not found")) if not settings.DEBUG and not user.is_staff: for tdelta, maxvotes in settings.OWS_LIMIT_VOTES: votes = (db.CommentVote.objects .filter(user=user, time__gt=now() - tdelta) .count()) if votes > maxvotes: raise APIException(_("you're voting too much")) if not user.userinfo.is_shadow_banned: if vote == "up": comment.upvote(user) elif vote == "down": comment.downvote(user) else: raise APIException(_("invalid vote")) return []
def message_send(user, to_username, content, **kwargs): """Send a private message""" if not (user and user.id): raise APIException(_("you're not logged in")) content = content.strip() if len(content) < 3: raise APIException(_("message too short")) try: to_user = db.User.objects.get(username=to_username, is_active=True) except db.User.DoesNotExist: raise APIException(_('user not found')) if user == to_user: raise APIException(_("you can't message yourself")) if not user.is_staff: hours24 = now() - timedelta(hours=24) rec = db.Message.objects.filter(from_user=user, published__gt=hours24) sentusers = set(m.to_user.username for m in rec) if len(sentusers) > settings.OWS_LIMIT_MSG_DAY: raise APIException( _("you can't send more than %(limit)s messages per day") % {"limit": settings.OWS_LIMIT_MSG_DAY}) msg = db.Message.objects.create(from_user=user, to_user=to_user, content=content) db.Notification.send( to_user, user.get_absolute_url(), _("%(username)s sent you a message" % {"username": user.username})) html = render_to_string('occupywallst/message.html', {'message': msg}) return [msg.as_dict({'html': html})]
def comment_vote(user, comment, vote, **kwargs): """Increases comment karma by one If a user is logged in, we track their votes in the database. If a user is not logged in, we still allow them to vote but to prevent them from clicking the downvote arrow repeatedly we only allow an IP to vote once. We track these votes in a non-persistant cache because we don't want to log IP addresses. """ if not (user and user.id): raise APIException(_("not logged in")) if not isinstance(comment, db.Comment): try: comment = db.Comment.objects.get(id=comment, is_deleted=False) except db.Comment.DoesNotExist: raise APIException(_("comment not found")) if not settings.DEBUG and not user.is_staff: for tdelta, maxvotes in settings.OWS_LIMIT_VOTES: votes = (db.CommentVote.objects.filter(user=user, time__gt=now() - tdelta).count()) if votes > maxvotes: raise APIException(_("you're voting too much")) if not user.userinfo.is_shadow_banned: if vote == "up": comment.upvote(user) elif vote == "down": comment.downvote(user) else: raise APIException(_("invalid vote")) return []
def test_article_delete(self): a = db.Article(author=self.red_user, title='test title', slug='test', published=utils.now(), content='this is a test') a.save() assert a.is_deleted == False a.delete() assert db.Article.objects.get(slug='test').is_deleted == True
def test_article_comments_as_user(self): a = db.Article(author=self.red_user, title='test title', slug='test', published=utils.now(), content='this is a test') a.save() # add comment as self.blue_user c = db.Comment(article=a, user=self.blue_user, content='nice test') c.save()
def new_article(user, **kwargs): vals = dict(author=user, published=utils.now(), title=random_words(7), slug=random_slug(), content=random_words(20), is_forum=True, is_visible=True) vals.update(kwargs) return db.Article.objects.create(**vals)
def test_article_translation(self): a = db.Article(author=self.red_user, title='test title', slug='test', published=utils.now(), content='this is a test') a.save() at = db.ArticleTranslation(article=a, language='piglatin', title='est-tay itle-tay', content='is-thay is-ay a-ay est-tay') at.save() a.translate('piglatin') assert 'itle-tay' in a.title assert 'is-thay' in a.content
def article_new(user, title, content, is_forum, **kwargs): """Create a news article or forum thread We mustn't allow users without staff privileges to post news articles. """ is_forum = _to_bool(is_forum) if not (user and user.id): raise APIException(_("you're not logged in")) if not is_forum: if not user.is_staff: raise APIException(_("insufficient privileges")) title = title.strip() content = content.strip() slug = slugify(title)[:50] if db.Article.objects.filter(slug=slug).count(): raise APIException(_("a thread with this title exists")) if not settings.DEBUG and not user.is_staff: last = user.article_set.order_by('-published')[:1] if last: _limiter(last[0].published, settings.OWS_LIMIT_THREAD) ip = _try_to_get_ip(kwargs) if ip: last = cache.get('api_article_new_' + ip) if last: _limiter(last, settings.OWS_LIMIT_THREAD) article = db.Article() article.author = user article.published = now() article.is_visible = True article.title = title article.slug = slug article.content = content article.is_forum = is_forum article.ip = _try_to_get_ip(kwargs) _check_post(user, article) article.save() return article_get(user, slug)
def comment_new(user, article_slug, parent_id, content, **kwargs): """Leave a comment on an article If parent_id is set, this will be a reply to an existing comment. Also upvotes comment and increments article comment count. """ if not (user and user.id): raise APIException(_("you're not logged in")) content = content.strip() try: article = db.Article.objects.get(slug=article_slug, is_deleted=False) except db.Article.DoesNotExist: raise APIException(_('article not found')) def comment_depth(id): depth = 0 current = id while current: current = comhash.get(current, 0).parent_id depth += 1 return depth if parent_id: other_comments = (db.Comment.objects .select_related("article") .filter(article=article, is_deleted=False)) comhash = dict((c.id, c) for c in other_comments) parent = comhash[int(parent_id)] if int(parent_id) not in comhash: raise APIException(_("parent comment not found")) if comment_depth(int(parent_id)) + 1 > settings.OWS_MAX_COMMENT_DEPTH: raise APIException(_("comment nested too deep")) else: parent = None parent_id = None if not settings.DEBUG and not user.is_staff: last = user.comment_set.order_by('-published')[:1] if last: _limiter(last[0].published, settings.OWS_LIMIT_COMMENT) ip = _try_to_get_ip(kwargs) if ip: last = cache.get('api_comment_new_' + ip) if last: _limiter(last, settings.OWS_LIMIT_COMMENT) comment = db.Comment() comment.article = article username = user.username comment.user = user comment.content = content comment.parent_id = parent_id comment.ip = _try_to_get_ip(kwargs) _check_post(user, comment) comment.save() comment_vote(user, comment, "up", **kwargs) if not comment.is_removed: article.comment_count += 1 article.killed = now() article.save() if not comment.is_removed: if parent: db.Notification.send( parent.user, comment.get_absolute_url(), '%s replied to your comment: %s' % ( username, synopsis(parent.content, 7))) else: db.Notification.send( article.author, comment.get_absolute_url(), '%s replied to your post: %s' % ( username, synopsis(article.content, 7))) return comment_get(user, comment.id)
def comment_new(user, article_slug, parent_id, content, **kwargs): """Leave a comment on an article If parent_id is set, this will be a reply to an existing comment. Also upvotes comment and increments article comment count. """ if not (user and user.id): raise APIException(_("you're not logged in")) content = content.strip() try: article = db.Article.objects.get(slug=article_slug, is_deleted=False) except db.Article.DoesNotExist: raise APIException(_('article not found')) def comment_depth(id): depth = 0 current = id while current: current = comhash.get(current, 0).parent_id depth += 1 return depth if parent_id: other_comments = (db.Comment.objects.select_related("article").filter( article=article, is_deleted=False)) comhash = dict((c.id, c) for c in other_comments) parent = comhash[int(parent_id)] if int(parent_id) not in comhash: raise APIException(_("parent comment not found")) if comment_depth(int(parent_id)) + 1 > settings.OWS_MAX_COMMENT_DEPTH: raise APIException(_("comment nested too deep")) else: parent = None parent_id = None if not settings.DEBUG and not user.is_staff: last = user.comment_set.order_by('-published')[:1] if last: _limiter(last[0].published, settings.OWS_LIMIT_COMMENT) ip = _try_to_get_ip(kwargs) if ip: last = cache.get('api_comment_new_' + ip) if last: _limiter(last, settings.OWS_LIMIT_COMMENT) comment = db.Comment() comment.article = article username = user.username comment.user = user comment.content = content comment.parent_id = parent_id comment.ip = _try_to_get_ip(kwargs) _check_post(user, comment) comment.save() comment_vote(user, comment, "up", **kwargs) if not comment.is_removed: article.comment_count += 1 article.killed = now() article.save() if not comment.is_removed: if parent: db.Notification.send( parent.user, comment.get_absolute_url(), '%s replied to your comment: %s' % (username, synopsis(parent.content, 7))) else: db.Notification.send( article.author, comment.get_absolute_url(), '%s replied to your post: %s' % (username, synopsis(article.content, 7))) return comment_get(user, comment.id)
def items(self): return (db.Comment.objects .filter(is_deleted=False, is_removed=False, published__lt=utils.now() - self.delay) .order_by('-published'))[:50]
def test_article(self): a = db.Article(author=self.red_user, title='test title', slug='test', published=utils.now(), content='this is a test') a.save() assert len(a.as_dict()) > 0