299 lines
11 KiB
Python
299 lines
11 KiB
Python
from five import grok
|
|
from Acquisition import aq_inner
|
|
from zope.interface import implements
|
|
|
|
from zope import interface, schema, component
|
|
|
|
from zope.component import getMultiAdapter, provideAdapter
|
|
from Products.CMFCore.utils import getToolByName
|
|
|
|
from z3c.form import form, field, button, validator
|
|
|
|
from plone.z3cform.layout import wrap_form
|
|
from z3c.form.ptcompat import ViewPageTemplateFile
|
|
from plone.dexterity.content import Item
|
|
|
|
from plone.formwidget.captcha.widget import CaptchaFieldWidget
|
|
from plone.formwidget.captcha.validator import CaptchaValidator
|
|
|
|
from zope.schema import ValidationError
|
|
from zope.schema.interfaces import IContextSourceBinder
|
|
from zope.schema.vocabulary import SimpleVocabulary
|
|
|
|
from plone.registry.interfaces import IRegistry
|
|
|
|
from tabellio.config.interfaces import ITabellioSettings
|
|
from tabellio.contact.interfaces import MessageFactory as _
|
|
|
|
|
|
class IContactForm(interface.Interface):
|
|
title = schema.TextLine(title=_(u'Title'))
|
|
description = schema.Text(title=_(u'Description'))
|
|
subjects = schema.Text(title=_(u'Available Subjects'))
|
|
|
|
class ContactForm(Item):
|
|
implements(IContactForm)
|
|
|
|
|
|
class View(grok.View):
|
|
grok.context(IContactForm)
|
|
grok.require('zope2.View')
|
|
|
|
def contact_form(self):
|
|
effective_contact = EffectiveContact(self.context)
|
|
effective_form = EffectiveContactForm(effective_contact, self.request)
|
|
effective_form.update()
|
|
return effective_form.render()
|
|
|
|
|
|
@grok.provider(IContextSourceBinder)
|
|
def get_possible_subjects(context):
|
|
terms = []
|
|
for line in context.context.subjects.splitlines():
|
|
try:
|
|
topic, email = line.strip().split('|')
|
|
except ValueError:
|
|
continue
|
|
if email == '->deputy':
|
|
terms.append(SimpleVocabulary.createTerm('-deputy', '-deputy', topic))
|
|
else:
|
|
terms.append(SimpleVocabulary.createTerm(topic, topic.encode('ascii', 'replace'), topic))
|
|
if len(terms) == 0:
|
|
terms.append(SimpleVocabulary.createTerm('-', '-', '-'))
|
|
return SimpleVocabulary(terms)
|
|
|
|
def get_email_for_subject(context, topic):
|
|
for line in context.context.subjects.splitlines():
|
|
try:
|
|
topic, email = line.strip().split('|')
|
|
except ValueError:
|
|
continue
|
|
if topic == topic:
|
|
return email
|
|
return None
|
|
|
|
class IEffectiveContact(interface.Interface):
|
|
subject = schema.Choice(title=_(u'Subject'), required=True,
|
|
source=get_possible_subjects)
|
|
name = schema.TextLine(title=_(u'Name'), required=True)
|
|
email = schema.TextLine(title=_(u'Email'), required=True)
|
|
phone = schema.TextLine(title=_(u'Phone'), required=False)
|
|
message = schema.Text(title=_(u'Message'), required=True)
|
|
captcha = schema.TextLine(title=_(u'Please type the different chars'), required=False)
|
|
|
|
class EffectiveContact(object):
|
|
implements(IEffectiveContact)
|
|
|
|
def __init__(self, context=None):
|
|
self.context = context
|
|
|
|
def absolute_url(self):
|
|
# this is used by the captcha
|
|
return self.context.absolute_url()
|
|
|
|
|
|
class EffectiveContactForm(form.Form):
|
|
fields = field.Fields(IEffectiveContact)
|
|
fields['captcha'].widgetFactory = CaptchaFieldWidget
|
|
template = ViewPageTemplateFile('form_templates/view_effectivecontact.pt')
|
|
|
|
def updateWidgets(self):
|
|
super(EffectiveContactForm, self).updateWidgets()
|
|
self.widgets['message'].rows = 10
|
|
|
|
@button.buttonAndHandler(_(u'Send'))
|
|
def handleApply(self, action):
|
|
data, errors = self.extractData()
|
|
if not errors and data.has_key('captcha'):
|
|
# Verify the user input against the captcha
|
|
try:
|
|
captcha = CaptchaValidator(self.context, self.request, None, IEffectiveContact['captcha'], None)
|
|
if captcha.validate(data['captcha']):
|
|
# if captcha validation passes, send the email.
|
|
portal = getToolByName(self.context.context, 'portal_url').getPortalObject()
|
|
plone_utils = getToolByName(self.context.context, 'plone_utils')
|
|
settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
|
|
topic_email = get_email_for_subject(self.context, data.get('subject'))
|
|
|
|
try:
|
|
sendmail(self.context.context, data, topic_email)
|
|
except: # TODO Too many things could possibly go wrong. So we catch all.
|
|
plone_utils = getToolByName(self.context.context, 'plone_utils')
|
|
exception = plone_utils.exceptionString()
|
|
message = _(u'Unable to send mail: ${exception}',
|
|
mapping={u'exception' : exception})
|
|
plone_utils.addPortalMessage(message, 'error')
|
|
return self.request.response.redirect('.')
|
|
|
|
plone_utils.addPortalMessage(_(u'Your message has been sent successfully.'))
|
|
return self.request.response.redirect(portal.absolute_url())
|
|
|
|
|
|
except ValidationError:
|
|
pass
|
|
return
|
|
|
|
|
|
def cmp_person(x, y):
|
|
t = cmp(x.lastname.lower(), y.lastname.lower())
|
|
if t: return t
|
|
return cmp(x.firstname.lower(), y.lastname.lower())
|
|
|
|
|
|
@grok.provider(IContextSourceBinder)
|
|
def get_deputies(context):
|
|
portal = getToolByName(context.context, 'portal_url').getPortalObject()
|
|
settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
|
|
path = settings.deputiesPath
|
|
current = portal
|
|
for part in settings.deputiesPath.split('/'):
|
|
if not part:
|
|
continue
|
|
current = getattr(current, part)
|
|
|
|
deputies = []
|
|
for object in current.objectValues():
|
|
if object.portal_type != 'themis.datatypes.deputy':
|
|
continue
|
|
if not object.active:
|
|
continue
|
|
deputies.append(object)
|
|
deputies.sort(cmp_person)
|
|
|
|
terms = []
|
|
for deputy in deputies:
|
|
deputy_id = deputy.getId()
|
|
terms.append(SimpleVocabulary.createTerm(deputy_id, deputy_id, deputy.Title()))
|
|
|
|
return SimpleVocabulary(terms)
|
|
|
|
|
|
class Deputy(grok.View):
|
|
grok.context(IContactForm)
|
|
grok.require('zope2.View')
|
|
grok.name('deputy')
|
|
|
|
def deputy_contact_form(self):
|
|
effective_contact = EffectiveDeputyContact(self.context)
|
|
effective_form = EffectiveDeputyContactForm(effective_contact, self.request)
|
|
effective_form.update()
|
|
return effective_form.render()
|
|
|
|
|
|
class IEffectiveDeputyContact(interface.Interface):
|
|
deputy = schema.Choice(title=_(u'Deputy'), required=True,
|
|
source=get_deputies)
|
|
subject = schema.TextLine(title=_(u'Subject'), required=True)
|
|
name = schema.TextLine(title=_(u'Name'), required=True)
|
|
email = schema.TextLine(title=_(u'Email'), required=True)
|
|
phone = schema.TextLine(title=_(u'Phone'), required=False)
|
|
message = schema.Text(title=_(u'Message'), required=True)
|
|
captcha = schema.TextLine(title=_(u'Please type the different chars'), required=False)
|
|
|
|
class EffectiveDeputyContact(object):
|
|
implements(IEffectiveDeputyContact)
|
|
|
|
def __init__(self, context=None):
|
|
self.context = context
|
|
|
|
def absolute_url(self):
|
|
# this is used by the captcha
|
|
return self.context.absolute_url()
|
|
|
|
|
|
class EffectiveDeputyContactForm(form.Form):
|
|
fields = field.Fields(IEffectiveDeputyContact)
|
|
fields['captcha'].widgetFactory = CaptchaFieldWidget
|
|
template = ViewPageTemplateFile('form_templates/view_effectivedeputycontact.pt')
|
|
|
|
def updateWidgets(self):
|
|
super(EffectiveDeputyContactForm, self).updateWidgets()
|
|
self.widgets['message'].rows = 10
|
|
|
|
@button.buttonAndHandler(_(u'Send'))
|
|
def handleApply(self, action):
|
|
data, errors = self.extractData()
|
|
if not errors and data.has_key('captcha'):
|
|
# Verify the user input against the captcha
|
|
try:
|
|
captcha = CaptchaValidator(self.context, self.request, None,
|
|
IEffectiveDeputyContact['captcha'], None)
|
|
if captcha.validate(data['captcha']):
|
|
# if captcha validation passes, send the email.
|
|
portal = getToolByName(self.context.context, 'portal_url').getPortalObject()
|
|
plone_utils = getToolByName(self.context.context, 'plone_utils')
|
|
settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
|
|
path = settings.deputiesPath
|
|
current = portal
|
|
for part in settings.deputiesPath.split('/'):
|
|
if not part:
|
|
continue
|
|
current = getattr(current, part)
|
|
|
|
deputy = getattr(current, data.get('deputy'))
|
|
deputy_email = None
|
|
if deputy.work_address:
|
|
deputy_email = deputy.work_address.email
|
|
if not deputy_email and deputy.work_address_2:
|
|
deputy_email = deputy.work_address_2.email
|
|
if not deputy_email and deputy.private_address:
|
|
deputy_email = deputy.private_address.email
|
|
|
|
try:
|
|
sendmail(self.context.context, data, deputy_email)
|
|
except: # TODO Too many things could possibly go wrong. So we catch all.
|
|
plone_utils = getToolByName(self.context.context, 'plone_utils')
|
|
exception = plone_utils.exceptionString()
|
|
message = _(u'Unable to send mail: ${exception}',
|
|
mapping={u'exception' : exception})
|
|
plone_utils.addPortalMessage(message, 'error')
|
|
return self.request.response.redirect('deputy')
|
|
|
|
plone_utils.addPortalMessage(_(u'Your message has been sent successfully.'))
|
|
return self.request.response.redirect(portal.absolute_url())
|
|
except ValidationError:
|
|
pass
|
|
return
|
|
|
|
|
|
# Register Captcha validator for the captcha field in the IContactForm
|
|
validator.WidgetValidatorDiscriminators(CaptchaValidator, field=IEffectiveContact['captcha'])
|
|
|
|
|
|
def sendmail(context, data, mto):
|
|
urltool = getToolByName(context, 'portal_url')
|
|
portal = urltool.getPortalObject()
|
|
|
|
send_to_address = portal.getProperty('email_from_address')
|
|
envelope_from = portal.getProperty('email_from_address')
|
|
encoding = portal.getProperty('email_charset')
|
|
|
|
message = _(u"""De: %(name)s (phone: %(phone)s, email: %(email)s)
|
|
Subject: %(subject)s
|
|
|
|
Message:
|
|
|
|
%(message)s
|
|
""") % data
|
|
u_message = message
|
|
message = message.encode(encoding)
|
|
|
|
context.MailHost.send('\n\n'+message, mto, envelope_from,
|
|
subject=_(u'New message from %s') % portal.title)
|
|
|
|
# and now, send a copy to the sender
|
|
if data.get('email'):
|
|
message = _(u"""Your message has been sent, here's a copy for reference.
|
|
|
|
%(message)s
|
|
""" % {'message': u_message})
|
|
|
|
try:
|
|
context.MailHost.send('\n\n'+message, data.get('email'), envelope_from,
|
|
subject=_(u'Your message on %s') % portal.title)
|
|
except:
|
|
# ignore everything here, as the most important part has been done
|
|
# successfully
|
|
pass
|
|
|