Ejemplo n.º 1
0
    def afterSetUp(self):
        self.my_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                             'my_tmpl')
        self.second_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                                 'second_tmpl')

        NyDocument.my_tmpl = self.my_tmpl
        NyDocument.second_tmpl = self.second_tmpl
Ejemplo n.º 2
0
 def afterSetUp(self):
     self.my_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                          'my_tmpl')
     NyDocument.my_tmpl = self.my_tmpl
     self.second_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                              'second_tmpl')
     NyDocument.second_tmpl = self.second_tmpl
Ejemplo n.º 3
0
class NaayaTemplateTestCase(NaayaTestCase.NaayaTestCase):
    def afterSetUp(self):
        self.my_tmpl = NaayaPageTemplateFile('the_template', globals(), 'my_tmpl')
        NyDocument.my_tmpl = self.my_tmpl

    def beforeTearDown(self):
        if hasattr(NyDocument, 'my_tmpl'):
            del NyDocument.my_tmpl

    def test_default(self):
        output = self.my_tmpl.__of__(self.portal)(a="26")
        self.assertTrue('[physical path: /portal]' in output)
        self.assertTrue('[option a: 26]' in output)

        output = self.portal.info.contact.my_tmpl(a="13")
        self.assertTrue('[physical path: /portal/info/contact]' in output)
        self.assertTrue('[option a: 13]' in output)

    def test_customize(self):
        forms_tool = self.portal.portal_forms
        ids = [f['id'] for f in forms_tool.listDefaultForms()]
        self.assertTrue('my_tmpl' in ids)
        my_tmpl_aq = forms_tool.getForm('my_tmpl')
        self.assertTrue(my_tmpl_aq.aq_self is NyDocument.my_tmpl)
        self.assertTrue(my_tmpl_aq.aq_parent is forms_tool)

        forms_tool.manage_customizeForm('my_tmpl')
        forms_tool.my_tmpl.pt_edit(text='new content', content_type='text/html')
        self.assertEqual(self.portal.info.contact.my_tmpl().strip(),
                         'new content')
Ejemplo n.º 4
0
class LogEntry(SimpleItem, UtilsManager):
    """LogEntry class"""

    meta_type = 'LogEntry'
    icon = 'misc_/NaayaLinkChecker/logentry'

    manage_options = ({
        'label': 'View',
        'action': 'index_html',
    }, )

    security = ClassSecurityInfo()

    def __init__(self, id, user, date_create, url_list):
        """Constructor"""
        self.id = id
        self.title = 'Log Entry at %s' % self.umFormatDateTimeToString(
            date_create)
        self.user = user
        self.date_create = date_create
        self.url_list = url_list
        UtilsManager.__dict__['__init__'](self)

    security.declareProtected(view, 'index_html')
    index_html = NaayaPageTemplateFile('zpt/LogEntry_index', globals(),
                                       'linkchecker_log_index')
Ejemplo n.º 5
0
class ExpertsLister(Implicit, Item):
    """
    Plug into the catalog to retrieve the list of experts
    """
    def __init__(self, id):
        self.id = id

    _index_template = NaayaPageTemplateFile('zpt/experts_list', globals(),
                                            'expert')

    def index_html(self, REQUEST):
        """ Render the list of organisations recorded for this site.  """
        return self._index_template(REQUEST, experts=[1, 2, 3])

    def items_in_topic(self, topic=None, filter_name=None, objects=False):
        filters = {'meta_type': 'Naaya Expert', 'approved': True}
        if topic is not None:
            filters['topics'] = topic
        if filter_name is not None:
            filters['title'] = '*%s*' % filter_name

        catalog = self.getCatalogTool()
        if objects:
            items = [catalog.getobject(ob.data_record_id_)
                     for ob in catalog.search(filters)]
            return sorted(items, key=lambda ob: ob.surname.strip().lower())
        else:
            return catalog.search(filters)
Ejemplo n.º 6
0
class ObjectListingPortlet(object):

    title = 'List contained objects'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        return self.template.__of__(context)()

    template = NaayaPageTemplateFile('zpt/listing_portlet', globals(),
                                     'naaya.core.folder.listing_portlet')
Ejemplo n.º 7
0
class InvitationsContainer(SimpleItem):
    security = ClassSecurityInfo()

    title = "Consultation invitations"

    def __init__(self, id):
        super(SimpleItem, self).__init__(id)
        self.id = id
        self._invites = OOBTree()

    _create_html = NaayaPageTemplateFile('zpt/invitations_create', globals(),
                                         'tbconsultation_invitations_create')
    security.declareProtected(PERMISSION_INVITE_TO_TALKBACKCONSULTATION,
                              'create')

    def create(self, REQUEST):
        """ Create an invitation, send e-mail """
        keys = ('name', 'email', 'organization', 'notes', 'message')
        formerrors = {}
        previews = []

        if REQUEST.REQUEST_METHOD == 'POST':
            do_preview = (REQUEST.form.get('do', '') == 'Preview')

            inviter_userid, inviter_name = self._get_inviter_info()

            formdata = dict((key, REQUEST.form.get(key, '')) for key in keys)
            kwargs = dict(formdata,
                          web_form=True,
                          inviter_userid=inviter_userid,
                          inviter_name=inviter_name)

            try:
                if do_preview:
                    preview = self._send_invitation(preview=True, **kwargs)
                    preview['preview_attribution'] = '%s (invited by %s)' % \
                        (formdata['name'], inviter_name)
                    previews.append(preview)
                else:
                    self._send_invitation(**kwargs)
                    self.setSessionInfoTrans(
                        'Invitation for ${name} '
                        'has been sent.',
                        name=formdata['name'])
                    return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                                     '/create')
            except FormError, e:
                self.setSessionErrorsTrans('The form contains errors. Please '
                                           'correct them and try again.')
                formerrors = dict(e.errors)

        else:
Ejemplo n.º 8
0
def register_naaya_content(_context, factory, **kwargs):
    """ Register a naaya content type.

    This is called for each content type using it's config dictionary. This will
    validate the config of the content type, perform a few sanity checks,
    declare the permissions for the content type and register the templates.

    """

    assert factory, "No factory provided"
    assert callable(factory), "Factory must be callable"
    config = factory()

    assert 'meta_type' in config, "Config must contain at least a meta_type"

    _contents = NaayaContent._contents
    _misc = NaayaContent._misc
    _constants = NaayaContent._constants

    _contents[config['meta_type']] = config
    _misc.update(config.get('_misc', {}))

    # register _misc into Zope
    if not Application.misc_.__dict__.has_key('NaayaContent'):
        Application.misc_.__dict__['NaayaContent'] = Misc_('NaayaContent',
                _misc)
    else:
        Application.misc_.__dict__['NaayaContent'].__dict__['_d'].update(_misc)

    # used by site_header
    _constants['METATYPE_FOLDER'] = 'Naaya Folder'

    security = ClassSecurityInfo()
    NyFolderBase.security = security

    # declare permissions for object constructors
    if (config['meta_type'] != 'Naaya Folder' and
        'folder_constructors' in config):
        for folder_property, object_constructor in config['folder_constructors']:
            setattr(NyFolderBase, folder_property, object_constructor)
            NyFolderBase.security.declareProtected(config['permission'],
                    folder_property)
    # register forms
    for form in config.get('forms', []):
        NaayaPageTemplateFile(os.path.join(config['package_path'], 'zpt', form),
                globals(), form)

    InitializeClass(NyFolderBase)
    # log success
    zLOG.LOG('naaya.content', zLOG.DEBUG,
            'Pluggable content type "%s" registered' % config['meta_type'])
Ejemplo n.º 9
0
class CHMTermsTagCloudPortlet(object):
    interface.implements(INyPortlet)
    component.adapts(ICHMSite)

    title = 'CHM Terms'

    def __init__(self, site):
        self.site = site

    def chm_terms_frequency(self):
        attribute = 'chm_terms'
        separator = '|'
        lang = self.site.gl_get_selected_language()

        objects = self.site.getCatalogedObjectsCheckView(meta_type=[
            'Naaya Folder', 'Naaya Photo Folder', 'Naaya Photo Gallery',
            'Naaya Contact', 'Naaya Survey', 'Naaya Educational Product',
            'Naaya News', 'Naaya Story', 'Naaya File', 'Naaya URL',
            'Naaya Extended File', 'Naaya Document', 'Naaya Event',
            'Naaya Media File', 'Naaya Pointer', 'Naaya Blob File',
            'Naaya Localized Blob File', 'Naaya GeoPoint'
        ])

        ret = {}
        for ob in objects:
            if ob.hasLocalProperty(attribute):
                value = ob.getLocalAttribute(attribute, lang)
            elif hasattr(ob, attribute):
                value = getattr(ob, attribute)
            else:
                continue

            if not value or not isinstance(value, basestring):
                continue

            for raw_term in value.split(separator):
                term = raw_term.strip()
                ret.setdefault(term, 0)
                ret[term] += 1

        return ret

    def __call__(self, context, position):
        macro = self.site.getPortletsTool()._get_macro(position)
        return self.template.__of__(context)(macro=macro,
                                             tags=self.chm_terms_frequency())

    template = NaayaPageTemplateFile(
        'skel/portlets/portlet_chmterms_tagcloud', globals(),
        'Products.CHM2.portlets.portlet_chmterms_tagcloud')
Ejemplo n.º 10
0
class MainSectionsPortlet(object):
    interface.implements(INyPortlet)
    component.adapts(INySite)

    title = 'Main sections'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        macro = self.site.getPortletsTool()._get_macro(position)
        return self.template.__of__(context)(macro=macro)

    template = NaayaPageTemplateFile('zpt/mainsections_portlet', globals(),
                                     'naaya.core.mainsections_portlet')
Ejemplo n.º 11
0
class ObjectListingPortlet(object):
    implements(INyPortlet)
    adapts(IEWSite)

    title = 'List contained objects'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        return self.template.__of__(context)()

    template = NaayaPageTemplateFile(
        'zpt/listing_portlet', globals(),
        'naaya.envirowindows.folder.listing_portlet')
Ejemplo n.º 12
0
class AdministrationPortlet(object):
    interface.implements(INyPortlet)
    component.adapts(ICHMBESite)

    title = 'Administration'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        macro = self.site.getPortletsTool()._get_macro(position)
        return self.template.__of__(context)(macro=macro)

    template = NaayaPageTemplateFile('skel/portlets/portlet_administration', globals(),
                                     'Products.CHM2BE.portlets.portlet_administration')
Ejemplo n.º 13
0
class NavigationPortlet(object):
    implements(INyPortlet)
    adapts(INySite)

    title = 'Navigation'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        macro = self.site.getPortletsTool()._get_macro(position)
        return self.template.__of__(context)(macro=macro)

    template = NaayaPageTemplateFile('zpt/navigation_portlet', globals(),
                                     'naaya.groupware.navigation_portlet')
