Пример #1
0
class SetMeetingTitleOnApproved(BaseSubstitution):
    category = _(u'Approve Subscriber')
    description = _(u'Meeting title')

    def safe_call(self):
        """ Safe call
        """
        if self.context.portal_type == 'eea.meeting.subscriber':
            """ This is the case for approving a subscriber:
                - Thank you for your registration
            """
            meeting = self.context.aq_parent.aq_parent

        elif self.context.portal_type == 'eea.meeting':
            """ This is the case for new subscriber registered:
                - A new participant has registered to the meeting
                - You have registered to the meeting
            """
            meeting = self.context

        try:
            title = meeting.title
        except Exception:
            title = ""

        return title
Пример #2
0
class SendEmail(form.Form):
    fields = field.Fields(IEmail)
    ignoreContext = True

    label = _(u"Send email")

    fields['receiver'].widgetFactory = CheckBoxFieldWidget

    prefix = 'send_email'

    template = FPT('main_form.pt')

    def update(self):
        super(SendEmail, self).update()
        self.search_user = SearchUser(self.context, self.request, self)
        self.search_user.update()
        self.widgets['body'].rows = 10
        if (not self.actions.executedActions
                and not self.widgets['receiver'].items):
            for widget in self.widgets.values():
                widget.disabled = 'disabled'
            self.actions['send_email'].disabled = 'disabled'
            msg = 'There are no subscribed users. Cannot send email.'
            IStatusMessage(self.request).addStatusMessage(msg, type='error')

    @button.buttonAndHandler(_('Send Email'), name='send_email')
    def handleSave(self, action):
        data, errors = self.extractData()

        if errors:
            return False

        types = api.portal.get_tool('portal_types')
        type_info = types.getTypeInfo('eea.meeting.email')

        name_chooser = INameChooser(self.context)
        content_id = name_chooser.chooseName(data['subject'], self.context)

        obj = type_info._constructInstance(self.context, content_id)

        obj.title = data['subject']
        obj.sender = data['sender']
        obj.receiver = data['receiver']
        obj.cc = data['cc']
        obj.subject = data['subject']
        obj.body = data['body']

        obj.reindexObject()

        notify(SendEmailAddEvent(self.context, data))

        msg = _(u"Email successfully sent")
        IStatusMessage(self.request).addStatusMessage(msg, type='info')
        self.request.response.redirect(
            self.context.getParentNode().absolute_url())

    @button.buttonAndHandler(_('Cancel'), name='cancel_send')
    def cancel_send(self, action):
        return self.request.response.redirect(
            self.context.aq_parent.absolute_url())
Пример #3
0
class ISubscriber(Interface):
    """ Meeting subscriber """
    userid = schema.TextLine(title=_("User id"), required=True)

    email = schema.TextLine(title=_(u"Email"),
                            required=True,
                            constraint=validate_email)
Пример #4
0
class IEmail(Interface):
    """ Email """
    sender = Email(
        title=_(u"From"),
        required=True,
    )

    receiver = schema.Set(
        title=u'Recipients',
        value_type=schema.Choice(
            vocabulary='eea.meeting.vocabularies.RecipientsVocabulary'))

    cc = schema.Text(
        title=_(u"CC"),
        description=_(u'Add CC addresses one per line, no separator'),
        constraint=cc_constraint,
        required=False,
    )

    subject = schema.TextLine(
        title=_(u"Subject"),
        required=True,
    )

    body = RichText(
        title=_(u"Body"),
        required=True,
        output_mime_type='text/plain',
        allowed_mime_types=('text/html', 'text/structured', 'text/plain'),
    )

    directives.widget('sender', TextFieldWidget, klass=u'mail_widget')
