def test_getDefaultPage_step_3_1(self): # 3. Else, look up the attribute default_page on the object, without # acquisition in place # 3.1 look for a content in the container with the id, no acquisition! self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") from plone.app.layout.navigation.defaultpage import getDefaultPage # set doc d1 must work self.folder.default_page = 'd1' self.assertEqual('d1', getDefaultPage(self.folder)) # set doc d2 must fail and return None self.folder.default_page = 'd2' self.assertIsNone(getDefaultPage(self.folder)) # list of possible values is allowed self.folder.default_page = ['d2', 'd1'] self.assertEqual('d1', getDefaultPage(self.folder)) # list of impossible values return None self.folder.default_page = ['d2', 'd3'] self.assertIsNone(getDefaultPage(self.folder)) # acquisition check, must not work self.folder.invokeFactory('Folder', 'f1', title=u"Sub Folder 1") self.folder.f1.invokeFactory('Document', 'd2', title=u"Document 2") self.folder.default_page = 'd2' self.assertIsNone(getDefaultPage(self.folder.f1))
def test_getDefaultPage_step_3_1(self): # 3. Else, look up the attribute default_page on the object, without # acquisition in place # 3.1 look for a content in the container with the id, no acquisition! self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") from plone.app.layout.navigation.defaultpage import getDefaultPage # set doc d1 must work self.folder.default_page = 'd1' self.assertEqual('d1', getDefaultPage(self.folder)) # set doc d2 must fail and return None self.folder.default_page = 'd2' self.assertIsNone(getDefaultPage(self.folder)) # list of possible values is allowed self.folder.default_page = ['d2', 'd1'] self.assertEqual('d1', getDefaultPage(self.folder)) # list of impossible values return None self.folder.default_page = ['d2', 'd3'] self.assertIsNone(getDefaultPage(self.folder)) # acquisition check, must not work self.folder.invokeFactory('Folder', 'f1', title=u"Sub Folder 1") self.folder.f1.invokeFactory('Document', 'd2', title=u"Document 2") self.folder.default_page = 'd2' self.assertIsNone(getDefaultPage(self.folder.f1))
def __call__(self): data = super(CastleSettingsAdapter, self).__call__() if api.user.is_anonymous(): return data folder = self.context if not IDexterityContainer.providedBy(folder): folder = aq_parent(folder) required_upload_fields = self.registry.get( 'castle.required_file_upload_fields', []) or [] data.update({ 'data-available-slots': json.dumps(self.get_available_slot_tiles()), 'data-required-file-upload-fields': json.dumps(required_upload_fields), 'data-google-maps-api-key': self.registry.get('castle.google_maps_api_key', '') or '', 'data-folder-url': folder.absolute_url() }) show_tour = False user = api.user.get_current() viewed = user.getProperty('tours_viewed', []) if ('all' not in viewed and set(viewed) != set([ 'welcome', 'dashboard', 'foldercontents', 'addcontentinitial', 'addcontentadd', 'editpage' ])): show_tour = True if show_tour and not api.env.test_mode(): data['data-show-tour'] = json.dumps({'viewed': viewed}) folder = self.context if not ISiteRoot.providedBy( folder) and not IDexterityContainer.providedBy(folder): folder = aq_parent(folder) site_path = self.site.getPhysicalPath() folder_path = folder.getPhysicalPath() data['data-base-path'] = '/' + '/'.join(folder_path[len(site_path):]) real_context = self.context if ISiteRoot.providedBy(real_context): # we're at site root but actually kind of want context front page try: real_context = real_context[getDefaultPage(real_context)] except (AttributeError, KeyError): pass if IDashboard.providedBy(real_context): real_context = self.site transform = theming.getTransform(real_context, self.request) if transform is not None: data['data-site-layout'] = transform.get_layout_name(real_context) data['data-site-default'] = getDefaultPage(self.site) or 'front-page' return data
def parent_link(self): if getDefaultPage(self.parent): page = self.parent.unrestrictedTraverse( getDefaultPage(self.parent)) return {'title': page.Title(), 'url': self.parent.absolute_url()} else: return {'title': self.parent.Title(), 'url': self.parent.absolute_url()}
def parent_link(self): if getDefaultPage(self.parent): page = self.parent.unrestrictedTraverse( getDefaultPage(self.parent)) return {'title': page.Title(), 'url': self.parent.absolute_url()} else: return {'title': self.parent.Title(), 'url': self.parent.absolute_url()}
def test_getDefaultPage_step_2(self): # Else check for IBrowserDefault, either if the container implements # it or if an adapter exists. In both cases fetch its FTI and either # take it if it implements IDynamicViewTypeInformation or adapt it to # IDynamicViewTypeInformation. call getDefaultPage on the implementer # and take value if given. # first check some preconditions # # 1) a folder provides IBrowserDefault from Products.CMFDynamicViewFTI.interfaces import IBrowserDefault self.assertTrue(IBrowserDefault.providedBy(self.folder)) # 2) a folder also provides an fti that implements # IDynamicViewTypeInformation from Products.CMFDynamicViewFTI.interfaces import IDynamicViewTypeInformation # noqa fti = self.folder.getTypeInfo() self.assertTrue(IDynamicViewTypeInformation.providedBy(fti)) # so if we set a document as defaultpage self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.setDefaultPage('d1') # 3) fti should return it self.assertEqual('d1', fti.getDefaultPage(self.folder, check_exists=True)) # now test since we're sure everythings set up correctly from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('d1', getDefaultPage(self.folder))
def test_getDefaultPage_step_3_2(self): # 3. Else, look up the attribute default_page on the object, without # acquisition in place # 3.2 look for a content at portal, with acquisition self.portal.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.default_page = 'd1' from plone.app.layout.navigation.defaultpage import getDefaultPage # now it must acquire from portal self.assertEqual('d1', getDefaultPage(self.folder)) # fetch from i.e. portal_skins by acquisition # test_rendering.pt is in portal_skins/plone_templates and so available # by acquisition self.folder.default_page = 'test_rendering' self.assertEqual('test_rendering', getDefaultPage(self.folder))
def test_getDefaultPage_step_2(self): # Else check for IBrowserDefault, either if the container implements # it or if an adapter exists. In both cases fetch its FTI and either # take it if it implements IDynamicViewTypeInformation or adapt it to # IDynamicViewTypeInformation. call getDefaultPage on the implementer # and take value if given. # first check some preconditions # # 1) a folder provides IBrowserDefault from Products.CMFDynamicViewFTI.interfaces import IBrowserDefault self.assertTrue(IBrowserDefault.providedBy(self.folder)) # 2) a folder also provides an fti that implements # IDynamicViewTypeInformation from Products.CMFDynamicViewFTI.interfaces import IDynamicViewTypeInformation # noqa fti = self.folder.getTypeInfo() self.assertTrue(IDynamicViewTypeInformation.providedBy(fti)) # so if we set a document as defaultpage self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.setDefaultPage('d1') # 3) fti should return it self.assertEqual( 'd1', fti.getDefaultPage(self.folder, check_exists=True) ) # now test since we're sure everythings set up correctly from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('d1', getDefaultPage(self.folder))
def test_getDefaultPage_step_3_2(self): # 3. Else, look up the attribute default_page on the object, without # acquisition in place # 3.2 look for a content at portal, with acquisition self.portal.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.default_page = 'd1' from plone.app.layout.navigation.defaultpage import getDefaultPage # now it must acquire from portal self.assertEqual('d1', getDefaultPage(self.folder)) # fetch from i.e. portal_skins by acquisition # test_rendering.pt is in portal_skins/plone_templates and so available # by acquisition self.folder.default_page = 'test_rendering' self.assertEqual('test_rendering', getDefaultPage(self.folder))
def default_context(self): # Try to get the default page context = self.context default = getDefaultPage(context) if default: context = context[default] return context
def get_basic_tags(self): try: context = self.context if ISiteRoot.providedBy(context): try: context = context[getDefaultPage(context)] except AttributeError: pass try: subject = context.Subject() except: subject = [] tags = { 'description': context.Description(), 'keywords': ','.join(subject), 'modificationDate': _date(context, 'modified'), 'publicationDate': _date(context, 'effective'), 'expirationDate': _date(context, 'expires'), 'generator': 'Castle CMS 1.0' } ldata = ILocation(context, None) if ldata is not None: if ldata.locations: location = ldata.locations if type(location) in (list, tuple, set): location = location[0] tags['location'] = location return ''.join([ u'<meta name="{}" content="{}">'.format(name, value) for name, value in tags.items() ]) except: return u''
def default_context(self): # Try to get the default page context = self.context default = getDefaultPage(context) if default: context = context[default] return context
def test_getDefaultPage_step_1(self): # A content object called 'index_html' wins self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.setDefaultPage('d1') self.folder.invokeFactory('Document', 'index_html', title=u"Doc 2") from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('index_html', getDefaultPage(self.folder))
def test_getDefaultPage_step_1(self): # A content object called 'index_html' wins self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") self.folder.setDefaultPage('d1') self.folder.invokeFactory('Document', 'index_html', title=u"Doc 2") from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('index_html', getDefaultPage(self.folder))
def test_getDefaultPage_step_4(self): # 4. Else, look up the property default_page in the configuration # registry for magic ids and test these registry = getUtility(IRegistry) registry['plone.default_page'] = [u'd1'] self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('d1', getDefaultPage(self.folder))
def test_getDefaultPage_step_4(self): # 4. Else, look up the property default_page in the configuration # registry for magic ids and test these registry = getUtility(IRegistry) registry['plone.default_page'] = [u'd1'] self.folder.invokeFactory('Document', 'd1', title=u"Doc 1") from plone.app.layout.navigation.defaultpage import getDefaultPage self.assertEqual('d1', getDefaultPage(self.folder))
def publish(self, item, level): default_page = getDefaultPage(item) if default_page is not None: try: item = item[default_page] except KeyError: pass title = '<h%d>%s</h%d>' % ( level, cgi.escape(item.Title()), level ) if default_page is not None: level += 1 try: text = item.getText() except AttributeError: if(item.portal_type == 'Image'): #text = '%s\n<img src="%s"/>' % (title, item.absolute_url_path()) return '' #don't show images for now elif(item.portal_type == 'Folder'): #text = '<div class="section" id="%s">%s</div>' % (item.UID(), title) return '' #don't show folders for now else: #return '<div class="section" id="%s">%s</div><p>%s content can not be embedded into the PDF.</p>' % (item.UID(), title, item.portal_type) return '' #don't show unkown types for now soup = BeautifulSoup(text) # Inline images. for link in soup.findAll("img"): self.inlineImage(item, link) # Resolve relative links. for link in soup.findAll("a"): self.resolveRelativeLink(item, link) headings = reduce( operator.add, itertools.imap(soup.findAll, ("h1", "h2", "h3", "h4", "h5")) ) if headings: levels = [(int(heading.name[1]), heading) for heading in headings] largest = min(l[0] for l in levels) difference = largest - level - 1 # Demote headings by the difference. if difference: for l, h in levels: h.name = "h%d" % (l - difference) return '<div class="section" id="%s">%s</div>' % (item.UID(),"\n".join((title, str(soup))))
def real_context(self): context = self.context if ISiteRoot.providedBy(context): # we're at site root but actually kind of want context front page try: context = context[getDefaultPage(context)] except (AttributeError, KeyError): pass if IDashboard.providedBy(context): context = self.site return context
def objects(self): """Returns the data to create the sitemap.""" catalog = getToolByName(self.context, 'portal_catalog') query = { 'sort_on': 'modified', 'sort_limit': MAX_ITEMS, 'sort_order': 'reverse' } utils = getToolByName(self.context, 'plone_utils') types = utils.getUserFriendlyTypes() if 'Image' in types: types.remove('Image') query['portal_type'] = types registry = getUtility(IRegistry) typesUseViewActionInListings = frozenset( registry.get('plone.types_use_view_action_in_listings', [])) is_plone_site_root = IPloneSiteRoot.providedBy(self.context) if not is_plone_site_root: query['path'] = '/'.join(self.context.getPhysicalPath()) root_page_uid = '' # The plone site root is not catalogued. if is_plone_site_root: loc = self.context.absolute_url() date = self.context.modified() # Comparison must be on GMT value modified = date.ISO8601() # special case, use front-page object try: page = self.context[getDefaultPage(self.context)] root_page_uid = IUUID(page) modified = page.modified().ISO8601() yield { 'loc': loc, 'lastmod': modified } except AttributeError: yield { 'loc': loc, 'lastmod': modified, } for item in catalog.searchResults(query)[:MAX_ITEMS]: # max of 50,000 items if root_page_uid == item.UID or item.id == 'Members': continue loc = item.getURL() date = item.modified.ISO8601() if item.portal_type in typesUseViewActionInListings: loc += '/view' yield { 'loc': loc, 'lastmod': date }
def get_ld_data(self): result = '' ld = ILDData(self.context, None) if ld is None: return '' result += self._wrap_ld(ld.get_data()) if ISiteRoot.providedBy(self.context): try: page = self.context[getDefaultPage(self.context)] result += self._wrap_ld(ILDData(page).get_data()) except AttributeError: pass return result
def publish(self, item, level): default_page = getDefaultPage(item) if default_page is not None: try: item = item[default_page] except KeyError: pass title = '<h%d>%s</h%d>' % ( level, cgi.escape(item.Title()), level ) if default_page is not None: level += 1 try: text = item.getText() except AttributeError: return title soup = BeautifulSoup(text) # Inline images. for link in soup.findAll("img"): self.inlineImage(item, link) # Resolve relative links. for link in soup.findAll("a"): self.resolveRelativeLink(item, link) headings = reduce( operator.add, itertools.imap(soup.findAll, ("h1", "h2", "h3", "h4", "h5")) ) if headings: levels = [(int(heading.name[1]), heading) for heading in headings] largest = min(l[0] for l in levels) difference = largest - level - 1 # Demote headings by the difference. if difference: for l, h in levels: h.name = "h%d" % (l - difference) return '<div class="section">%s</div>' % "\n".join((title, str(soup)))
def get_main_links(self): viewlet = GlobalSectionsViewlet(self.context, self.request, None) viewlet.update() selected_tab = viewlet.selected_portal_tab site = api.portal.get() site_default_page = getDefaultPage(site) if selected_tab == site_default_page: selected_tab = 'index_html' default_page_url = '{}/{}'.format(site.absolute_url(), site_default_page) tabs = [] for tab in viewlet.portal_tabs: if tab['url'] == default_page_url: continue tabs.append(tab) return {'selected_portal_tab': selected_tab, 'portal_tabs': tabs}
def __init__(self, context, request): super(EventListing, self).__init__(context, request) self.now = now = localized_now(context) # Try to get the default page default = getDefaultPage(context) self.default_context = context[default] if default else context self.is_collection = False if ICollection: self.is_collection = ICollection.providedBy(self.default_context) # Request parameter req = self.request.form b_size = int(req.get('b_size', 0)) if not b_size and self.is_collection: collection_behavior = ICollection(self.default_context) b_size = getattr(collection_behavior, 'item_count', 0) self.b_size = b_size or 10 self.b_start = int(req.get('b_start', 0)) self.orphan = int(req.get('orphan', 1)) self.mode = req.get('mode', None) self._date = req.get('date', None) self.tags = req.get('tags', None) self.searchable_text = req.get('SearchableText', None) self.path = req.get('path', None) day = int(req.get('day', 0)) or None month = int(req.get('month', 0)) or None year = int(req.get('year', 0)) or None if not self._date and day or month or year: self._date = date(year or now.year, month or now.month, day or now.day).isoformat() if self.mode is None: self.mode = 'day' if self._date else 'future' self.uid = None # Used to get all occurrences from a single event. Overrides all other settings # noqa
def save(self): adapted = ILayoutAware(self.context) data = self.request.form.get('data') if not data: return data = json.loads(data) adapted.pageSiteLayout = data['page_layout'] adapted.sectionSiteLayout = data['section_layout'] parent = aq_parent(self.context) if ISiteRoot.providedBy(parent): # check if default page... if getDefaultPage(parent) == self.context.id: # also set site wide global layout setting... registry = getUtility(IRegistry) field = registry_field.TextLine(title=u'Default layout', required=False) new_record = Record(field) registry.records['castle.cms.default_layout'] = new_record registry['castle.cms.default_layout'] = data['section_layout'] return {'success': True}
def migrateChildFolders(context): """Migrates Child Folder objects to normal Folder objects that are subtyped""" logger.info('Migrating child folder objects to normal folder objects') # allow the Child Folder type to be addable pt = getToolByName(context, "portal_types") pw = getToolByName(context, "portal_workflow") cf_type = pt["Child Folder"] cf_type.global_allow = True pc = getToolByName(context, 'portal_catalog') brains = pc.searchResults(portal_type="Child Folder") while brains: child_folder = brains[0].getObject() logger.info('Migrating child folder %s' % child_folder.getId()) parent = child_folder.getParentNode() # we will keep the same state, title, description, id # and display cf_state = pw.getInfoFor(child_folder, "review_state") cf_wf = pw.getDefaultChainFor(child_folder) cf_wf = cf_wf and cf_wf[0] cf_title = child_folder.Title() cf_desc = child_folder.Description() cf_orig_id = child_folder.getId() has_layout = base_hasattr(child_folder, "layout") if has_layout: cf_display = child_folder.layout cf_default_page = getDefaultPage(child_folder) f_temp_id = '%s-temp' % cf_orig_id parent.invokeFactory("Folder", f_temp_id) new_folder = parent[f_temp_id] new_folder.setTitle(cf_title) new_folder.setDescription(cf_desc) if has_layout: new_folder.layout = cf_display new_folder.processForm() provideUtility(engine.Subtyper()) subtyper = getUtility(interfaces.ISubtyper) subtyper.change_type(new_folder, u'collective.lineage.childsite') if cf_wf: new_state = { 'actor': 'Administrator', 'action': None, 'review_state': cf_state, 'time': DateTime(), 'comments': 'setting up the workflow of the item correctly', } pw.setStatusOf(cf_wf, new_folder, new_state) new_folder.reindexObject() children_ids = child_folder.objectIds() if children_ids: cut_items = child_folder.manage_cutObjects(ids=children_ids) new_folder.manage_pasteObjects(cut_items) if cf_default_page: new_folder.setDefaultPage(cf_default_page) copy_portlet_assignments_and_settings(child_folder, new_folder) copy_sharing_settings(child_folder, new_folder) parent.manage_delObjects([cf_orig_id]) transaction.savepoint() parent.manage_renameObjects([f_temp_id], [cf_orig_id]) transaction.savepoint() brains = pc.searchResults(portal_type="Child Folder") pw.updateRoleMappings() cf_type.global_allow = False logger.info('Finished migrating child folders')
def getTranslationActionItems(context, request): """Return action menu items for 'Translate' menu.""" parent = context.__parent__ is_default_page = isDefaultPage(parent, context) # There is a special case here which is when the ``context`` is a # default page. In this case, we compute the nearest translations # of the parent folder, unless the parent is a navigation or site # root. use_parent = False graph = ITranslationGraph(context) current_lang = getattr(aq_base(context), "language", "") lt = getToolByName(context, 'portal_languages') pt = getToolByName(context, name="portal_url") showflags = lt.showFlags() default_lang = lt.getDefaultLanguage() display_languages = request.locale.displayNames.languages site = pt.getPortalObject() site_url = site.absolute_url() if use_parent: lang_items = ITranslationGraph(parent).getNearestTranslations() else: lang_items = graph.getNearestTranslations() menu = [] for lang_id, item, distance in lang_items: if lang_id == current_lang: continue if not current_lang and lang_id == default_lang: continue icon = showflags and lt.getFlagForLanguageCode(lang_id) or None display_lang_name = display_languages[lang_id] title = unicode(display_lang_name) if use_parent: if distance >= 0: distance += 1 if item is not None: default_page = getDefaultPage(item) if default_page is not None: item = item[default_page] distance = 0 else: add_context = context else: add_context = parent else: add_context = context # If the item already exists, link to its default view. if distance == 0: assert item is not None fti = getUtility(IDexterityFTI, name=item.portal_type) info = fti.getActionInfo('object/view') url = "/" + info['url'] title += u" ✓" # Otherwise, link to the add form. else: uuid = str(IUUID(add_context)) portal_type = add_context.portal_type title = _(u"${title} (add...)", mapping={'title': title}) url = "/++add++%s?%s" % (portal_type, urllib.urlencode({ 'translation': uuid, 'language': lang_id, })) if item is None: if lang_id == default_lang: item = site else: try: item = site[lang_id] except KeyError: title = _(u"${lang_name} (setup required)", mapping={'lang_name': title}) url = site_url + "/" + lang_id + url url = "/@@setup-language?language=%s&next_url=%s" % ( lang_id, urllib.quote_plus(url)) action_url = site_url + url if item is not None: action_url = item.absolute_url() + url.rstrip('/') entry = { "title": translate(title, context=request), "description": _(u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": display_lang_name}), "action": action_url, "selected": False, "icon": icon, "width": 14, "height": 11, "extra": { "id": "translate_into_%s" % lang_id, "separator": None, "class": "" }, "submenu": None, } menu.append(entry) menu.sort(key=lambda item: unicode(item['title'])) if graph.getTranslations(): menu.append({ "title": _(u"Clear..."), "description": _(u"Clear the list of translation references."), "action": graph.context.absolute_url() + "/@@clear-translations", "selected": False, "icon": None, "extra": { "id": "clearTranslations", "separator": None, "class": "" }, "submenu": None, }) else: menu.append({ "title": _(u"This is a translation of..."), "description": _(u"Mark this item as the translation for " u"another content item on the site."), "action": graph.context.absolute_url() + "/@@set-translation-for", "selected": False, "icon": None, "extra": { "id": "setTranslationFor", "separator": None, "class": "" }, "submenu": None, }) return menu
def get_popularity(site): setSite(site) catalog = api.portal.get_tool('portal_catalog') es = ElasticSearchCatalog(catalog) if not es.enabled: return service = analytics.get_ga_service() if not service: return profile = analytics.get_ga_profile(service) if not profile: return bulk_data = [] bulk_size = es.get_setting('bulk_size', 50) conn = es.connection site._p_jar.sync() for path, page_views in get_results(service, profile)['rows']: path = path.split('?')[0].lstrip('/').replace('/view', '').split('@@')[0] ob = site.restrictedTraverse(str(path), None) if ob is None: continue annotations = IAnnotations(ob) data = {'page_views': int(page_views)} counts = annotations.get(COUNT_ANNOTATION_KEY, OOBTree()) counts['page_views'] = int(page_views) annotations[COUNT_ANNOTATION_KEY] = counts for key, value in counts.items(): if key in ('page_views', ): continue data[key + '_shares'] = value if IPloneSiteRoot.providedBy(ob): ob = ob[getDefaultPage(ob)] bulk_data.extend([{ 'update': { '_index': es.index_name, '_type': es.doc_type, '_id': IUUID(ob) } }, { 'doc': data }]) if len(bulk_data) % bulk_size == 0: conn.bulk(index=es.index_name, doc_type=es.doc_type, body=bulk_data) bulk_data = [] transaction.commit() site._p_jar.sync() if len(bulk_data) > 0: conn.bulk(index=es.index_name, doc_type=es.doc_type, body=bulk_data) transaction.commit()
def _get_default_page(self, content): default_page = getDefaultPage(content) if not default_page: default_page = content.getProperty('default_page') return default_page
def getTranslationActionItems(context, request): """Return action menu items for 'Translate' menu.""" parent = context.__parent__ is_default_page = isDefaultPage(parent, context) # There is a special case here which is when the ``context`` is a # default page. In this case, we compute the nearest translations # of the parent folder, unless the parent is a navigation or site # root. use_parent = False graph = ITranslationGraph(context) current_lang = getattr(aq_base(context), "language", "") lt = getToolByName(context, 'portal_languages') pt = getToolByName(context, name="portal_url") showflags = lt.showFlags() default_lang = lt.getDefaultLanguage() display_languages = request.locale.displayNames.languages site = pt.getPortalObject() site_url = site.absolute_url() if use_parent: lang_items = ITranslationGraph(parent).getNearestTranslations() else: lang_items = graph.getNearestTranslations() menu = [] for lang_id, item, distance in lang_items: if lang_id == current_lang: continue if not current_lang and lang_id == default_lang: continue icon = showflags and lt.getFlagForLanguageCode(lang_id) or None display_lang_name = display_languages[lang_id] title = unicode(display_lang_name) if use_parent: if distance >= 0: distance += 1 if item is not None: default_page = getDefaultPage(item) if default_page is not None: item = item[default_page] distance = 0 else: add_context = context else: add_context = parent else: add_context = context # If the item already exists, link to its default view. if distance == 0: assert item is not None fti = getUtility(IDexterityFTI, name=item.portal_type) info = fti.getActionInfo('object/view') url = "/" + info['url'] title += u" ✓" # Otherwise, link to the add form. else: uuid = str(IUUID(add_context)) portal_type = add_context.portal_type title = _(u"${title} (add...)", mapping={'title': title}) url = "/++add++%s?%s" % ( portal_type, urllib.urlencode({ 'translation': uuid, 'language': lang_id, })) if item is None: if lang_id == default_lang: item = site else: try: item = site[lang_id] except KeyError: title = _(u"${lang_name} (setup required)", mapping={'lang_name': title}) url = site_url + "/" + lang_id + url url = "/@@setup-language?language=%s&next_url=%s" % ( lang_id, urllib.quote_plus(url)) action_url = site_url + url if item is not None: action_url = item.absolute_url() + url.rstrip('/') entry = { "title": translate(title, context=request), "description": _(u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": display_lang_name}), "action": action_url, "selected": False, "icon": icon, "width": 14, "height": 11, "extra": {"id": "translate_into_%s" % lang_id, "separator": None, "class": ""}, "submenu": None, } menu.append(entry) menu.sort(key=lambda item: unicode(item['title'])) if graph.getTranslations(): menu.append({ "title": _(u"Clear..."), "description": _(u"Clear the list of translation references."), "action": graph.context.absolute_url() + "/@@clear-translations", "selected": False, "icon": None, "extra": {"id": "clearTranslations", "separator": None, "class": ""}, "submenu": None, }) else: menu.append({ "title": _(u"This is a translation of..."), "description": _(u"Mark this item as the translation for " u"another content item on the site."), "action": graph.context.absolute_url() + "/@@set-translation-for", "selected": False, "icon": None, "extra": {"id": "setTranslationFor", "separator": None, "class": ""}, "submenu": None, }) return menu
def archive(site): setup_site(site) if (not api.portal.get_registry_record('castle.archival_enabled') or not api.portal.get_registry_record('castle.aws_s3_bucket_name') or not api.portal.get_registry_record('castle.aws_s3_key') or not api.portal.get_registry_record('castle.aws_s3_secret') or not api.portal.get_registry_record('plone.public_url')): logger.error( 'Can not archive content. Either not enabled, S3 API not set or no public ' 'url set') return storage = archival.Storage(site) for brain in archival.getContentToArchive(): try: ob = brain.getObject() container = aq_parent(ob) if (IPloneSiteRoot.providedBy(container) and getDefaultPage(container) == ob.getId()): continue allowed = set(rolesForPermissionOn('View', ob)) if 'Anonymous' not in allowed: # we can *not* archive unpublished content continue new_url = storage.add_content(ob) # resets login creds.. login_as_admin(app) # noqa if new_url: logger.warn('imported %s -> %s' % (ob.absolute_url(), new_url)) # XXX might need to re-architect... might get conflict errors with how slow # archiving takes... api.content.delete(ob) transaction.commit() else: logger.error('error importing %s' % ob.absolute_url()) except: logger.error('Error archiving %s' % brain.getPath(), exc_info=True) content_to_archive = archival.getContentToArchive(7) if len(content_to_archive) == 0: return backend_url = get_backend_url() # send out email warning of content about to be archived email_text = """ <p>Warning, this content will be archived in 7 days. Login to <a href="{site_url}">{site_title}</a> to extend this content. </p> <ul>""".format(site_title=api.portal.get_registry_record('plone.site_title'), site_url=backend_url) site_url = api.portal.get().absolute_url() for brain in content_to_archive: url = brain.getURL() url = url.replace(site_url, backend_url) email_text += """<li> <a href="{url}">{title}</a></li>""".format(url=url, title=brain.Title) email_text += '</ul>' for user in api.user.get_users(): roles = api.user.get_roles(user=user) if ('Site Administrator' not in roles and 'Manager' not in roles): continue email = user.getProperty('email') if not email: continue name = user.getProperty('fullname') or user.getId() html = '<p>Hi {name},</p>'.format(name=name) + email_text send_email(recipients=email, subject="Content will be archived(Site: %s)" % (api.portal.get_registry_record('plone.site_title')), html=html)
def _get_default_page(self, content): default_page = getDefaultPage(content) if not default_page: default_page = content.getProperty('default_page') return default_page
def objectAddedEvent(context, event): """Handle event that translation was added. By convention, when a translation is created, its ``translations`` attribute is set to a list with a single item, which is the translation source. In this event handler, we simply reverse that relationship. """ container = event.newParent # If we're copying an item, than we can expect a volatile # attribute to contain a reference to the original item. This # information is turned into a translation reference below. try: uuid, language = context._v_multilingual_copy except AttributeError: is_copy = False translations = getattr(aq_base(context), "translations", None) if translations: uuid = list(translations)[0] del context.translations else: uuid = None else: # The Plone site root is a special case, because it always has # a language setting, so the check below won't work. if IPloneSiteRoot.providedBy(container): return # If we're copying the item into the same language, then we do # nothing. if language == getattr(aq_base(container), "language"): return is_copy = True # Inherit the language of the container to which the item is # added. if not IPloneSiteRoot.providedBy(container): if not context.language: context.language = aq_base(container).language catalog = getToolByName(container, 'portal_catalog') result = catalog(UID=uuid) if len(result) != 1: return parent = result[0].getObject() if not is_copy and parent.creation_date >= context.creation_date: logger.warn( "parent %r is newer than translation %r." % ( uuid, str(IUUID(context))) ) # If the item being copied or translated was a default page, apply # the same setting to this item, relative to its container. if getDefaultPage(container) is None: if isDefaultPage(parent.__parent__, parent): objectId = context.getId() container.setDefaultPage(objectId) modified(container) # If this item is being copied into a language folder, make sure # we unregister an existing translation. if is_copy: for language, obj in ITranslationGraph(parent).getTranslations(): if language == container.language: ITranslationGraph(obj).unregisterTranslation(parent) # Now, append the translation to the source item's list. wrapped = context.__of__(container) ITranslationGraph(wrapped).registerTranslation(parent) modified(parent) # For technical reasons, we need to invalidate the counter # explicitly because the item being added might not yet be # catalogued. getPersistentTranslationCounter(parent).change(1)
def objectAddedEvent(context, event): """Handle event that translation was added. By convention, when a translation is created, its ``translations`` attribute is set to a list with a single item, which is the translation source. In this event handler, we simply reverse that relationship. """ container = event.newParent # If we're copying an item, than we can expect a volatile # attribute to contain a reference to the original item. This # information is turned into a translation reference below. try: uuid, language = context._v_multilingual_copy except AttributeError: is_copy = False translations = getattr(aq_base(context), "translations", None) if translations: uuid = list(translations)[0] del context.translations else: uuid = None else: # The Plone site root is a special case, because it always has # a language setting, so the check below won't work. if IPloneSiteRoot.providedBy(container): return # If we're copying the item into the same language, then we do # nothing. if language == getattr(aq_base(container), "language"): return is_copy = True # Inherit the language of the container to which the item is # added. if not IPloneSiteRoot.providedBy(container): if not context.language: context.language = aq_base(container).language catalog = getToolByName(container, 'portal_catalog') result = catalog(UID=uuid) if len(result) != 1: return parent = result[0].getObject() if not is_copy and parent.creation_date >= context.creation_date: logger.warn("parent %r is newer than translation %r." % (uuid, str(IUUID(context)))) # If the item being copied or translated was a default page, apply # the same setting to this item, relative to its container. if getDefaultPage(container) is None: if isDefaultPage(parent.__parent__, parent): objectId = context.getId() container.setDefaultPage(objectId) modified(container) # If this item is being copied into a language folder, make sure # we unregister an existing translation. if is_copy: for language, obj in ITranslationGraph(parent).getTranslations(): if language == container.language: ITranslationGraph(obj).unregisterTranslation(parent) # Now, append the translation to the source item's list. wrapped = context.__of__(container) ITranslationGraph(wrapped).registerTranslation(parent) modified(parent) # For technical reasons, we need to invalidate the counter # explicitly because the item being added might not yet be # catalogued. getPersistentTranslationCounter(parent).change(1)