Ejemplo n.º 1
0
 def validateDatamodel(self, value):
     """Validate datamodel"""
     if not self.required:
         return
     unanswered = [x for x in value if x is None]
     if unanswered:
         raise WidgetError('Value required for "%s"' % self.title)
Ejemplo n.º 2
0
    def test_invalid_widget_no_request(self, manage_addSurveyAnswer):
        survey = self.survey
        widget = Mock()
        widget.getDatamodel = Mock(return_value='')
        widget.validateDatamodel = Mock(side_effect=WidgetError('test_error'))
        survey.getWidgets = Mock(return_value=[widget])

        self.assertRaises(WidgetError, survey.addSurveyAnswer)
        self.assertEqual(manage_addSurveyAnswer.call_count, 0)
Ejemplo n.º 3
0
 def getDatamodel(self, form):
     """Get datamodel from form"""
     value = form.get(self.getWidgetId(), None)
     if not value:
         return None
     try:
         day, month, year = [int(i) for i in value.strip().split('/')]
         value = DateTime(year, month, day)
     except:
         raise WidgetError('Invalid date string for "%s"' % self.title)
     return value
Ejemplo n.º 4
0
 def validateDatamodel(self, value):
     """Validate datamodel"""
     # Required
     if not value:
         if self.required:
             raise WidgetError('Value required for "%s"' % self.title)
         return
     # Max size
     if self.size_max == 0:
         return True
     read_size = len(value.read(self.size_max + 1))
     if self.required and not read_size:
         value.seek(0)
         raise WidgetError('Value required for "%s". Empty file provided.' %
                           self.title)
     if read_size > self.size_max:
         max_size_str = utils().utShowSize(self.size_max)
         value.seek(0)
         raise WidgetError(
             'The uploaded file for "%s" is too big, the maximum allowed size is %s bytes'
             % (self.title, max_size_str))
Ejemplo n.º 5
0
    def test_invalid_widget_with_request(self, manage_addSurveyAnswer):
        survey = self.survey
        widget = Mock()
        widget.getWidgetId = Mock(return_value='test_widget')
        widget.getDatamodel = Mock(return_value='')
        widget.validateDatamodel = Mock(side_effect=WidgetError('test_error'))
        survey.getWidgets = Mock(return_value=[widget])
        REQUEST = Mock()
        REQUEST.form = {}

        survey.addSurveyAnswer(REQUEST=REQUEST)

        survey.setSessionErrorsTrans.assert_called_with(['test_error'])
        survey.setSessionAnswer.assert_called_with({'test_widget': None})
        survey.setSession.assert_called_with('notify_respondent', False)
        REQUEST.RESPONSE.redirect.assert_called_with("http://survey")
        self.assertEqual(manage_addSurveyAnswer.call_count, 0)
Ejemplo n.º 6
0
    def test_add_draft(self, manage_addSurveyAnswer):
        manage_addSurveyAnswer.return_value = 'answer_12345'
        survey = self.survey
        survey.canAddAnswerDraft = Mock(return_value=True)
        widget = Mock()
        widget.getWidgetId = Mock(return_value='test_widget')
        widget.getDatamodel = Mock(return_value='')
        widget.validateDatamodel = Mock(side_effect=WidgetError('test_error'))
        survey.getWidgets = Mock(return_value=[widget])

        survey.addSurveyAnswer(draft=True)

        self.assertEqual(widget.validateDatamodel.call_count, 0)
        self.assertEqual(validation_onsubmit.call_count, 0)
        manage_addSurveyAnswer.assert_called_with(survey, {'test_widget': ''},
                                                  REQUEST=None,
                                                  draft=True,
                                                  id=None,
                                                  respondent=None,
                                                  creation_date=None)
Ejemplo n.º 7
0
    def getDatamodel(self, form):
        """Get datamodel from form"""
        lat = form.get(self.getWidgetId() + '.lat', None)
        lon = form.get(self.getWidgetId() + '.lon', None)
        address = form.get(self.getWidgetId() + '.address', '')
        if not (lat and lon):
            coordinates = geocoding.location_geocode(address)
            if coordinates is not None:
                lat, lon = coordinates
        if not lat:
            lat = None
        if not lon:
            lon = None

        if lat is None and lon is None and address == '':
            return None

        try:
            return Geo(lat, lon, address)
        except ValueError:
            raise WidgetError('Invalid geo values for "%s"' % self.title)
