def send_template_mail(sender, receiver, subject, templatename, templateattr={}, usergenerated=False, cc=None, replyto=None, receivername=None, sendername=None, messageid=None): d = { 'link_root': settings.SITE_ROOT, } d.update(templateattr) send_simple_mail(sender, receiver, subject, template_to_string(templatename, d), usergenerated=usergenerated, cc=cc, replyto=replyto, receivername=receivername, sendername=sendername, messageid=messageid)
def _submitted_item_withdraw(request, objtype, model, obj): if obj.modstate != ModerationState.PENDING: # Can only withdraw if it's in pending state return HttpResponseRedirect("/account/edit/{}/".format(objtype)) obj.modstate = ModerationState.CREATED obj.send_notification = False if obj.twomoderators: obj.firstmoderator = None obj.save(update_fields=['modstate', 'firstmoderator']) else: obj.save(update_fields=[ 'modstate', ]) send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{} '{}' withdrawn from moderation".format( model._meta.verbose_name.capitalize(), obj.title), "{} {} with title {} withdrawn from moderation by {}".format( model._meta.verbose_name.capitalize(), obj.id, obj.title, request.user.username), ) return HttpResponseRedirect("/account/edit/{}/".format(objtype))
def handle(self, *args, **options): with transaction.atomic(): newly_visible = [] for s in SecurityPatch.objects.filter(cve_visible=False): r = requests.get(s.cvelink, timeout=10) if r.status_code == 200: # RedHat have started requiring both a HTML page and a JSON api call to view # CVEs. Dumb dumb dumb, but what can we do... r = requests.get( 'https://access.redhat.com/api/redhat_node/CVE-{}.json' .format(s.cve)) if r.status_code == 200: newly_visible.append(s.cve) s.cve_visible = True s.save() if newly_visible: send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "CVE entries made public", """The following CVE entries are now public upstream, and have been made visible on the website. {0} """.format("\n".join(newly_visible))) list(map(varnish_purge, SecurityPatch.purge_urls))
def _submitted_item_submit(request, objtype, model, obj): if obj.modstate != ModerationState.CREATED: # Can only submit if state is created return HttpResponseRedirect("/account/edit/{}/".format(objtype)) if request.method == 'POST': form = ConfirmSubmitForm(obj._meta.verbose_name, data=request.POST) if form.is_valid(): with transaction.atomic(): obj.modstate = ModerationState.PENDING obj.send_notification = False obj.save() send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{} '{}' submitted for moderation".format(obj._meta.verbose_name.capitalize(), obj.title), "{} {} with title '{}' submitted for moderation by {}\n\nModerate at: {}\n".format( obj._meta.verbose_name.capitalize(), obj.id, obj.title, request.user.username, '{}/admin/_moderate/{}/{}/'.format(settings.SITE_ROOT, obj._meta.model_name, obj.pk), ), ) return HttpResponseRedirect("/account/edit/{}/".format(objtype)) else: form = ConfirmSubmitForm(obj._meta.verbose_name) return render_pgweb(request, 'account', 'account/submit_preview.html', { 'obj': obj, 'form': form, 'objtype': obj._meta.verbose_name, 'preview': obj.get_preview_fields(), })
def my_m2m_changed_handler(sender, **kwargs): instance = kwargs['instance'] if getattr(instance, 'send_m2m_notification', False) and get_current_user(): (cl, f) = sender.__name__.split('_') if not hasattr(instance, '_stored_m2m'): instance._stored_m2m = {} if kwargs['action'] == 'pre_clear': instance._stored_m2m[f] = set( [unicode(t) for t in getattr(instance, f).all()]) elif kwargs['action'] == 'post_add': newset = set([unicode(t) for t in getattr(instance, f).all()]) added = newset.difference(instance._stored_m2m.get(f, set())) removed = instance._stored_m2m.get(f, set()).difference(newset) subj = '{0} id {1} has been modified'.format( instance._meta.verbose_name, instance.id) if added or removed: send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, get_current_user()), "The following values for {0} were changed:\n\n{1}\n{2}\n\n" .format( instance._meta.get_field(f).verbose_name, "\n".join([u"Added: %s" % a for a in added]), "\n".join([u"Removed: %s" % r for r in removed]), ))
def send_news_email(news): html, attachments = render_news_template(news) messageid = make_msgid() # If configured to, add the tags and sign them so that a pglister delivery system can filter # recipients based on it. if settings.NEWS_MAIL_TAGKEY: date = formatdate(localtime=True) tagstr = ",".join([t.urlname for t in news.tags.all()]) h = hmac.new( settings.NEWS_MAIL_TAGKEY.encode('ascii'), tagstr.encode('ascii') + messageid.encode('ascii') + date.encode('ascii'), hashlib.sha256) headers = { 'X-pglister-tags': tagstr, 'X-pglister-tagsig': h.hexdigest(), 'Date': date, } else: headers = {} send_simple_mail( settings.NEWS_MAIL_SENDER, settings.NEWS_MAIL_RECEIVER, news.title, news.content, replyto=news.email.address, sendername=news.sentfrom, receivername=settings.NEWS_MAIL_RECEIVER_NAME, messageid=messageid, htmlbody=html, attachments=attachments, headers=headers, )
def my_pre_delete_handler(sender, **kwargs): instance = kwargs['instance'] if getattr(instance, 'send_notification', False) and get_current_user(): send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s id %s has been deleted by %s" % (instance._meta.verbose_name, instance.id, get_current_user()), _get_full_text_representation(instance))
def my_pre_save_handler(sender, **kwargs): instance = kwargs['instance'] if getattr(instance, 'send_notification', False) and get_current_user(): (subj, cont) = _get_notification_text(instance) if cont: cont = _build_url(instance) + "\n\n" + cont send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, get_current_user()), cont)
def my_pre_save_handler(sender, **kwargs): instance = kwargs['instance'] if getattr(instance, 'send_notification', False): (subj, cont) = _get_notification_text(instance) if cont: cont = _build_url(instance) + "\n\n" + cont send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, get_current_user()), cont)
def my_pre_delete_handler(sender, **kwargs): instance = kwargs['instance'] if getattr(instance, 'send_notification', False): send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s id %s has been deleted by %s" % ( instance._meta.verbose_name, instance.id, get_current_user()), _get_full_text_representation(instance))
def send_template_mail(sender, receiver, subject, templatename, templateattr={}, usergenerated=False): send_simple_mail(sender, receiver, subject, template_to_string(templatename, templateattr), usergenerated=usergenerated)
def save(self, commit=True): model = super(OrganisationForm, self).save(commit=False) ops = [] if self.cleaned_data.get('add_email', None): # Create the email record e = OrganisationEmail( org=model, address=self.cleaned_data['add_email'].lower(), token=generate_random_token()) e.save() # Send email for confirmation send_template_mail( settings.NOTIFICATION_FROM, e.address, "Email address added to postgresql.org organisation", 'core/org_add_email.txt', { 'org': model, 'email': e, }, ) ops.append('Added email {}, confirmation request sent'.format( e.address)) if self.cleaned_data.get('remove_email', None): for e in self.cleaned_data['remove_email']: ops.append('Removed email {}'.format(e.address)) e.delete() if 'add_manager' in self.cleaned_data and self.cleaned_data[ 'add_manager']: u = User.objects.get( email=self.cleaned_data['add_manager'].lower()) model.managers.add(u) ops.append('Added manager {}'.format(u.username)) if 'remove_manager' in self.cleaned_data and self.cleaned_data[ 'remove_manager']: for toremove in self.cleaned_data['remove_manager']: model.managers.remove(toremove) ops.append('Removed manager {}'.format(toremove.username)) if ops: send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{0} modified {1}".format(get_current_user().username, model), "The following changes were made to {}:\n\n{}".format( model, "\n".join(ops))) return model
def subscribe(request): if request.POST: form = SubscribeForm(request.POST) if form.is_valid(): if form.cleaned_data['action'] == 'subscribe': mailsubject = "subscribe" # Default is get mail and not digest, in which case we send a regular # subscribe request. In other cases, we send subscribe-set which also # sets those flags. if form.cleaned_data['receive'] and not form.cleaned_data['digest']: mailtxt = "subscribe %s\n" % form.cleaned_data['lists'] else: tags = [] if not form.cleaned_data['receive']: tags.append('nomail') if form.cleaned_data['digest']: tags.append('digest') mailtxt = "subscribe-set %s %s\n" % (form.cleaned_data['lists'], ",".join(tags)) else: mailtxt = "unsubscribe %s\n" % form.cleaned_data['lists'] mailsubject = "unsubscribe" send_simple_mail(form.cleaned_data['email'], settings.LISTSERVER_EMAIL, mailsubject, mailtxt) return render_to_response('lists/subscribed.html', { }, NavContext(request, "community")) else: # GET, so render up the form form = SubscribeForm() return render_to_response('lists/subscribe_form.html', { 'form': form, 'operation': 'Subscribe', 'jquery': True, 'form_intro': """ <b>Note 1:</b> Please ensure you read the <a href="https://wiki.postgresql.org/wiki/Archives_Policy">Archive Policy</a> before posting to the lists.</p> <p><b>Note 2:</b> Please do not subscribe to mailing lists using e-mail accounts protected by mail-back anti-spam systems. These are extremely annoying to the list maintainers and other members, and you may be automatically unsubscribed.""" }, NavContext(request, "community"))
def save_model(self, request, obj, form, change): if change and self.model.send_notification: # We only do processing if something changed, not when adding # a new object. if request.POST.has_key( 'new_notification') and request.POST['new_notification']: # Need to send off a new notification. We'll also store # it in the database for future reference, of course. if not obj.org.email: # Should not happen because we remove the form field. Thus # a hard exception is ok. raise Exception( "Organization does not have an email, canot send notification!" ) n = ModerationNotification() n.objecttype = obj.__class__.__name__ n.objectid = obj.id n.text = request.POST['new_notification'] n.author = request.user.username n.save() # Now send an email too msgstr = _get_notification_text( request.POST.has_key('remove_after_notify'), obj, request.POST['new_notification']) send_simple_mail(settings.NOTIFICATION_FROM, obj.org.email, "postgresql.org moderation notification", msgstr) # Also generate a mail to the moderators send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "Moderation comment on %s %s" % (obj.__class__._meta.verbose_name, obj.id), _get_moderator_notification_text( request.POST.has_key('remove_after_notify'), obj, request.POST['new_notification'], request.user.username)) if request.POST.has_key('remove_after_notify'): # Object should not be saved, it should be deleted obj.delete() return # Either no notifications, or done with notifications super(PgwebAdmin, self).save_model(request, obj, form, change)
def handle(self, *args, **options): with transaction.atomic(): newly_visible = [] for s in SecurityPatch.objects.filter(cve_visible=False): r = requests.get(s.cvelink, timeout=10) if r.status_code == 200: newly_visible.append(s.cve) s.cve_visible = True s.save() if newly_visible: send_simple_mail(settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "CVE entries made public", """The following CVE entries are now public upstream, and have been made visible on the website. {0} """.format("\n".join(newly_visible))) list(map(varnish_purge, SecurityPatch.purge_urls))
def handle(self, *args, **options): with transaction.atomic(): newly_visible = [] for s in SecurityPatch.objects.filter(cve_visible=False): r = requests.get(s.cvelink, timeout=10) if r.status_code == 200: newly_visible.append(s.cve) s.cve_visible = True s.save() if newly_visible: send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "CVE entries made public", """The following CVE entries are now public upstream, and have been made visible on the website. {0} """.format("\n".join(newly_visible))) map(varnish_purge, SecurityPatch.purge_urls)
def save(self, commit=True): model = super(OrganisationForm, self).save(commit=False) ops = [] if 'add_manager' in self.cleaned_data and self.cleaned_data['add_manager']: u = User.objects.get(email=self.cleaned_data['add_manager'].lower()) model.managers.add(u) ops.append('Added manager {}'.format(u.username)) if 'remove_manager' in self.cleaned_data and self.cleaned_data['remove_manager']: for toremove in self.cleaned_data['remove_manager']: model.managers.remove(toremove) ops.append('Removed manager {}'.format(toremove.username)) if ops: send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{0} modified managers of {1}".format(get_current_user().username, model), "The following changes were made to managers:\n\n{0}".format("\n".join(ops)) ) return model
def save_model(self, request, obj, form, change): if change and hasattr(self.model, 'send_notification') and self.model.send_notification: # We only do processing if something changed, not when adding # a new object. if 'new_notification' in request.POST and request.POST['new_notification']: # Need to send off a new notification. We'll also store # it in the database for future reference, of course. if not obj.org.email: # Should not happen because we remove the form field. Thus # a hard exception is ok. raise Exception("Organisation does not have an email, canot send notification!") n = ModerationNotification() n.objecttype = obj.__class__.__name__ n.objectid = obj.id n.text = request.POST['new_notification'] n.author = request.user.username n.save() # Now send an email too msgstr = _get_notification_text(obj, request.POST['new_notification']) send_simple_mail(settings.NOTIFICATION_FROM, obj.org.email, "postgresql.org moderation notification", msgstr) # Also generate a mail to the moderators send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "Moderation comment on %s %s" % (obj.__class__._meta.verbose_name, obj.id), _get_moderator_notification_text( obj, request.POST['new_notification'], request.user.username ) ) # Either no notifications, or done with notifications super(PgwebAdmin, self).save_model(request, obj, form, change)
def simple_form(instancetype, itemid, request, formclass, formtemplate='base/form.html', redirect='/account/', navsection='account', fixedfields=None, createifempty=False): if itemid == 'new': instance = instancetype() is_new = True else: is_new = False # Regular form item, attempt to edit it try: int(itemid) except ValueError: raise Http404("Invalid URL") if createifempty: (instance, wascreated) = instancetype.objects.get_or_create(pk=itemid) else: instance = get_object_or_404(instancetype, pk=itemid) if hasattr(instance, 'submitter'): if not instance.submitter == request.user: raise PermissionDenied("You are not the owner of this item!") elif hasattr(instance, 'verify_submitter'): if not instance.verify_submitter(request.user): raise PermissionDenied("You are not the owner of this item!") if request.method == 'POST': # Process this form form = formclass(data=request.POST, instance=instance) # Save away the old value from the instance before it's saved if not is_new: old_values = { fn: str(getattr(instance, fn)) for fn in form.changed_data if hasattr(instance, fn) } if form.is_valid(): # We are handling notifications, so disable the ones we'd otherwise send do_notify = getattr(instance, 'send_notification', False) instance.send_notification = False if not getattr(instance, 'approved', True) and not is_new: # If the object has an "approved" field and it's set to false, we don't # bother notifying about the changes. But if it lacks this field, we notify # about everything, as well as if the field exists and the item has already # been approved. # Newly added objects are always notified. do_notify = False notify = io.StringIO() r = form.save(commit=False) r.submitter = request.user # Set fixed fields. Note that this will not work if the fixed fields are ManyToMany, # but we'll fix that sometime in the future if fixedfields: for k, v in list(fixedfields.items()): setattr(r, k, v) r.save() # If we have a callback with the current user if hasattr(form, 'apply_submitter'): form.apply_submitter(r, request.user) r.save() if is_new: subj = 'A new {0} has been added'.format( instance._meta.verbose_name) for f in form.fields: notify.write("{}:\n".format(f)) if instance._meta.get_field( f) in instance._meta.many_to_many: notify.write("{}\n".format("\n".join( [str(x) for x in form.cleaned_data[f]]))) else: notify.write("{}\n".format(str(form.cleaned_data[f]))) notify.write("\n") else: subj = '{0} id {1} has been modified'.format( instance._meta.verbose_name, instance.id) for fn in form.changed_data: if not hasattr(instance, fn): continue f = instance._meta.get_field(fn) if f in instance._meta.many_to_many: # m2m field have separate config of notificatgions if getattr(instance, 'send_m2m_notification', False): for f in instance._meta.many_to_many: if f.name in form.cleaned_data: old = set([ str(x) for x in getattr( instance, f.name).all() ]) new = set([ str(x) for x in form.cleaned_data[f.name] ]) added = new.difference(old) removed = old.difference(new) if added or removed: notify.write( "--- {}\n+++ {}\n{}\n{}\n".format( f.verbose_name, f.verbose_name, "\n".join([ "+ %s" % a for a in added ]), "\n".join([ "- %s" % r for r in removed ]), )) else: # Regular field! # Sometimes it shows up as changed even if it hasn't changed, so do # a second check on if the diff is non-empty. diffrows = [ x for x in difflib.unified_diff( old_values[f.name].splitlines(), str(form.cleaned_data[f.name]).splitlines(), n=1, lineterm='', fromfile=f.verbose_name, tofile=f.verbose_name, ) if not x.startswith("@@") ] if diffrows: notify.write("\n".join(diffrows)) notify.write("\n\n") if do_notify and notify.tell(): send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, request.user.username), "Title: {0}\n\n{1}".format( str(instance), notify.getvalue(), ), ) form.save_m2m() return HttpResponseRedirect(redirect) else: # Generate form form = formclass(instance=instance) if hasattr(form, 'filter_by_user'): form.filter_by_user(request.user) for fn in form.fields: if fn in getattr(instancetype, 'markdown_fields', []): form.fields[fn].widget.attrs.update({'class': 'markdown-content'}) for togg in getattr(form, 'toggle_fields', []): form.fields[togg['name']].widget.attrs.update({ 'data-toggles': ','.join(togg['fields']), 'data-toggle-invert': togg['invert'] and 'true' or 'false', 'class': 'toggle-checkbox', }) return render_pgweb( request, navsection, formtemplate, { 'form': form, 'formitemtype': instance._meta.verbose_name, 'form_intro': hasattr(form, 'form_intro') and form.form_intro or None, 'described_checkboxes': getattr(form, 'described_checkboxes', {}), 'savebutton': (itemid == "new") and "Submit New" or "Save", 'operation': (itemid == "new") and "New" or "Edit", })
def _send_moderation_message(request, obj, message, notice, what): if message and notice: msg = "{}\n\nThe following further information was provided:\n{}".format( message, notice) elif notice: msg = notice else: msg = message n = ModerationNotification( objectid=obj.id, objecttype=type(obj).__name__, text=msg, author=request.user, ) n.save() # In the email, add a link back to the item in the bottom msg += "\n\nYou can view your {} by going to\n{}/account/edit/{}/".format( obj._meta.verbose_name, settings.SITE_ROOT, obj.account_edit_suburl, ) # Send message to org admins if isinstance(obj, Organisation): org = obj else: org = obj.org for m in org.managers.all(): send_simple_mail( settings.NOTIFICATION_FROM, m.email, "Your submitted {} with title {}".format(obj._meta.verbose_name, obj.title), msg, suppress_auto_replies=False, receivername='{} {}'.format(m.first_name, m.last_name), ) # Send notification to admins if obj.twomoderators and obj.firstmoderator: # For two-moderator objects, only one is required to reject or send back for editing. In that case, # just log the current user who is the one that did that. modname = "{} and {}".format(obj.firstmoderator, request.user) else: modname = request.user if what: # If an actual change happened, notify of that admmsg = message if obj.is_approved: admmsg += "\n\nNOTE! This {} was previously approved!!".format( obj._meta.verbose_name) if notice: admmsg += "\n\nModeration notice:\n{}".format(notice) if what != "rejected": # No point in sending an edit link to a page that doesn't exist anymore admmsg += "\n\nEdit at: {}/admin/_moderate/{}/{}/\n".format( settings.SITE_ROOT, obj._meta.model_name, obj.id) send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "{} '{}' {} by {}".format(obj._meta.verbose_name.capitalize(), obj.title, what, modname), admmsg) elif notice: # There was no change, but there was a moderation notice. We still want to inform the moderators that this happened admmsg = "No changes were made, but the following notice was sent:\n{}\n\nEdit at: {}/admin/_moderate/{}/{}/\n".format( notice, settings.SITE_ROOT, obj._meta.model_name, obj.id, ) send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "Moderation notice on '{}' {} by {}".format( obj._meta.verbose_name.capitalize(), obj.title, modname), admmsg)
def simple_form(instancetype, itemid, request, formclass, formtemplate='base/form.html', redirect='/account/', navsection='account', fixedfields=None, createifempty=False): if itemid == 'new': instance = instancetype() is_new = True else: is_new = False # Regular form item, attempt to edit it try: int(itemid) except ValueError: raise Http404("Invalid URL") if createifempty: (instance, wascreated) = instancetype.objects.get_or_create(pk=itemid) else: instance = get_object_or_404(instancetype, pk=itemid) if hasattr(instance, 'submitter'): if not instance.submitter == request.user: raise Exception("You are not the owner of this item!") elif hasattr(instance, 'verify_submitter'): if not instance.verify_submitter(request.user): raise Exception("You are not the owner of this item!") if request.method == 'POST': # Process this form form = formclass(data=request.POST, instance=instance) # Save away the old value from the instance before it's saved if not is_new: old_values = {fn: str(getattr(instance, fn)) for fn in form.changed_data if hasattr(instance, fn)} if form.is_valid(): # We are handling notifications, so disable the ones we'd otherwise send do_notify = getattr(instance, 'send_notification', False) instance.send_notification = False if not getattr(instance, 'approved', True) and not is_new: # If the object has an "approved" field and it's set to false, we don't # bother notifying about the changes. But if it lacks this field, we notify # about everything, as well as if the field exists and the item has already # been approved. # Newly added objects are always notified. do_notify = False notify = io.StringIO() r = form.save(commit=False) r.submitter = request.user # Set fixed fields. Note that this will not work if the fixed fields are ManyToMany, # but we'll fix that sometime in the future if fixedfields: for k, v in list(fixedfields.items()): setattr(r, k, v) r.save() # If we have a callback with the current user if hasattr(form, 'apply_submitter'): form.apply_submitter(r, request.user) r.save() if is_new: subj = 'A new {0} has been added'.format(instance._meta.verbose_name) for f in form.fields: notify.write("{}:\n".format(f)) if instance._meta.get_field(f) in instance._meta.many_to_many: notify.write("{}\n".format("\n".join([str(x) for x in form.cleaned_data[f]]))) else: notify.write("{}\n".format(str(form.cleaned_data[f]))) notify.write("\n") else: subj = '{0} id {1} has been modified'.format(instance._meta.verbose_name, instance.id) for fn in form.changed_data: if not hasattr(instance, fn): continue f = instance._meta.get_field(fn) if f in instance._meta.many_to_many: # m2m field have separate config of notificatgions if getattr(instance, 'send_m2m_notification', False): for f in instance._meta.many_to_many: if f.name in form.cleaned_data: old = set([str(x) for x in getattr(instance, f.name).all()]) new = set([str(x) for x in form.cleaned_data[f.name]]) added = new.difference(old) removed = old.difference(new) if added or removed: notify.write("--- {}\n+++ {}\n{}\n{}\n".format( f.verbose_name, f.verbose_name, "\n".join(["+ %s" % a for a in added]), "\n".join(["- %s" % r for r in removed]), )) else: # Regular field! # Sometimes it shows up as changed even if it hasn't changed, so do # a second check on if the diff is non-empty. diffrows = [x for x in difflib.unified_diff( old_values[f.name].splitlines(), str(form.cleaned_data[f.name]).splitlines(), n=1, lineterm='', fromfile=f.verbose_name, tofile=f.verbose_name, ) if not x.startswith("@@")] if diffrows: notify.write("\n".join(diffrows)) notify.write("\n\n") if do_notify and notify.tell(): send_simple_mail( settings.NOTIFICATION_FROM, settings.NOTIFICATION_EMAIL, "%s by %s" % (subj, request.user.username), "Title: {0}\n\n{1}".format( str(instance), notify.getvalue(), ), ) form.save_m2m() return HttpResponseRedirect(redirect) else: # Generate form form = formclass(instance=instance) if hasattr(form, 'filter_by_user'): form.filter_by_user(request.user) for fn in form.fields: if fn in getattr(instancetype, 'markdown_fields', []): form.fields[fn].widget.attrs.update({'class': 'markdown-content'}) for togg in getattr(form, 'toggle_fields', []): form.fields[togg['name']].widget.attrs.update({ 'data-toggles': ','.join(togg['fields']), 'data-toggle-invert': togg['invert'] and 'true' or 'false', 'class': 'toggle-checkbox', }) return render_pgweb(request, navsection, formtemplate, { 'form': form, 'formitemtype': instance._meta.verbose_name, 'form_intro': hasattr(form, 'form_intro') and form.form_intro or None, 'described_checkboxes': getattr(form, 'described_checkboxes', {}), 'savebutton': (itemid == "new") and "Submit New" or "Save", 'operation': (itemid == "new") and "New" or "Edit", })