Пример #5
0
class SearchUser(form.Form):

    fields = field.Fields(ISearchUser)
    ignoreContext = True

    fields['results'].widgetFactory = CustomCheckBoxFieldWidget

    prefix = 'search_user'
    template = FiveViewPageTemplateFile('search_user.pt')

    _parent_form = None

    def __init__(self, context, request, parent_form=None):
        super(SearchUser, self).__init__(context, request)
        self._parent_form = parent_form

    @button.buttonAndHandler(_('Search'), name='search_user')
    def handleSave(self, action):
        data, errors = self.extractData()

        if errors:
            return False

    @button.buttonAndHandler(_('Add'), name='addCC')
    def handle_addCC(self, action):
        data, errors = self.extractData()

        self._parent_form.widgets['cc'].value += '\n'+"\n".join(data['results'])

        del self.widgets['results'].items
        self.widgets['results'].value = ''

        if errors:
            return False
Пример #6
0
class SendEmail(form.Form):
    fields = field.Fields(IEmail)
    ignoreContext = True

    label = _(u"Send email")

    fields['receiver'].widgetFactory = CheckBoxFieldWidget

    prefix = 'send_email'

    template = FiveViewPageTemplateFile('main_form.pt')

    def update(self):
        super(SendEmail, self).update()
        self.search_user = SearchUser(self.context, self.request, self)
        self.search_user.update()


    @button.buttonAndHandler(_('Send Email'), name='send_email')
    def handleSave(self, action):
        data, errors = self.extractData()

        if errors:
            return False

        types = api.portal.get_tool('portal_types')
        type_info = types.getTypeInfo('eea.meeting.email')

        name_chooser = INameChooser(self.context)
        content_id = name_chooser.chooseName(data['subject'], self.context)

        obj = type_info._constructInstance(self.context, content_id)

        obj.title = data['subject']

        obj.sender = data['sender']

        obj.receiver = "\r\n".join(data['receiver'])

        data['receiver'] = obj.receiver

        obj.cc = data['cc']

        obj.subject = data['subject']
        obj.body = data['body']
        obj.reindexObject()

        notify(SendEmailAddEvent(self.context, data))

        msg = _(u"Email successfully sent")
        IStatusMessage(self.request).addStatusMessage(msg, type='info')
        self.request.response.redirect(self.context.getParentNode().absolute_url())
Пример #7
0
class SetMeetingContactEmail(BaseSubstitution):
    category = _(u'eea.meeting')
    description = _(u'Meeting contact email')

    def safe_call(self):
        """ Safe call
        """
        try:
            email = self.context.contact_email
        except Exception:
            email = ''

        return email
Пример #8
0
class SetMeetingPlaceOnApproved(BaseSubstitution):
    category = _(u'Approve Subscriber')
    description = _(u'Meeting place')

    def safe_call(self):
        """ Safe call
        """
        try:
            location = self.context.aq_parent.aq_parent.location
        except Exception:
            location = ""

        return location
Пример #9
0
class SetNameReceiverOnApproved(BaseSubstitution):
    category = _(u'Approve Subscriber')
    description = _(u'Subscriber Name')

    def safe_call(self):
        """ Safe call
        """
        try:
            return self.context.get_details().get('fullname', 'user')
        except Exception:
            name = 'user'

        return name
Пример #10
0
class SetEmailReceiverOnApproved(BaseSubstitution):
    category = _(u'Approve Subscriber')
    description = _(u'Subscriber Email')

    def safe_call(self):
        """ Safe call
        """
        try:
            email = self.context.email
        except Exception:
            email = ''

        return email
Пример #11
0
class SetMeetingURL(BaseSubstitution):
    category = _(u'eea.meeting')
    description = _(u'Finds the closest meeting and returns it\'s URL.')

    def safe_call(self):
        """ Safe call
        """
        def find_meeting(context):
            return (
                IMeeting.providedBy(context) and context
                or find_meeting(context.aq_parent)
            )

        meeting = find_meeting(self.context)
        return meeting.absolute_url() if meeting else ''
Пример #12
0
def cc_constraint(value):
    for idx, email in enumerate(value):
        idx += 1
        if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
            raise Invalid(_(u"Invalid email address on line %d" % idx))

    return True
