Exemple #1
0
class MailToAuthorSchema(interface.Interface):

    inquirerfirstname = schema.TextLine(
        title=_(safe_unicode('Your First Name')),
        description=_(safe_unicode('Please fill in your first name(s)')),
    )

    inquirerfamilyname = schema.TextLine(
        title=_(safe_unicode('Your Family Name')),
        description=_(safe_unicode('Please fill in your familiy name')),
    )

    inquireremailaddress = schema.TextLine(
        title=_(safe_unicode('Your Email Address')),
        description=_(safe_unicode('Please fill in your email address.')),
        constraint=validateemail,
    )

    projectname = schema.TextLine(
        title=_(safe_unicode('Project Name')),
        description=_(safe_unicode('The name of the project, to which author '
                                   'you want to send feedback.')),
        constraint=validateprojectname,
    )

    inquiry = schema.Text(
        title=_(safe_unicode('Your Message To The Author')),
        description=_(safe_unicode('What is your message to the author of '
                                   'the project? Your message is limited to '
                                   '1000 characters.')),
        max_length=1000,
    )
Exemple #2
0
 def legaldeclarationaccepted(data):
     if data.accept_legal_declaration is not True:
         raise AcceptLegalDeclaration(_(
             safe_unicode(
                 'Please accept the Legal '
                 'Declaration about your Release '
                 'and your linked File')))
 def compatibilitynotchoosen(data):
     if not data.compatibility_choice:
         raise Invalid(
             _(
                 safe_unicode(
                     'Please choose one or more compatible product '
                     'versions for your release.')))
Exemple #4
0
    def validate(self, value):
        # Perform the standard validation first
        super(ValidateAddonLinkedReleaseUniqueness, self).validate(value)

        if value is not None:
            if IAddonLinkedRelease.providedBy(self.context):
                # The release number is the same as the previous value stored
                # in the object
                if self.context.releasenumber == value:
                    return None

            catalog = api.portal.get_tool(name='portal_catalog')
            # Differentiate between possible contexts (on creation or editing)
            # on creation the context is the container
            # on editing the context is already the object
            if IAddonLinkedRelease.providedBy(self.context):
                query = '/'.join(self.context.aq_parent.getPhysicalPath())
            else:
                query = '/'.join(self.context.getPhysicalPath())

            result = catalog({
                'path': {'query': query, 'depth': 1},
                'portal_type': ['collective.addons.addonrelease',
                                'collective.addons.addonlinkedrelease'],
                'addon_release_number': value})

            if len(result) > 0:
                raise Invalid(_(
                    safe_unicode(
                        'The release number is already in use. '
                        'Please choose another one.')))
Exemple #5
0
 def missingScreenshotOrLogo(data):
     if not data.screenshot and not data.project_logo:
         raise ProvideScreenshotLogo(
             _(
                 safe_unicode('Please add a screenshot or a logo '
                              'to your project page. You will '
                              'find the appropriate fields below '
                              'on this page.')))
Exemple #6
0
 def testingvalue(data):
     if data.source_code_inside != 1 and data.link_to_source is None:
         raise Invalid(_(
             safe_unicode(
                 'You answered the question, whether the source '
                 'code is inside your add-on with no '
                 '(default answer). If this is the correct '
                 'answer, please fill in the Link (URL) '
                 'to the Source Code.')))
Exemple #7
0
def validateprojectname(value):
    catalog = api.portal.get_tool('portal_catalog')
    project = catalog(
        portal_type='collective.addons.addonproject',
        Title=value,
    )

    for brain in project[:1]:
        if brain.Title is None:
            raise Invalid(_(safe_unicode('Not a valid project name. Please '
                                         'retry.')))
        return True
Exemple #8
0
    def validate(self, value):
        # Perform the standard validation first

        super(ValidateAddonProjectUniqueness, self).validate(value)
        if value is not None:
            catalog = api.portal.get_tool(name='portal_catalog')
            results = catalog({
                'Title': quote_chars(value),
                'object_provides': IAddonProject.__identifier__
            })
            contextUUID = api.content.get_uuid(self.context)
            for result in results:
                if result.UID != contextUUID:
                    raise Invalid(_(u'The project title is already in use.'))
