def text_view(request, key, adminkey=None): text = get_text_by_keys_or_404(key) register_activity(request, "text_view", text=text) text_version = text.get_latest_version() embed_code = embed_html(key, 'id="text_view_frame" name="text_view_frame" onload="if (window.iframe_onload) iframe_onload();"', None, request.META.get('QUERY_STRING')) template_dict = { 'embed_code':embed_code, 'text' : text, 'text_version' : text_version, 'title' : text_version.title} return render_to_response('site/text_view.html', template_dict, context_instance=RequestContext(request))
def _text_create_upload(request, createForm): if request.method == 'POST': form = createForm(request.POST, request.FILES) if form.is_valid(): # should convert? if form.cleaned_data['file']: try: uploaded_file = form.cleaned_data['file'] content, attachs = convert_from_mimetype(uploaded_file.temporary_file_path(), uploaded_file.content_type, format=form.cleaned_data['format'], ) form.cleaned_data['content'] = content form.cleaned_data['attachs'] = attachs # set title if not present if not form.cleaned_data.get('title', None): form.cleaned_data['title'] = remove_extension(uploaded_file.name) del form.cleaned_data['file'] except: raise text = create_text(request.user, form.cleaned_data) register_activity(request, "text_created", text) display_message(request, _(u'Text "%(text_title)s" has been created')%{"text_title":text.get_latest_version().title}) return text, redirect_post_create(text) else: form = createForm() return None, render_to_response('site/text_create_upload.html', {'form' : form}, context_instance=RequestContext(request))
def text_delete(request, key): text = Text.objects.get(key=key) if request.method != 'POST': raise UnauthorizedException('Unauthorized') display_message(request, _(u'Text %(text_title)s deleted') %{'text_title':text.title}) register_activity(request, "text_removed", text=text) text.delete() return HttpResponse('') # no redirect because this is called by js
def add_comment(request, key, version_key): # if edit_comment_id : # # if self.request.user.is_anonymous() : # accessing via an admin url ? # and comment.user == self.request.user user = None if request.user.is_anonymous() else request.user name, email, title, content, tags, category, reply_to_id, format, start_wrapper, end_wrapper, start_offset, end_offset = read_comment_args(request) errors = {} errors = validate_comment_args(name, email, title, content, tags) if start_wrapper == "" : errors['selection_place'] = selection_place_error_msg #TODO validate pandoc conversion content_html = pandoc_convert(content, format, "html", full=False) ret = {} if errors != {} : ret['errors'] = errors else : # INSERT # TODO check version still exist ... reply_to = None if reply_to_id : reply_to = Comment.objects.get(id=reply_to_id) text = Text.objects.get(key=key) text_version = TextVersion.objects.get(key=version_key) comment_state = 'approved' if text_version.mod_posteriori else 'pending' comment = Comment.objects.create(state=comment_state, text_version=text_version, user=user, name=name, email=email, title=title, content=content, content_html=content_html, tags = tags, category = category, start_wrapper = start_wrapper, end_wrapper = end_wrapper, start_offset = start_offset, end_offset = end_offset, reply_to=reply_to) ask_for_notification = True if user : workspace_notify_count = Notification.objects.filter(text=None,type='workspace',user=user, active=True).count() text_notify_count = Notification.objects.filter(text=text,type='text',user=user, active=True).count() if workspace_notify_count > 0 or text_notify_count > 0 : ask_for_notification = False if ask_for_notification : ask_for_notification = ( None == Notification.objects.get_notifications(text=None, type='own', email_or_user=(user if user else email))) ret['ask_for_notification'] = ask_for_notification ret['email'] = '' if user else email if text_version.mod_posteriori or has_perm(request, 'can_view_unapproved_comment', text=text) or has_perm(request, 'can_view_comment_own', text=text) : ret['comment'] = comment ret['msg'] = _(u"comment saved") else : ret['msg'] = _(u"comment saved, it is being held for moderation") if AUTO_CONTRIB_REGISTER: Notification.objects.set_notification(text=text, type='own', active=True, email_or_user=user or email) register_activity(request, "comment_created", text, comment) cache.clear() return ret
def remove_comment(request, key, comment_key): ret={} try: text = Text.objects.get(key=key) comment = Comment.objects.get(key = comment_key) comment.delete() ret['msg'] = _(u'comment removed') register_activity(request, "comment_removed", text=text, comment=comment) except ObjectDoesNotExist: pass return ret ;
def remove_comment(request, key, comment_key): ret={} try: text = Text.objects.get(key=key) comment = Comment.objects.get(key = comment_key) comment.delete() ret['msg'] = _(u'comment removed') register_activity(request, "comment_removed", text=text, comment=comment) cache.clear() except ObjectDoesNotExist: pass return ret ;
def user_enable(request, key): if request.method == 'POST': profile = get_object_or_404(UserProfile, key=key) profile.is_suspended = False profile.save() if profile.user.is_active: display_message(request, _(u"User's access %(prof)s has been restored.") % {'prof':profile.simple_print()}) register_activity(request, "user_enabled", user=profile.user) else: # new member approval profile.send_activation_email() display_message(request, _(u"User's access %(prof)s has been approved.") % {'prof':profile.simple_print()}) register_activity(request, "user_approved", user=profile.user) return HttpResponse('') # no redirect because this is called by js raise UnauthorizedException('')
def _text_create_content(request, createForm): document = "" if request.method == 'POST': form = createForm(request.POST) if form.is_valid(): text = create_text(request.user, form.cleaned_data) register_activity(request, "text_created", text) display_message(request, _(u'Text "%(text_title)s" has been created') %{"text_title":text.get_latest_version().title}) return text, redirect_post_create(text) else: form = createForm() return None, render_to_response('site/text_create_content.html', {'document':document, 'form' : form}, context_instance=RequestContext(request))
def user_suspend(request, key): if request.method == 'POST': profile = get_object_or_404(UserProfile, key=key) profile.is_suspended = True profile.save() if profile.user.is_active: display_message(request, _(u"User's access %(prof)s has been suspended.") % {'prof':profile.simple_print()}) register_activity(request, "user_suspended", user=profile.user) else: # make use active but disabled profile.user.is_active = True profile.user.save() display_message(request, _(u"User's access %(prof)s has been refused.") % {'prof':profile.simple_print()}) register_activity(request, "user_refused", user=profile.user) return HttpResponse('') # no redirect because this is called by js raise UnauthorizedException('')
def user_activate(request, key): try: profile = UserProfile.objects.get(adminkey=key) user = profile.user if not user.is_active: if request.method == 'POST': userform = UserValidateForm(request.POST, instance=user) pwform = SetPasswordForm(profile.user, request.POST) if userform.is_valid() and pwform.is_valid(): userform.save() pwform.save() user.is_active = True user.save() # login user.backend = 'django.contrib.auth.backends.ModelBackend' django_login(request, user) register_activity(request, "user_activated", user=user) display_message( request, _(u"Your account has been activated. You're now logged-in." )) return HttpResponseRedirect(reverse('index')) else: user.username = '' userform = UserValidateForm(instance=user) pwform = SetPasswordForm(user) cache.clear() return render_to_response('site/activate.html', { 'forms': [userform, pwform], 'title': _(u'Activate your account'), 'save_name': _(u'activate account'), }, context_instance=RequestContext(request)) else: user.backend = 'django.contrib.auth.backends.ModelBackend' django_login(request, user) display_message( request, _(u"Your account has been activated. You're now logged-in.")) return HttpResponseRedirect(reverse('index')) except UserProfile.DoesNotExist: raise UnauthorizedException('No profile')
def user_add(request, key=None, mass=False): text = get_text_by_keys_or_404(key) if key else None if request.method == 'POST': userform = UserForm(request.POST) if not mass else MassUserForm(request.POST) userroleform = UserRoleForm(request.POST) if not(key) else None noteform = UserAddForm(request.POST) userprofileform = UserProfileAddForm(request.POST) localroleform = UserRoleTextForm(request.POST, prefix="local") if key else None if userform.is_valid() and (not userroleform or userroleform.is_valid()) and noteform.is_valid() and userprofileform.is_valid() and (not localroleform or localroleform.is_valid()): data = userform.cleaned_data data.update(userprofileform.cleaned_data) data.update(noteform.cleaned_data) emails = data['email'] del data['email'] email_created = set() for email in [s.strip() for s in SEPARATORS_RE.split(emails)]: if email and not User.objects.filter(email__iexact=email) and email not in email_created: user = UserProfile.objects.create_inactive_user(email, True, **data) if key: localuserrole = UserRole.objects.create(user=user, role=localroleform.cleaned_data['role'], text=text) else: userrole = UserRole.objects.create(user=user, role=userroleform.cleaned_data['role'], text=None) email_created.add(email) register_activity(request, "user_created", user=user) display_message(request, ungettext(u'%(nb_users)d user added', u'%(nb_users)d users added', len(email_created)) % {'nb_users': len(email_created)}) if key: return HttpResponseRedirect(reverse('text-share', args=[text.key])) else: return HttpResponseRedirect(reverse('user')) else: userform = UserForm() if not mass else MassUserForm() userroleform = UserRoleForm() if not(key) else None userprofileform = UserProfileAddForm() noteform = UserAddForm() localroleform = UserRoleTextForm(prefix="local") if key else None if key: template = 'site/user_mass_add_text.html' if mass else 'site/user_add_text.html' else: template = 'site/user_mass_add.html' if mass else 'site/user_add.html' return render_to_response(template, {'forms' : [userform, userprofileform , userroleform, noteform, localroleform], 'save_name' : ungettext(u'Add user', u'Add users', 2 if mass else 1), 'mass' : mass, 'text' : text, }, context_instance=RequestContext(request))
def user_enable(request, key): if request.method == 'POST': profile = get_object_or_404(UserProfile, key=key) profile.is_suspended = False profile.save() if profile.user.is_active: display_message( request, _(u"User's access %(prof)s has been restored.") % {'prof': profile.simple_print()}) register_activity(request, "user_enabled", user=profile.user) else: # new member approval profile.send_activation_email() display_message( request, _(u"User's access %(prof)s has been approved.") % {'prof': profile.simple_print()}) register_activity(request, "user_approved", user=profile.user) return HttpResponse('') # no redirect because this is called by js raise UnauthorizedException('')
def text_edit(request, key, adminkey=None): text = get_text_by_keys_or_404(key) text_version = text.get_latest_version() if request.method == 'POST': if request.user.is_authenticated(): form = EditTextForm(request.POST) else: form = EditTextFormAnon(request.POST) if form.is_valid(): if request.POST.get('new_version'): new_version = form.save_new_version(text, request) register_activity(request, "text_edited_new_version", text=text, text_version=new_version) else: form.save_into_text(text, request) register_activity(request, "text_edited", text=text) return redirect(request, 'text-view', args=[text.key]) else: default_data = { 'content': text_version.content, 'title': text_version.title, 'format': text_version.format, 'tags': text_version.tags, 'new_version': NEW_TEXT_VERSION_ON_EDIT, 'note': '', 'keep_comments': True, 'cancel_modified_scopes': True, } if request.user.is_authenticated(): form = EditTextForm(default_data) else: form = EditTextFormAnon(default_data) template_dict = {'text': text, 'form': form} return render_to_response('site/text_edit.html', template_dict, context_instance=RequestContext(request))
def user_activate(request, key): try: profile = UserProfile.objects.get(adminkey=key) user = profile.user if not user.is_active: if request.method == 'POST': userform = UserValidateForm(request.POST, instance=user) pwform = SetPasswordForm(profile.user, request.POST) if userform.is_valid() and pwform.is_valid(): userform.save() pwform.save() user.is_active = True user.save() # login user.backend = 'django.contrib.auth.backends.ModelBackend' django_login(request, user) register_activity(request, "user_activated", user=user) display_message(request, _(u"Your account has been activated. You're now logged-in.")) return HttpResponseRedirect(reverse('index')) else: user.username = '' userform = UserValidateForm(instance=user) pwform = SetPasswordForm(user) cache.clear() return render_to_response('site/activate.html', { 'forms' : [userform, pwform], 'title': _(u'Activate your account'), 'save_name' : _(u'activate account'), }, context_instance=RequestContext(request)) else: user.backend = 'django.contrib.auth.backends.ModelBackend' django_login(request, user) display_message(request, _(u"Your account has been activated. You're now logged-in.")) return HttpResponseRedirect(reverse('index')) except UserProfile.DoesNotExist: raise UnauthorizedException('No profile')
def user_suspend(request, key): if request.method == 'POST': profile = get_object_or_404(UserProfile, key=key) profile.is_suspended = True profile.save() if profile.user.is_active: display_message( request, _(u"User's access %(prof)s has been suspended.") % {'prof': profile.simple_print()}) register_activity(request, "user_suspended", user=profile.user) else: # make use active but disabled profile.user.is_active = True profile.user.save() display_message( request, _(u"User's access %(prof)s has been refused.") % {'prof': profile.simple_print()}) register_activity(request, "user_refused", user=profile.user) return HttpResponse('') # no redirect because this is called by js raise UnauthorizedException('')
def text_edit(request, key, adminkey=None): text = get_text_by_keys_or_404(key) text_version = text.get_latest_version() if request.method == 'POST': if request.user.is_authenticated(): form = EditTextForm(request.POST) else: form = EditTextFormAnon(request.POST) if form.is_valid(): if request.POST.get('new_version'): new_version = form.save_new_version(text, request) register_activity(request, "text_edited_new_version", text=text, text_version=new_version) else: form.save_into_text(text, request) register_activity(request, "text_edited", text=text) return redirect(request, 'text-view', args=[text.key]) else: default_data = { 'content': text_version.content, 'title': text_version.title, 'format': text_version.format, 'tags': text_version.tags, 'new_version': NEW_TEXT_VERSION_ON_EDIT, 'note' : '', 'keep_comments' : True, 'cancel_modified_scopes' : True, } if request.user.is_authenticated(): form = EditTextForm(default_data) else: form = EditTextFormAnon(default_data) template_dict = {'text' : text, 'form' : form} return render_to_response('site/text_edit.html', template_dict , context_instance=RequestContext(request))
def _text_create_import(request, createForm): if request.method == 'POST': form = createForm(request.POST, request.FILES) if form.is_valid(): soup = form.cleaned_data['soup'] if not soup.co_ment_text: raise Exception('Bad Soup') # Process attachments first to create new keys. attachments_keys_map = {} if soup.co_ment_text.attachments: for imported_attachement in soup.co_ment_text.attachments.findAll('attachment'): # Creates attachment object. filename = 'imported_attachment' attachment = Attachment.objects.create_attachment(filename=filename, data=b64decode(imported_attachement.data.renderContents()), text_version=None) # Stores key mapping. attachments_keys_map[imported_attachement.key.renderContents()] = attachment.key # Process text. form.cleaned_data['title'] = soup.co_ment_text.title.renderContents() form.cleaned_data['format'] = soup.co_ment_text.format.renderContents() form.cleaned_data['content'] = re.sub(r'^<!\[CDATA\[|\]\]>$', '', soup.co_ment_text.content.renderContents()) form.cleaned_data['name'] = soup.co_ment_text.find('name').renderContents() form.cleaned_data['email'] = soup.co_ment_text.email.renderContents() if soup.co_ment_text.tags: form.cleaned_data['tags'] = soup.co_ment_text.tags.renderContents() # Replaces attachements keys in content. for old_key in attachments_keys_map.keys(): form.cleaned_data['content'] = re.sub(old_key, attachments_keys_map[old_key], form.cleaned_data['content']) form.cleaned_data['content'] = re.sub(r'src="/attach/', 'src="' + settings.SITE_URL + '/attach/', form.cleaned_data['content']) # Creates text. text = create_text(request.user, form.cleaned_data) # Brute updates of dates (cannot do it through django models since fields are set with auto_now or auto_now_add). created = soup.co_ment_text.created.renderContents() modified = soup.co_ment_text.modified.renderContents() cursor = connection.cursor() cursor.execute("UPDATE cm_textversion SET created = %s, modified = %s WHERE id = %s", [created, modified, text.last_text_version_id]) cursor.execute("UPDATE cm_text SET created = %s, modified = %s WHERE id = %s", [created, modified, text.id]) transaction.commit_unless_managed() # Process comments. if soup.co_ment_text.comments: comments_ids_map = {} all_comments = soup.co_ment_text.comments.findAll('comment') # Sort by id in order to have parent processed before reply_to for imported_comment in sorted(all_comments, key=lambda cid: cid.id.renderContents()): # Creates each comment. comment = Comment.objects.create( text_version=text.get_latest_version(), title=imported_comment.title.renderContents(), state=imported_comment.state.renderContents(), name=imported_comment.find('name').renderContents(), email=imported_comment.email.renderContents(), format=imported_comment.format.renderContents(), content=re.sub(r'^<!\[CDATA\[|\]\]>$', '', imported_comment.content.renderContents()), content_html=re.sub(r'^<!\[CDATA\[|\]\]>$', '', imported_comment.content_html.renderContents()), ) # Stores id for reply_to mapping. comments_ids_map[imported_comment.id.renderContents()] = comment # Process boolean and potentially null integer/foreign key attributes. save = False if imported_comment.deleted.renderContents() == 'True': comment.deleted = True save = True if imported_comment.start_wrapper.renderContents() != 'None': comment.start_wrapper = imported_comment.start_wrapper.renderContents() save = True if imported_comment.end_wrapper.renderContents() != 'None': comment.end_wrapper = imported_comment.end_wrapper.renderContents() save = True if imported_comment.start_offset.renderContents() != 'None': comment.start_offset = imported_comment.start_offset.renderContents() save = True if imported_comment.end_offset.renderContents() != 'None': comment.end_offset = imported_comment.end_offset.renderContents() save = True if imported_comment.find('parent'): comment.reply_to = comments_ids_map.get(imported_comment.find('parent').renderContents()) save = True if save: comment.save() # Brute updates of dates (cannot do it through django models since fields are set with auto_now or auto_now_add). created=imported_comment.created.renderContents(), modified=imported_comment.modified.renderContents(), cursor.execute("UPDATE cm_comment SET created = %s, modified = %s WHERE id = %s", [created, modified, comment.id]) transaction.commit_unless_managed() # Logs on activity. register_activity(request, "text_imported", text) display_message(request, _(u'Text "%(text_title)s" has been imported')%{"text_title":text.get_latest_version().title}) return text, HttpResponseRedirect(reverse('text-view', args=[text.key])) else: form = createForm() return None, render_to_response('site/text_create_import.html', {'form' : form}, context_instance=RequestContext(request))
def _text_create_import(request, createForm): if request.method == 'POST': form = createForm(request.POST, request.FILES) if form.is_valid(): soup = form.cleaned_data['soup'] if not soup.co_ment_text: raise Exception('Bad Soup') # Process attachments first to create new keys. attachments_keys_map = {} if soup.co_ment_text.attachments: for imported_attachement in soup.co_ment_text.attachments.findAll( 'attachment'): # Creates attachment object. filename = 'imported_attachment' attachment = Attachment.objects.create_attachment( filename=filename, data=b64decode( imported_attachement.data.renderContents()), text_version=None) # Stores key mapping. attachments_keys_map[imported_attachement.key. renderContents()] = attachment.key # Process text. form.cleaned_data[ 'title'] = soup.co_ment_text.title.renderContents() form.cleaned_data[ 'format'] = soup.co_ment_text.format.renderContents() form.cleaned_data['content'] = re.sub( r'^<!\[CDATA\[|\]\]>$', '', soup.co_ment_text.content.renderContents()) form.cleaned_data['name'] = soup.co_ment_text.find( 'name').renderContents() form.cleaned_data[ 'email'] = soup.co_ment_text.email.renderContents() if soup.co_ment_text.tags: form.cleaned_data[ 'tags'] = soup.co_ment_text.tags.renderContents() # Replaces attachements keys in content. for old_key in attachments_keys_map.keys(): form.cleaned_data['content'] = re.sub( old_key, attachments_keys_map[old_key], form.cleaned_data['content']) form.cleaned_data['content'] = re.sub( r'src="/attach/', 'src="' + settings.SITE_URL + '/attach/', form.cleaned_data['content']) # Creates text. text = create_text(request.user, form.cleaned_data) # Brute updates of dates (cannot do it through django models since fields are set with auto_now or auto_now_add). created = soup.co_ment_text.created.renderContents() modified = soup.co_ment_text.modified.renderContents() cursor = connection.cursor() cursor.execute( "UPDATE cm_textversion SET created = %s, modified = %s WHERE id = %s", [created, modified, text.last_text_version_id]) cursor.execute( "UPDATE cm_text SET created = %s, modified = %s WHERE id = %s", [created, modified, text.id]) transaction.commit_unless_managed() # Process comments. if soup.co_ment_text.comments: comments_ids_map = {} all_comments = soup.co_ment_text.comments.findAll('comment') # Sort by id in order to have parent processed before reply_to for imported_comment in sorted( all_comments, key=lambda cid: cid.id.renderContents()): # Creates each comment. comment = Comment.objects.create( text_version=text.get_latest_version(), title=imported_comment.title.renderContents(), state=imported_comment.state.renderContents(), name=imported_comment.find('name').renderContents(), email=imported_comment.email.renderContents(), format=imported_comment.format.renderContents(), content=re.sub( r'^<!\[CDATA\[|\]\]>$', '', imported_comment.content.renderContents()), content_html=re.sub( r'^<!\[CDATA\[|\]\]>$', '', imported_comment.content_html.renderContents()), ) # Stores id for reply_to mapping. comments_ids_map[ imported_comment.id.renderContents()] = comment # Process boolean and potentially null integer/foreign key attributes. save = False if imported_comment.deleted.renderContents() == 'True': comment.deleted = True save = True if imported_comment.start_wrapper.renderContents( ) != 'None': comment.start_wrapper = imported_comment.start_wrapper.renderContents( ) save = True if imported_comment.end_wrapper.renderContents() != 'None': comment.end_wrapper = imported_comment.end_wrapper.renderContents( ) save = True if imported_comment.start_offset.renderContents( ) != 'None': comment.start_offset = imported_comment.start_offset.renderContents( ) save = True if imported_comment.end_offset.renderContents() != 'None': comment.end_offset = imported_comment.end_offset.renderContents( ) save = True if imported_comment.find('parent'): comment.reply_to = comments_ids_map.get( imported_comment.find('parent').renderContents()) save = True if save: comment.save() # Brute updates of dates (cannot do it through django models since fields are set with auto_now or auto_now_add). created = imported_comment.created.renderContents(), modified = imported_comment.modified.renderContents(), cursor.execute( "UPDATE cm_comment SET created = %s, modified = %s WHERE id = %s", [created, modified, comment.id]) transaction.commit_unless_managed() # Logs on activity. register_activity(request, "text_imported", text) display_message( request, _(u'Text "%(text_title)s" has been imported') % {"text_title": text.get_latest_version().title}) return text, HttpResponseRedirect( reverse('text-view', args=[text.key])) else: form = createForm() return None, render_to_response('site/text_create_import.html', {'form': form}, context_instance=RequestContext(request))
def user_add(request, key=None, mass=False): text = get_text_by_keys_or_404(key) if key else None if request.method == 'POST': userform = UserForm(request.POST) if not mass else MassUserForm( request.POST) userroleform = UserRoleForm(request.POST) noteform = UserAddForm(request.POST) userprofileform = UserProfileAddForm(request.POST) localroleform = UserRoleTextForm(request.POST, prefix="local") if key else None if userform.is_valid() and userroleform.is_valid( ) and noteform.is_valid() and userprofileform.is_valid() and ( not localroleform or localroleform.is_valid()): data = userform.cleaned_data data.update(userprofileform.cleaned_data) data.update(noteform.cleaned_data) emails = data['email'] del data['email'] email_created = set() for email in [s.strip() for s in SEPARATORS_RE.split(emails)]: if email and not User.objects.filter( email__iexact=email) and email not in email_created: user = UserProfile.objects.create_inactive_user( email, True, **data) userrole = UserRole.objects.create( user=user, role=userroleform.cleaned_data['role'], text=None) if key: localuserrole = UserRole.objects.create( user=user, role=localroleform.cleaned_data['role'], text=text) email_created.add(email) register_activity(request, "user_created", user=user) display_message( request, ungettext(u'%(nb_users)d user added', u'%(nb_users)d users added', len(email_created)) % {'nb_users': len(email_created)}) if key: return HttpResponseRedirect( reverse('text-share', args=[text.key])) else: return HttpResponseRedirect(reverse('user')) else: userform = UserForm() if not mass else MassUserForm() userroleform = UserRoleForm() userprofileform = UserProfileAddForm( {'preferred_language': request.LANGUAGE_CODE}) noteform = UserAddForm() localroleform = UserRoleTextForm(prefix="local") if key else None if key: template = 'site/user_mass_add_text.html' if mass else 'site/user_add_text.html' else: template = 'site/user_mass_add.html' if mass else 'site/user_add.html' return render_to_response(template, { 'forms': [userform, userprofileform, userroleform, noteform, localroleform], 'save_name': ungettext(u'Add user', u'Add users', 2 if mass else 1), 'mass': mass, 'text': text, }, context_instance=RequestContext(request))