Пример #13
0
    def handleSave(self, action):
        data, errors = self.extractData()

        if errors:
            return False

        types = api.portal.get_tool('portal_types')
        type_info = types.getTypeInfo('eea.meeting.email')

        name_chooser = INameChooser(self.context)
        content_id = name_chooser.chooseName(data['subject'], self.context)

        obj = type_info._constructInstance(self.context, content_id)

        obj.title = data['subject']
        obj.sender = data['sender']
        obj.receiver = data['receiver']
        obj.cc = data['cc']
        obj.subject = data['subject']
        obj.body = data['body']

        obj.reindexObject()

        notify(SendEmailAddEvent(self.context, data))

        msg = _(u"Email successfully sent")
        IStatusMessage(self.request).addStatusMessage(msg, type='info')
        self.request.response.redirect(
            self.context.getParentNode().absolute_url())
Пример #14
0
    def handleSave(self, action):
        data, errors = self.extractData()

        if errors:
            return False

        types = api.portal.get_tool('portal_types')
        type_info = types.getTypeInfo('eea.meeting.email')

        name_chooser = INameChooser(self.context)
        content_id = name_chooser.chooseName(data['subject'], self.context)

        obj = type_info._constructInstance(self.context, content_id)

        obj.title = data['subject']

        obj.sender = data['sender']

        obj.receiver = "\r\n".join(data['receiver'])

        data['receiver'] = obj.receiver

        obj.cc = data['cc']

        obj.subject = data['subject']
        obj.body = data['body']
        obj.reindexObject()

        notify(SendEmailAddEvent(self.context, data))

        msg = _(u"Email successfully sent")
        IStatusMessage(self.request).addStatusMessage(msg, type='info')
        self.request.response.redirect(self.context.getParentNode().absolute_url())
Пример #15
0
def cc_constraint(value):
    data_lines = value.split('\r\n')

    for idx, email in enumerate(data_lines):
        idx += 1
        if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
            raise Invalid(_(u"Invalid email address on line %d" % idx))

    return True
Пример #16
0
class IMeeting(Interface):
    """ Meeting """
    text = RichText(
        title=_(u"Body text"),
        required=True,
    )

    meeting_type = schema.Choice(
        title=_(u"Meeting type"),
        vocabulary=meeting_types,
        required=True,
    )

    allow_register = schema.Bool(
        title=_(u"Allow users to register to the meeting"),
        required=True,
    )

    restrict_content_access = schema.Bool(
        title=(u"Restrict user access to the contents in the meeting"),
        required=True)

    auto_approve = schema.Bool(
        title=_(u"Automatically approve registrations"),
        required=True,
    )

    max_participants = schema.Int(
        title=_(u"Maximum number of participants"),
        required=True,
    )

    contact_name = schema.TextLine(
        title=_(u"Contact person"),
        required=True,
    )

    contact_email = schema.TextLine(title=_(u"Contact email"),
                                    required=True,
                                    constraint=validate_email)

    location = schema.TextLine(title=_(u'label_event_location',
                                       default=u'Location'),
                               description=_(
                                   u'help_event_location',
                                   default=u'Location of the event.'),
                               required=True,
                               default=None)
Пример #17
0
class ISearchUser(Interface):
    """ Search user """
    containing = schema.TextLine(
        title=_(u"Add users to E-mail CC"),
        required=True,
    )

    results = schema.Set(
        required=False,
        value_type=schema.Choice(
            vocabulary='eea.meeting.vocabularies.LDAPListingVocabulary'))
Пример #18
0
class IEmail(Interface):
    """ Email """
    sender = Email(
        title=_(u"From"),
        required=True,
    )

    receiver = schema.Set(
        title=u'Recipients',
        missing_value=set(),
        value_type=schema.Choice(
            vocabulary='eea.meeting.vocabularies.RecipientsVocabulary',
            required=True,
        ),
        required=True,
    )

    cc = schema.List(
        title=_(u"CC"),
        description=_(u'Add CC addresses one per line, no separator'),
        value_type=schema.TextLine(),
        constraint=cc_constraint,
        required=False,
    )

    subject = schema.TextLine(
        title=_(u"Subject"),
        required=True,
    )

    body = schema.Text(
        title=_(u"Body"),
        required=True,
    )

    email_type = schema.TextLine(
        title=_(u"Email type"),
        required=False,
    )

    directives.widget('sender', TextFieldWidget, klass=u'mail_widget')