Exemple #9
0
 def noOSChosen(data):
     if data.link_to_file is not None and data.platform_choice == []:
         raise Invalid(_(
             safe_unicode(
                 'Please choose a compatible platform for the '
                 'linked file.')))
Exemple #10
0
 def licensenotchoosen(value):
     if not value.licenses_choice:
         raise Invalid(_(safe_unicode('Please choose a license for your release.')))
Exemple #11
0
    def handleApply(self, action):
        data, errors = self.extractData()
        captcha = getMultiAdapter(
            (aq_inner(self.context), self.request),
            name='recaptcha',
        )

        if errors:
            self.status = self.formErrorsMessage
            return

        elif captcha.verify():
            logger.info('ReCaptcha validation passed.')
        else:
            logger.info(
                'Please validate the recaptcha field before sending the form.')
            api.portal.show_message(
                message=_(
                    safe_unicode('Please validate the recaptcha field before '
                                 'sending the form.')),
                request=self.request,
                type='error')
            return

        if api.portal.get_registry_record('plone.email_from_address') \
                is not None:
            contactaddress = api.portal.get_registry_record(
                'plone.email_from_address')

        catalog = api.portal.get_tool('portal_catalog')
        project = catalog(
            portal_type='collective.addons.addonproject',
            Title=data['projectname'],
        )

        for brain in project[:1]:
            if brain.getObject().addoncontactAddress is not None:
                projectemail = brain.getObject().addoncontactAddress

            else:
                projectemail = contactaddress

        mailrecipient = (safe_unicode('{0}')).format(projectemail)
        api.portal.send_email(
            recipient=mailrecipient,
            sender=(safe_unicode('{0} {1} <{2}>')).format(
                data['inquirerfirstname'],
                data['inquirerfamilyname'],
                data['inquireremailaddress']),
            subject=(safe_unicode('Your Project: {0}')).format(
                data['projectname']),
            body=(safe_unicode('{0}')).format(data['inquiry']),
        )

        # Redirect back to the front page with a status message

        api.portal.show_message(
            message=_(safe_unicode('We send your message to the author '
                                   "of the project. It's on her / his choice, "
                                   "if she'll / he'll get back to you.")),
            request=self.request,
            type='info')

        contextURL = self.context.absolute_url()
        self.request.response.redirect(contextURL)
