def can_auto_anonymize(self): min_age = utils.get_config('min_account_age_to_anonymize') min_posts = utils.get_config('min_posts_to_anonymize') account_age = (timezone.now() - self.date_joined) post_count = self.post_set.count() return account_age >= min_age and post_count >= min_posts
def GET(self, request): sortBy = request.GET.get('sortby', 'id') if sortBy == 'post_count': posters = (Poster.objects .annotate(post_count=Count('post')) .order_by('-post_count')) elif sortBy == 'username': posters = Poster.objects.all().order_by('username') elif sortBy == 'id': posters = Poster.objects.all().order_by('id') else: raise PermissionDenied('Invalid sortby value') posters_per_page = utils.get_config('general_items_per_page') paginator = Paginator(posters, posters_per_page) page = utils.page_by_request(paginator, request) ctx = { 'rel_page': page, 'posters': page } return render(request, 'user_index.html', ctx)
def _get_theme(user): if user.is_authenticated: theme_name = user.theme else: theme_name = utils.get_config('default_theme') return theme_name
def pre_method_check(self, request, *args, **kwargs): if not utils.get_config('enable_registration'): message = ('Registration is temporarily closed. Check back later ' 'to register a new account. If you think this is in ' 'error, please contact the administrator.') if utils.get_config('enable_invites'): url = reverse('register-with-code') message += (' If you have a registration code, you may use it ' 'by clicking [url="%s"]here[/url].') % url return render(request, 'generic_message.html', { 'page_title': 'Registration Closed', 'heading': 'Registration Closed', 'message': message })
def GET(self, request): try: code = uuid.UUID(request.GET.get('code', '')) except ValueError: return self._error_out(request) try : poster = Poster.objects.get(email_verification_code=code) except Poster.DoesNotExist: return self._error_out(request) if poster.is_active: return self._error_out(request) poster.is_active = True poster.save() message = ('You\'ve successfully verified your account, welcome to ' '%s. You can now [url="%s"]log in[/url] to your account.') message = message % (utils.get_config('forum_name'), reverse('login')) return render(request, 'generic_message.html', { 'page_title': 'Verification Successful', 'heading': 'Verification Successful', 'message': message })
def __call__(self, request): ip_addr = request.META.get(utils.get_config('client_ip_field'), None) if IPBan.objects.filter(on=ip_addr).count() > 0: raise PermissionDenied('F**k right off') else: return self.get_response(request)
def setUp2(self): tutils.create_std_forums() self.scrub = tutils.create_user(thread_count=1, post_count=0) self.thread = Thread.objects.get(author=self.scrub) self.scrub_client = Client() self.scrub_client.force_login(self.scrub) self.path = reverse('new-reply', args=(self.thread.pk, )) self.limit = utils.get_config('initial_account_period_limit')
def test_initial_account_period_violation_cooldown(self): tutils.create_posts(self.scrub, self.limit, bulk=True) new_created = timezone.now() - utils.get_config( 'initial_account_period_width') self.scrub.post_set.update(created=new_created) # Post should be created self.assertEqual(self._attempt_new_post(), 1)
def banner(request): if not banners: return '' banner_name = random.choice(banners) return { 'banner': os.path.join(utils.get_config('banner_dir'), banner_name) }
def latest_threads(request): effective_prefs = (LatestThreadsForumPreference .get_effective_preferences( request.user if request.user.is_authenticated() else None)) excluded_forums = [ fpk for fpk, include in effective_prefs.items() if not include] threads = (Thread.objects.all() .filter(~Q(forum_id__in=excluded_forums)) .order_by('-last_update') .select_related('author')) threads_per_page = utils.get_config('threads_per_forum_page') paginator = utils.MappingPaginator(threads, threads_per_page) paginator.install_map_func(lambda t: utils.ThreadFascet(t, request)) page = utils.page_by_request(paginator, request) # We can apparently do aggregate queries faster than the ORM, so do that. # This is ugly but this is one of the highest traffic pages in the project # and we can make a _big_ perf difference (as in an order of magnitude) by # doing these queries together like this. with connection.cursor() as cursor: cursor.execute(""" SELECT post.thread_id, COUNT(*) FROM "ISS_post" AS post WHERE post.thread_id = ANY(%s) GROUP BY post.thread_id """, ([tf._thread.pk for tf in page],)) counts = dict(cursor.fetchall()) for tf in page: tf._thread.post_count = counts[tf._thread.pk] if request.user.is_authenticated(): ppk = request.user.pk flags = ThreadFlag.objects.raw(""" SELECT tf.* FROM "ISS_thread" AS thread JOIN "ISS_threadflag" AS tf ON tf.thread_id = thread.id AND tf.poster_id = %s WHERE thread.id = ANY(%s) """, (ppk, [tf._thread.pk for tf in page])) fd = dict([(flag.thread_id, flag) for flag in flags]) for tf in page: if tf._thread.pk in fd: tf._thread._flag_cache[ppk] = fd[tf._thread.pk] ctx = { 'rel_page': page, 'threads': page } return render(request, 'latest_threads.html', ctx)
def show_edit_line(self): if not self.has_been_edited: return False snapshot = self.get_last_edit_snapshot() edit_time = snapshot.time - self.created max_seconds = utils.get_config('ninja_edit_grace_time') return edit_time.total_seconds() > max_seconds
def wrapped_view(self, request, *args, **kwargs): addr = request.META.get(utils.get_config('client_ip_field'), None) is_valid = cls.check_limit(limit_key, access_limit, addr, window) if is_valid: return view(self, request, *args, **kwargs) else: raise PermissionDenied('Rate limit exceded.')
def posts_by_user(request, user_id): poster = get_object_or_404(Poster, pk=user_id) posts = (poster.post_set.order_by('-created').select_related('thread')) posts_per_page = utils.get_config('general_items_per_page') paginator = Paginator(posts, posts_per_page) page = utils.page_by_request(paginator, request) ctx = {'rel_page': page, 'poster': poster, 'posts': page} return render(request, 'posts_by_user.html', ctx)
def threads_by_user(request, user_id): poster = get_object_or_404(Poster, pk=user_id) threads = Thread.objects.filter(author=poster).order_by('-created') threads_per_page = utils.get_config('general_items_per_page') paginator = Paginator(threads, threads_per_page) page = utils.page_by_request(paginator, request) ctx = {'rel_page': page, 'poster': poster, 'threads': page} return render(request, 'threads_started.html', ctx)
def get_url(self, post=None): self_url = reverse('thread', kwargs={'thread_id': self.pk}) if post: predecessors = (self.get_posts_in_thread_order().filter( created__lt=post.created).count()) page_num = predecessors / utils.get_config('posts_per_thread_page') self_url += '?p=%d#post-%d' % (page_num + 1, post.pk) return self_url
def POST(self, request, post_id): post = get_object_or_404(Post, pk=post_id) form = forms.EditPostForm(request.POST) if not form.is_valid(): ctx = {'form': form, 'post': post} return render(request, 'edit_post.html', ctx) ip_addr = request.META.get(utils.get_config('client_ip_field'), None) form.save(editor=request.user, editor_ip=ip_addr) return HttpResponseRedirect(post.get_url())
def POST(self, request): form = forms.InitiatePasswordRecoveryForm(request.POST) if form.is_valid(): normalized = Poster.normalize_username( form.cleaned_data['username']) user = Poster.objects.get(normalized_username=normalized) user.recovery_code = str(uuid.uuid4()) user.recovery_expiration = (timezone.now() + timedelta(days=1)) user.save() forum_name = utils.get_config('forum_name') ctx = { 'forum_name': forum_name, 'url': ('http://' + utils.get_config('forum_domain') + reverse('recovery-reset') + '?code=' + user.recovery_code), } send_mail('Password Recovery for %s' % forum_name, render_to_string('email/password_recovery.txt', ctx), settings.EMAIL_HOST_USER, [user.email]) return render( request, 'generic_message.html', { 'page_title': 'Recovery Email Sent', 'heading': 'Recovery Email Sent', 'message': ('You should receive an email containing further ' 'instructions on how to reset your password at the ' 'address you submitted shortly. If you don\'t see ' 'it please check your spam folder.') }) else: ctx = {'form': form} return render(request, 'initiate_password_recovery.html', ctx)
def latest_threads(request): threads = (Thread.objects.all().filter( forum__is_trash=False).order_by('-last_update')) threads_per_page = utils.get_config('threads_per_forum_page') paginator = utils.MappingPaginator(threads, threads_per_page) paginator.install_map_func(lambda t: utils.ThreadFascet(t, request)) page = utils.page_by_request(paginator, request) ctx = {'rel_page': page, 'threads': page} return render(request, 'latest_threads.html', ctx)
def search(request): q = request.GET.get('q', None) # Special case for no query param, user is probably landing here # without having filled out a query yet. if not q: return render(request, 'search_results.html', { 'form': forms.SearchForm() }) else: form = forms.SearchForm(request.GET) if form.is_valid(): d = form.cleaned_data terms = ' & '.join(d['q'].split(' ')) model = None filter_q = {} if d['search_type'] == 'threads': model = Thread filter_q['title__tsmatch'] = terms if d['forum']: filter_q['forum__in'] = d['forum'] else: model = Post filter_q['content__tsmatch'] = terms if d['forum']: filter_q['thread__forum__in'] = d['forum'] if d['author']: filter_q['author__in'] = d['author'] qs = model.objects.filter(**filter_q).order_by('-created') items_per_page = utils.get_config('general_items_per_page') paginator = Paginator(qs, items_per_page) page = utils.page_by_request(paginator, request) ctx = { 'rel_page': page, 'page': page, 'form': form, 'q': d['q'] } else: ctx = { 'form': form } return render(request, 'search_results.html', ctx)
def usercp(request): threads = (Thread.objects.all().filter( threadflag__poster_id=request.user.id, threadflag__subscribed=True, last_update__gt=F('threadflag__last_read_date')).order_by( '-last_update')) threads_per_page = utils.get_config('threads_per_forum_page') paginator = utils.MappingPaginator(threads, threads_per_page) paginator.install_map_func(lambda t: utils.ThreadFascet(t, request)) page = utils.page_by_request(paginator, request) ctx = {'rel_page': page, 'threads': page} return render(request, 'user_cp.html', ctx)
def search(request): q = request.GET.get('q', None) if not q: return render(request, 'search_results.html', {}) terms = ' & '.join(q.split(' ')) qs = Post.objects.filter(content__tsmatch=terms).order_by('-created') posts_per_page = utils.get_config('general_items_per_page') paginator = Paginator(qs, posts_per_page) page = utils.page_by_request(paginator, request) ctx = {'rel_page': page, 'q': q, 'posts': page} return render(request, 'search_results.html', ctx)
def humans(request): humans = utils.get_config('humans') s = '/* THOSE RESPONSIBLE */\n\n' for role, name, contact in humans: s += '%s: %s\nContact: %s\n\n' % (role, name, contact) top_posters = (Poster.objects.all().annotate( num_posts=Count('post')).order_by('-num_posts'))[:3] if top_posters: s += '\n/* TOP SHITPOSTERS */\n\n' for poster in top_posters: s += 'Top Shitposter: %s\nContact: %s\nDamage Done: %d\n\n' % ( poster.username, poster.get_url(), poster.num_posts) return HttpResponse(s, content_type='text/plain')
def sent(request): messages = (request.user.privatemessage_set.filter( sender=request.user).order_by('-created')) items_per_page = utils.get_config('general_items_per_page') paginator = Paginator(messages, items_per_page) page = utils.page_by_request(paginator, request) ctx = { 'messages': page, 'page_name': 'Sent', 'active_tab': 'sent', 'show_from': False, 'show_to': True, 'pm_action_form': forms.PrivateMessageActionForm(), 'breadcrumbs': [('Private Messages', ''), ('Sent', 'sent-pms')] } return render(request, 'private_messages/pm_list.html', ctx)
def POST(self, request, thread_id): thread = get_object_or_404(Thread, pk=thread_id) author = request.user form = self._get_form(request)(request.POST, author=author) if form.is_valid(): post = form.get_post() post.posted_from = request.META.get( utils.get_config('client_ip_field'), None) post.save() if request.user.auto_subscribe == 1: thread.subscribe(request.user) return HttpResponseRedirect(post.get_url()) else: ctx = {'thread': thread, 'form': form} return render(request, 'new_post.html', ctx)
def _send_verificaiton_email(self, poster): forum_name = utils.get_config('forum_name') email_address = poster.email verification_url = '%s?code=%s' % ( utils.reverse_absolute('verify-email'), poster.email_verification_code) ctx = { 'forum_name': forum_name, 'username': poster.username, 'email_address': email_address, 'verification_url': verification_url, } send_mail( 'Account Verification for %s' % forum_name, render_to_string('email/account_verification.txt', ctx), settings.EMAIL_HOST_USER, [email_address])
def POST(self, request, forum_id): forum = get_object_or_404(Forum, pk=forum_id) form = self._get_form(request)(request.POST, author=request.user) forum.create_thread_pack.validate_request(request) if form.is_valid(): ip_addr = request.META.get(utils.get_config('client_ip_field'), None) thread = form.save(request.user, ip_addr) if request.user.auto_subscribe >= 1: thread.subscribe(request.user) return HttpResponseRedirect(thread.get_url()) else: ctx = {'forum': forum, 'form': form} return render(request, 'new_thread.html', ctx)
def setUp(self): self.limit = utils.get_config()['initial_account_period_total'] = 3 tutils.create_std_forums() self.thankee = tutils.create_user(thread_count=1, post_count=4) self.thanker = tutils.create_user(post_count=4) self.noob_thanker = tutils.create_user(post_count=1) self.thanker_client = Client() self.thanker_client.force_login(self.thanker) self.noob_thanker_client = Client() self.noob_thanker_client.force_login(self.noob_thanker) self.thankee_client = Client() self.thankee_client.force_login(self.thankee) self.url = reverse('thank-post', args=(self.thankee.post_set.all()[0].pk, ))
def POST(self, request, post_id): min_posts = utils.get_config('initial_account_period_total') if request.user.post_set.count() < min_posts: raise PermissionDenied('Not enough posts to thank.') post = get_object_or_404(Post, pk=post_id) thanks = Thanks(post=post, thanker=request.user, thankee=post.author) try: thanks.save() except IntegrityError: pass if request.is_ajax(): return utils.render_mixed_mode( request, (('thanksBlock', 'thanks_block.html', {'post': post}), ('postControls', 'post_controls.html', {'post': post})), additional={'status': 'SUCCESS'}) else: return HttpResponseRedirect(post.get_url())
def thread_index(request, forum_id): forum = get_object_or_404(Forum, pk=forum_id) threads = forum.thread_set.order_by('-stickied', '-last_update') threads_per_page = utils.get_config('threads_per_forum_page') paginator = utils.MappingPaginator(threads, threads_per_page) paginator.install_map_func(lambda t: utils.ThreadFascet(t, request)) page = utils.page_by_request(paginator, request) ctx = { 'rel_page': page, 'forum': forum, 'threads': page, 'can_start_thread': forum.create_thread_pack.check_request(request) } if request.user.is_authenticated(): forum.mark_read(request.user) return render(request, 'thread_index.html', ctx)
def setUp(self): tutils.create_std_forums() self.admin = tutils.create_user() self.scrub = tutils.create_user() self.admin.is_admin = True self.admin.is_staff = True self.admin.save() self.admin_client = Client() self.admin_client.force_login(self.admin) self.scrub_client = Client() self.scrub_client.force_login(self.scrub) auth_package = AuthPackage.objects.create( logic_package='ADMIN_REQUIRED') self.admin_only_forum = Forum.objects.all()[0] self.admin_only_forum.create_thread_pack = auth_package self.admin_only_forum.save() self.limit = utils.get_config()['captcha_period'] = 0