Пример #19
0
class RegisterUser(BrowserView):
    """ Register a user
    """
    label = _(u"Register user")

    def __init__(self, context, request):
        super(RegisterUser, self).__init__(context, request)
        self._searchString = ''

    @property
    def searchString(self):
        """ Search string
        """
        if not self._searchString:
            self._searchString = self.request.get('searchstring', '')
        return self._searchString

    @property
    def users(self):
        """ Users
        """
        if not self.searchString:
            return []

        site = getSite()
        cpanel = getMultiAdapter((site, self.request),
                                 name=u"usergroup-userprefs")
        return cpanel.doSearch(self.searchString)

    def _register(self, users):
        """ Register users
        """
        subscribers = self.context.get('subscribers')
        emails = [sub.email for sub in subscribers.values()]
        for username in users:
            user = api.user.get(username)
            fullname = user.getProperty('fullname', username)
            email = user.getProperty('email')
            if email in emails:
                continue

            createContentInContainer(subscribers,
                                     'eea.meeting.subscriber',
                                     checkConstraints=False,
                                     title=fullname,
                                     id=username,
                                     userid=username,
                                     email=email)

        IStatusMessage(self.request).addStatusMessage(
            "Users registered to this meeting", type="info")
        return self.request.response.redirect(self.context.absolute_url() +
                                              '/register_user')

    def __call__(self, *args, **kwargs):
        if self.request.method.lower() != 'post':
            return self.index()

        if not self.request.get('form.button.register', None):
            return self.index()

        users = self.request.get('users', [])
        if not users:
            return self.index()

        return self._register(users)
Пример #20
0
# -*- coding: utf-8 -*-

from eea.meeting import _
from eea.meeting.interfaces.util import validate_email
from plone.app.textfield import RichText
from zope import schema
from zope.interface import Interface
from zope.interface import invariant, Invalid
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm

meeting_types = SimpleVocabulary([
    SimpleTerm(value=u'meeting', title=_(u'Meeting')),
    SimpleTerm(value=u'conference', title=_(u'Conference')),
    SimpleTerm(value=u'workshop', title=_(u'Workshop')),
    SimpleTerm(value=u'webinar', title=_(u'Webinar'))
])

meeting_levels = SimpleVocabulary([
    SimpleTerm(value=u'national', title=_(u'National Level')),
    SimpleTerm(value=u'regional', title=_(u'Regional Level')),
    SimpleTerm(value=u'other', title=_(u'Other'))
])


class IMeeting(Interface):
    """ Meeting """
    text = RichText(
        title=_(u"Body text"),
        required=True,
    )
Пример #21
0
 def validate_location_required(data):
     if data.meeting_type != 'webinar' and data.location is None:
         raise Invalid(_(
             u"Event location input is missing." +
             " This field is not required only in " +
             "'Meeting type: webinar' case."))
Пример #22
0
from eea.meeting.interfaces.util import validate_userid
from plone.app.textfield import RichText
from plone.namedfile.field import NamedBlobFile
from zope import schema
from zope.interface import Interface
from zope.interface import invariant, Invalid
from zope.interface import provider
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary
import datetime


meeting_types = SimpleVocabulary(
    [
        SimpleTerm(value=u'conference', title=_(u'Conference')),
        SimpleTerm(value=u'meeting', title=_(u'Meeting')),
        SimpleTerm(value=u'workshop', title=_(u'Workshop')),
        SimpleTerm(value=u'webinar', title=_(u'Webinar')),
        SimpleTerm(value=u'eionet-copernicus-nrc-lc-meeting',
                   title=_(u'EIONET Copernicus NRC LC Meeting')),
        SimpleTerm(value=u'other', title=_(u'Other')),
    ]
)