Exemple #12
0
class IAddonProject(model.Schema):
    directives.mode(information='display')
    information = schema.Text(
        title=_(safe_unicode('Information')),
        description=_(
            safe_unicode('The Dialog to create a new project consists of '
                         'different register. Please go through this register '
                         'and fill in the appropriate data for your project. '
                         "The register 'Documentation' and its fields are "
                         'optional.')),
    )

    dexteritytextindexer.searchable('title')
    title = schema.TextLine(
        title=_(safe_unicode('Title')),
        description=_(
            safe_unicode(
                'Project Title - minimum 5 and maximum 50 characters')),
        min_length=5,
        max_length=50,
    )

    dexteritytextindexer.searchable('description')
    description = schema.Text(title=_(safe_unicode('Project Summary')), )

    dexteritytextindexer.searchable('details')
    primary('details')
    details = RichText(
        title=_(safe_unicode('Full Project Description')),
        required=False,
    )

    model.fieldset(
        'Categories',
        label=_(safe_unicode('Category / Categories')),
        fields=['category_choice'],
    )

    model.fieldset(
        'logo_screenshot',
        label=_(safe_unicode('Logo / Screenshot')),
        fields=[
            'addonimageextension', 'project_logo', 'addonimageextension1',
            'screenshot'
        ],
    )

    model.fieldset(
        'documentation',
        label=_(safe_unicode('Documentation')),
        fields=[
            'documentation_link', 'addondocextension', 'documentation_file'
        ],
    )

    dexteritytextindexer.searchable('category_choice')
    directives.widget(category_choice=CheckBoxFieldWidget)
    category_choice = schema.List(
        title=_(safe_unicode('Choose your categories')),
        description=_(
            safe_unicode('Please select the appropriate categories (one or '
                         'more) for your project.')),
        value_type=schema.Choice(source='Categories'),
        constraint=isNotEmptyCategory,
        required=True,
    )

    addoncontactAddress = schema.TextLine(
        title=_(safe_unicode('Contact email-address')),
        description=_(safe_unicode('Contact email-address for the project.')),
        constraint=validateemail,
    )

    make_addon_contact_address_public = schema.Choice(
        title=_(safe_unicode('Email Public?')),
        description=_(
            safe_unicode('Please decide if your email address '
                         'should be displayed on the project website.')),
        vocabulary=yesnochoice,
        required=True,
    )

    display_addon_user_name = schema.Choice(
        title=_(safe_unicode('Project Author Public?')),
        description=_(
            safe_unicode('Please decide if your name '
                         'should be displayed on the project website.')),
        vocabulary=yesnochoice,
        required=True,
    )

    homepage = schema.URI(
        title=_(safe_unicode('Homepage')),
        description=_(
            safe_unicode('If the project has an external home page, enter its '
                         "URL (example: 'http://www.mysite.org').")),
        required=False,
    )

    documentation_link = schema.URI(
        title=_(safe_unicode('URL of documentation repository ')),
        description=_(
            safe_unicode('If the project has externally hosted '
                         'documentation, enter its URL '
                         "(example: 'http://www.mysite.org').")),
        required=False,
    )

    directives.mode(addondocextension='display')
    addondocextension = schema.TextLine(
        title=_(
            safe_unicode(
                'The following file extensions are allowed for documentation '
                'files (upper case and lower case and mix of both):')),
        defaultFactory=alloweddocextensions,
    )

    documentation_file = NamedBlobFile(
        title=_(safe_unicode('Dokumentation File')),
        description=_(
            safe_unicode(
                "If you have a Documentation in the file format 'PDF' "
                "or 'ODT' you could add it here.")),
        required=False,
        constraint=validatedocextension,
    )

    directives.mode(addonimageextension='display')
    addonimageextension = schema.TextLine(
        title=_(
            safe_unicode(
                'The following file extensions are allowed for project logo '
                'files (upper case and lower case and mix of both):')),
        defaultFactory=allowedimageextensions,
    )

    project_logo = NamedBlobImage(
        title=_(safe_unicode('Logo')),
        description=_(
            safe_unicode(
                'Add a logo for the project (or organization/company) '
                "by clicking the 'Browse' button. You could provide "
                "an image of the file format 'png', 'gif' or 'jpg'.")),
        required=False,
        constraint=validateimageextension,
    )

    directives.mode(addonimageextension1='display')
    addonimageextension1 = schema.TextLine(
        title=_(
            safe_unicode(
                'The following file extensions are allowed for screenshot '
                'files (upper case and lower case and mix of both):')),
        defaultFactory=allowedimageextensions,
    )

    screenshot = NamedBlobImage(
        title=_(safe_unicode('Screenshot of the Add-on')),
        description=_(
            safe_unicode(
                "Add a screenshot by clicking the 'Browse' button. You "
                "could provide an image of the file format 'png', "
                "'gif' or 'jpg'.")),
        required=False,
        constraint=validateimageextension,
    )

    @invariant
    def missingScreenshotOrLogo(data):
        if not data.screenshot and not data.project_logo:
            raise ProvideScreenshotLogo(
                _(
                    safe_unicode('Please add a screenshot or a logo '
                                 'to your project page. You will '
                                 'find the appropriate fields below '
                                 'on this page.')))
Exemple #13
0
class ProvideScreenshotLogo(Invalid):
    __doc__ = _(
        safe_unicode(
            'Please add a screenshot or a logo to your project. You find '
            'the appropriate fields below on this page.'))
