def __call__(self, request, **kwargs): self.request = request self.mode = kwargs['mode'] try: if not request.user.is_authenticated(): raise ACLError403(_("Guest, you have to sign-in in order to be able to delete replies.")) self.fetch_thread(kwargs) if self.mode in ['hide_post', 'delete_post']: self.fetch_post(kwargs) except (Thread.DoesNotExist, Post.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) if self.mode == 'delete_thread': self.thread.delete() self.forum.sync() self.forum.save(force_update=True) request.messages.set_flash(Message(_('Thread "%(thread)s" has been deleted.') % {'thread': self.thread.name}), 'success', 'threads') return redirect(reverse('forum', kwargs={'forum': self.thread.forum.pk, 'slug': self.thread.forum.slug})) if self.mode == 'hide_thread': self.thread.start_post.deleted = True self.thread.start_post.save(force_update=True) self.thread.last_post.set_checkpoint(request, 'deleted') self.thread.last_post.save(force_update=True) self.thread.sync() self.thread.save(force_update=True) self.forum.sync() self.forum.save(force_update=True) request.messages.set_flash(Message(_('Thread "%(thread)s" has been deleted.') % {'thread': self.thread.name}), 'success', 'threads') if request.acl.threads.can_see_deleted_threads(self.thread.forum): return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug})) return redirect(reverse('forum', kwargs={'forum': self.thread.forum.pk, 'slug': self.thread.forum.slug})) if self.mode == 'delete_post': self.post.delete() self.thread.sync() self.thread.save(force_update=True) self.forum.sync() self.forum.save(force_update=True) request.messages.set_flash(Message(_("Selected Reply has been deleted.")), 'success', 'threads') return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug})) if self.mode == 'hide_post': self.post.deleted = True self.post.edit_date = timezone.now() self.post.edit_user = request.user self.post.edit_user_name = request.user.username self.post.edit_user_slug = request.user.username_slug self.post.save(force_update=True) self.thread.sync() self.thread.save(force_update=True) self.forum.sync() self.forum.save(force_update=True) request.messages.set_flash(Message(_("Selected Reply has been deleted.")), 'success', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def __call__(self, request, slug=None, thread=None, post=None): self.request = request try: self.fetch_thread(thread) if post: self.fetch_post(post) return self.make_jump() except (Thread.DoesNotExist, Post.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message)
def ignore(request, user): if request.user.pk == user.pk: return error404(request) if not request.user.is_ignoring(user): request.messages.set_flash(Message(_("You are now ignoring %(username)s") % {'username': user.username}), 'success') request.user.ignores.add(user) return fallback(request)
def unignore(request, user): if request.user.pk == user.pk: return error404(request) if request.user.is_ignoring(user): request.messages.set_flash(Message(_("You have stopped ignoring %(username)s") % {'username': user.username})) request.user.ignores.remove(user) return fallback(request)
def activate(request, username="", user="******", token=""): user = int(user) try: user = User.objects.get(pk=user) current_activation = user.activation # Run checks user_ban = check_ban(username=user.username, email=user.email) if user_ban: return error_banned(request, user, user_ban) if user.activation == User.ACTIVATION_NONE: return error403(request, Message(request, "users/activation/not_required", extra={"user": user})) if user.activation == User.ACTIVATION_ADMIN: return error403(request, Message(request, "users/activation/only_by_admin", extra={"user": user})) if not token or not user.token or user.token != token: return error403(request, Message(request, "users/invalid_confirmation_link", extra={"user": user})) # Activate and sign in our member user.activation = User.ACTIVATION_NONE sign_user_in(request, user) # Update monitor request.monitor["users_inactive"] = request.monitor["users_inactive"] - 1 if current_activation == User.ACTIVATION_CREDENTIALS: request.messages.set_flash( Message(request, "users/activation/credentials", extra={"user": user}), "success" ) else: request.messages.set_flash(Message(request, "users/activation/new", extra={"user": user}), "success") return redirect(reverse("index")) except User.DoesNotExist: return error404(request)
def reset(request, username="", user="******", token=""): user = int(user) try: user = User.objects.get(pk=user) user_ban = check_ban(username=user.username, email=user.email) if user_ban: return error_banned(request, user, user_ban) if user.activation != User.ACTIVATION_NONE: return error403(request, Message(request, 'users/activation/required', {'user': user})) if not token or not user.token or user.token != token: return error403(request, Message(request, 'users/invalid_confirmation_link', {'user': user})) new_password = get_random_string(6) user.token = None user.set_password(new_password) user.save(force_update=True) # Logout signed in and kill remember me tokens Session.objects.filter(user=user).update(user=None) Token.objects.filter(user=user).delete() # Set flash and mail new password request.messages.set_flash(Message(request, 'users/password/reset_done', extra={'user':user}), 'success') user.email_user( request, 'users/password/new', _("Your New Password"), {'password': new_password} ) return redirect(reverse('sign_in')) except User.DoesNotExist: return error404(request)
def __call__(self, request, **kwargs): self.request = request self.forum = None self.thread = None self.post = None try: self.fetch_target(kwargs) if not request.user.is_authenticated(): raise ACLError403(_("Guest, you have to sign-in in order to see posts changelogs.")) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist, Change.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) return self.dispatch(request, **kwargs)
def reset(request, username="", user="******", token=""): user = int(user) try: user = User.objects.get(pk=user) user_ban = check_ban(username=user.username, email=user.email) if user_ban: return error_banned(request, user, user_ban) if user.activation != User.ACTIVATION_NONE: return error403( request, Message(request, 'users/activation/required', {'user': user})) if not token or not user.token or user.token != token: return error403( request, Message(request, 'users/invalid_confirmation_link', {'user': user})) new_password = get_random_string(6) user.token = None user.set_password(new_password) user.save(force_update=True) # Logout signed in and kill remember me tokens Session.objects.filter(user=user).update(user=None) Token.objects.filter(user=user).delete() # Set flash and mail new password request.messages.set_flash( Message(request, 'users/password/reset_done', extra={'user': user}), 'success') user.email_user(request, 'users/password/new', _("Your New Password"), {'password': new_password}) return redirect(reverse('sign_in')) except User.DoesNotExist: return error404(request)
def settings(request, group_id=None, group_slug=None): # Load groups and find selected group settings_groups = Group.objects.all().order_by('key') if not group_id: active_group = settings_groups[0] group_id = active_group.pk else: group_id = int(group_id) for group in settings_groups: if group.pk == group_id: active_group = group break else: return error404(request, BasicMessage(_('The requested settings group could not be found.'))) # Load selected group settings and turn them into form group_settings = Setting.objects.filter(group=active_group).order_by('position') last_fieldset = (None, []) group_form = {'layout': []} for setting in group_settings: # New field subgroup? if setting.separator and last_fieldset[0] != setting.separator: if last_fieldset[0]: group_form['layout'].append(last_fieldset) last_fieldset = (_(setting.separator), []) last_fieldset[1].append(setting.pk) group_form[setting.pk] = setting.get_field() group_form['layout'].append(last_fieldset) SettingsGroupForm = type('SettingsGroupForm', (Form,), group_form) #Submit form message = request.messages.get_message('admin_settings') if request.method == 'POST': form = SettingsGroupForm(request.POST, request=request) if form.is_valid(): for setting in form.cleaned_data.keys(): request.settings[setting] = form.cleaned_data[setting] request.messages.set_flash(BasicMessage(_('Configuration has been saved.')), 'success', 'admin_settings') return redirect(reverse('admin_settings', kwargs={ 'group_id': active_group.pk, 'group_slug': active_group.key, })) else: message = Message(request, form.non_field_errors()[0]) message.type = 'error' else: form = SettingsGroupForm(request=request) # Display settings group form return request.theme.render_to_response('settings/settings.html', { 'message': message, 'groups': settings_groups, 'active_group': active_group, 'search_form': FormFields(SearchForm(request=request)), 'form': FormLayout(form), 'raw_form': form, }, context_instance=RequestContext(request));
def crop(request, upload=False): if upload and (not request.user.avatar_temp or not 'upload' in request.settings.avatars_types): return error404(request) if not upload and request.user.avatar_type != 'upload': request.messages.set_flash(Message(_("Crop Avatar option is avaiable only when you use uploaded image as your avatar.")), 'error', 'usercp_avatar') return redirect(reverse('usercp_avatar')) message = request.messages.get_message('usercp_avatar') if request.method == 'POST': if request.csrf.request_secure(request): try: image_path = settings.MEDIA_ROOT + 'avatars/' if upload: source = Image.open(image_path + request.user.avatar_temp) else: source = Image.open(image_path + request.user.avatar_original) width, height = source.size aspect = float(width) / float(request.POST['crop_b']) crop_x = int(aspect * float(request.POST['crop_x'])) crop_y = int(aspect * float(request.POST['crop_y'])) crop_w = int(aspect * float(request.POST['crop_w'])) crop = source.crop((crop_x, crop_y, crop_x + crop_w, crop_y + crop_w)) if upload: image_name, image_extension = path(request.user.avatar_temp).splitext() else: image_name, image_extension = path(request.user.avatar_original).splitext() image_name = '%s_%s%s' % (request.user.pk, get_random_string(8), image_extension) resizeimage(crop, settings.AVATAR_SIZES[0], image_path + image_name, info=source.info, format=source.format) for size in settings.AVATAR_SIZES[1:]: resizeimage(crop, size, image_path + str(size) + '_' + image_name, info=source.info, format=source.format) request.user.delete_avatar_image() if upload: request.user.delete_avatar_original() request.user.avatar_type = 'upload' request.user.avatar_original = '%s_org_%s%s' % (request.user.pk, get_random_string(8), image_extension) source.save(image_path + request.user.avatar_original) request.user.delete_avatar_temp() request.user.avatar_image = image_name request.user.save(force_update=True) request.messages.set_flash(Message(_("Your avatar has been cropped.")), 'success', 'usercp_avatar') return redirect(reverse('usercp_avatar')) except Exception: message = Message(_("Form contains errors."), 'error') else: message = Message(_("Request authorisation is invalid."), 'error') return request.theme.render_to_response('usercp/avatar_crop.html', context_instance=RequestContext(request, { 'message': message, 'after_upload': upload, 'avatar_size': settings.AVATAR_SIZES[0], 'source': 'avatars/%s' % (request.user.avatar_temp if upload else request.user.avatar_original), 'tab': 'avatar', }));
def inner_decorator(request, user, *args, **kwargs): request = request user_pk = int(user) try: user = User.objects.get(pk=user_pk) return f(request, user, *args, **kwargs) except User.DoesNotExist: return error404(request)
def make_jump(self): if not self.request.acl.threads.can_mod_posts(self.forum): raise ACLError404() try: return self.redirect( self.thread.post_set.get(reported=True)) except Post.DoesNotExist: return error404(self.request)
def __call__(self, request, slug=None, thread=None, page=0): self.request = request self.pagination = None self.parents = None self.ignored = False self.watcher = None try: self.fetch_thread(thread) self.fetch_posts(page) self.message = request.messages.get_message('threads') self.make_thread_form() if self.thread_form: response = self.handle_thread_form() if response: return response self.make_posts_form() if self.posts_form: response = self.handle_posts_form() if response: return response except Thread.DoesNotExist: return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) # Merge proxy into forum self.forum.closed = self.proxy.closed return request.theme.render_to_response('threads/thread.html', { 'message': self.message, 'forum': self.forum, 'parents': self.parents, 'thread': self.thread, 'is_read': self.tracker.is_read(self.thread), 'count': self.count, 'posts': self.posts, 'ignored_posts': self.ignored, 'watcher': self.watcher, 'pagination': self.pagination, 'quick_reply': FormFields(QuickReplyForm(request=request)).fields, 'thread_form': FormFields(self.thread_form).fields if self.thread_form else None, 'posts_form': FormFields(self.posts_form).fields if self.posts_form else None, }, context_instance=RequestContext(request));
def username(request): if not request.acl.usercp.show_username_change(): return error404(request) changes_left = request.acl.usercp.changes_left(request.user) next_change = None if request.acl.usercp.changes_expire() and not changes_left: next_change = request.user.namechanges.filter( date__gte=timezone.now() - timedelta(days=request.acl.usercp.acl['changes_expire']), ).order_by('-date')[0] next_change = next_change.date + timedelta(days=request.acl.usercp.acl['changes_expire']) message = request.messages.get_message('usercp_username') if request.method == 'POST': if not changes_left: message = Message(_("You have exceeded the maximum number of name changes."), 'error') form = UsernameChangeForm(request=request) else: org_username = request.user.username form = UsernameChangeForm(request.POST, request=request) if form.is_valid(): request.user.set_username(form.cleaned_data['username']) request.user.save(force_update=True) request.user.sync_username() request.user.namechanges.create(date=timezone.now(), old_username=org_username) request.messages.set_flash(Message(_("Your username has been changed.")), 'success', 'usercp_username') # Alert followers of namechange alert_time = timezone.now() bulk_alerts = [] alerted_users = [] for follower in request.user.follows_set.iterator(): alerted_users.append(follower.pk) alert = Alert(user=follower, message=ugettext_lazy("User that you are following, %(username)s, has changed his name to %(newname)s").message, date=alert_time) alert.strong('username', org_username) alert.profile('newname', request.user) alert.hydrate() bulk_alerts.append(alert) if bulk_alerts: Alert.objects.bulk_create(bulk_alerts) User.objects.filter(id__in=alerted_users).update(alerts=F('alerts') + 1) # Hop back return redirect(reverse('usercp_username')) message = Message(form.non_field_errors()[0], 'error') else: form = UsernameChangeForm(request=request) return request.theme.render_to_response('usercp/username.html', context_instance=RequestContext(request, { 'message': message, 'changes_left': changes_left, 'form': FormLayout(form), 'next_change': next_change, 'changes_history': request.user.namechanges.order_by('-date')[:10], 'tab': 'username', }));
def graph(request, model, date_start, date_end, precision): """ Generate fancy graph for model and stuff """ if date_start == date_end: # Bad dates raise error404() # Turn stuff into datetime's date_start = datetime.strptime(date_start, '%Y-%m-%d') date_end = datetime.strptime(date_end, '%Y-%m-%d') statistics_providers = [] models_map = {} for model_obj in models.get_models(): try: getattr(model_obj.objects, 'filter_stats') statistics_providers.append((str(model_obj.__name__).lower(), model_obj.statistics_name)) models_map[str(model_obj.__name__).lower()] = model_obj except AttributeError: pass if not statistics_providers: # Like before, q.q on lack of models return request.theme.render_to_response('stats/not_available.html', context_instance=RequestContext(request)); if not model in models_map or check_dates(date_start, date_end, precision): # Bad model name or graph data! raise error404() form = GenerateStatisticsForm( provider_choices=statistics_providers, request=request, initial={'provider_model': model, 'date_start': date_start, 'date_end': date_end, 'stats_precision': precision}) return request.theme.render_to_response('stats/graph.html', { 'title': models_map[model].statistics_name, 'graph': build_graph(models_map[model], date_start, date_end, precision), 'form': FormLayout(form), 'message': request.messages.get_message('admin_stats'), }, context_instance=RequestContext(request));
def unfollow(request, user): if request.user.pk == user.pk: return error404(request) if request.user.is_following(user): request.messages.set_flash(Message(_("You have stopped following %(username)s") % {'username': user.username})) request.user.follows.remove(user) request.user.following -= 1 request.user.save(force_update=True) user.followers -= 1 user.save(force_update=True) return fallback(request)
def __call__(self, request, **kwargs): self.request = request self.forum = None self.thread = None self.post = None try: self.fetch_target(kwargs) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) return request.theme.render_to_response('threads/details.html', { 'forum': self.forum, 'parents': self.parents, 'thread': self.thread, 'post': self.post, }, context_instance=RequestContext(request))
def inner_decorator(request, user, username, *args, **kwargs): request = request user_pk = int(user) user_slug = username try: user = User.objects.get(pk=user_pk) if user.username_slug != user_slug: # Force crawlers to take notice of updated username return redirect(reverse(fallback, args=(user.username_slug, user.pk)), permanent=True) return f(request, user, *args, **kwargs) except User.DoesNotExist: return error404(request)
def gravatar(request): if not 'gravatar' in request.settings.avatars_types: return error404(request) if request.user.avatar_type != 'gravatar': if request.csrf.request_secure(request): request.user.delete_avatar() request.user.avatar_type = 'gravatar' request.user.save(force_update=True) request.messages.set_flash(Message(_("Your avatar has been changed to Gravatar.")), 'success', 'usercp_avatar') else: request.messages.set_flash(Message(_("Request authorisation is invalid.")), 'error', 'usercp_avatar') return redirect(reverse('usercp_avatar'))
def user_profile(request, user, username): user = int(user) try: user = User.objects.get(pk=user) if user.username_slug != username: # Force crawlers to take notice of updated username return redirect(reverse('user', args=(user.username_slug, user.pk)), permanent=True) return request.theme.render_to_response('users/profile.html', { 'profile': user, }, context_instance=RequestContext(request)); except User.DoesNotExist: return error404(request)
def activate(request, username="", user="******", token=""): user = int(user) try: user = User.objects.get(pk=user) current_activation = user.activation # Run checks user_ban = check_ban(username=user.username, email=user.email) if user_ban: return error_banned(request, user, user_ban) if user.activation == User.ACTIVATION_NONE: return error403( request, Message(request, 'users/activation/not_required', extra={'user': user})) if user.activation == User.ACTIVATION_ADMIN: return error403( request, Message(request, 'users/activation/only_by_admin', extra={'user': user})) if not token or not user.token or user.token != token: return error403( request, Message(request, 'users/invalid_confirmation_link', extra={'user': user})) # Activate and sign in our member user.activation = User.ACTIVATION_NONE sign_user_in(request, user) # Update monitor request.monitor[ 'users_inactive'] = request.monitor['users_inactive'] - 1 if current_activation == User.ACTIVATION_CREDENTIALS: request.messages.set_flash( Message(request, 'users/activation/credentials', extra={'user': user}), 'success') else: request.messages.set_flash( Message(request, 'users/activation/new', extra={'user': user}), 'success') return redirect(reverse('index')) except User.DoesNotExist: return error404(request)
def show(request, user, username): user = int(user) try: user = User.objects.get(pk=user) if user.username_slug != username: # Force crawlers to take notice of updated username return redirect(reverse('user', args=(user.username_slug, user.pk)), permanent=True) return request.theme.render_to_response( 'users/profile.html', { 'profile': user, }, context_instance=RequestContext(request)) except User.DoesNotExist: return error404(request)
def follow(request, user): if request.user.pk == user.pk: return error404(request) if not request.user.is_following(user): request.messages.set_flash(Message(_("You are now following %(username)s") % {'username': user.username}), 'success') request.user.follows.add(user) request.user.following += 1 request.user.save(force_update=True) user.followers += 1 if not user.is_ignoring(request.user): alert = user.alert(ugettext_lazy("%(username)s is now following you").message) alert.profile('username', request.user) alert.save_all() else: user.save(force_update=True) return fallback(request)
def gallery(request): if not 'gallery' in request.settings.avatars_types: return error404(request) allowed_avatars = [] galleries = [] for directory in path(settings.STATICFILES_DIRS[0]).joinpath('avatars').dirs(): if directory[-7:] != '_locked' and directory[-8:] != '_default': gallery = {'name': directory[-7:], 'avatars': []} avatars = directory.files('*.gif') avatars += directory.files('*.jpg') avatars += directory.files('*.jpeg') avatars += directory.files('*.png') for item in avatars: gallery['avatars'].append('/'.join(path(item).splitall()[-2:])) galleries.append(gallery) allowed_avatars += gallery['avatars'] if not allowed_avatars: request.messages.set_flash(Message(_("No avatars are avaiable.")), 'info', 'usercp_avatar') return redirect(reverse('usercp_avatar')) message = request.messages.get_message('usercp_avatar') if request.method == 'POST': if request.csrf.request_secure(request): new_avatar = request.POST.get('avatar_image') if new_avatar in allowed_avatars: request.user.delete_avatar() request.user.avatar_type = 'gallery' request.user.avatar_image = new_avatar request.user.save(force_update=True) request.messages.set_flash(Message(_("Your avatar has been changed to one from gallery.")), 'success', 'usercp_avatar') return redirect(reverse('usercp_avatar')) message = Message(_("Selected Avatar is incorrect."), 'error') else: message = Message(_("Request authorisation is invalid."), 'error') return request.theme.render_to_response('usercp/avatar_gallery.html', context_instance=RequestContext(request, { 'message': message, 'galleries': galleries, 'tab': 'avatar', }));
def activate(request, token): new_credentials = request.session.get('new_credentials') if not new_credentials or new_credentials['token'] != token: return error404(request) if new_credentials['new_email']: request.user.set_email(new_credentials['new_email']) if new_credentials['new_password']: request.user.set_password(new_credentials['new_password']) try: request.user.full_clean() request.user.save(force_update=True) request.user.sessions.exclude(id=request.session.id).delete() request.user.signin_tokens.all().delete() request.messages.set_flash(Message(_("%(username)s, your Sign-In credentials have been changed.") % {'username': request.user.username}), 'success', 'security') request.session.sign_out(request) del request.session['new_credentials'] return redirect(reverse('sign_in')) except ValidationError: request.messages.set_flash(Message(_("Your new credentials have been invalidated. Please try again.")), 'error', 'usercp_credentials') return redirect(reverse('usercp_credentials'))
def settings(request, group_id=None, group_slug=None): # Load groups and find selected group settings_groups = Group.objects.all().order_by('key') if not group_id: active_group = settings_groups[0] group_id = active_group.pk else: group_id = int(group_id) for group in settings_groups: if group.pk == group_id: active_group = group break else: return error404( request, BasicMessage( _('The requested settings group could not be found.'))) # Load selected group settings and turn them into form group_settings = Setting.objects.filter( group=active_group).order_by('position') last_fieldset = (None, []) group_form = {'layout': []} for setting in group_settings: # New field subgroup? if setting.separator and last_fieldset[0] != setting.separator: if last_fieldset[0]: group_form['layout'].append(last_fieldset) last_fieldset = (_(setting.separator), []) last_fieldset[1].append(setting.pk) group_form[setting.pk] = setting.get_field() group_form['layout'].append(last_fieldset) SettingsGroupForm = type('SettingsGroupForm', (Form, ), group_form) #Submit form message = request.messages.get_message('admin_settings') if request.method == 'POST': form = SettingsGroupForm(request.POST, request=request) if form.is_valid(): for setting in form.cleaned_data.keys(): request.settings[setting] = form.cleaned_data[setting] request.messages.set_flash( BasicMessage(_('Configuration has been saved.')), 'success', 'admin_settings') return redirect( reverse('admin_settings', kwargs={ 'group_id': active_group.pk, 'group_slug': active_group.key, })) else: message = Message(request, form.non_field_errors()[0]) message.type = 'error' else: form = SettingsGroupForm(request=request) # Display settings group form return request.theme.render_to_response( 'settings/settings.html', { 'message': message, 'groups': settings_groups, 'active_group': active_group, 'search_form': FormFields(SearchForm(request=request)), 'form': FormLayout(form), 'raw_form': form, }, context_instance=RequestContext(request))
def list(request, rank_slug=None): ranks = Rank.objects.filter(as_tab=1).order_by('order') # Find active rank active_rank = None if rank_slug: for rank in ranks: if rank.name_slug == rank_slug: active_rank = rank if not active_rank: return error404(request) elif ranks: active_rank = ranks[0] # Empty Defaults message = None users = [] in_search = False # Users search? if request.method == 'POST': in_search = True active_rank = None search_form = QuickFindUserForm(request.POST, request=request) if search_form.is_valid(): # Direct hit? username = search_form.cleaned_data['username'] try: user = User.objects.get(username__iexact=username) return redirect( reverse('user', args=(user.username_slug, user.pk))) except User.DoesNotExist: pass # Looks like well have to find near match if len(username) > 6: username = username[0:-3] elif len(username) > 5: username = username[0:-2] elif len(username) > 4: username = username[0:-1] username = slugify(username.strip()) # Go for rought match if len(username) > 0: print username users = User.objects.filter(username_slug__startswith=username ).order_by('username_slug')[:10] elif search_form.non_field_errors()[0] == 'form_contains_errors': message = Message(request, 'users/search_empty', 'error') else: message = Message(request, search_form.non_field_errors()[0], 'error') else: search_form = QuickFindUserForm(request=request) if active_rank: users = User.objects.filter( rank=active_rank).order_by('username_slug') return request.theme.render_to_response( 'users/list.html', { 'message': message, 'search_form': FormFields(search_form).fields, 'in_search': in_search, 'active_rank': active_rank, 'ranks': ranks, 'users': users, }, context_instance=RequestContext(request))
def __call__(self, request, **kwargs): self.request = request self.forum = None self.thread = None self.quote = None self.post = None self.parents = None self.mode = kwargs.get('mode') if self.request.POST.get('quick_reply') and self.mode == 'new_post': self.mode = 'new_post_quick' try: self.fetch_target(kwargs) if not request.user.is_authenticated(): raise ACLError403(_("Guest, you have to sign-in in order to post replies.")) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) message = request.messages.get_message('threads') if request.method == 'POST': form = self.get_form(True) # Show message preview if 'preview' in request.POST: if form['post'].value(): md, preparsed = post_markdown(request, form['post'].value()) else: md, preparsed = None, None form.empty_errors() return request.theme.render_to_response('threads/posting.html', { 'mode': self.mode, 'forum': self.forum, 'thread': self.thread, 'post': self.post, 'quote': self.quote, 'parents': self.parents, 'message': message, 'preview': preparsed, 'form': FormLayout(form), }, context_instance=RequestContext(request)); # Commit form to database if form.is_valid(): # Record original vars if user is editing if self.mode in ['edit_thread', 'edit_post']: old_name = self.thread.name old_post = self.post.post # If there is no change, throw user back changed_name = (old_name != form.cleaned_data['thread_name']) if self.mode == 'edit_thread' else False changed_post = old_post != form.cleaned_data['post'] changed_anything = changed_name or changed_post # Some extra initialisation now = timezone.now() md = None moderation = False if not request.acl.threads.acl[self.forum.pk]['can_approve']: if self.mode == 'new_thread' and request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1: moderation = True if self.mode in ['new_post', 'new_post_quick'] and request.acl.threads.acl[self.forum.pk]['can_write_posts'] == 1: moderation = True # Get or create new thread if self.mode == 'new_thread': thread = Thread.objects.create( forum=self.forum, name=form.cleaned_data['thread_name'], slug=slugify(form.cleaned_data['thread_name']), start=now, last=now, moderated=moderation, score=request.settings['thread_ranking_initial_score'], ) if moderation: thread.replies_moderated += 1 else: thread = self.thread if self.mode == 'edit_thread': thread.name = form.cleaned_data['thread_name'] thread.slug = slugify(form.cleaned_data['thread_name']) thread.previous_last = thread.last # Create new message if self.mode in ['new_thread', 'new_post', 'new_post_quick']: # Use last post instead? if self.mode in ['new_post', 'new_post_quick']: merge_diff = (now - self.thread.last) merge_diff = (merge_diff.days * 86400) + merge_diff.seconds if (self.mode in ['new_post', 'new_post_quick'] and request.settings.post_merge_time and merge_diff < (request.settings.post_merge_time * 60) and self.thread.last_poster_id == request.user.id): # Overtake posting post = self.thread.last_post post.appended = True post.moderated = moderation post.date = now post.post = '%s\n\n- - -\n**%s**\n%s' % (post.post, _("Added on %(date)s:") % {'date': date(now, 'SHORT_DATETIME_FORMAT')}, form.cleaned_data['post']) md, post.post_preparsed = post_markdown(request, post.post) post.save(force_update=True) thread.last = now thread.save(force_update=True) self.forum.last = now self.forum.save(force_update=True) # Ignore rest of posting action request.messages.set_flash(Message(_("Your reply has been added to previous one.")), 'success', 'threads_%s' % post.pk) return self.redirect_to_post(post) else: md, post_preparsed = post_markdown(request, form.cleaned_data['post']) post = Post.objects.create( forum=self.forum, thread=thread, merge=thread.merges, user=request.user, user_name=request.user.username, ip=request.session.get_ip(request), agent=request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) post.appended = False elif changed_post: # Change message post = self.post post.post = form.cleaned_data['post'] md, post.post_preparsed = post_markdown(request, form.cleaned_data['post']) post.edits += 1 post.edit_date = now post.edit_user = request.user post.edit_user_name = request.user.username post.edit_user_slug = request.user.username_slug post.save(force_update=True) # Record this edit in changelog? if self.mode in ['edit_thread', 'edit_post'] and changed_anything: self.post.change_set.create( forum=self.forum, thread=self.thread, post=self.post, user=request.user, user_name=request.user.username, user_slug=request.user.username_slug, date=now, ip=request.session.get_ip(request), agent=request.META.get('HTTP_USER_AGENT'), reason=form.cleaned_data['edit_reason'], size=len(self.post.post), change=len(self.post.post) - len(old_post), thread_name_old=old_name if self.mode == 'edit_thread' and form.cleaned_data['thread_name'] != old_name else None, thread_name_new=self.thread.name if self.mode == 'edit_thread' and form.cleaned_data['thread_name'] != old_name else None, post_content=old_post, ) # Set thread start post and author data if self.mode == 'new_thread': thread.start_post = post thread.start_poster = request.user thread.start_poster_name = request.user.username thread.start_poster_slug = request.user.username_slug if request.user.rank and request.user.rank.style: thread.start_poster_style = request.user.rank.style # Reward user for posting new thread? if not request.user.last_post or request.user.last_post < timezone.now() - timedelta(seconds=request.settings['score_reward_new_post_cooldown']): request.user.score += request.settings['score_reward_new_thread'] # New post - increase post counters, thread score # Notify quoted post author and close thread if it has hit limit if self.mode in ['new_post', 'new_post_quick']: if moderation: thread.replies_moderated += 1 else: thread.replies += 1 if thread.last_poster_id != request.user.pk: thread.score += request.settings['thread_ranking_reply_score'] # Notify quoted poster of reply? if self.quote and self.quote.user_id and self.quote.user_id != request.user.pk and not self.quote.user.is_ignoring(request.user): alert = self.quote.user.alert(ugettext_lazy("%(username)s has replied to your post in thread %(thread)s").message) alert.profile('username', request.user) alert.post('thread', self.thread, post) alert.save_all() if (self.request.settings.thread_length > 0 and not thread.closed and thread.replies >= self.request.settings.thread_length): thread.closed = True post.set_checkpoint(self.request, 'limit') # Reward user for posting new post? if not post.appended and (not request.user.last_post or request.user.last_post < timezone.now() - timedelta(seconds=request.settings['score_reward_new_post_cooldown'])): request.user.score += request.settings['score_reward_new_post'] # Update last poster data if not moderation and self.mode not in ['edit_thread', 'edit_post']: thread.last = now thread.last_post = post thread.last_poster = request.user thread.last_poster_name = request.user.username thread.last_poster_slug = request.user.username_slug thread.last_poster_style = request.user.rank.style # Final update of thread entry if self.mode != 'edit_post': thread.save(force_update=True) # Update forum and monitor if not moderation: if self.mode == 'new_thread': self.request.monitor['threads'] = int(self.request.monitor['threads']) + 1 self.forum.threads += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick']: self.request.monitor['posts'] = int(self.request.monitor['posts']) + 1 self.forum.posts += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick'] or ( self.mode == 'edit_thread' and self.forum.last_thread_id == thread.pk and self.forum.last_thread_name != thread.name): self.forum.last_thread = thread self.forum.last_thread_name = thread.name self.forum.last_thread_slug = thread.slug self.forum.last_thread_date = thread.last if self.mode in ['new_thread', 'new_post', 'new_post_quick']: self.forum.last_poster = thread.last_poster self.forum.last_poster_name = thread.last_poster_name self.forum.last_poster_slug = thread.last_poster_slug self.forum.last_poster_style = thread.last_poster_style if self.mode != 'edit_post': self.forum.save(force_update=True) # Update user if not moderation: if self.mode == 'new_thread': request.user.threads += 1 request.user.posts += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick']: request.user.last_post = thread.last request.user.save(force_update=True) # Notify users about post if md: try: if self.quote and self.quote.user_id: del md.mentions[self.quote.user.username_slug] except KeyError: pass if md.mentions: post.notify_mentioned(request, md.mentions) post.save(force_update=True) # Set thread watch status if self.mode == 'new_thread' and request.user.subscribe_start: ThreadWatch.objects.create( user=request.user, forum=self.forum, thread=thread, last_read=now, email=(request.user.subscribe_start == 2), ) if self.mode in ['new_post', 'new_post_quick'] and request.user.subscribe_reply: try: watcher = ThreadWatch.objects.get(user=request.user, thread=self.thread) except ThreadWatch.DoesNotExist: ThreadWatch.objects.create( user=request.user, forum=self.forum, thread=thread, last_read=now, email=(request.user.subscribe_reply == 2), ) # Set flash and redirect user to his post if self.mode == 'new_thread': if moderation: request.messages.set_flash(Message(_("New thread has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads') else: request.messages.set_flash(Message(_("New thread has been posted.")), 'success', 'threads') return redirect(reverse('thread', kwargs={'thread': thread.pk, 'slug': thread.slug}) + ('#post-%s' % post.pk)) if self.mode in ['new_post', 'new_post_quick']: thread.email_watchers(request, post) if moderation: request.messages.set_flash(Message(_("Your reply has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads_%s' % post.pk) else: request.messages.set_flash(Message(_("Your reply has been posted.")), 'success', 'threads_%s' % post.pk) return self.redirect_to_post(post) if self.mode == 'edit_thread': request.messages.set_flash(Message(_("Your thread has been edited.")), 'success', 'threads_%s' % self.post.pk) if self.mode == 'edit_post': request.messages.set_flash(Message(_("Your reply has been edited.")), 'success', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post) return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % self.post.pk)) message = Message(form.non_field_errors()[0], 'error') else: form = self.get_form() # Merge proxy into forum self.forum.closed = self.proxy.closed return request.theme.render_to_response('threads/posting.html', { 'mode': self.mode, 'forum': self.forum, 'thread': self.thread, 'post': self.post, 'quote': self.quote, 'parents': self.parents, 'message': message, 'form': FormLayout(form), }, context_instance=RequestContext(request));
def list(request, rank_slug=None): ranks = Rank.objects.filter(as_tab=1).order_by('order') # Find active rank active_rank = None if rank_slug: for rank in ranks: if rank.name_slug == rank_slug: active_rank = rank if not active_rank: return error404(request) elif ranks: active_rank = ranks[0] # Empty Defaults message = None users = [] in_search = False # Users search? if request.method == 'POST': in_search = True active_rank = None search_form = QuickFindUserForm(request.POST, request=request) if search_form.is_valid(): # Direct hit? username = search_form.cleaned_data['username'] try: user = User.objects.get(username__iexact=username) return redirect(reverse('user', args=(user.username_slug, user.pk))) except User.DoesNotExist: pass # Looks like well have to find near match if len(username) > 6: username = username[0:-3] elif len(username) > 5: username = username[0:-2] elif len(username) > 4: username = username[0:-1] username = slugify(username.strip()) # Go for rought match if len(username) > 0: print username users = User.objects.filter(username_slug__startswith=username).order_by('username_slug')[:10] elif search_form.non_field_errors()[0] == 'form_contains_errors': message = Message(request, 'users/search_empty', 'error') else: message = Message(request, search_form.non_field_errors()[0], 'error') else: search_form = QuickFindUserForm(request=request) if active_rank: users = User.objects.filter(rank=active_rank).order_by('username_slug') return request.theme.render_to_response('users/list.html', { 'message': message, 'search_form': FormFields(search_form).fields, 'in_search': in_search, 'active_rank': active_rank, 'ranks': ranks, 'users': users, }, context_instance=RequestContext(request));
def forum_tos(request): if request.settings.tos_url or not request.settings.tos_content: return error404(request) return request.theme.render_to_response('forum_tos.html', context_instance=RequestContext(request));
def view(request): if self.post.user_id == request.user.id: return error404(request) self.check_acl(request) try: vote = Karma.objects.get(user=request.user, post=self.post) if self.thread.start_post_id == self.post.pk: if vote.score > 0: self.thread.upvotes -= 1 else: self.thread.downvotes -= 1 if vote.score > 0: self.post.upvotes -= 1 request.user.karma_given_p -= 1 if self.post.user_id: self.post.user.karma_p -= 1 else: self.post.downvotes -= 1 request.user.karma_given_n -= 1 if self.post.user_id: self.post.user.karma_n -= 1 except Karma.DoesNotExist: vote = Karma() vote.forum = self.forum vote.thread = self.thread vote.post = self.post vote.user = request.user vote.user_name = request.user.username vote.user_slug = request.user.username_slug vote.date = timezone.now() vote.ip = request.session.get_ip(request) vote.agent = request.META.get('HTTP_USER_AGENT') self.make_vote(request, vote) request.messages.set_flash(Message(_('Your vote has been saved.')), 'success', 'threads_%s' % self.post.pk) if vote.pk: vote.save(force_update=True) else: vote.save(force_insert=True) if self.thread.start_post_id == self.post.pk: if vote.score > 0: self.thread.upvotes += 1 else: self.thread.downvotes += 1 self.thread.save(force_update=True) if vote.score > 0: self.post.upvotes += 1 request.user.karma_given_p += 1 if self.post.user_id: self.post.user.karma_p += 1 self.post.user.score += request.settings['score_reward_karma_positive'] else: self.post.downvotes += 1 request.user.karma_given_n += 1 if self.post.user_id: self.post.user.karma_n += 1 self.post.user.score -= request.settings['score_reward_karma_negative'] self.post.save(force_update=True) request.user.save(force_update=True) if self.post.user_id: self.post.user.save(force_update=True) return self.redirect(self.post)
def upload(request): if not 'upload' in request.settings.avatars_types: return error404(request) message = request.messages.get_message('usercp_avatar') if request.method == 'POST': form = UploadAvatarForm(request.POST, request.FILES, request=request) if form.is_valid(): request.user.delete_avatar_temp() image = form.cleaned_data['avatar_upload'] image_name, image_extension = path(image.name.lower()).splitext() image_name = '%s_tmp_%s%s' % (request.user.pk, get_random_string(8), image_extension) image_path = settings.MEDIA_ROOT + 'avatars/' + image_name request.user.avatar_temp = image_name with open(image_path, 'wb+') as destination: for chunk in image.chunks(): destination.write(chunk) request.user.save() try: image = Image.open(image_path) if not image.format in ['GIF', 'PNG', 'JPEG']: raise ValidationError() image.seek(0) image.save(image_path) if request.POST.get('js_check'): return redirect(reverse('usercp_avatar_upload_crop')) # Redirect to crop page didnt happen, handle avatar with old school hollywood way image_path = settings.MEDIA_ROOT + 'avatars/' source = Image.open(image_path + request.user.avatar_temp) image_name, image_extension = path(request.user.avatar_temp).splitext() image_name = '%s_%s%s' % (request.user.pk, get_random_string(8), image_extension) resizeimage(source, settings.AVATAR_SIZES[0], image_path + image_name, info=source.info, format=source.format) for size in settings.AVATAR_SIZES[1:]: resizeimage(source, size, image_path + str(size) + '_' + image_name, info=source.info, format=source.format) # Update user model one more time request.user.delete_avatar_image() request.user.delete_avatar_original() request.user.avatar_type = 'upload' request.user.avatar_original = '%s_org_%s%s' % (request.user.pk, get_random_string(8), image_extension) source.save(image_path + request.user.avatar_original) request.user.delete_avatar_temp() request.user.avatar_image = image_name request.user.save(force_update=True) # Set message and adios! request.messages.set_flash(Message(_("Your avatar has changed.")), 'success', 'usercp_avatar') return redirect(reverse('usercp_avatar')) except ValidationError: request.user.delete_avatar() request.user.default_avatar(request.settings) message = Message(_("Only gif, jpeg and png files are allowed for member avatars."), 'error') else: message = Message(form.non_field_errors()[0], 'error') else: form = UploadAvatarForm(request=request) return request.theme.render_to_response('usercp/avatar_upload.html', context_instance=RequestContext(request, { 'message': message, 'form': FormLayout(form), 'tab': 'avatar', }));