Ejemplo n.º 14
0
class OrganisationLister(Implicit, Item):

    _index_template = NaayaPageTemplateFile('zpt/organisations_list',
                                            globals(), 'organisation')
    """
    Plug into the catalog to retrieve the list of organisations
    Render the list of organisations recorded for this site.
    """
    def __init__(self, id):
        self.id = id

    def index_html(self, REQUEST):
        """ Index page """
        return self._index_template(REQUEST)

    def items_in_topic(self, topic=None, filter_name=None, objects=False):
        filters = {'meta_type': METATYPE_OBJECT, 'approved': True}
        if topic is not None:
            default_lang = self.gl_get_default_language()
            default_lang_name = self.gl_get_language_name(default_lang)
            glossary = self.getSite().chm_terms
            try:
                item_brains = glossary.getObjectByCode(topic)
                if item_brains:
                    #if the topic is a glossary element, the list is not empty
                    #this list should contain only one object if the id is unique
                    glossary_item = item_brains[0].getObject()
                else:
                    #the topic is a glossary folder
                    glossary_item = getattr(glossary, topic)
                topic_title = glossary_item.get_translation_by_language(
                    default_lang_name)
                filters['topics'] = topic_title
            except AttributeError:
                #an invalid topic was passed
                return None
        if filter_name is not None:
            filters['title'] = '*%s*' % filter_name

        catalog = self.getCatalogTool()
        if objects:
            items = [
                catalog.getobject(ob.data_record_id_)
                for ob in catalog.search(filters)
            ]
            return sorted(items, key=lambda ob: ob.title.strip().lower())
        else:
            return catalog.search(filters)
Ejemplo n.º 15
0
class AdministrationPortlet(object):
    implements(INyPortlet)
    adapts(IGWSite)

    title = 'Administration'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        macro = self.site.getPortletsTool()._get_macro(position)
        return self.template.__of__(context)(macro=macro)

    template = NaayaPageTemplateFile(
        'skel/portlets/portlet_administration', globals(),
        'naaya.groupware.portlets.portlet_administration')
Ejemplo n.º 16
0
def register_templates_in_directory(templates_path, bundle_name):
    """ Register all templates found in a folder. """

    from Products.NaayaCore.FormsTool.NaayaTemplate import NaayaPageTemplateFile

    if not os.path.isdir(templates_path):
        return

    count = 0
    for filename in os.listdir(templates_path):
        fileroot, ext = os.path.splitext(filename)
        if ext in ('.zpt', '.pt', ):
            tmpl_path = os.path.join(templates_path, filename)
            NaayaPageTemplateFile(tmpl_path, globals(), fileroot, bundle_name)
            count += 1

    if count:
        log.debug("Loaded %d templates from %r into bundle %r",
                  count, templates_path, bundle_name)
Ejemplo n.º 17
0
class NotificationsPortlet(object):
    title = 'Subscribe to notifications'

    def __init__(self, site):
        self.site = site

    def __call__(self, context, position):
        notif_tool = self.site.getNotificationTool()
        #The portlet should only be rendered if at least one notification type
        #is activated, of if the user has administrative rights, so he should
        #be able to subscribe to administrative notifications
        if not list(notif_tool.available_notif_types()) and not \
                    self.site.checkPermissionPublishObjects():
            return ''

        macro = self.site.getPortletsTool()._get_macro(position)
        tmpl = self.template.__of__(context)
        location = path_in_site(context)
        if context == notif_tool:
            location = ''
        return tmpl(macro=macro, notif_tool=notif_tool,
                    location=location)

    template = NaayaPageTemplateFile('zpt/portlet', globals(), 'naaya.core.notifications.notifications_portlet')
Ejemplo n.º 18
0
from events import ItemTranslationChanged

# constants
LABEL_OBJECT = 'Glossary element'


class ElementBasic:
    """ define the basic properties for NyGlossaryElement """
    def __init__(self, title, source, contributor):
        """ constructor """
        self.title = title
        self.source = source
        self.contributor = contributor


manage_addGlossaryElement_html = NaayaPageTemplateFile(
    'zpt/NaayaGlossaryElement/add', globals(), 'glossary_element_add')


def manage_addGlossaryElement(self,
                              id='',
                              title='',
                              source='',
                              subjects=[],
                              contributor='',
                              approved=1,
                              REQUEST=None):
    """ adds a new NyGlossaryElement object """
    ob = NyGlossaryElement(id, title, source, subjects, contributor, approved)
    self._setObject(id, ob)
    element_obj = self._getOb(id)
    element_obj.subjects = self.get_subject_by_codes(subjects)
Ejemplo n.º 19
0
class MegaSurvey(SurveyQuestionnaire, BaseSurveyTemplate):
    """ """

    meta_type = 'Naaya Mega Survey'
    meta_label = 'Survey'

    _constructors = (manage_addMegaSurvey, )

    security = ClassSecurityInfo()

    edit_access = NyAccess(
        'edit_access', {
            PERMISSION_ADD_ANSWER: "Submit answer",
            PERMISSION_ADD_REPORT: "Create report",
            PERMISSION_ADD_ATTACHMENT: "Attach file",
            PERMISSION_VIEW_ANSWERS: "View answers",
            PERMISSION_EDIT_ANSWERS: "Edit answers",
            PERMISSION_VIEW_REPORTS: "View reports",
        })

    def __init__(self, id, **kwargs):
        """ """
        # BaseSurveyTemplate.__init__(self, id, **kwargs)
        SurveyQuestionnaire.__init__(self, id, None, **kwargs)
        self.contributor = kwargs.get('contributor')
        self.approved = 1

    def can_be_seen(self):
        """
        Indicates if the current user has access to the current folder.

        """
        return self.checkPermission(view)

    def all_meta_types(self, interfaces=None):
        """What can you put inside me?"""
        return BaseSurveyTemplate.all_meta_types(self, interfaces)

    def getSurveyTemplate(self):
        """ """
        return self

    security.declareProtected(view, 'download')

    def download(self, REQUEST=None, RESPONSE=None):
        """returns all the answers in a csv file"""
        def stringify(value):
            if not isinstance(value, basestring):
                value = unicode(value)
            if isinstance(value, str):
                return unicode(value, 'utf-8')
            return value

        def all_stringify(row):
            return [stringify(value) for value in row]

        answers = self.getAnswers()
        widgets = self.getSortedWidgets()
        header = ['Respondent']
        for widget in widgets:
            header += [widget.title_or_id()]
            if widget.meta_type == 'Naaya Radio Matrix Widget':
                header += widget.rows
        rows = [answer.answer_values() for answer in answers]
        rows = [all_stringify(item) for item in rows]

        file_type = REQUEST.get('file_type', 'CSV')
        if file_type == 'CSV':
            RESPONSE.setHeader('Content-Type', 'text/csv')
            RESPONSE.setHeader('Content-Disposition',
                               'attachment; filename=%s.csv' % self.id)
            return generate_csv(header, rows)
        if file_type == 'Excel' and self.rstk.we_provide('Excel export'):
            RESPONSE.setHeader('Content-Type', 'application/vnd.ms-excel')
            RESPONSE.setHeader('Content-Disposition',
                               'attachment; filename=%s.xls' % self.id)
            return generate_excel(header, rows)
        else:
            raise ValueError('unknown file format %r' % file_type)

    #
    # Site pages
    #
    security.declareProtected(view, 'index_html')

    def index_html(self):
        """ """
        if (not self.checkPermissionSkipCaptcha()
                and not self.recaptcha_is_present()):
            raise ValueError("Invalid recaptcha keys")
        return self._index_html()

    _index_html = NaayaPageTemplateFile('zpt/megasurvey_index', globals(),
                                        'NaayaSurvey.megasurvey_index')

    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html')
    edit_html = NaayaPageTemplateFile('zpt/megasurvey_edit', globals(),
                                      'NaayaSurvey.megasurvey_edit')

    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_attachments_html')
    edit_attachments_html = NaayaPageTemplateFile(
        'zpt/megasurvey_edit_attachments', globals(),
        'NaayaSurvey.megasurvey_edit_attachments')

    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_questions_html')
    edit_questions_html = NaayaPageTemplateFile(
        'zpt/megasurvey_edit_questions', globals(),
        'NaayaSurvey.megasurvey_edit_questions')

    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_reports_html')
    edit_reports_html = NaayaPageTemplateFile(
        'zpt/megasurvey_edit_reports', globals(),
        'NaayaSurvey.megasurvey_edit_reports')

    #
    # change the security of the inherited methods
    #
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'addWidget')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'deleteItems')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'setSortOrder')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'addReport')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'generateFullReport')
    security.declareProtected(PERMISSION_EDIT_OBJECTS, 'addAttachment')

    # static files
    css_survey_common = DTMLFile('www/survey_common.css', globals())
    css_survey_print = DTMLFile('www/survey_print.css', globals())
    fancy_checkmark = ImageFile('www/fancy_checkmark.gif', globals())
    survey_js = ImageFile('www/survey.js', globals())

    security.declareProtected(PERMISSION_EDIT_ANSWERS, 'bogus')

    def bogus(self):
        """ Needed in Naaya Access. It is mandatory that a permission must be
        declared so it can be used in Naaya Access.
        This should be removed once this issue is solved

        """
        pass

    security.declarePublic('display_admin_warning')

    def display_admin_warning(self):
        return self.checkPermissionPublishObjects()\
            and self.anonymous_has_access()\
            and not self.recaptcha_is_present()\
            and not self.anonymous_skips_captcha()

    security.declarePublic('anonymous_has_access')

    def anonymous_has_access(self):
        return 'Anonymous' in self.edit_access.getPermissionMapping(
        )['Naaya - Add Naaya Survey Answer']

    security.declarePublic('anonymous_skips_captcha')

    def anonymous_skips_captcha(self):
        permission = 'Naaya - Skip Captcha'
        permission_object = Permission(permission, (), self)
        return 'Anonymous' in permission_object.getRoles()

    security.declarePrivate('dont_inherit_view_permission')

    def dont_inherit_view_permission(self):
        permission = Permission(view, (), self)
        roles = permission.getRoles()
        roles = tuple(set(roles) | set(['Manager', 'Administrator', 'Owner']))
        permission.setRoles(roles)

    security.declarePrivate('inherit_view_permission')

    def inherit_view_permission(self):
        permission = Permission(view, (), self)
        roles = permission.getRoles()
        roles = list(roles)
        permission.setRoles(roles)
Ejemplo n.º 20
0
from Products.NaayaBase.NyAccess import NyAccess
from Products.NaayaCore.FormsTool.NaayaTemplate import NaayaPageTemplateFile
from Products.NaayaCore.managers.import_export import generate_csv
from Products.NaayaCore.managers.import_export import generate_excel

from Products.NaayaWidgets.constants import PERMISSION_ADD_WIDGETS
from BaseSurveyTemplate import BaseSurveyTemplate
from SurveyQuestionnaire import SurveyQuestionnaire
from permissions import (PERMISSION_ADD_MEGASURVEY, PERMISSION_ADD_ANSWER,
                         PERMISSION_ADD_REPORT, PERMISSION_ADD_ATTACHMENT,
                         PERMISSION_VIEW_ANSWERS, PERMISSION_EDIT_ANSWERS,
                         PERMISSION_VIEW_REPORTS)