class ICollectiveaddonsControlPanel(Interface):
    available_category = schema.Tuple(
        title=_(u'Available Categories'),
        default=('Product one', ),
        value_type=schema.TextLine(),
    )

    available_licenses = schema.Tuple(
        title=_(u'Available Licenses'),
        default=('GNU-GPL-v2 (GNU General Public'
                 'License Version 2)', 'GNU-GPL-v3+ (General Public License'
                 'Version 3 and later)', 'LGPL-v2.1 (GNU Lesser General'
                 'Public License Version 2.1)',
                 'LGPL-v3+ (GNU Lesser General Public'
                 'License Version 3 and later)', 'BSD (BSD License (revised))',
                 'MPL-v1.1 (Mozilla Public License'
                 'Version 1.1)', 'MPL-v2.0+ (Mozilla Public License'
                 'Version 2.0 or later)', 'CC-by-sa-v3 (Creative Commons'
                 'Attribution-ShareAlike 3.0)', 'CC-BY-SA-v4 (Creative Commons'
                 'Attribution-ShareAlike 4.0 '
                 'International)', 'AL-v2 (Apache License Version 2.0)'),
        value_type=schema.TextLine(),
    )

    available_versions = schema.Tuple(
        title=_(u'Available Versions'),
        default=('Product 1.0', ),
        value_type=schema.TextLine(),
    )

    available_platforms = schema.Tuple(
        title=_(u'Available Platforms'),
        default=('All platforms', 'Linux', 'Linux-x64', 'Mac OS X', 'Windows',
                 'BSD', 'UNIX (other)'),
        value_type=schema.TextLine(),
    )

    model.fieldset(
        'fileextensions',
        label=u'Allowed File Extensions',
        fields=[
            'allowed_addonfileextension', 'allowed_apimageextension',
            'allowed_apdocfileextensions'
        ],
    )

    allowed_addonfileextension = schema.TextLine(
        title=_(safe_unicode('Allowed add-on file extensions')),
        description=_(
            safe_unicode(
                'Fill in the allowed file extensions for add-ons, seperated by '
                "a pipe '|'.")),
        default=safe_unicode('oxt'),
    )

    allowed_apimageextension = schema.TextLine(
        title=_(safe_unicode('Allowed image file extension')),
        description=_(
            safe_unicode(
                'Fill in the allowed image file extensions, seperated '
                "by a pipe '|'.")),
        default=safe_unicode('jpg|jpeg|png|gif'),
    )

    allowed_apdocfileextensions = schema.TextLine(
        title=_(safe_unicode('Allowed documentation file extension')),
        description=_(
            safe_unicode('Fill in the allowed documentation file extensions, '
                         "seperated by a pipe '|'.")),
        default=safe_unicode('pdf|odt'),
    )

    model.fieldset(
        'disclaimer',
        label=safe_unicode('Legal Disclaimer'),
        fields=[
            'title_legaldisclaimer', 'legal_disclaimer',
            'title_legaldownloaddisclaimer', 'legal_downloaddisclaimer'
        ],
    )

    title_legaldisclaimer = schema.TextLine(
        title=_(safe_unicode('Title for Legal Disclaimer and Limitations')),
        default=_(safe_unicode('Legal Disclaimer and Limitations')),
        required=False,
    )

    legal_disclaimer = schema.Text(
        title=_(safe_unicode('Text of the Legal Disclaimer and Limitations')),
        description=_(
            safe_unicode('Enter the text of the legal disclaimer and '
                         'limitations that should be displayed to the '
                         'project creator and should be accepted by '
                         'the owner of the project.')),
        default=_(
            safe_unicode('Fill in the legal disclaimer, that had to be '
                         'accepted by the project owner.')),
        required=False,
    )

    title_legaldownloaddisclaimer = schema.TextLine(
        title=_(
            safe_unicode(
                'Title of the Legal Disclaimer and Limitations for Downloads')
        ),
        default=_(
            safe_unicode('Legal Disclaimer and Limitations for Downloads')),
        required=False,
    )

    legal_downloaddisclaimer = schema.Text(
        title=_(
            safe_unicode(
                'Text of the Legal Disclaimer and Limitations for Downlaods')),
        description=_(
            safe_unicode('Enter any legal disclaimer and limitations for '
                         'downloads that should appear on each page for '
                         'dowloadable files.')),
        default=_(
            safe_unicode(
                'Fill in the text for the legal download disclaimer.')),
        required=False,
    )
