def export_url(self): params = copy(self.request.form) params = dict((key.replace('[]', ''), val) for key, val in params.items()) ignored_params = ('version', 'b_start', 'reversed') for ignored in ignored_params: if ignored in params: del params[ignored] criteria = ICriteria(self.context) for param in params.keys(): try: widgetclass = criteria.widget(cid=param) except KeyError: # if widget has been removed continue widget = widgetclass(self.context, self.request, criteria.get(param)) if widget.widget_type == 'resultsperpage': del params[param] params['excelexport.policy'] = 'eea.facetednavigation' export_url = "%s/@@collective.excelexport?%s" % (self.context.absolute_url(), urllib.urlencode(params, doseq=True)) return export_url
def widget_render(self): # get the IFacetedNavigable element the criteria are define on criteriaHolder = self._criteriaHolder criteria = ICriteria(criteriaHolder) widgets = [] for criterion in criteria.values(): if criterion.widget != CollectionWidget.widget_type: continue widget_cls = criteria.widget(wid=criterion.widget) widget = widget_cls(criteriaHolder, self.request, criterion) widget.display_fieldset = False # if we are not on the criteriaHolder, it means # that the portlet is displayed on children, we use another template # for rendering the widget no_redirect = self._isPortletOutsideFaceted(self.context, self._criteriaHolder) if no_redirect: # avoid redirect self.request.set('no_redirect', '1') # initialize the widget rendered_widget = widget() # render the widget as "portlet outside facetednav" if no_redirect: # compute default criteria to display in the URL widget.base_url = self._buildBaseLinkURL(criteria) rendered_widget = ViewPageTemplateFile('templates/widget.pt')(widget) widgets.append(rendered_widget) return ''.join([w for w in widgets])
def export_url(self): params = copy(self.request.form) params = dict( (key.replace('[]', ''), val) for key, val in params.items()) ignored_params = ('version', 'b_start', 'reversed') for ignored in ignored_params: if ignored in params: del params[ignored] criteria = ICriteria(self.context) for param in params.keys(): try: widgetclass = criteria.widget(cid=param) except KeyError: # if widget has been removed continue widget = widgetclass(self.context, self.request, criteria.get(param)) if widget.widget_type == 'resultsperpage': del params[param] params['excelexport.policy'] = 'eea.facetednavigation' export_url = "%s/@@collective.excelexport?%s" % ( self.context.absolute_url(), urllib.urlencode(params, doseq=True)) return export_url
def projectspace_moved(obj, event): """ When a projectspace is renamed, we correct collections """ if IObjectRemovedEvent.providedBy(event): return portal = api.portal.get() path = '/'.join(obj.getPhysicalPath()) # correct path criteria in collections for brain in portal.portal_catalog(path=path, portal_type='DashboardCollection'): ob = brain.getObject() query = ob.query for elt in query: if elt['i'] == 'path': elt['v'] = path ob.query = query # correct default collection for brain in portal.portal_catalog( path=path, object_provides=ICollectionCategories.__identifier__): ob = brain.getObject() criterion = getCollectionLinkCriterion(ob) criterias = ICriteria(ob) old_uid = criterias.get(criterion.__name__).get('default') old_path = uuidToPhysicalPath(old_uid) old_id = os.path.basename(old_path) if old_path.endswith('/{}/{}'.format(ob.id, old_id)): default_col = ob[old_id].UID() _updateDefaultCollectionFor(ob, default_col) logger.info('Replaced default col {} by {} on {}'.format( old_uid, default_col, ob.absolute_url())) else: raise ValueError("Cannot update default col on {}".format( ob.absolute_url()))
def _get_criterion_by_attr(faceted_context, attr_name, value_to_match): """ """ if not IFacetedNavigable.providedBy(faceted_context): raise NoFacetedViewDefinedException(NO_FACETED_EXCEPTION_MSG) criterions = ICriteria(faceted_context) for criterion in criterions.values(): if not hasattr(criterion, attr_name): continue else: attr = getattr(criterion, attr_name) value = hasattr(attr, '__call__') and attr() or attr if value == value_to_match: return criterion
def update_dashboards(): # update daterange criteria brains = api.content.find(object_provides=IFacetedNavigable.__identifier__, portal_type='Folder') for brain in brains: obj = brain.getObject() criterion = ICriteria(obj) for key, criteria in criterion.items(): if criteria.get("widget") != "daterange": continue if criteria.get("usePloneDateFormat") is True: continue logger.info("Upgrade daterange widget for faceted {0}".format(obj)) position = criterion.criteria.index(criteria) values = criteria.__dict__ values["usePloneDateFormat"] = True values["labelStart"] = u'Start date' values["labelEnd"] = u'End date' criterion.criteria[position] = Criterion(**values) criterion.criteria._p_changed = 1
def various(self): """ corrections diverses avec ipdb """ # Changer le default d'un tb, ici ne rien mettre au niveau le plus haut context = self from imio.dashboard.utils import getCollectionLinkCriterion criterion = getCollectionLinkCriterion(context) criterion.default = u'' from eea.facetednavigation.criteria.interfaces import ICriteria ICriteria(context).criteria._p_changed = True # Réparer la vue de la page pst context.setLayout('view') from imio.project.pst.setuphandlers import configure_faceted_folder configure_faceted_folder(context, xml='default_dashboard_widgets.xml', default_UID=None)
def migrate(self, old, new): new_path = "/".join(new.getPhysicalPath()) for iface in interfaces: if iface.providedBy(old): alsoProvides(new, iface) logger.warn("{0} also provides {1}".format(new_path, str(iface))) if old.getConstrainTypesMode() != 0: behaviour = ISelectableConstrainTypes(new) behaviour.setConstrainTypesMode(1) if old.getConstrainTypesMode() == 1: behaviour.setLocallyAllowedTypes(old.getLocallyAllowedTypes()) behaviour.setImmediatelyAddableTypes(old.getImmediatelyAddableTypes()) if IFacetedNavigable.providedBy(old): criteria = Criteria(new) criteria._update(ICriteria(old).criteria) IFacetedLayout(new).update_layout('faceted-table-items') logger.warn("Added faceted criteria and layout to {0}".format(new_path))
def test_configure_group_encoder(self): setRoles(self.portal, TEST_USER_ID, ['Manager']) # activate imail group encoder activate_group_encoder(self.portal) self.assertIn(CREATING_GROUP_SUFFIX, [fct['fct_id'] for fct in get_registry_functions()]) for portal_type in ('dmsincomingmail', 'dmsincoming_email'): fti = getUtility(IDexterityFTI, name=portal_type) self.assertIn( 'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup', fti.behaviors) self.assertIn('creating_group', [tup[0] for tup in get_localrole_fields(fti)]) self.assertTrue( fti.localroles.get('creating_group')) # config dic not empty crit = ICriteria(self.portal['incoming-mail']['mail-searches']) self.assertIn('c90', crit.keys()) fields = api.portal.get_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.imail_fields') self.assertIn('IDmsMailCreatingGroup.creating_group', [f['field_name'] for f in fields]) # activate omail group encoder activate_group_encoder(self.portal, typ='omail') self.assertIn(CREATING_GROUP_SUFFIX, [fct['fct_id'] for fct in get_registry_functions()]) # for portal_type in ('dmsoutgoingmail', 'dmsoutgoing_email'): for portal_type in ('dmsoutgoingmail', ): fti = getUtility(IDexterityFTI, name=portal_type) self.assertIn( 'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup', fti.behaviors, portal_type) self.assertIn('creating_group', [tup[0] for tup in get_localrole_fields(fti)], portal_type) self.assertTrue(fti.localroles.get('creating_group'), portal_type) # config dic not empty crit = ICriteria(self.portal['outgoing-mail']['mail-searches']) self.assertIn('c90', crit.keys()) fields = api.portal.get_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_fields') self.assertIn('IDmsMailCreatingGroup.creating_group', [f['field_name'] for f in fields]) # activate contact group encoder activate_group_encoder(self.portal, typ='contact') self.assertIn(CREATING_GROUP_SUFFIX, [fct['fct_id'] for fct in get_registry_functions()]) self.assertIn(CONTACTS_PART_SUFFIX, [fct['fct_id'] for fct in get_registry_functions()]) for portal_type in ('organization', 'person', 'held_position', 'contact_list'): fti = getUtility(IDexterityFTI, name=portal_type) self.assertIn( 'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup', fti.behaviors) self.assertIn('creating_group', [tup[0] for tup in get_localrole_fields(fti)]) for fid in ('orgs-searches', 'persons-searches', 'hps-searches', 'cls-searches'): crit = ICriteria(self.portal['contacts'][fid]) self.assertIn('c90', crit.keys())
def test_DashboardPODTemplateViewlet(self): """Test the IDDashboardDocumentGeneratorLinksViewlet that list available DashboardPODTemplates.""" # by default, viewlet is not displayed as no template to display # but it needs a faceted enabled folder and to be able to getCurrentCollection self.assertTrue(IFacetedNavigable.providedBy(self.folder)) dashboardcoll = api.content.create(id='dc1', type='DashboardCollection', title='Dashboard collection 1', container=self.folder) self.request.form['c1[]'] = dashboardcoll.UID() self.assertEquals(getCurrentCollection(self.folder), dashboardcoll) viewlet = DashboardDocumentGeneratorLinksViewlet( self.folder, self.request, None, None) viewlet.update() self.assertFalse(viewlet.available()) self.assertFalse(viewlet.get_generable_templates()) # add a PODTemplate, still not available api.content.create(id='template', type='PODTemplate', title='POD template', container=self.portal) # need to clean memoize because available() calls # get_generable_templates that use it del IAnnotations(self.request)['plone.memoize'] self.assertFalse(viewlet.available()) self.assertFalse(viewlet.get_generable_templates()) # add a DashboardPODTemplate, this time it is available dashtemplate = api.content.create(id='dashtemplate', type='DashboardPODTemplate', title='Dashboard template', container=self.portal) # clean memoize del IAnnotations(self.request)['plone.memoize'] self.assertTrue(viewlet.available()) self.assertEquals(len(viewlet.get_generable_templates()), 1) self.assertEquals(viewlet.get_generable_templates()[0].UID(), dashtemplate.UID()) # this viewlet will not be displayed if current context is not a faceted self.assertFalse(IFacetedNavigable.providedBy(self.folder2)) self.assertTrue(IFacetedNavigable.providedBy(self.folder)) # not faceted context viewlet = self._get_viewlet( context=self.folder2, manager_name='collective.eeafaceted.z3ctable.topabovenav', viewlet_name='dashboard-document-generation-link') self.assertIsNone(viewlet) # collection criterion not found viewlet = self._get_viewlet( context=self.folder, manager_name='collective.eeafaceted.z3ctable.topabovenav', viewlet_name='dashboard-document-generation-link') self.assertIsNotNone(viewlet) del IAnnotations(self.request)['plone.memoize'] self.assertTrue(viewlet.available()) criteria = ICriteria(self.folder).criteria index = [ i for i, crit in enumerate(criteria) if crit.widget == u'collection-link' ][0] del criteria[index] # we remove collectionwidget criterion self.assertFalse(viewlet.available()) # no matter there are pod templates self.assertTrue(viewlet.get_generable_templates())
def manage_classification(context, active): """Activate or deactivate classification""" logger.info('Manage classification by {}activating related things'.format( not active and 'de-' or '')) site = context.getSite() # handle navtree_properties unlisted = list( site.portal_properties.navtree_properties.metaTypesNotToList) update = False for ptype in ('ClassificationFolders', 'ClassificationContainer'): if active and ptype in unlisted: unlisted.remove(ptype) update = True elif not active and ptype not in unlisted: unlisted.append(ptype) update = True if update: site.portal_properties.navtree_properties.manage_changeProperties( metaTypesNotToList=unlisted) # handle fields for rec in ('imail_fields', 'omail_fields'): update = False rec_name = 'imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.format( rec) showed = api.portal.get_registry_record(rec_name, default=[]) showed_ids = [dic['field_name'] for dic in showed] # imf = [ for v in im_fo] for fld in (u'IClassificationFolder.classification_folders', u'IClassificationFolder.classification_categories'): if active and fld not in showed_ids: idx = showed_ids.index('internal_reference_no') showed.insert( idx, { "field_name": fld, "read_tal_condition": u"", "write_tal_condition": u"" }) update = True elif not active and fld in showed_ids: showed = [dic for dic in showed if dic['field_name'] != fld] update = True if update: api.portal.set_registry_record(rec_name, list(showed)) # handle criterias for dpath, crit_ids in (('incoming-mail', ['c20', 'c21']), ('outgoing-mail', ['c19', 'c20'])): mspath = os.path.join(dpath, 'mail-searches') folder = site.unrestrictedTraverse(mspath) criterias = ICriteria(folder) for crit_id in crit_ids: criterion = criterias.get(crit_id) if active and criterion.hidden: criterion.hidden = False criterias.criteria._p_changed = 1 elif not active and not criterion.hidden: criterion.hidden = True criterias.criteria._p_changed = 1 # handle columns for dpath in ('incoming-mail', 'outgoing-mail'): obj = site.unrestrictedTraverse(dpath) brains = site.portal_catalog(portal_type='DashboardCollection', path='/'.join(obj.getPhysicalPath())) for brain in brains: col = brain.getObject() buf = list(col.customViewFields) if active and u'classification_folders' not in buf: if 'actions' in buf: buf.insert(buf.index('actions'), u'classification_folders') else: buf.append(u'classification_folders') col.customViewFields = tuple(buf) elif not active and u'classification_folders' in buf: buf.remove(u'classification_folders') col.customViewFields = tuple(buf)
def test_portlet_widget_render(self): """The portlet will render collection-link widgets defined on the faceted config. This portlet has 2 behaviours : - classic faceted widget behaviour when displayed directly on the folder on which the faceted is applied : it uses the faceted js onclick to update the faceted; - 'fake' widget displayed as the real widget but instead of controlling the faceted it has a link on every disiplayed collection that will move to the faceted correctly initialized.""" self.subtyper.enable() criteria = ICriteria(self.renderer._criteriaHolder) # remove the collection-link widget collcriterion = getCollectionLinkCriterion(self.renderer._criteriaHolder) ICriteria(self.renderer._criteriaHolder).delete(collcriterion.getId()) # by defaut no collection-link widget so nothing is rendered self.assertTrue(not [criterion for criterion in criteria.values() if criterion.widget == CollectionWidget.widget_type]) with self.assertRaises(NoCollectionWidgetDefinedException): getCollectionLinkCriterion(self.renderer._criteriaHolder) self.assertTrue(not self.renderer.widget_render) # add a collection-link widget data = {'vocabulary': 'collective.eeafaceted.collectionwidget.collectionvocabulary', 'hidealloption': True} ICriteria(self.folder).add('collection-link', 'top', **data) # still displaying nothing as the collection widget does not find any collection self.assertTrue(not self.renderer.widget_render.strip()) # add a DashboardCollection in self.folder collection = api.content.create( id='dashboardcollection1', type='DashboardCollection', title='Dashboard collection 1', container=self.folder, query='', sort_on='', sort_reversed=False, showNumberOfItems=True, tal_condition=u'', roles_bypassing_talcondition=[]) # clean memoize for widget.categories, # it was memoized when calling _generate_vocabulary here above del IAnnotations(self.request)['plone.memoize'] # now it is displayed and as we are on the faceted, it behaves like the collection widget # a <form> with an action # get the '<ul>' displaying collections # update renderer self.renderer = self._get_portlet_renderer() self.assertTrue("<form" in self.renderer.widget_render) ul_tag = lxml.html.fromstring(self.renderer.widget_render)[0][0] # only 1 children, the collection and the href is as special javascript call that does nothing self.assertTrue(len(ul_tag.getchildren()) == 1) div_tag = ul_tag.getchildren()[0] li_tag = div_tag.getchildren()[0] self.assertTrue(li_tag.attrib['value'] == collection.UID()) self.assertTrue(len(li_tag.getchildren()) == 1) a_tag = li_tag.getchildren()[0] self.assertTrue(a_tag.attrib['href'] == 'javascript:;') # now get the portlet from a sub element so it behaves differently # it is no more a faceted widget but and the href will redirect to the faceted with default parameters subrenderer = getMultiAdapter((collection, self.request, self.view, self.manager, self.assignment), IPortletRenderer) # no more <form> this time self.assertTrue("<form" not in subrenderer.widget_render) ul_tag = lxml.html.fromstring(subrenderer.widget_render)[0] # only 1 children, the collection and the href is a link back to the href with correct default parameters self.assertTrue(len(ul_tag.getchildren()) == 1) li_tag = ul_tag.getchildren()[0] self.assertTrue(li_tag.attrib['value'] == collection.UID()) self.assertTrue(len(li_tag.getchildren()) == 1) a_tag = li_tag.getchildren()[0] # the URL is generated and contains every default values and relevant collection UID url = "http://nohost/plone/folder#c3=20&c1={0}".format(collection.UID()) self.assertEquals(a_tag.attrib['href'], url)