log = logging.getLogger(__name__)

megasurvey_add_html = NaayaPageTemplateFile('zpt/megasurvey_add', globals(),
                                            'NaayaSurvey.megasurvey_add')


def manage_addMegaSurvey(context,
                         id='',
                         title='',
                         lang=None,
                         REQUEST=None,
                         **kwargs):
    """ """
    title = title or 'Survey'
    id = make_id(context, id=id, title=title)

    # Get selected language
    lang = REQUEST and REQUEST.form.get('lang', None)
    lang = lang or kwargs.get('lang', context.gl_get_selected_language())
Ejemplo n.º 21
0
    'default_schema': DEFAULT_SCHEMA,
    'schema_name': 'NyInfoFolder',
    '_module': sys.modules[__name__],
    'additional_style': AdditionalStyle('www/InfoFolder.css', globals()),
    'icon': os.path.join(os.path.dirname(__file__), 'www', 'NyInfoFolder.gif'),
    'on_install': setupContentType,
    '_misc': {
        'NyInfoFolder.gif':
        ImageFile('www/NyInfoFolder.gif', globals()),
        'NyInfoFolder_marked.gif':
        ImageFile('www/NyInfoFolder_marked.gif', globals()),
    },
}

#Portal portlets
NaayaPageTemplateFile('zpt/latest_uploads_portlet', globals(),
                      'naaya.content-sdo.infofolder.latest_uploads_portlet')
NaayaPageTemplateFile(
    'zpt/infofolder_search_portlet', globals(),
    'naaya.content-sdo.infofolder.infofolder_search_portlet')
NaayaPageTemplateFile('zpt/events_filter', globals(),
                      'naaya.content-sdo.infofolder.events_filter')
NaayaPageTemplateFile('zpt/submit_site_portlet', globals(),
                      'naaya.content-sdo.infofolder.submit_site_portlet')