def validateemail(value):
    if not checkemail(value):
        raise Invalid(_(u'Invalid email address'))
    return True
# -*- coding: utf-8 -*-
from collective.addons import _
from plone import api
from Products.CMFPlone.utils import safe_unicode
from zope.interface import Invalid
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary

import re

yesnochoice = SimpleVocabulary([
    SimpleTerm(value=0, title=_(safe_unicode('No'))),
    SimpleTerm(value=1, title=_(safe_unicode('Yes')))
], )

checkemail = re.compile(
    r'[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,4}').match


def validateemail(value):
    if not checkemail(value):
        raise Invalid(_(u'Invalid email address'))
    return True


def allowedaddonfileextensions():
    return api.portal.get_registry_record(
        'collectiveaddons.allowed_addonfileextension').replace('|', ', ')


def allowedimageextensions():
Exemple #17
0
class MailToAuthorForm(AutoExtensibleForm, form.Form):
    schema = MailToAuthorSchema
    form_name = 'authormail_form'

    label = _(safe_unicode('Mail To The Project Author'))
    description = _(safe_unicode('Contact the project author and send '
                                 'your feedback'))

    fields = field.Fields(MailToAuthorSchema, IReCaptchaForm)
    fields['captcha'].widgetFactory = ReCaptchaFieldWidget

    def update(self):
        # disable Plone's editable border
        self.request.set('disable_border', True)

        # call the base class version - this is very important!
        super(MailToAuthorForm, self).update()

    @button.buttonAndHandler(_(u'Send Email'))
    def handleApply(self, action):
        data, errors = self.extractData()
        captcha = getMultiAdapter(
            (aq_inner(self.context), self.request),
            name='recaptcha',
        )

        if errors:
            self.status = self.formErrorsMessage
            return

        elif captcha.verify():
            logger.info('ReCaptcha validation passed.')
        else:
            logger.info(
                'Please validate the recaptcha field before sending the form.')
            api.portal.show_message(
                message=_(
                    safe_unicode('Please validate the recaptcha field before '
                                 'sending the form.')),
                request=self.request,
                type='error')
            return

        if api.portal.get_registry_record('plone.email_from_address') \
                is not None:
            contactaddress = api.portal.get_registry_record(
                'plone.email_from_address')

        catalog = api.portal.get_tool('portal_catalog')
        project = catalog(
            portal_type='collective.addons.addonproject',
            Title=data['projectname'],
        )

        for brain in project[:1]:
            if brain.getObject().addoncontactAddress is not None:
                projectemail = brain.getObject().addoncontactAddress

            else:
                projectemail = contactaddress

        mailrecipient = (safe_unicode('{0}')).format(projectemail)
        api.portal.send_email(
            recipient=mailrecipient,
            sender=(safe_unicode('{0} {1} <{2}>')).format(
                data['inquirerfirstname'],
                data['inquirerfamilyname'],
                data['inquireremailaddress']),
            subject=(safe_unicode('Your Project: {0}')).format(
                data['projectname']),
            body=(safe_unicode('{0}')).format(data['inquiry']),
        )

        # Redirect back to the front page with a status message

        api.portal.show_message(
            message=_(safe_unicode('We send your message to the author '
                                   "of the project. It's on her / his choice, "
                                   "if she'll / he'll get back to you.")),
            request=self.request,
            type='info')

        contextURL = self.context.absolute_url()
        self.request.response.redirect(contextURL)

    @button.buttonAndHandler(_(safe_unicode('Cancel')))
    def handleCancel(self, action):
        """User cancelled. Redirect back to the front page.
            """
        contextURL = self.context.absolute_url()
        self.request.response.redirect(contextURL)