class IMeeting(Interface):
    """ Meeting """
    text = RichText(
        title=_(u"Body text"),
        required=True,
Пример #23
0
class IMeeting(Interface):
    """ Meeting """
    text = RichText(
        title=_(u"Body text"),
        required=True,
    )

    meeting_type = schema.Choice(
        title=_(u"Meeting type"),
        vocabulary=meeting_types,
        required=True,
    )

    allow_register = schema.Bool(
        title=_(u"Allow users to register for the meeting"),
        required=True,
    )

    allow_register_above_max = schema.Bool(
        title=_(u"Continue to allow registration when maximum number of"
                " participants is reached"),
        required=True,
    )

    allow_register_start = schema.Datetime(
        title=_(u"From"),
        description=_(u"Allow registration starting with this datetime."),
        required=False,
        min=datetime.datetime(2018, 1, 1),
        max=datetime.datetime(datetime.datetime.now().year + 10, 12, 31)
    )

    allow_register_end = schema.Datetime(
        title=_(u"To"),
        description=_(u"Allow registration until this datetime."),
        required=False,
        min=datetime.datetime(2018, 1, 1),
        max=datetime.datetime(datetime.datetime.now().year + 10, 12, 31)
    )

    need_e_pass = schema.Bool(
        title=_(u"E-pass is required"),
        required=True,
    )

    is_unlisted = schema.Bool(
        title=_(u"Make this event unlisted"),
        required=True,
    )

    restrict_content_access = schema.Bool(
        title=_(u"Hide the content of Additional materials table for not "
                "registered users"),
        required=True
    )

    auto_approve = schema.Bool(
        title=_(u"Automatically approve registrations"),
        required=True,
    )

    max_participants = schema.Int(
        title=_(u"Maximum number of subscribers"),
        required=True,
    )

    hosting_organisation = schema.TextLine(
        title=_(u"Supporting organisations"),
        required=True,
        default=None,
    )

    contact_name = schema.TextLine(
        title=_(u"Contact name"),
        required=True,
    )

    contact_email = schema.TextLine(
        title=_(u"Contact email"),
        required=True,
        constraint=validate_email
    )

    location = schema.TextLine(
        title=_(
            u'label_event_location',
            default=u'Event location'
        ),
        description=_(
            u'help_event_location',
            default=u'Location of the event.'
        ),
        required=False,
        default=None
    )

    agenda = NamedBlobFile(
        title=_(u"Event agenda"),
        description=_(u"Upload your agenda file."),
        required=False,
    )

    event_timezone = schema.TextLine(
        title=_(u"Event timezone info"),
        description=_(u"Human readable info about timezone for this event."),
        required=False,
        default=_(u"Time zone: Copenhagen, Denmark"),
    )

    @invariant
    def validate_location_required(data):
        if data.meeting_type != 'webinar' and data.location is None:
            raise Invalid(_(
                u"Event location input is missing." +
                " This field is not required only in " +
                "'Meeting type: webinar' case."))
Пример #24
0
class ISubscriber(Interface):
    """ Meeting subscriber """

    userid = schema.TextLine(
        title=_("User id"),
        required=True,
        constraint=validate_userid,
    )

    email = schema.TextLine(
        title=_(u"Email"),
        required=True,
        constraint=validate_email
    )

    # directives.widget(reimbursed=RadioFieldWidget)
    # reimbursed = schema.Bool(
    #     title=_(u"Reimbursed participation"),
    #     required=True
    # )

    role = schema.Choice(
        title=_(u"Role"),
        vocabulary="subscriber_roles",
        required=True,
    )

    role_other = schema.TextLine(
        title=_(u"Role (other)"),
        required=False,
    )

    delegate_type = schema.Choice(
        title=_(u"Delegate type"),
        vocabulary="subscriber_delegate_types",
        required=True,
    )

    date_of_birth = schema.Date(
        title=_(u"DATE OF BIRTH"),
        required=False,
        min=datetime.date(1900, 1, 1),
        max=datetime.date(2050, 1, 1),

    )

    nationality = schema.TextLine(
        title=_(u"NATIONALITY"),
        required=False,
    )

    id_card_nbr = schema.TextLine(
        title=_(u"ID CARD NBR"),
        required=False,
    )

    id_valid_date = schema.Date(
        title=_(u"ID VALID DATE"),
        required=False,
        min=datetime.date(1900, 1, 1),
        max=datetime.date(2050, 1, 1),
    )

    request_data_deletion = schema.Bool(
        title=_(u"Request account deletion"),
        description=_(u"Please delete my account on the website after the "
                      "event has ended, latest after 4 weeks.")
    )
Пример #25
0
class SetEmailReceiver(SetEmailSubstitution):
    category = _(u'Email Send')
    description = _(u'Email receiver address')
    attribute = u'receiver'
Пример #26
0
class IMeeting(Interface):
    """ Meeting """
    text = RichText(
        title=_(u"Body text"),
        required=True,
    )

    meeting_type = schema.Choice(
        title=_(u"Meeting type"),
        vocabulary=meeting_types,
        required=True,
    )

    meeting_level = schema.Choice(
        title=_(u"Meeting level"),
        vocabulary=meeting_levels,
        required=True,
    )

    allow_register = schema.Bool(
        title=_(u"Allow users to register to the meeting"),
        required=True,
    )

    allow_register_start = schema.Datetime(
        title=_(u"From"),
        description=_(u"Allow registration starting with this datetime."),
        required=False,
    )

    allow_register_end = schema.Datetime(
        title=_(u"To"),
        description=_(u"Allow registration until this datetime."),
        required=False,
    )

    restrict_content_access = schema.Bool(title=_(
        u"Hide the content of Additional materials table for not "
        "registered users"),
                                          required=True)

    auto_approve = schema.Bool(
        title=_(u"Automatically approve registrations"),
        required=True,
    )

    max_participants = schema.Int(
        title=_(u"Maximum number of participants"),
        required=True,
    )

    hosting_organisation = schema.TextLine(
        title=_(u"Hosting organisation"),
        required=True,
        default=None,
    )

    contact_name = schema.TextLine(
        title=_(u"Contact person"),
        required=True,
    )

    contact_email = schema.TextLine(title=_(u"Contact email"),
                                    required=True,
                                    constraint=validate_email)

    location = schema.TextLine(title=_(u'label_event_location',
                                       default=u'Event location'),
                               description=_(
                                   u'help_event_location',
                                   default=u'Location of the event.'),
                               required=False,
                               default=None)

    @invariant
    def validate_location_required(data):
        if data.meeting_type != 'webinar' and data.location is None:
            raise Invalid(
                _(u"Event location input is missing." +
                  " This field is not required only in " +
                  "'Meeting type: webinar' case."))
Пример #27
0
from zope.interface import Interface
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from Products.CMFDefault.utils import checkEmailAddress
from Products.CMFDefault.exceptions import EmailAddressInvalid
from plone.app.textfield import RichText

from plone.schema import Email
from plone.autoform import directives
from z3c.form.browser.text import TextFieldWidget

from zope.interface import Invalid
import re

meeting_types = SimpleVocabulary([
    SimpleTerm(value=u'meeting', title=_(u'Meeting')),
    SimpleTerm(value=u'conference', title=_(u'Conference')),
    SimpleTerm(value=u'workshop', title=_(u'Workshop'))
])


def validate_email(email):
    try:
        checkEmailAddress(email)
    except EmailAddressInvalid:
        raise EmailAddressInvalid(email)
    return True


def cc_constraint(value):
    data_lines = value.split('\r\n')
Пример #28
0
class SetEmailSubject(SetEmailSubstitution):
    category = _(u'Email Send')
    description = _(u'Email subject')
    attribute = u'subject'
Пример #29
0
def validate_userid(userid):
    user = api.user.get(userid=userid)
    if user:
        return True

    raise Invalid(_(u'User does not exist!'))
Пример #30
0
class SetEmailCC(SetEmailSubstitution):
    category = _(u'Email Send')
    description = _(u'Email CC addresses')
    attribute = u'cc'
Пример #31
0
class SetEmailBody(SetEmailSubstitution):
    category = _(u'Email Send')
    description = _(u'Email body')
    attribute = u'body'