def infofolder_add_html(self, REQUEST=None, RESPONSE=None):
    """ """
    form_helper = get_schema_helper_for_metatype(self, config['meta_type'])
    return self.getFormsTool().getContent(
        {
            'here': self,
Ejemplo n.º 22
0
    def handleUpload(self, file):
        """
        Upload a file from disk.
        """
        filename = getattr(file, 'filename', '')
        if not filename:
            return
        self.manage_delObjects(self.objectIds())
        file_id = cookId('', '', file)[0]  #cleanup id
        self.manage_addFile(id=file_id, file=file)


InitializeClass(NySemNews)

#Custom folder listing
NaayaPageTemplateFile('zpt/semnews_folder_index', globals(),
                      'semnews_folder_index')

config.update({
    'constructors': (manage_addNySemNews_html, addNySemNews),
    'folder_constructors': [
        ('manage_addNySemNews_html', manage_addNySemNews_html),
        ('semnews_add_html', semnews_add_html),
        ('addNySemNews', addNySemNews),
        ('import_NySemNews', importNySemNews),
    ],
    'add_method':
    addNySemNews,
    'validation':
    issubclass(NySemNews, NyValidation),
    '_class':
    NySemNews,
Ejemplo n.º 23
0
class NaayaTemplateTestCase(NaayaTestCase.NaayaTestCase):
    def afterSetUp(self):
        self.my_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                             'my_tmpl')
        NyDocument.my_tmpl = self.my_tmpl
        self.second_tmpl = NaayaPageTemplateFile('the_template', globals(),
                                                 'second_tmpl')
        NyDocument.second_tmpl = self.second_tmpl


    def beforeTearDown(self):
        del NyDocument.my_tmpl
        del NyDocument.second_tmpl
        del FormsTool.naaya_templates['my_tmpl']
        del FormsTool.naaya_templates['second_tmpl']

    def test_default(self):
        output = self.my_tmpl.__of__(self.portal)(a="26")
        self.assertTrue('[physical path: /portal]' in output)
        self.assertTrue('[option a: 26]' in output)

        output = self.portal.info.contact.my_tmpl(a="13")
        self.assertTrue('[physical path: /portal/info/contact]' in output)
        self.assertTrue('[option a: 13]' in output)

    def test_customize(self):
        forms_tool = self.portal.portal_forms
        ids = [f['id'] for f in forms_tool.listDefaultForms()]
        self.assertTrue('my_tmpl' in ids)
        my_tmpl_aq = forms_tool.getForm('my_tmpl')
        self.assertTrue(my_tmpl_aq.aq_self is NyDocument.my_tmpl)
        self.assertTrue(my_tmpl_aq.aq_parent is forms_tool)

        forms_tool.manage_customizeForm('my_tmpl')
        forms_tool.my_tmpl.pt_edit(text='new content', content_type='text/html')
        self.assertEqual(self.portal.info.contact.my_tmpl().strip(),
                         'new content')

    def test_template_traversal(self):
        forms_tool = self.portal.getFormsTool()

        # Customize 2nd template to include a macro def
        second_tmpl = forms_tool['second_tmpl']
        my_tmpl = forms_tool['my_tmpl']
        self.assertEqual(second_tmpl, forms_tool.getForm('second_tmpl'))
        forms_tool.manage_customizeForm('second_tmpl')
        text = ('<metal:block define-macro="hole">'
                'Bugs Bunny</metal:block>')
        forms_tool.second_tmpl.pt_edit(text=text, content_type='text/html')

        # Customize 1st template to include previous macro in several ways
        forms_tool.manage_customizeForm('my_tmpl')
        text = ('<tal:block metal:use-macro="'
                "python:here.getFormsTool().getForm('second_tmpl')"
                ".macros['hole']\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output =self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)

        text = ('<tal:block metal:use-macro="'
                "python:here.getFormsTool()['second_tmpl']"
                ".macros['hole']\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output = self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)

        text = ('<tal:block metal:use-macro="'
                "here/portal_forms/second_tmpl/"
                "macros/hole\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output = self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)
Ejemplo n.º 24
0
class NaayaPage(DiggPage, Implicit):
    security = ClassSecurityInfo()

    security.declareProtected(view, 'pagination')
    pagination = NaayaPageTemplateFile('zpt/pagination', globals(),
                                       'naaya.core.pagination')
Ejemplo n.º 25
0
        ]
        rows = []
        participants = self.getAttendees()
        for participant in participants:
            part_info = self.getAttendeeInfo(participant)
            participant_info = [
                part_info['uid'], part_info['name'], part_info['email'],
                part_info['organization'], part_info['role'], '',
                part_info['phone'], '', '', '', '', '', '', '', '', '', '',
                country_from_country_code.get(part_info['country'], ''), '',
                '', '', part_info['uid'], ''
            ]
            rows.append(participant_info)

        filename = '%s_%s_%s.csv' % (self.getMeeting().getId(
        ), self.id, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
        RESPONSE.setHeader('Content-Type', 'text/csv')
        RESPONSE.setHeader('Content-Disposition',
                           'attachment; filename=%s' % filename)
        return generate_csv(header, rows)


InitializeClass(Participants)

NaayaPageTemplateFile('zpt/participants_index', globals(),
                      'naaya.content.meeting.participants_index')
NaayaPageTemplateFile('zpt/participants_pickrole', globals(),
                      'naaya.content.meeting.participants_pickrole')
NaayaPageTemplateFile('zpt/participants_table', globals(),
                      'naaya.content.meeting.participants_table')
Ejemplo n.º 26
0
class AnalyticsTool(SimpleItem, utils):
    """ """

    meta_type = METATYPE_ANALYTICSTOOL
    icon = 'misc_/NaayaCore/AnalyticsTool.gif'

    security = ClassSecurityInfo()

    _google_access_token = None
    _google_refresh_token = None
    profile_code = None
    profile = None

    def __init__(self, id, title):
        """ """
        self.id = id
        self.title = title
        self._reset()

    def _reset(self):
        self.account = None
        self.date_interval = 30
        self.start_date = ''
        self.ga_id = ''  # Google Analytics web property ID (UA-number)
        self.gw_verify = ''  # Google Webmaster verification meta tag
        self._google_access_token = None
        self._google_refresh_token = None
        self.profile_code = None
        self.profile = None
        self.clear_cache()

    #cache
    def _set_cache(self, data, view_name):
        self._cache[view_name] = data
        self._cache_timestamp = datetime.datetime.now()

    security.declarePrivate('get_cache')

    def get_cache(self, view_name):
        interval = datetime.datetime.now() - self._cache_timestamp
        if interval.days > 0:
            return None
        return self._cache.get(view_name, None)

    security.declarePrivate('get_cache')

    def clear_cache(self):
        self._cache = {}
        self._cache_timestamp = datetime.datetime.now()

    #administration
    def index_html(self, REQUEST):
        """ redirect to admin_account """
        REQUEST.RESPONSE.redirect(self.absolute_url() + '/admin_account')

    _admin_account_zpt = NaayaPageTemplateFile('zpt/account', globals(),
                                               'site_admin_account')
    _admin_verify = NaayaPageTemplateFile('zpt/verify', globals(),
                                          'site_admin_verify')
    _stats_info = NaayaPageTemplateFile('zpt/stats_info', globals(),
                                        'site_admin_stats_info')

    _admin_stats = NaayaPageTemplateFile('zpt/stats', globals(),
                                         'site_admin_stats')

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'admin_stats')

    def admin_stats(self, REQUEST):
        """ """
        if self._google_access_token is None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/authorize')
            return
        elif self.profile is None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/admin_account')
            return
        return self._admin_stats()

    _authorize = NaayaPageTemplateFile('zpt/authorize', globals(),
                                       'site_admin_stats_authorize')

    def authorize(self):
        """ """
        is_configured = bool('GOOGLE_AUTH_CLIENT_ID' in os.environ
                             and 'GOOGLE_AUTH_CLIENT_SECRET' in os.environ)
        return self._authorize(is_configured=is_configured)

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'stats_info')

    def stats_info(self):
        """ """
        view_name = 'stats'
        cached_data = self.get_cache(view_name=view_name)
        if cached_data is None:
            # no data in the cache, so cache it
            data_to_cache = self._stats_info(self.REQUEST)
            self._set_cache(data_to_cache, view_name=view_name)
            return data_to_cache
        # get cached data
        return cached_data

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'admin_verify')

    def admin_verify(self, REQUEST):
        """ Administration page for Google verification codes """
        if REQUEST.has_key('save'):
            self.ga_id = REQUEST.get('ga_id', '')
            self.gw_verify = REQUEST.get('gw_verify', '')
            self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES,
                                     date=self.utGetTodayDate())
        return self._admin_verify(REQUEST)

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'admin_account')

    def admin_account(self, REQUEST):
        """ Administration page for Google accounts """
        if self._google_access_token is None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/authorize')
            return

        options = {}
        if self.profile is None:
            options.update(choose_profile=True, accounts=self.getAccounts())

        else:
            options.update(choose_profile=False, profile_name="")
            profile_info = self._get_profile_info(self.account,
                                                  self.profile_code)
            if profile_info is not None:
                options['profile_name'] = profile_info['name']

        return self._admin_account_zpt(REQUEST, **options)

    def _update_access_token(self):
        if self._google_access_token is None:
            raise RuntimeError("Google access token is not set.")
        access_token, expiry = self._google_access_token
        if time.time() > expiry:
            code = self._google_refresh_token
            data = {
                'grant_type': 'refresh_token',
                'client_id': os.environ['GOOGLE_AUTH_CLIENT_ID'],
                'client_secret': os.environ['GOOGLE_AUTH_CLIENT_SECRET'],
                'refresh_token': code,
            }
            resp = requests.post(GOOGLE_TOKEN_URI, data)
            self._save_access_token(resp)
            access_token, expiry = self._google_access_token

        return access_token

    def _api_get(self, path, params={}):
        access_token = self._update_access_token()
        url = GOOGLE_ANALYTICS_API + path
        headers = {'Authorization': 'Bearer ' + access_token}
        resp = requests.get(url, params=params, headers=headers)
        if resp.status_code != 200:
            raise RuntimeError("API call error: %r (%r)" % (resp, resp.json))
        return resp.json

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getAccounts')

    def getAccounts(self):
        """ get accounts list """
        resp_json = self._api_get('management/accounts')
        return [(i['id'], i['name']) for i in resp_json['items']]

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getProfiles')

    def getProfiles(self, account, REQUEST=None):
        """ """
        resp_json = self._api_get('management/accounts/%s/webproperties' %
                                  account)
        data = {
            'profiles': [{
                'code': i['id'],
                'name': i['name']
            } for i in resp_json['items']]
        }

        if REQUEST is not None:
            return json_response(data, REQUEST.RESPONSE)
        else:
            return data

    def _get_profile_info(self, account, profile_code):
        resp_json = self._api_get('management/accounts/%s/'
                                  'webproperties/%s/profiles' %
                                  (account, profile_code))
        if 'items' not in resp_json:
            return None
        else:
            return resp_json['items'][0]

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'admin_account_save')

    def admin_account_save(self,
                           account=None,
                           profile_code=None,
                           date_interval='30',
                           start_date='',
                           REQUEST=None):
        """ """
        if account:
            self.account = account

        if profile_code and self.profile is None:
            # We check `self.profile is None` in order to disallow changing
            # a profile. De-authorize the account first.
            profile_info = self._get_profile_info(self.account, profile_code)
            if profile_info is None:
                self.setSessionErrorsTrans(
                    "The site you selected is not available.")
            else:
                self.profile_code = profile_code
                self.profile = profile_info['id']

        if start_date:
            self.start_date = start_date
            self.date_interval = 0
        else:
            self.date_interval = int(date_interval or '30')
            self.start_date = ''
        if self.account or self.start_date or self.date_interval:
            self.clear_cache()  #clear cached data
            self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES,
                                     date=self.utGetTodayDate())

        if REQUEST is not None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/admin_account')

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS,
                              'admin_account_revoke')

    def admin_account_revoke(self, REQUEST=None):
        """ """
        self._reset()
        if REQUEST is not None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/admin_account')

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'generateAuthUrl')

    def generateAuthUrl(self):
        """ generate authentication URL """
        query = {
            'response_type': 'code',
            'client_id': os.environ['GOOGLE_AUTH_CLIENT_ID'],
            'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
            'scope': GOOGLE_SCOPE,
            'access_type': 'offline',
        }
        return ('https://accounts.google.com/o/oauth2/auth?' +
                urllib.urlencode(query))

    def _save_access_token(self, resp):
        if 'error' in resp.json:
            raise RuntimeError("Error fetching new token: %r" %
                               resp.json['error'])
        assert resp.json['token_type'] == 'Bearer'
        expiry = time.time() + resp.json['expires_in']
        self._google_access_token = (resp.json['access_token'], expiry)
        if 'refresh_token' in resp.json:
            self._google_refresh_token = resp.json['refresh_token']

        import transaction
        transaction.get().note('(Saving new Google oauth2 token)')

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS,
                              'saveAuthorizationCode')

    def saveAuthorizationCode(self, code, REQUEST=None):
        """ """
        data = {
            'grant_type': 'authorization_code',
            'client_id': os.environ['GOOGLE_AUTH_CLIENT_ID'],
            'client_secret': os.environ['GOOGLE_AUTH_CLIENT_SECRET'],
            'code': code,
            'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
            'scope': GOOGLE_SCOPE,
        }
        resp = requests.post(GOOGLE_TOKEN_URI, data)
        self._save_access_token(resp)

        if REQUEST is not None:
            REQUEST.RESPONSE.redirect(self.absolute_url() + '/admin_account')

    def _api_get_ga_data(self, params):
        sd, ed = self.get_date_interval()
        params.setdefault('ids', 'ga:' + self.profile)
        params.setdefault('start-date', sd.strftime('%Y-%m-%d'))
        params.setdefault('end-date', ed.strftime('%Y-%m-%d'))
        return self._api_get('data/ga', params=params)

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getVisitsGraph')

    def getVisitsGraph(self):
        """ Get the visitors graph """
        sd, ed = self.get_date_interval()
        data = self._api_get_ga_data({
            'dimensions': 'ga:date',
            'metrics': 'ga:visits',
            'sort': 'ga:date',
        })
        valid = False
        if 'rows' in data:
            maximum = 0
            res = []
            for row in data['rows']:
                visit_value = int(row[1])
                if visit_value > maximum:
                    maximum = visit_value
                if visit_value and not valid:
                    valid = True  #check for 0 values
                res.append(row[1])
            if valid:
                #chart values, y-axis maxi value, y-axis intermediate values, x-axis labels
                return ','.join(res), maximum * 1.1, '||%s|%s|%s|%s|' % (
                    maximum / 3, maximum / 2, 2 * maximum / 3,
                    maximum), '|%s|%s|' % (sd.strftime('%d %b'),
                                           ed.strftime('%d %b'))

    security.declareProtected(view, 'getSiteSummary')

    def getSiteSummary(self):
        """ Get esential date about site usage """
        view_name = 'summary'
        if self.profile is None:
            return None

        cached_data = self.get_cache(view_name=view_name)
        if cached_data is not None:
            return cached_data

        data = self._api_get_ga_data({
            'metrics':
            'ga:visits,ga:visitors,ga:pageviews,ga:timeOnSite',
        })
        if 'rows' in data:
            #take the first entry
            [stats] = self._data_rows(data)
            res = {
                'visits':
                formatter.format(float(stats['ga:visits'])),
                'visitors':
                formatter.format(float(stats['ga:visitors'])),
                'pageviews':
                formatter.format(float(stats['ga:pageviews'])),
                'timeOnSite':
                humanize_time(
                    float(stats['ga:timeOnSite']) / float(stats['ga:visits'])),
            }
            # no data in the cache, so cache it
            self._set_cache(res, view_name=view_name)
            return res

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getSiteUsage')

    def getSiteUsage(self):
        """ Get the site usage """
        data = self._api_get_ga_data({
            'metrics': ('ga:visits,ga:bounces,ga:pageviews,'
                        'ga:timeOnSite,ga:newVisits,ga:entrances'),
        })
        if 'rows' in data:
            #take the first entry
            [stats] = self._data_rows(data)
            bounce_rate = (float(stats['ga:bounces']) /
                           float(stats['ga:entrances']) * 100)
            pages_visit = (float(stats['ga:pageviews']) /
                           float(stats['ga:visits']))
            newVisits = (float(stats['ga:newVisits']) /
                         float(stats['ga:visits']) * 100)
            return {
                'visits':
                formatter.format(float(stats['ga:visits'])),
                'bounces':
                '%.2f%%' % bounce_rate,
                'pages_visit':
                '%.2f' % pages_visit,
                'pageviews':
                formatter.format(float(stats['ga:pageviews'])),
                'timeOnSite':
                humanize_time(
                    float(stats['ga:timeOnSite']) / float(stats['ga:visits'])),
                'newVisits':
                '%.2f%%' % newVisits,
            }

    def _data_rows(self, data):
        columns = [c['name'] for c in data['columnHeaders']]
        for row in data['rows']:
            yield dict(zip(columns, row))

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getTopPages')

    def getTopPages(self):
        """ Get the top pages """
        data = self._api_get_ga_data({
            'dimensions': 'ga:pagePath',
            'metrics': 'ga:pageviews',
            'sort': 'ga:date',
            'sort': '-ga:pageviews',
            'max_results': '10',
        })
        if 'rows' in data:
            res = []
            for row in self._data_rows(data):
                res.append({
                    'pagePath':
                    row['ga:pagePath'],
                    'pageviews':
                    formatter.format(float(row['ga:pageviews']))
                })
            return res, ''

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getTopReferers')

    def getTopReferers(self):
        """ Get the top referers """
        data = self._api_get_ga_data({
            'dimensions': 'ga:source',
            'metrics': 'ga:visits',
            'filters': 'ga:medium==referral',
            'sort': '-ga:visits',
            'max_results': '10',
        })
        if 'rows' in data:
            res = []
            for row in self._data_rows(data):
                res.append({
                    'source': row['ga:source'],
                    'visits': formatter.format(float(row['ga:visits']))
                })
            return res

    security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'getTopSearches')

    def getTopSearches(self):
        """ Get the top searches """
        data = self._api_get_ga_data({
            'dimensions': 'ga:keyword',
            'metrics': 'ga:visits',
            'filters': 'ga:keyword!=(not set)',
            'sort': '-ga:visits',
            'max_results': '10',
        })
        if 'rows' in data:
            res = []
            for row in self._data_rows(data):
                res.append({
                    'keyword': row['ga:keyword'],
                    'visits': formatter.format(float(row['ga:visits']))
                })
            return res

    security.declarePublic('get_date_interval')

    def get_date_interval(self):
        """ """
        end_date = datetime.datetime.today()
        if self.start_date:
            sd = time.strptime(self.start_date, '%d/%m/%Y')
            start_date = datetime.datetime(*sd[0:6])
        else:
            start_date = end_date - datetime.timedelta(days=self.date_interval)
        return start_date, end_date

    security.declarePublic('get_intervals')

    def get_intervals(self):
        """ """
        return INTERVALS