Exemple #18
0
class IAddonCenter(model.Schema):
    """ A Templates Upload Center.
    """

    title = schema.TextLine(title=_(
        safe_unicode('Name of the Add-on Center')), )

    description = schema.Text(title=_(
        safe_unicode('Description of the Add-on Center')), )

    product_description = schema.Text(title=_(
        safe_unicode('Description of the features of Add-ons')), )

    product_title = schema.TextLine(
        title=_(safe_unicode('Add-on product name')),
        description=_(
            safe_unicode('Name of the Add-on product, e.g. only Add-ons')),
    )

    model.fieldset(
        'instructions',
        label=safe_unicode('Instructions'),
        fields=['install_instructions', 'reporting_bugs'],
    )

    primary('install_instructions')
    install_instructions = RichText(
        title=_(safe_unicode('Add-on installation instructions')),
        description=_(safe_unicode('Please fill in the install instructions')),
        required=False,
    )

    primary('reporting_bugs')
    reporting_bugs = RichText(
        title=_(safe_unicode('Instruction how to report Bugs')),
        required=False,
    )

    primary('information_oldversions')
    information_oldversions = RichText(
        title=_(
            safe_unicode('Information about search for old product versions')),
        description=_(
            safe_unicode('Enter an information about the search for older '
                         'versions of the product, if they are not on the '
                         'versions list (compatibility) anymore.')),
        required=False,
    )

    model.fieldset(
        'contactadresses',
        label=u'Special email adresses',
        fields=['releaseAllert', 'contactForCenter'],
    )

    releaseAllert = schema.ASCIILine(
        title=_(
            safe_unicode('EMail address for the messages about new releases')),
        description=_(
            safe_unicode(
                'Enter an email address to which information about a new '
                'release should be send.')),
        required=False,
    )

    contactForCenter = schema.ASCIILine(
        title=_(
            safe_unicode(
                'EMail address for communication with the add-on center '
                'manager and reviewer')),
        description=_(
            safe_unicode(
                'Enter an email address for the communication with add-on '
                'center manager and reviewer')),
        default='*****@*****.**',
        constraint=validateemail,
    )
Exemple #19
0
def validateemail(value):
    if not checkemail(value):
        raise Invalid(_(safe_unicode('Invalid email address')))
    return True
Exemple #20
0
class AcceptLegalDeclaration(Invalid):
    __doc__ = _(u'It is necessary that you accept the Legal Declaration')