Ejemplo n.º 8
0
class SurveyQuestionnaire(NyRoleManager, NyAttributes, questionnaire_item,
                          NyContainer):
    """ """
    meta_type = "Naaya Survey Questionnaire"
    meta_label = "Survey Instance"
    icon = 'misc_/NaayaSurvey/NySurveyQuestionnaire.gif'
    icon_marked = 'misc_/NaayaSurvey/NySurveyQuestionnaire_marked.gif'

    _constructors = ()

    all_meta_types = ()

    manage_options = (
        {
            'label': 'Contents',
            'action': 'manage_main',
            'help': ('OFSP', 'ObjectManager_Contents.stx')
        },
        {
            'label': 'Properties',
            'action': 'manage_propertiesForm',
            'help': ('OFSP', 'Properties.stx')
        },
        {
            'label': 'View',
            'action': 'index_html'
        },
        {
            'label': 'Migrations',
            'action': 'manage_migrate_html'
        },
        {
            'label': 'Updates',
            'action': 'manage_update_combo_answers_html'
        },
        {
            'label': 'Security',
            'action': 'manage_access',
            'help': ('OFSP', 'Security.stx')
        },
    )

    security = ClassSecurityInfo()

    notify_owner = True
    notify_respondents = 'LET_THEM_CHOOSE_YES'
    allow_overtime = 0
    allow_drafts = False
    allow_anonymous = False
    allow_multiple_answers = False

    def __init__(self, id, survey_template, lang=None, **kwargs):
        """
            @param id: id
            @param survey_template: id of the survey template
        """
        self.id = id
        self._survey_template = survey_template

        self.save_properties(lang=lang, **kwargs)
        NyContainer.__dict__['__init__'](self)
        self.imageContainer = NyImageContainer(self, True)

    #
    # Self edit methods
    #
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties')

    def saveProperties(self, REQUEST=None, **kwargs):
        """ """
        if REQUEST:
            kwargs.update(REQUEST.form)
            kwargs.setdefault('contributor',
                              REQUEST.AUTHENTICATED_USER.getUserName())

        lang = kwargs.get('lang', self.get_selected_language())

        kwargs.setdefault('title', '')
        kwargs.setdefault('description', '')
        kwargs.setdefault('keywords', '')
        kwargs.setdefault('coverage', '')
        kwargs.setdefault('sortorder', DEFAULT_SORTORDER)

        releasedate = kwargs.get('releasedate', DateTime())
        releasedate = self.process_releasedate(releasedate)
        kwargs['releasedate'] = releasedate

        expirationdate = kwargs.get('expirationdate', DateTime())
        expirationdate = self.process_releasedate(expirationdate)
        kwargs['expirationdate'] = expirationdate

        self.save_properties(**kwargs)
        self.updatePropertiesFromGlossary(lang)
        self.recatalogNyObject(self)

        if REQUEST:
            # Log date
            contributor = REQUEST.AUTHENTICATED_USER.getUserName()
            auth_tool = self.getAuthenticationTool()
            auth_tool.changeLastPost(contributor)
            # Redirect
            self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES,
                                     date=self.utGetTodayDate())
            REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' %
                                      (self.absolute_url(), lang))

    #
    # Methods required by the Naaya framework
    #
    security.declareProtected(view, 'hasVersion')

    def hasVersion(self):
        """ """
        return False

    security.declareProtected(view, 'getVersionLocalProperty')

    def getVersionLocalProperty(self, id, lang):
        """ """
        return self.getLocalProperty(id, lang)

    security.declareProtected(view, 'getVersionProperty')

    def getVersionProperty(self, id):
        """ """
        return getattr(self, id, '')

    #
    # Answer edit methods
    #

    security.declareProtected(view, 'canAddAnswerDraft')

    def canAddAnswerDraft(self):
        """ Check if current user can add an answer draft """
        auth_tool = self.getAuthenticationTool()
        return self.allow_drafts and not auth_tool.isAnonymousUser()

    security.declareProtected(PERMISSION_ADD_ANSWER, 'addSurveyAnswerDraft')

    def addSurveyAnswerDraft(self,
                             REQUEST=None,
                             notify_respondent=False,
                             **kwargs):
        """This is just to be able to specify submit method in zpt"""
        return self.addSurveyAnswer(REQUEST,
                                    notify_respondent,
                                    draft=True,
                                    **kwargs)

    messages_html = NaayaPageTemplateFile('zpt/survey_messages', globals(),
                                          'NaayaSurvey.survey_messages')

    security.declareProtected(PERMISSION_ADD_ANSWER, 'addSurveyAnswer')

    def addSurveyAnswer(self,
                        REQUEST=None,
                        notify_respondent=False,
                        draft=False,
                        **kwargs):
        """Add someone's answer"""
        translate = self.getPortalI18n().get_translation
        if REQUEST:
            kwargs.update(REQUEST.form)

        # check survey expiration
        if self.expired() and not self.checkPermissionPublishObjects():
            error_msg = translate("The survey has expired")
            if not REQUEST:
                raise SurveyQuestionnaireException(error_msg)
            self.setSessionErrorsTrans(error_msg)
            REQUEST.RESPONSE.redirect(self.absolute_url())
            return

        # check datamodel
        datamodel = {}
        errors = []
        if self.allow_anonymous and not self.isAnonymousUser():
            anonymous_answer = kwargs.get('anonymous_answer')
            if anonymous_answer not in [0, 1]:
                errors.append(
                    translate(
                        'Please specify if you want your answer to be anonymous'
                    ))

        for widget in self.getWidgets():
            try:
                value = widget.getDatamodel(kwargs)
                if not draft:
                    widget.validateDatamodel(value)
            except WidgetError, ex:
                if not REQUEST:
                    raise
                value = None
                errors.append(translate(ex.message))
            datamodel[widget.getWidgetId()] = value
        if draft:
            if not self.canAddAnswerDraft():
                error_msg = translate(
                    "Can't add draft (not logged in or not allowed)")
                if not REQUEST:
                    raise SurveyQuestionnaireException(error_msg)
                errors.append(error_msg)
        else:
            try:
                validation_onsubmit = self['validation_onsubmit']
            except KeyError:
                pass
            else:
                validation_onsubmit(datamodel, errors)

        if not REQUEST and errors:
            raise WidgetError(errors[0])

        # check Captcha/reCaptcha
        if REQUEST and not self.checkPermission(PERMISSION_SKIP_CAPTCHA):
            captcha_errors = self.getSite().validateCaptcha('', REQUEST)
            if captcha_errors:
                errors.append(captcha_errors)

        answer_id = kwargs.pop('answer_id', None)
        if errors:
            # assumed that REQUEST is not None
            self.setSessionErrorsTrans(errors)
            self.setSessionAnswer(datamodel)
            self.setSession('notify_respondent', notify_respondent)
            if answer_id is not None:
                answer = self._getOb(answer_id)
                REQUEST.RESPONSE.redirect('%s?edit=1' % answer.absolute_url())
            else:
                REQUEST.RESPONSE.redirect(self.absolute_url())
            return

        suggestions = []
        cf_approval_list = []
        if getattr(self, 'meeting_eionet_survey', None):
            respondent = REQUEST.get('respondent')
        else:
            respondent = None
        creation_date = None
        anonymous_editing_key = None
        if answer_id is not None:
            old_answer = self._getOb(answer_id)
            respondent = old_answer.respondent
            cf_approval_list = getattr(old_answer, 'cf_approval_list', [])
            suggestions = getattr(old_answer, 'suggestions', [])
            anonymous_editing_key = getattr(old_answer,
                                            'anonymous_editing_key', None)
            if not getattr(old_answer, 'draft', False):
                creation_date = old_answer.get('creation_date')
            # an answer ID was provided explicitly for us to edit, so we
            # remove the old one
            self._delObject(answer_id)
            LOG('NaayaSurvey.SurveyQuestionnaire', DEBUG,
                'Deleted previous answer %s while editing' % answer_id)

        if not self.allow_multiple_answers:
            # look for all old answers and remove them
            # (there can be more than one because of a previous bug)
            while True:
                old_answer = self.getAnswerForRespondent(respondent=respondent,
                                                         all=True)
                if old_answer is None:
                    break
                else:
                    self._delObject(old_answer.id)
                    LOG(
                        'NaayaSurvey.SurveyQuestionnaire', DEBUG,
                        'Deleted previous answer %s' %
                        old_answer.absolute_url())

        # If we are in edit mode, keep the answer_id from the "old answer"
        answer_id = manage_addSurveyAnswer(self,
                                           datamodel,
                                           REQUEST=REQUEST,
                                           draft=draft,
                                           respondent=respondent,
                                           id=answer_id,
                                           creation_date=creation_date)

        answer = self._getOb(answer_id)

        if suggestions:
            answer.suggestions = suggestions
        if cf_approval_list:
            answer.cf_approval_list = cf_approval_list
        if self.allow_anonymous and not self.isAnonymousUser():
            answer.anonymous_answer = bool(anonymous_answer)

        if self.isAnonymousUser():
            if anonymous_editing_key:
                answer.anonymous_editing_key = anonymous_editing_key
            anonymous_responder_email = kwargs.pop('anonymous_responder_email',
                                                   None)
            if anonymous_responder_email:
                answer.anonymous_responder_email = anonymous_responder_email
                if not answer.get('anonymous_editing_key'):
                    answer.anonymous_editing_key = self.utGenRandomId(16)
                    self.sendNotificationToUnauthenticatedRespondent(answer)
        elif not draft:
            if (self.notify_respondents == 'ALWAYS'
                    or (self.notify_respondents.startswith('LET_THEM_CHOOSE')
                        and notify_respondent)):
                self.sendNotificationToRespondent(answer)
        if self.notify_owner:
            self.sendNotificationToOwner(answer)

        if REQUEST:
            self.delSessionKeys(datamodel.keys())
            if not draft:
                if self.aq_parent.meta_type == 'Naaya Meeting':
                    self.setSessionInfoTrans('Thank you for taking the survey')
                    REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url())
                else:
                    self.setSession('title', 'Thank you for taking the survey')
                    if answer.anonymous_answer:
                        self.setSession('body',
                                        'You answer was recorded anonymously')
                    self.setSession('referer', self.absolute_url())
                    REQUEST.RESPONSE.redirect('%s/messages_html' %
                                              self.absolute_url())
            else:
                REQUEST.RESPONSE.redirect('%s?edit=1' % answer.absolute_url())
        return answer_id
Ejemplo n.º 9
0
 def validateDatamodel(self, value):
     """Validate datamodel"""
     if self.required and not value:
         raise WidgetError('Value required for "%s"' % self.title)