Ejemplo n.º 27
0
class NotificationTool(Folder):
    """ """

    meta_type = core_constants.METATYPE_NOTIFICATIONTOOL
    icon = 'misc_/NaayaCore/NotificationTool.gif'

    meta_types = ()
    all_meta_types = meta_types

    security = ClassSecurityInfo()

    # default configuration settings
    default_config = {
        'admin_on_error': True,
        'admin_on_edit': True,
        'enable_instant': True,
        'enable_daily': True,
        'enable_anonymous': False,  # Enable anonymous notifications
        'daily_hour': 0,
        'enable_weekly': True,
        'weekly_day': 1,  # 1 = monday, 7 = sunday
        'weekly_hour': 0,
        'enable_monthly': True,
        'monthly_day': 1,  # 1 = first day of the month
        'monthly_hour': 0,
        'notif_content_types': [],
    }

    def __init__(self, id, title):
        """ """
        self.id = id
        self.title = title
        self.config = PersistentDict(self.default_config)
        self.timestamps = PersistentDict()
        # Confirmations list
        self.pending_anonymous_subscriptions = PersistentList()

    def get_config(self, key):
        return self.config.get(key)

    def get_location_link(self, location):
        if location:
            return self.restrictedTraverse(location,
                                           self.getSite()).absolute_url()
        else:
            return self.getSite().absolute_url()

    def _validate_subscription(self, **kw):
        """ Validate add/edit subscription for authorized and anonymous users

        """
        if (kw['notif_type'] not in self.available_notif_types(kw['location'])
                and not (kw['notif_type'] == 'administrative'
                         and self.checkPermissionPublishObjects())):
            raise i18n_exception(ValueError, 'Subscribing to ${notif_type} '
                                 'notifications in "${location}" not allowed',
                                 location=kw['location']
                                 or self.getSite().title,
                                 notif_type=kw['notif_type'])
        try:
            obj = self.getSite().restrictedTraverse(kw['location'])
        except:
            raise i18n_exception(ValueError,
                                 'This path is invalid or protected')
        try:
            subscription_container = ISubscriptionContainer(obj)
        except:
            raise i18n_exception(ValueError, 'Cannot subscribe to this folder')

        if kw.get('anonymous', False):
            # Check if subscription exists for this anonymous subscriber
            if not is_valid_email(kw.get('email', '')):
                raise i18n_exception(
                    ValueError, 'Your e-mail address does not appear '
                    'to be valid.')
            for id, subscription in subscription_container.list_with_keys():
                # Normal subscriptions don't have e-mail
                if isinstance(subscription, AnonymousSubscription):
                    if (subscription.email == kw['email']
                            and subscription.notif_type == kw['notif_type']
                            and subscription.lang == kw['lang']):
                        raise i18n_exception(ValueError,
                                             'Subscription already exists')

    def _sitemap_dict(self, form):
        """ Compose a sitemap dict """

        node = form.get('node', '')
        if not node or node == '/':
            node = ''

        def traverse(objects, level=0, stop_level=2, exclude_root=False):
            """ Create a dict with node properties and children.
            This is a fixed level recursion. On some sites there are a lot of
            objects so we don't need to get the whole tree.

            """

            res = []
            for ob in objects:
                if ISubscriptionTarget.providedBy(ob) is False:
                    continue
                children_objects = []
                if level != stop_level:  # Stop if the level is reached
                    # Create a list of object's children
                    if hasattr(ob, 'objectValues'):
                        # Get only naaya container objects
                        for child in ob.objectValues(
                                self.get_naaya_containers_metatypes()):
                            # Skip unsubmited/unapproved
                            if not getattr(child, 'approved', False):
                                continue
                            elif not getattr(child, 'submitted', False):
                                continue
                            else:
                                children_objects.append(child)

                if hasattr(ob, 'approved'):
                    icon = ob.approved and ob.icon or ob.icon_marked
                else:
                    icon = ob.icon

                children = traverse(children_objects, level + 1, stop_level)

                if exclude_root:  # Return only the children if this is set
                    return children

                res.append({
                    'data': {
                        'title':
                        self.utStrEscapeHTMLTags(
                            self.utToUtf8(ob.title_or_id())),
                        'icon':
                        icon
                    },
                    'attributes': {
                        'title': path_in_site(ob)
                    },
                    'children': children
                })
            return res

        if node == '':
            tree_dict = traverse([self.getSite()])
        else:
            tree_dict = traverse([self.restrictedTraverse(node)],
                                 exclude_root=True)
        return tree_dict

    security.declarePublic('sitemap')

    def sitemap(self, REQUEST=None, **kw):
        """ Return a json (for Ajax tree) representation of published objects
        marked with `ISubscriptionTarget` including the portal organized in a
        tree (sitemap)

        """

        form = {}
        if REQUEST is not None:
            form = REQUEST.form
            REQUEST.RESPONSE.setHeader('content-type', 'application/json')
        else:
            form.update(kw)
        return json.dumps(self._sitemap_dict(form))

    security.declarePrivate('add_account_subscription')

    def add_account_subscription(self,
                                 user_id,
                                 location,
                                 notif_type,
                                 lang,
                                 content_types=[]):
        """ Subscribe the user `user_id` """
        self._validate_subscription(user_id=user_id,
                                    location=location,
                                    notif_type=notif_type,
                                    lang=lang,
                                    content_types=content_types)

        try:
            self.remove_account_subscription(user_id, location, notif_type,
                                             lang)
        except ValueError:
            pass

        obj = self.getSite().restrictedTraverse(location)
        subscription_container = ISubscriptionContainer(obj)
        subscription = AccountSubscription(user_id, notif_type, lang,
                                           content_types)
        subscription_container.add(subscription)

    security.declarePrivate('add_anonymous_subscription')

    def add_anonymous_subscription(self, **kw):
        """ Handle anonymous users """
        self._validate_subscription(anonymous=True, **kw)
        subscription = AnonymousSubscription(**kw)
        # Add to temporary container
        self.pending_anonymous_subscriptions.append(subscription)

        # Send email
        email_tool = self.getSite().getEmailTool()
        email_from = email_tool.get_addr_from()
        email_template = EmailPageTemplateFile('emailpt/confirm.zpt',
                                               globals())
        email_data = email_template.render_email(**{
            'key': subscription.key,
            'here': self
        })
        email_to = subscription.email
        email_tool.sendEmail(email_data['body_text'], email_to, email_from,
                             email_data['subject'])

    security.declarePrivate('remove_account_subscription')

    def remove_account_subscription(self,
                                    user_id,
                                    location,
                                    notif_type,
                                    lang,
                                    content_types=None):
        obj = self.getSite().restrictedTraverse(location)
        subscription_container = ISubscriptionContainer(obj)
        n = utils.match_account_subscription(subscription_container, user_id,
                                             notif_type, lang, content_types)
        if n is None:
            raise ValueError('Subscription not found')
        subscription_container.remove(n)

    security.declarePrivate('unsubscribe_links_html')
    unsubscribe_links_html = PageTemplateFile("emailpt/unsubscribe_links.zpt",
                                              globals())
    security.declarePrivate('remove_anonymous_subscription')

    def remove_anonymous_subscription(self, email, location, notif_type, lang):
        try:
            obj = self.getSite().restrictedTraverse(location)
        except:
            raise i18n_exception(ValueError, 'Invalid location')

        try:
            subscription_container = ISubscriptionContainer(obj)
        except:
            raise i18n_exception(ValueError, 'Invalid container')
        anonymous_subscriptions = [
            (n, s) for n, s in subscription_container.list_with_keys()
            if hasattr(s, 'email')
        ]
        subscriptions = filter(
            lambda s: (s[1].email == email and s[1].location == location and s[
                1].notif_type == notif_type), anonymous_subscriptions)
        if len(subscriptions) == 1:
            subscription_container.remove(subscriptions[0][0])
        else:
            raise i18n_exception(ValueError, 'Subscription not found')

    security.declareProtected(view, 'available_notif_types')

    def available_notif_types(self, location=''):
        if self.config['enable_instant']:
            yield 'instant'
        if self.config['enable_daily']:
            yield 'daily'
        if self.config['enable_weekly']:
            yield 'weekly'
        if self.config['enable_monthly']:
            yield 'monthly'

    security.declarePrivate('notify_maintainer')

    def notify_maintainer(self, ob, folder, **kwargs):
        """
        Process and notify by email that B{p_object} has been
        uploaded into the B{p_folder}.
        """

        auth_tool = self.getSite().getAuthenticationTool()
        emails = self.getMaintainersEmails(ob)
        person = self.REQUEST.AUTHENTICATED_USER.getUserName()
        if len(emails) > 0:
            maintainers_data = {}
            for email in emails:
                maintainers_data[email] = {
                    'ob':
                    ob,
                    'here':
                    self,
                    'person':
                    auth_tool.name_from_userid(person),
                    'ob_edited':
                    kwargs.get('ob_edited'),
                    'approved':
                    ob.approved,
                    'container_basket':
                    '%s/basketofapprovals_html' % folder.absolute_url(),
                }
            notif_logger.info('Maintainer notifications on %r', ofs_path(ob))
            template = self._get_template('maintainer')
            self._send_notifications(maintainers_data, template)

    security.declarePrivate('notify_comment_maintainer')

    def notify_comment_maintainer(self, comment, parent, **kwargs):
        """
        Process and notify by email that a comment B{comemnt} has been added
        to the object B{parent}.
        """

        auth_tool = self.getSite().getAuthenticationTool()
        emails = self.getMaintainersEmails(parent)
        if len(emails) > 0:
            maintainers_data = {}
            for email in emails:
                maintainers_data[email] = {
                    'parent':
                    parent,
                    'here':
                    self,
                    'comment':
                    comment,
                    'person':
                    auth_tool.name_from_userid(comment.author),
                    'container_basket':
                    '%s/basketofapprovals_html' % parent.absolute_url(),
                }
            notif_logger.info('Maintainer comment notifications on %r',
                              ofs_path(parent))
            template = self._get_template('maintainer')
            self._send_notifications(maintainers_data, template)

    security.declarePrivate('notify_administrative')

    def notify_administrative(self, ob, user_id, ob_edited=False):
        """
        send administrative notifications because object `ob` was added or
        edited by the user `user_id`
        """

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self,
            ob,
            notif_type='administrative',
            **{
                'person':
                auth_tool.name_from_userid(user_id),
                'ob_edited':
                ob_edited,
                'approved':
                ob.approved,
                'container_basket':
                '%s/basketofapprovals_html' % ob.aq_parent.absolute_url(),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Administrative notifications on %r',
                              ofs_path(ob))
            template = self._get_template('administrative')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_comment_administrative')

    def notify_comment_administrative(self, comment, parent, user_id):
        """
        send administrative notifications because a comment was added to
        object `ob` by the user `user_id`
        """

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self,
            parent,
            notif_type='administrative',
            **{
                'comment': comment,
                'parent': parent,
                'here': self,
                'person': auth_tool.name_from_userid(user_id),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Administrative comment notifications on %r',
                              ofs_path(parent))
            template = self._get_template('administrative')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_instant')

    def notify_instant(self, ob, user_id, ob_edited=False):
        """
        send instant notifications because object `ob` was changed by
        the user `user_id`
        """
        if not self.config['enable_instant']:
            return

        # Don't send notifications if the object is unapproved, but store them
        # into a queue to send them later when it becomes approved
        if not ob.approved:
            return

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self, ob, **{
                'person': auth_tool.name_from_userid(user_id),
                'ob_edited': ob_edited,
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Instant notifications on %r', ofs_path(ob))
            template = self._get_template('instant')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_comment_instant')

    def notify_comment_instant(self, comment, parent, user_id):
        """
        send instant notifications because a comment was added to
        object `ob` by the user `user_id`
        """
        if not self.config['enable_instant']:
            return

        # Don't send notifications if the object is unapproved, but store them
        # into a queue to send them later when it becomes approved
        if not parent.approved:
            return

        auth_tool = self.getSite().getAuthenticationTool()
        subscribers_data = utils.get_subscribers_data(
            self, parent, **{
                'comment': comment,
                'parent': parent,
                'person': auth_tool.name_from_userid(user_id),
            })

        if len(subscribers_data.keys()) > 0:
            notif_logger.info('Comment instant notifications on %r',
                              ofs_path(parent))
            template = self._get_template('instant')
            self._send_notifications(subscribers_data, template)

    security.declarePrivate('notify_account_modification')

    def notify_account_modification(self,
                                    email,
                                    obj,
                                    username=None,
                                    new_roles=[],
                                    removed_roles=[]):
        """
        Send notification that the user received or lost one or more roles
        in the specified location
        """
        email_data = {
            email: {
                'new_roles': new_roles,
                'removed_roles': removed_roles,
                'username': username,
                'obj': obj,
            }
        }

        notif_logger.info('Account modification notification on %s' %
                          self.getSite().getId())
        template = self._get_template('account_modified')
        self._send_notifications(email_data, template)

    def _get_template(self, name):

        template = self._getOb('emailpt_%s' % name, None)
        if template is not None:
            return template.render_email

        template = self._getOb(name, None)
        if template is not None:
            return template.render_email

        template = email_templates.get(name, None)
        if template is not None:
            return template.render_email

        raise ValueError('template for %r not found' % name)

    def _send_notifications(self, messages_by_email, template):
        """
        Send the notifications described in the `messages_by_email` data
        structure, using the specified EmailTemplate.

        `messages_by_email` should be a dictionary, keyed by email
        address. The values should be dictionaries suitable to be passed
        as kwargs (options) to the template.
        """
        portal = self.getSite()
        email_tool = portal.getEmailTool()
        addr_from = email_tool.get_addr_from()
        for addr_to, kwargs in messages_by_email.iteritems():
            translate = self.portal_i18n.get_translation
            kwargs.update({'portal': portal, '_translate': translate})
            mail_data = template(**kwargs)
            notif_logger.info('.. sending notification to %r', addr_to)
            utils.send_notification(email_tool, addr_from, addr_to,
                                    mail_data['subject'],
                                    mail_data['body_text'])

    def _send_newsletter(self, notif_type, when_start, when_end):
        """
        We'll look in the ``Products.Naaya.NySite.getActionLogger`` for object
        creation/modification log entries. Then we'll send notifications for
        the period between `when_start` and `when_end` using the
        `notif_type` template.

        """
        notif_logger.info(
            'Notifications newsletter on site %r, type %r, '
            'from %s to %s', ofs_path(self.getSite()), notif_type, when_start,
            when_end)
        objects_by_email = {}
        langs_by_email = {}
        subscriptions_by_email = {}
        anonymous_users = {}
        for log_type, ob in utils.get_modified_objects(self.getSite(),
                                                       when_start, when_end):
            notif_logger.info('.. modified object: %r', ofs_path(ob))
            for subscription in utils.fetch_subscriptions(ob, inherit=True):
                if subscription.notif_type != notif_type:
                    continue
                if not subscription.check_permission(ob):
                    continue
                email = subscription.get_email(ob)
                if email is None:
                    continue
                content_types = getattr(subscription, 'content_types', [])
                if content_types and ob.meta_type not in content_types:
                    continue
                notif_logger.info('.. .. sending newsletter to %r', email)
                objects_by_email.setdefault(email, []).append({
                    'ob': ob,
                    'type': log_type,
                })
                langs_by_email[email] = subscription.lang

                subscriptions_by_email[email] = subscription
                anonymous_users[email] = isinstance(subscription,
                                                    AnonymousSubscription)

        messages_by_email = {}
        for email in objects_by_email:
            messages_by_email[email] = {
                'objs': objects_by_email[email],
                '_lang': langs_by_email[email],
                'subscription': subscriptions_by_email[email],
                'here': self,
                'anonymous': anonymous_users[email]
            }

        template = self._get_template(notif_type)
        self._send_notifications(messages_by_email, template)

    def _cron_heartbeat(self, when):
        transaction.commit()  # commit earlier stuff; fresh transaction
        transaction.get().note('notifications cron at %s' % ofs_path(self))

        # Clean temporary subscriptions after a week:
        if self.config.get('enable_anonymous', False):
            a_week_ago = when - timedelta(weeks=1)
            for tmp_subscription in self.pending_anonymous_subscriptions[:]:
                if tmp_subscription.datetime <= a_week_ago:
                    self.pending_anonymous_subscriptions.remove(
                        tmp_subscription)

        #  daily newsletter ###
        if self.config['enable_daily']:
            # calculate the most recent daily newsletter time
            daily_time = time(hour=self.config['daily_hour'])
            latest_daily = datetime.combine(when.date(), daily_time)
            if latest_daily > when:
                latest_daily -= timedelta(days=1)

            # check if we should send a daily newsletter
            prev_daily = self.timestamps.get('daily', when - timedelta(days=1))
            if prev_daily < latest_daily < when:
                self._send_newsletter('daily', prev_daily, when)
                self.timestamps['daily'] = when

        #  weekly newsletter ###
        if self.config['enable_weekly']:
            # calculate the most recent weekly newsletter time
            weekly_time = time(hour=self.config['daily_hour'])
            t = datetime.combine(when.date(), weekly_time)
            days_delta = self.config['weekly_day'] - t.isoweekday()
            latest_weekly = t + timedelta(days=days_delta)
            if latest_weekly > when:
                latest_weekly -= timedelta(weeks=1)

            # check if we should send a weekly newsletter
            prev_weekly = self.timestamps.get('weekly',
                                              when - timedelta(weeks=1))
            if prev_weekly < latest_weekly < when:
                self._send_newsletter('weekly', prev_weekly, when)
                self.timestamps['weekly'] = when

        #  monthly newsletter ###
        if self.config['enable_monthly']:
            # calculate the most recent monthly newsletter time
            monthly_time = time(hour=self.config['monthly_hour'])
            the_day = utils.set_day_of_month(when.date(),
                                             self.config['monthly_day'])
            latest_monthly = datetime.combine(the_day, monthly_time)
            if latest_monthly > when:
                latest_monthly = utils.minus_one_month(latest_monthly)

            # check if we should send a monthly newsletter
            prev_monthly = self.timestamps.get('monthly',
                                               utils.minus_one_month(when))
            if prev_monthly < latest_monthly < when:
                self._send_newsletter('monthly', prev_monthly, when)
                self.timestamps['monthly'] = when

        transaction.commit()  # make sure our timestamp updates are saved

    def index_html(self, RESPONSE):
        """ redirect to admin page """
        RESPONSE.redirect(self.absolute_url() + '/my_subscriptions_html')

    security.declareProtected(view, 'my_subscriptions_html')
    my_subscriptions_html = NaayaPageTemplateFile(
        'zpt/index', globals(), 'naaya.core.notifications.my_subscriptions')

    security.declarePrivate('list_user_subscriptions')

    def user_subscriptions(self, user, cutoff_level=None):
        """
        Returns all user subscriptions in the portal.
        Use with caution as this iterates almost all the objects in site.
        You can use `cutoff_level` to limit the depth.

        """
        out = []
        user_id = user.getId()
        for obj, n, subscription in utils.walk_subscriptions(
                self.getSite(), cutoff_level):
            if not isinstance(subscription, AccountSubscription):
                continue
            if subscription.user_id != user_id:
                continue
            out.append({
                'object':
                obj,
                'notif_type':
                subscription.notif_type,
                'content_types':
                getattr(subscription, 'content_types', []),
                'lang':
                subscription.lang
            })

        return out

    security.declareProtected(view, 'user_not_found')

    def user_not_found(self, REQUEST):
        """
        Returns True if the user is not Anonymous, but is still not found by
        the AuthenticationTool (i.e. is maybe defined in the Zope root)

        """
        user = REQUEST.AUTHENTICATED_USER
        if not isinstance(user, basestring):
            # with LDAP authentication, user is LDAP user instance
            user = user.id
        acl_tool = self.getAuthenticationTool()
        if acl_tool.get_user_with_userid(user) is None:
            return True

    security.declareProtected(view, 'list_my_subscriptions')

    def list_my_subscriptions(self, REQUEST):
        """
        Returns a list of mappings (location, notif_type, lang)
        for all subscriptions of logged-in user

        """
        user = REQUEST.AUTHENTICATED_USER
        if user.getId() is None and not self.config.get(
                'enable_anonymous', False):
            raise Unauthorized  # to force login

        subscriptions = self.user_subscriptions(user)
        for subscription in subscriptions:
            subscription['location'] = path_in_site(subscription['object'])
            del subscription['object']

        return subscriptions

    security.declareProtected(view, 'my_first_subscription')

    def get_location_subscription(self, location, notif_type=None):
        """
        Returns the first of the authenticated user's subscriptions in location

        """
        for subscription in self.list_my_subscriptions(self.REQUEST):
            if subscription['location'] == location:
                if notif_type:
                    if subscription['notif_type'] == notif_type:
                        return subscription
                else:
                    return subscription

    security.declareProtected(view, 'subscribe_me')

    def subscribe_me(self,
                     REQUEST,
                     location,
                     notif_type,
                     lang=None,
                     content_types=[]):
        """ add subscription for currently-logged-in user """
        # Even if some content types were selected (by turning off javascript)
        # they should be ignored, no filtering in administrative notifications
        if notif_type == 'administrative':
            content_types = []
        if isinstance(content_types, basestring):
            content_types = [content_types]
        if lang is None:
            lang = self.gl_get_selected_language()
            REQUEST.form['lang'] = lang
        user_id = REQUEST.AUTHENTICATED_USER.getId()
        if location == '/':
            location = ''
        if user_id is None and not self.config.get('enable_anonymous', False):
            raise Unauthorized  # to force login
        try:
            if user_id:
                self.add_account_subscription(user_id, location, notif_type,
                                              lang, content_types)
                if content_types:
                    self.setSessionInfoTrans(
                        'You will receive ${notif_type} notifications'
                        ' for any changes in "${location}" for objects of '
                        'types ${content_types}.',
                        notif_type=notif_type,
                        location=location or self.getSite().title,
                        content_types=', '.join(content_types))
                else:
                    self.setSessionInfoTrans(
                        'You will receive ${notif_type} notifications'
                        ' for any changes in "${location}".',
                        notif_type=notif_type,
                        location=location)
            else:
                self.add_anonymous_subscription(**dict(REQUEST.form))
                self.setSessionInfoTrans(
                    'An activation e-mail has been sent to ${email}. '
                    'Follow the instructions to subscribe to ${notif_type} '
                    'notifications for any changes in "${location}".',
                    notif_type=notif_type,
                    location=location,
                    content_types=content_types,
                    email=REQUEST.form.get('email'))
        except ValueError, msg:
            self.setSessionErrors([unicode(msg)])
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/my_subscriptions_html')
Ejemplo n.º 28
0
from Products.NaayaCore.FormsTool.NaayaTemplate import NaayaPageTemplateFile

_admin_assign_role = NaayaPageTemplateFile('zpt/site_admin_editor_role',
                                           globals(), 'site_admin_editor_role')


def admin_assign_role(context, REQUEST):
    orig_id = REQUEST.get('orig_id')
    object_paths = REQUEST.get('object_paths', [])
    new_users = REQUEST.get('new_users', [])
    messages = []
    options = {}
    user_list = context.getAuthenticationTool().getUsers()
    users = {}
    for user in user_list:
        users[user.name] = {
            'name': user.firstname + ' ' + user.lastname,
            'email': user.email
        }
    user_ids = sorted(users.keys(), key=lambda x: x.lower())
    if orig_id == '':
        messages.append('Please select a user to search for content.')
        orig_id = None
    options['users'] = users
    options['user_ids'] = user_ids
    if not orig_id:
        options['messages'] = messages
        return _admin_assign_role.__of__(context)(REQUEST, **options)
    if REQUEST.has_key('assign_role'):
        if isinstance(object_paths, basestring):
            object_paths = [object_paths]
Ejemplo n.º 29
0
    security.declarePublic('checkPermissionAddAnswer')

    def checkPermissionAddAnswer(self):
        """Check if the user has the ADD_ANSWER permission"""
        return self.checkPermission(PERMISSION_ADD_ANSWER)

    def checkPermissionEditAnswers(self):
        """ Check if the user has  EDIT_ANSWER permission"""
        return self.checkPermission(PERMISSION_EDIT_ANSWERS)

    #
    # Site pages
    #
    security.declareProtected(PERMISSION_VIEW_REPORTS, 'view_reports_html')
    view_reports_html = NaayaPageTemplateFile(
        'zpt/questionnaire_view_reports', globals(),
        'NaayaSurvey.questionnaire_view_reports')

    security.declareProtected(PERMISSION_VIEW_ANSWERS, 'view_answers_html')
    view_answers_html = NaayaPageTemplateFile(
        'zpt/questionnaire_view_answers', globals(),
        'NaayaSurvey.questionnaire_view_answers')

    manage_main = folder_manage_main_plus
    ny_before_listing = PageTemplateFile('zpt/questionnaire_manage_header',
                                         globals())

    security.declareProtected(view_management_screens,
                              'manage_create_validation_html')

    def manage_create_validation_html(self, REQUEST=None):
Ejemplo n.º 30
0
class NyGlossaryElement(SimpleItem, ElementBasic, utils, catalog_utils):
    """ NyGlossaryElement """

    interface.implements(INyGlossaryElement)
    meta_type = NAAYAGLOSSARY_ELEMENT_METATYPE
    meta_label = LABEL_OBJECT
    product_name = NAAYAGLOSSARY_PRODUCT_NAME
    icon = 'misc_/NaayaGlossary/element.gif'

    manage_options = (
        {
            'label': 'Translations',
            'action': 'translations_html'
        },
        {
            'label': 'Properties',
            'action': 'properties_html'
        },
        {
            'label': "View",
            'action': 'index_html'
        },
        {
            'label': 'Undo',
            'action': 'manage_UndoForm'
        },
    )

    security = ClassSecurityInfo()

    def __init__(self, id, title, source, subjects, contributor, approved):
        """ constructor """
        self.id = id
        self.subjects = subjects
        self.approved = approved
        ElementBasic.__dict__['__init__'](self, title, source, contributor)

    def is_published(self):
        return self.approved

    #####################
    #  BASIC PROPERTIES #
    #####################
    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'manageBasicProperties')

    def manageBasicProperties(self,
                              title='',
                              source='',
                              subjects=[],
                              contributor='',
                              approved=0,
                              further_references='',
                              REQUEST=None):
        """ manage basic properties for NyGlossaryElement """
        self.title = title
        self.source = source
        self.subjects = self.get_subject_by_codes(subjects)
        self.contributor = contributor
        self.approved = approved
        self.further_references = further_references
        self._p_changed = 1
        self.cu_recatalog_object(self)
        if REQUEST:
            return REQUEST.RESPONSE.redirect('properties_html?save=ok')

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'approveElement')

    def approveElement(self, REQUEST=None):
        """ used for approval link in basket of approvals"""
        self.approved = 1
        if REQUEST:
            return REQUEST.RESPONSE.redirect('index_approvals_html')

    #########################
    #     THEME FUNCTIONS   #
    #########################
    def code_in_subjects(self, code):
        """ check if code is in the list """
        for subj_info in self.subjects:
            if subj_info['code'] == code:
                return 1
        return 0

    def get_subjects(self):
        """ get the languages """
        self.utSortListOfDictionariesByKey(self.subjects, 'code')
        return self.subjects

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY, 'set_subjects')

    def set_subjects(self, code, name):
        """ set the languages """
        append = self.subjects.append
        append({'code': code, 'name': name})

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY, 'del_subject')

    def del_subject(self, code):
        """ remove a language from list """
        for subj_info in self.subjects:
            if subj_info['code'] == code:
                self.subjects.remove(subj_info)

    #################################
    #  NAME TRANSLATIONS FUNCTIONS  #
    #################################
    def get_translation_by_language(self, language):
        """ get translation by language """
        try:
            return getattr(self.aq_base, language)
        except:
            return ''

    def get_translation_by_language_for_js(self, language):
        """ get translation by language for the javascript code"""
        try:
            translation = self.get_translation_by_language(language)
            if not translation:
                translation = self.title_or_id()
        except AttributeError:
            translation = self.title_or_id()
        return translation.replace('_', ' ')

    def check_if_no_translations(self):
        """ check if translation """
        for lang in self.get_english_names():
            if self.get_translation_by_language(lang) != '':
                return 1
        return 0

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'set_translations_list')

    def set_translations_list(self, language, translation):
        """ set the languages """
        real_self = self.aq_base
        if getattr(real_self, language, u"") == translation:
            # no need to do anything, so let's avoid generating a transaction
            return
        if translation == "":
            if hasattr(real_self, language):
                delattr(real_self, language)
        else:
            setattr(real_self, language, translation)
        event.notify(ItemTranslationChanged(self, language, translation))

    def load_translations_list(self):
        """ load languages """
        for lang in self.get_english_names():
            self.set_translations_list(lang, '')

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'manageNameTranslations')

    def manageNameTranslations(self,
                               lang_code='',
                               translation='',
                               REQUEST=None):
        """ save translation for a language """
        self.set_translations_list(lang_code, translation)
        if REQUEST:
            return REQUEST.RESPONSE.redirect('translations_html?tab=0')

    #######################################
    #  DEFINITION TRANSLATIONS FUNCTIONS  #
    #######################################
    def get_def_trans_by_language(self, language):
        """ get translation by language """
        return getattr(self.aq_base, self.definition_lang(language), '')

    def check_if_no_def_trans(self):
        """ check if translation """
        for lang in self.get_english_names():
            if self.get_def_trans_by_language(lang) != '':
                return 1
        return 0

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'set_def_trans_list')

    def set_def_trans_list(self, language, translation):
        """ set the languages """
        self.set_translations_list(self.definition_lang(language), translation)

    def load_def_trans_list(self):
        """ load languages """
        for lang in self.get_english_names():
            self.set_translations_list(self.definition_lang(lang), '')

    security.declareProtected(PERMISSION_MANAGE_NAAYAGLOSSARY,
                              'manageDefinitionTranslations')

    def manageDefinitionTranslations(self,
                                     lang_code='',
                                     translation='',
                                     REQUEST=None):
        """ save translation for a language """
        self.set_def_trans_list(lang_code, translation)
        if REQUEST:
            return REQUEST.RESPONSE.redirect('translations_html?tab=1')

    #####################
    #   MANAGEMENT TABS #
    #####################
    security.declareProtected(view_management_screens, 'translations_html')
    translations_html = PageTemplateFile(
        "zpt/NaayaGlossaryElement/translations", globals())

    security.declareProtected(view_management_screens, 'name_trans_html')
    name_trans_html = PageTemplateFile("zpt/NaayaGlossaryElement/name_trans",
                                       globals())

    security.declareProtected(view_management_screens, 'definition_trans_html')
    definition_trans_html = PageTemplateFile(
        "zpt/NaayaGlossaryElement/definition_trans", globals())

    security.declareProtected(view_management_screens, 'properties_html')
    properties_html = NaayaPageTemplateFile(
        'zpt/NaayaGlossaryElement/properties', globals(),
        'glossary_element_properties')

    view_elements_html = PageTemplateFile(
        "zpt/NaayaGlossaryElement/view_elements", globals())
    index_html = NaayaPageTemplateFile("zpt/NaayaGlossaryElement/index",
                                       globals(), 'glossary_element_index')

    #################
    #   SITE MAP    #
    #################
    security.declarePublic('getGlossaryObTree')

    def getGlossaryObTree(self):
        """ """
        return None

    security.declareProtected(view_management_screens, 'manage_tabs')

    def manage_tabs(self):
        # we override manage_tabs to insert warning about synchronized glossary
        if self.sync_remote_url:
            extra_html = self.sync_info_text(zmi=True)
        else:
            extra_html = ''
        return super(NyGlossaryElement, self).manage_tabs() + extra_html