Exemple #21
0
class IAddonLinkedRelease(model.Schema):
    directives.mode(information='display')
    information = schema.Text(
        title=_(safe_unicode('Information')),
        description=_(safe_unicode(
            'This Dialog to create a new release consists of different '
            'register. Please go through this register and fill in the '
            'appropriate data for your linked release. This register '
            "'Default' provide fields for general information of your "
            "linked release. The next register 'compatibility' is the "
            'place to submit information about the versions with which '
            'your linked release file(s) is / are compatible. The '
            'following register asks for some legal informations. '
            "The next register 'Linked File' provide a field to link "
            'your release file. The further register are optional. '
            'There is the opportunity to link further release files '
            '(for different platforms).')),
    )

    directives.mode(projecttitle='hidden')
    projecttitle = schema.TextLine(
        title=_(safe_unicode('The computed project title')),
        description=_(safe_unicode(
            'The linked release title will be computed from the parent '
            'project title')),
        defaultFactory=getContainerTitle,
    )

    releasenumber = schema.TextLine(
        title=_(safe_unicode('Release Number')),
        description=_(safe_unicode('Release Number (up to twelf chars)')),
        default=_(safe_unicode('1.0')),
        max_length=12,
    )

    description = schema.Text(
        title=_(safe_unicode('Release Summary')),
    )

    primary('details')
    details = RichText(
        title=_(safe_unicode('Full Release Description')),
        required=False,
    )

    primary('changelog')
    changelog = RichText(
        title=_(safe_unicode('Changelog')),
        description=_(safe_unicode(
            'A detailed log of what has changed since the '
            'previous release.')),
        required=False,
    )

    model.fieldset('compatibility',
                   label=_(safe_unicode('Compatibility')),
                   fields=['compatibility_choice'])

    model.fieldset('legal',
                   label=_(safe_unicode('Legal')),
                   fields=['licenses_choice', 'title_declaration_legal',
                           'declaration_legal', 'accept_legal_declaration',
                           'source_code_inside', 'link_to_source'])

    directives.widget(licenses_choice=CheckBoxFieldWidget)
    licenses_choice = schema.List(
        title=_(safe_unicode('License of the uploaded file')),
        description=_(safe_unicode(
            'Please mark one or more licenses you publish your '
            'release.')),
        value_type=schema.Choice(source='Licenses'),
        required=True,
    )

    directives.widget(compatibility_choice=CheckBoxFieldWidget)
    compatibility_choice = schema.List(
        title=_(safe_unicode('Compatible with the versions of the product')),
        description=_(safe_unicode(
            'Please mark one or more program versions with which '
            'this release is compatible with.')),
        value_type=schema.Choice(source='Versions'),
        required=True,
    )

    directives.mode(title_declaration_legal='display')
    title_declaration_legal = schema.TextLine(
        title=_(safe_unicode('')),
        required=False,
        defaultFactory=legaldeclarationtitle,
    )

    directives.mode(declaration_legal='display')
    declaration_legal = schema.Text(
        title=_(safe_unicode('')),
        required=False,
        defaultFactory=legaldeclarationtext,
    )

    accept_legal_declaration = schema.Bool(
        title=_(safe_unicode('Accept the above legal disclaimer')),
        description=_(safe_unicode(
            'Please declare that you accept the above legal '
            'disclaimer.')),
        required=True,
    )

    contact_address2 = schema.TextLine(
        title=_(safe_unicode('Contact email-address')),
        description=_(safe_unicode(
            'Contact email-address for the project.')),
        required=False,
        defaultFactory=contactinfoDefault,
    )

    source_code_inside = schema.Choice(
        title=_(safe_unicode('Is the source code inside the add-on?')),
        vocabulary=yesnochoice,
        required=True,
    )

    link_to_source = schema.URI(
        title=_(safe_unicode('Please fill in the Link (URL) to the Source Code.')),
        required=False,
    )

    model.fieldset('linked_file',
                   label=_(safe_unicode('Linked File')),
                   fields=['addonlinkedfileextension',
                           'link_to_file',
                           'external_file_size',
                           'platform_choice',
                           'information_further_file_uploads'])

    directives.mode(addonlinkedfileextension='display')
    addonlinkedfileextension = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=True,
        constraint=validatelinkedaddonextension,
    )

    external_file_size = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external hosted '
            'file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice=CheckBoxFieldWidget)
    platform_choice = schema.List(
        title=_(safe_unicode('First linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'uploaded file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    directives.mode(information_further_file_uploads='display')
    primary('information_further_file_uploads')
    information_further_file_uploads = RichText(
        title=_(safe_unicode('Further linked files for this Release')),
        description=_(safe_unicode(
            'If you want to link more files for this release, e.g. because '
            "there are files for other operating systems, you'll find the "
            'fields to link this files on the next registers, e.g. '
            "'Second linked file' for this Release'.")),
        required=False,
    )

    model.fieldset('fieldset1',
                   label=_(safe_unicode('Second linked file')),
                   fields=['addonlinkedfileextension1',
                           'link_to_file1',
                           'external_file_size1',
                           'platform_choice1'],
                   )

    model.fieldset('fieldset2',
                   label=_(safe_unicode('Third linked file')),
                   fields=['addonlinkedfileextension2',
                           'link_to_file2',
                           'external_file_size2',
                           'platform_choice2'],
                   )

    model.fieldset('fieldset3',
                   label=_(safe_unicode('Fourth linked file')),
                   fields=['addonlinkedfileextension3',
                           'link_to_file3',
                           'external_file_size3',
                           'platform_choice3'],
                   )

    model.fieldset('fieldset4',
                   label=_(safe_unicode('Fifth linked file')),
                   fields=['addonlinkedfileextension4',
                           'link_to_file4',
                           'external_file_size4',
                           'platform_choice4'],
                   )

    model.fieldset('fieldset5',
                   label=_(safe_unicode('Sixth linked file')),
                   fields=['addonlinkedfileextension5',
                           'link_to_file5',
                           'external_file_size5',
                           'platform_choice5'],
                   )

    directives.mode(addonlinkedfileextension1='display')
    addonlinkedfileextension1 = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file1 = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=False,
        constraint=validatelinkedaddonextension,
    )

    external_file_size1 = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external '
            'hosted file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice1=CheckBoxFieldWidget)
    platform_choice1 = schema.List(
        title=_(safe_unicode('Second linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'linked file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    directives.mode(addonlinkedfileextension2='display')
    addonlinkedfileextension2 = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file2 = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=False,
        constraint=validatelinkedaddonextension,
    )

    external_file_size2 = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external '
            'hosted file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice2=CheckBoxFieldWidget)
    platform_choice2 = schema.List(
        title=_(safe_unicode('Third linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'linked file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    directives.mode(addonlinkedfileextension3='display')
    addonlinkedfileextension3 = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file3 = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=False,
        constraint=validatelinkedaddonextension,
    )

    external_file_size3 = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external '
            'hosted file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice3=CheckBoxFieldWidget)
    platform_choice3 = schema.List(
        title=_(safe_unicode('Fourth linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'linked file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    directives.mode(addonlinkedfileextension4='display')
    addonlinkedfileextension4 = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file4 = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=False,
        constraint=validatelinkedaddonextension,
    )

    external_file_size4 = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external '
            'hosted file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice4=CheckBoxFieldWidget)
    platform_choice4 = schema.List(
        title=_(safe_unicode('Fifth linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'linked file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    directives.mode(addonlinkedfileextension5='display')
    addonlinkedfileextension5 = schema.TextLine(
        title=_(safe_unicode(
            'The following file extensions are allowed for linked '
            'files (upper case and lower case and mix of '
            'both):')),
        defaultFactory=allowedaddonfileextensions,
    )

    link_to_file5 = schema.URI(
        title=_(safe_unicode('The Link to the file of the release')),
        description=_(safe_unicode('Please insert a link to your add-on file.')),
        required=False,
        constraint=validatelinkedaddonextension,
    )

    external_file_size5 = schema.Float(
        title=_(safe_unicode('The size of the external hosted file')),
        description=_(safe_unicode(
            'Please fill in the size in kilobyte of the external '
            'hosted file (e.g. 633, if the size is 633 kb)')),
        required=False,
    )

    directives.widget(platform_choice5=CheckBoxFieldWidget)
    platform_choice5 = schema.List(
        title=_(safe_unicode('Sixth linked file is compatible with the Platform(s)')),
        description=_(safe_unicode(
            'Please mark one or more platforms with which the '
            'linked file is compatible.')),
        value_type=schema.Choice(source='Platforms'),
        required=True,
    )

    @invariant
    def licensenotchoosen(value):
        if not value.licenses_choice:
            raise Invalid(_(safe_unicode('Please choose a license for your release.')))

    @invariant
    def compatibilitynotchoosen(data):
        if not data.compatibility_choice:
            raise Invalid(_(safe_unicode(
                'Please choose one or more compatible product '
                'versions for your release.')))

    @invariant
    def legaldeclarationaccepted(data):
        if data.accept_legal_declaration is not True:
            raise AcceptLegalDeclaration(_(
                safe_unicode(
                    'Please accept the Legal '
                    'Declaration about your Release '
                    'and your linked File')))

    @invariant
    def testingvalue(data):
        if data.source_code_inside != 1 and data.link_to_source is None:
            raise Invalid(_(
                safe_unicode(
                    'You answered the question, whether the source '
                    'code is inside your add-on with no '
                    '(default answer). If this is the correct '
                    'answer, please fill in the Link (URL) '
                    'to the Source Code.')))

    @invariant
    def noOSChosen(data):
        if data.link_to_file is not None and data.platform_choice == []:
            raise Invalid(_(
                safe_unicode(
                    'Please choose a compatible platform for the '
                    'linked file.')))
class AcceptLegalDeclaration(Invalid):
    __doc__ = _(
        safe_unicode('It is necessary that you accept the Legal Declaration'))