class NaayaTemplateTestCase(NaayaTestCase.NaayaTestCase):
    def afterSetUp(self):
        self.my_tmpl = NaayaPageTemplateFile('the_template', globals(),
                'my_tmpl')
        self.second_tmpl = NaayaPageTemplateFile('the_template', globals(),
                'second_tmpl')

        NyDocument.my_tmpl = self.my_tmpl
        NyDocument.second_tmpl = self.second_tmpl

    def beforeTearDown(self):
        del NyDocument.my_tmpl
        del NyDocument.second_tmpl

    def test_render(self):
        """ Render templates by calling the template """
        output = self.my_tmpl.__of__(self.portal)(a="26")
        self.assertTrue('[physicalpath: /portal]' in output)
        self.assertTrue('[optiona: 26]' in output)

        output = self.portal.info.contact.my_tmpl(a="13")
        self.assertTrue('[physicalpath: /portal/info/contact]' in output)
        self.assertTrue('[optiona: 13]' in output)

    def test_get_content(self):
        """ Test getContent """
        forms_tool = self.portal.portal_forms
        forms_tool.manage_customizeForm('my_tmpl')
        forms_tool.my_tmpl.pt_edit(text='<tal:block replace="a" />',
                content_type='text/html')
        output = forms_tool.getContent({'a': 26 }, 'my_tmpl')
        self.assertTrue('26' in output)

    def test_customized_templates(self):
        forms_tool = self.portal.portal_forms
        forms_tool.manage_customizeForm('my_tmpl')
        self.assertTrue('my_tmpl' in forms_tool.customized_templates())

    def test_customize(self):
        forms_tool = self.portal.portal_forms
        self.assertTrue('my_tmpl' in dict(forms_tool.get_all_templates()))
        my_tmpl_aq = forms_tool.getForm('my_tmpl')
        self.assertTrue(my_tmpl_aq.aq_self is NyDocument.my_tmpl)
        self.assertTrue(my_tmpl_aq.aq_parent is forms_tool)

        forms_tool.manage_customizeForm('my_tmpl')
        forms_tool.my_tmpl.pt_edit(text='new content', content_type='text/html')
        self.assertEqual(self.portal.info.contact.my_tmpl().strip(),
                         'new content')

    def test_template_traversal(self):
        forms_tool = self.portal.getFormsTool()

        # Customize 2nd template to include a macro def
        second_tmpl = forms_tool.getForm('second_tmpl')
        self.assertEqual(second_tmpl, forms_tool.getForm('second_tmpl'))
        forms_tool.manage_customizeForm('second_tmpl')
        text = ('<metal:block define-macro="hole">'
                'Bugs Bunny</metal:block>')
        forms_tool.second_tmpl.pt_edit(text=text, content_type='text/html')

        # Customize 1st template to include previous macro in several ways
        forms_tool.manage_customizeForm('my_tmpl')
        text = ('<tal:block metal:use-macro="'
                "python:here.getFormsTool().getForm('second_tmpl')"
                ".macros['hole']\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output =self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)

        text = ('<tal:block metal:use-macro="'
                "python:here.getFormsTool()['second_tmpl']"
                ".macros['hole']\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output = self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)

        text = ('<tal:block metal:use-macro="'
                "here/portal_forms/second_tmpl/"
                "macros/hole\"></tal:block>")
        forms_tool.my_tmpl.pt_edit(text=text, content_type='text/html')
        output = self.my_tmpl.__of__(self.portal)()
        self.assertTrue(output.find("Bugs Bunny")>-1)
Ejemplo n.º 32
0
class CommentsAdmin(SimpleItem):
    security = ClassSecurityInfo()

    title = "Comments administration"

    def __init__(self, id):
        self.id = id

    def _iter_comments(self):
        for section in self.list_sections():
            for paragraph in section.get_paragraphs():
                for comment in sorted(paragraph.get_comments(),
                                      key=lambda c: c.comment_date):
                    yield comment

    _admin_template = NaayaPageTemplateFile('zpt/comments_admin', globals(),
                                            'tbconsultation_comments_admin')

    security.declarePublic('index_html')

    def index_html(self, REQUEST):
        """ the admin page for comments """

        if self.checkPermissionManageTalkBackConsultation():
            pass
        elif self.checkPermissionInviteToTalkBackConsultation():
            pass
        elif self.own_comments():
            pass
        else:
            raise Unauthorized

        total_count = 0
        invited_count = 0
        anonymous_count = 0

        for comment in self._iter_comments():
            total_count += 1
            if comment.is_invited:
                invited_count += 1
            elif comment.is_anonymous:
                anonymous_count += 1

        contributors = self._get_contributors_stats()
        invited = filter(lambda x: x['invited'], contributors)
        anonymous = filter(lambda x: x['anonymous'], contributors)

        options = {
            'contributors_count': len(contributors),
            'invited_contributors_count': len(invited),
            'anonymous_contributors_count': len(anonymous),
            'contributors_details': contributors,
            'total_count': total_count,
            'invited_count': invited_count,
            'anonymous_count': anonymous_count,
            'comment_macros': Paragraph.comments_html.macros,
            'get_comments_trend': self.get_comments_trend(),
        }
        return self._admin_template(REQUEST, **options)

    def _get_contributors_stats(self):

        contrib_stats = {}
        for comment in self._iter_comments():
            try:
                test = contrib_stats[comment.contributor]
            except KeyError:
                new_user_info = comment.get_contributor_info()
                new_user_info['count'] = 1
                contrib_stats[comment.contributor] = new_user_info
            else:
                contrib_stats[comment.contributor]['count'] += 1
        contrib_stats = [v for k, v in contrib_stats.items()]

        return contrib_stats

    security.declareProtected(PERMISSION_MANAGE_TALKBACKCONSULTATION,
                              'get_comments_trend')

    def get_comments_trend(self):
        """ get comments trend """
        days = {self.start_date.Date(): 0, self.end_date.Date(): 0}

        for comment in self._iter_comments():
            date = comment.comment_date.Date()
            count = days.setdefault(date, 0)
            days[date] = count + 1

        data = []
        for day, comments in days.items():
            data.append({'day': day, 'comments': comments})

        return json.dumps(sorted(data, key=lambda x: x['day']))

    security.declarePrivate('generate_csv_output')

    def generate_csv_output(self, fields, comments):

        output = StringIO()
        csv_writer = csv.writer(output)

        csv_writer.writerow([
            'Consultation deadline',
            (self.end_date + 1).strftime('%Y/%m/%d %H:%M')
        ])
        csv_writer.writerow(
            ['Date of export',
             DateTime().strftime('%Y/%m/%d %H:%M')])

        csv_writer.writerow([field[0] for field in fields])

        for n, item in enumerate(comments):
            row = [field[1](item).encode('utf-8') for field in fields]
            csv_writer.writerow(row)

        return codecs.BOM_UTF8 + output.getvalue()

    security.declarePrivate('generate_excel_output')

    def generate_excel_output(self, fields, comments):

        header_style = xlwt.easyxf('font: bold on; align: horiz left;')
        normal_style = xlwt.easyxf('align: horiz left, vert top;')

        wb = xlwt.Workbook(encoding='utf-8')
        ws = wb.add_sheet('Sheet 1')

        ws.row(0).set_cell_text(0, 'Consultation deadline', header_style)
        ws.row(0).set_cell_text(1,
                                (self.end_date + 1).strftime('%Y/%m/%d %H:%M'),
                                normal_style)
        ws.row(1).set_cell_text(0, 'Date of export', header_style)
        ws.row(1).set_cell_text(1,
                                DateTime().strftime('%Y/%m/%d %H:%M'),
                                normal_style)

        row = 2
        for col in range(len(fields)):
            ws.row(row).set_cell_text(col, fields[col][0], header_style)

        for item in comments:
            row += 1
            for col in range(len(fields)):
                ws.row(row).set_cell_text(col, fields[col][1](item),
                                          normal_style)
        output = StringIO()
        wb.save(output)

        return output.getvalue()

    security.declarePrivate('generate_custom_excel_output')

    def generate_custom_excel_output(self, fields, comments):

        normal_style = xlwt.easyxf('align: wrap on, horiz left, vert top;')
        header_style = xlwt.easyxf(
            'font: bold on; align: wrap on, horiz left;')

        wb = xlwt.Workbook(encoding='utf-8')
        ws = wb.add_sheet('Sheet 1')
        row = 0
        for col in range(len(fields)):
            ws.row(row).set_cell_text(col, fields[col][0], header_style)

        ws.col(0).width = 3000
        ws.col(1).width = 20000
        ws.col(2).width = 7500
        ws.col(3).width = 5000
        for item in comments:
            row += 1
            for col in range(len(fields)):
                ws.row(row).set_cell_text(col, fields[col][1](item),
                                          normal_style)
            row += 1
            ws.row(row).set_cell_text(0, 'EEA Comments', header_style)
        output = StringIO()
        wb.save(output)

        return output.getvalue()

    def _all_comments(self):
        def replies(this_comment):
            yield this_comment
            for child_comment in this_comment['children']:
                for c in replies(child_comment):
                    yield c

        for section in self.list_sections():
            for paragraph in section.get_paragraphs():
                for top_comment in paragraph.get_comment_tree():
                    for c in replies(top_comment):
                        yield c

    def all_comments(self):
        perm_manage = self.checkPermissionManageTalkBackConsultation()
        if perm_manage:
            return self._all_comments()
        own_comments = self.own_comments()
        if own_comments:
            return own_comments
        raise Unauthorized

    def export(self, file_type="CSV", as_attachment=False, REQUEST=None):
        """ """
        perm_manage = self.checkPermissionManageTalkBackConsultation()
        if not (perm_manage or self.own_comments):
            raise Unauthorized

        html2text = self.getSite().html2text

        def plain(s, trim=None):
            return html2text(s, trim)

        fields = [
            ('Section', lambda i: i['comment'].get_section().title_or_id()),
            ('Paragraph', lambda i:
             (i['comment'].get_paragraph().plaintext_summary())),
            ('Message Id', lambda i: i['comment'].getId()),
            ('Replies', lambda i: str(len(i['children']))),
            ('In reply to', lambda i: i['comment'].reply_to or ''),
            ('Message', lambda i: plain(i['comment'].message)),
            ('Contributor', lambda i: i['comment'].get_contributor_name()),
            ('Date', lambda i:
             (i['comment'].comment_date.strftime('%Y/%m/%d %H:%M'))),
            ('Paragraph url', lambda i:
             (i['comment'].get_paragraph().absolute_url())),
        ]

        comments = self.all_comments()

        if file_type == 'CSV':
            ret = self.generate_csv_output(fields, comments)
            content_type = 'text/csv; charset=utf-8'
            filename = 'comments.csv'

        elif file_type == 'Excel':
            ret = self.generate_excel_output(fields, comments)
            content_type = 'application/vnd.ms-excel'
            filename = 'comments.xls'

        elif file_type == 'CustomExcel':
            fields = [
                ('Section', lambda c: c.get_section().title_or_id()),
                ('Message', lambda c: plain(c.message)),
                ('Contributor', lambda c: c.get_contributor_name()),
                ('Date', lambda c: c.comment_date.strftime('%Y/%m/%d %H:%M')),
            ]
            ret = self.generate_custom_excel_output(fields, comments)
            content_type = 'application/vnd.ms-excel'
            filename = 'comments.xls'

        else:
            raise ValueError('unknown file format %r' % file_type)

        if as_attachment and REQUEST is not None:
            filesize = len(ret)
            set_response_attachment(REQUEST.RESPONSE, filename, content_type,
                                    filesize)
        return ret

    _comments_table_html = NaayaPageTemplateFile(
        'zpt/comments_table', globals(), 'tbconsultation_comments_table')

    def comments_table_html(self):
        """ table showing all comments from all participants (manager)
        or all the user's comments, if the user is just a commenter """
        if self.checkPermissionManageTalkBackConsultation():
            pass
        elif self.own_comments():
            pass
        else:
            raise Unauthorized

        return self._comments_table_html()
Ejemplo n.º 33
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.º 34
0
            jstree.append({
                'data': {
                    'title': organization,
                    'icon': self.organization_icon
                },
                'children': meeting_nodes
            })
        return json.dumps(jstree)

    security.declareProtected(view, 'report_meeting_participants')

    def report_meeting_participants(self, REQUEST=None, RESPONSE=None):
        """ """
        return self.getFormsTool().getContent({'here': self},
                                              'report_meeting_participants')

    security.declareProtected(view, 'report_meeting_organizations')

    def report_meeting_organizations(self, REQUEST=None, RESPONSE=None):
        """ """
        return self.getFormsTool().getContent({'here': self},
                                              'report_meeting_organizations')


# Custom page templates
NaayaPageTemplateFile('zpt/report_meeting_participants', globals(),
                      'report_meeting_participants')
NaayaPageTemplateFile('zpt/report_meeting_organizations', globals(),
                      'report_meeting_organizations')