def publishTraverse(self, request, name): match = re.compile('^(\d+)-(\d+)$').match(name) if match: version1 = self.context._getOb(match.group(1), None) version2 = self.context._getOb(match.group(2), None) if IVersion.providedBy(version1) and IVersion.providedBy(version2): self.version1 = version1 self.version2 = version2 self.__name__ = '/'.join((self.__name__, name)) return self return super(CompareVersionScreen, self).publishTraverse(request, name)
def endElementNS(self, name, qname): if (NS_EDITOR_URI, 'text') == name: # Close the root tag self.proxy.endElementNS((NS_HTML_URI, 'div'), 'div') # Find the version. It is should the result of on the parent handler version = None handler = self.parentHandler() while handler: result = handler.result() if IVersion.providedBy(result): version = result break handler = handler.parentHandler() if version is None: raise RuntimeError( 'expected an IVersion in handler parent chain results') # Get the text to save without the root element we added. text = u'\n'.join( map(lxml.etree.tostring, self.proxy.etree.getroot())) # Save the text and clear the proxy. self.parent().save(version, self, text, ISilvaXMLImportFilter) self.proxy = None else: ns, localname = name if self.proxy is None: raise RuntimeError('Invalid HTML') self.proxy.endElementNS(name, qname)
def get_lookup_content(content): if IVersion.providedBy(content): content = content.get_silva_object() if (ISilvaObject.providedBy(content) and not IContainer.providedBy(content)): return content.get_container() return content
def make_import_log(context, importer, identifier='import_log'): # All of this need improvements log = context._getOb(identifier, None) if log is None: factory = context.manage_addProduct['silva.app.document'] factory.manage_addDocument(identifier, 'Import log') log = context._getOb(identifier) version = log.get_editable() service = getUtility(IReferenceService) html = ['<h2> Import inside {0}</h2><ul>'.format( importer.root.get_title_or_id())] for reason, content in importer.getProblems(): if IVersion.providedBy(content): content = content.get_silva_object() tag = unicode(uuid.uuid1()) reference = service.new_reference(version, name=u"body link") reference.set_target(content) reference.add_tag(tag) html.extend(['<li><a class="link" reference="{0}">'.format(tag), content.get_title_or_id(), '</a>: ', reason, '</li>']) html.append('</ul>') version.body.save_raw_text(''.join(html) + unicode(version.body)) notify(ObjectModifiedEvent(version))
def remove_markers(content, event): target = content if IVersion.providedBy(content): target = content.get_silva_object() for marker in event.design.markers: if marker.providedBy(target): noLongerProvides(target, marker)
def update(self): references = {} service = getUtility(IReferenceService) get_icon = IIconResolver(self.request).get_tag for reference in service.get_references_to(self.context): source = reference.source source_versions = [] if IVersion.providedBy(source): source_versions.append(source.id) source = source.get_silva_object() url = getMultiAdapter((source, self.request), IContentURL) edit_url = str(url) + '/edit' if edit_url in references and source_versions: previous_versions = references[edit_url]['versions'] if previous_versions[-1] > source_versions[0]: bisect.insort_right( previous_versions, source_versions[0]) continue else: source_versions = previous_versions + source_versions source_title = source.get_title_or_id() references[edit_url] = { 'title': source_title, 'path': self.view.get_content_path(source), 'icon': get_icon(source), 'versions': source_versions} self.references = references.values() self.references.sort(key=lambda info: info['title'].lower()) for info in self.references: if info['versions']: info['title'] += ' (' + ', '.join(info['versions']) + ')'
def set_smi_skin(context, request, default='silva.ui.interfaces.ISilvaUITheme'): """Set the SMI skin. """ if ISilvaObject.providedBy(context) or IVersion.providedBy(context): skin_name = context.get_root()._smi_skin if not skin_name: skin_name = default applySkin(request, getUtility(Interface, skin_name))
def is_silva_content(self, content): """Is the content a Silva content ? You can override this method in a subclass to change this behaviour. """ cls = content['instance'] return (ISilvaObject.implementedBy(cls) or IVersion.implementedBy(cls))
def has_default_metadata(self, content): """Tell if the content should have default metadata set sets. You can override this method in a subclass to change this behaviour. """ cls = content['instance'] return ((ISilvaObject.implementedBy(cls) and not interfaces.IVersionedObject.implementedBy(cls)) or IVersion.implementedBy(cls))
def publishTraverse(self, request, name): match = re.compile('^(\d+)$').match(name) if match: version = self.context._getOb(match.group(1), None) if IVersion.providedBy(version): self.version = version self.__name__ = '/'.join((self.__name__, name)) return self return super(ViewVersion, self).publishTraverse(request, name)
def render(self, item): content = item.getObject() title = content.get_title_or_id() if IVersion.providedBy(content): url = absoluteURL(content.get_silva_object(), self.request) else: url = absoluteURL(content, self.request) ellipsis = '…' if len(title) > 50: title = title[:50] + ellipsis return '<a href="%s" class="searchresult-link">%s</a>' % (url, title)
def _validate(self, value): super(ID, self)._validate(value) if self.context: context = self.context if IVersion.providedBy(context) or ISilvaObject.providedBy(context): context = context.get_container() try: ISilvaNameChooser(context).checkName(value, None) except ContentError as error: raise InvalidID(error.reason) return
def __init__(self, page, reference, content): if IVersion.providedBy(content): self.content = content.get_silva_object() self.title = u'{} (version {})'.format( self.content.get_title_or_id(), content.getId()) else: self.content = content self.title = self.content.get_title_or_id() self.icon = page.get_icon(self.content) self.path = page.get_content_path(self.content) self.tags = reference.tags
def test_get_versions(self): """ get versions ordered by id """ content = self.root.test publisher = IPublicationWorkflow(content) for i in range(0, 10): publisher.publish() publisher.new_version() versions = publisher.get_versions() self.assertEquals(11, len(versions)) for version in versions: self.assertTrue(IVersion.providedBy(version)) self.assertTrue(content, version.get_content())
def configure_content(self, root, extension): """Configure extension content: metadata, addables, security. """ contents = extension.get_content() # Configure addables if not self._is_installed.addables: addables = [] not_addables = [] for content in contents: if self.is_silva_addable(content): if content['name'] not in self.not_globally_addables: addables.append(content['name']) else: not_addables.append(content['name']) self.configure_addables(root, addables, not_addables) # Configure security if not self._is_installed.security: secured_contents = [] for content in contents: if self.is_silva_content(content): secured_contents.append(content['name']) self.configure_security(root, secured_contents) # Configure metadata if not self._is_installed.metadata: viewables = [] others = [] for content in contents: if self.has_default_metadata(content): if (IViewableObject.implementedBy(content['instance']) or IVersion.implementedBy(content['instance'])): viewables.append(content['name']) else: others.append(content['name']) if viewables: root.service_metadata.addTypesMapping( viewables, ('silva-content', 'silva-extra', 'silva-settings')) if others: root.service_metadata.addTypesMapping( others, ('silva-content', 'silva-extra'))
def __init__(self, screen): # Follow Zope 2 information to appear in the undo log. note = [] if ISilvaObject.providedBy(screen.context) or IVersion.providedBy(screen.context): note.append("/".join(screen.context.getPhysicalPath())) else: note.append("/") names = [] while IRESTComponent.providedBy(screen): names.append(screen.__name__) screen = screen.__parent__ if names: note.extend(["SMI action:", "/".join(reversed(names))]) self.note = " ".join(note) self.user = getSecurityManager().getUser() self.user_path = "" auth_folder = aq_parent(self.user) if auth_folder is not None: self.user_path = "/".join(auth_folder.getPhysicalPath()[1:-1])
def to_html(self, content, request, **parameters): """ render HTML for SQL source """ values = self._get_data(parameters) names = values.names() batch_size = self._default_batch_size if parameters.get('sqlbatchsize'): batch_size = int(parameters.get('sqlbatchsize')) data = Batch( values.dictionaries(), factory=self._decode_dict_helper, count=batch_size, name=self.getId(), request=request) model = content if IVersion.providedBy(content): model = content.get_content() layout = self._getOb(self._layout_id) batch = getMultiAdapter((model, data, request), IBatching)() return layout( table=data, batch=batch, names=names, parameters=parameters)
def to_html(self, content, request, **parameters): """ render HTML for CSV source """ rows = self._data[:] param = {} param.update(parameters) if not param.get('csvtableclass'): param['csvtableclass'] = 'default' batch_size = self._default_batch_size batch = '' if param.get('csvbatchsize'): batch_size = int(param.get('csvbatchsize')) model = content if IVersion.providedBy(content): model = content.get_content() if rows: headings = rows[0] rows = Batch( rows[1:], count=batch_size, name=self.getId(), request=request) param['headings'] = headings batch = getMultiAdapter((model, rows, request), IBatching)() return self.layout(table=rows, batch=batch, parameters=param)
def to_html(self, content, request, **parameters): """ render HTML for CSV source """ rows = self._data[:] param = {} param.update(parameters) if not param.get('csvtableclass'): param['csvtableclass'] = 'default' batch_size = self._default_batch_size batch = '' if param.get('csvbatchsize'): batch_size = int(param.get('csvbatchsize')) model = content if IVersion.providedBy(content): model = content.get_content() if rows: headings = rows[0] rows = Batch(rows[1:], count=batch_size, name=self.getId(), request=request) param['headings'] = headings batch = getMultiAdapter((model, rows, request), IBatching)() return self.layout(table=rows, batch=batch, parameters=param)
def render(self, item): ellipsis = '…' maxwords = 40 searchterm = str(self.request.form.get('fulltext', ''), 'utf8') catalog = self.context.service_catalog fulltext = catalog.getIndexDataForRID(item.getRID()).get( 'fulltext', []) if not fulltext: # no fulltext available, probably an image return '' content = item.getObject() # since fulltext always starts with id and title, lets remove that idstring = content.id if IVersion.providedBy(content): idstring = content.get_silva_object().id skipwords = len(('%s %s' % (idstring, content.get_title())).split(' ')) fulltext = fulltext[skipwords:] fulltextstr = ' '.join(fulltext) searchterms = searchterm.split() if not searchterms: # searchterm is not specified, # return the first 20 words text = ' '.join(fulltext[:maxwords]) if IVersion.providedBy(content) and hasattr(content, 'fulltext'): realtext = ' '.join(content.fulltext()[2:]) # replace multiple whitespace characters with one space realtext = re.compile('[\ \n\t\xa0]+').sub(' ', realtext) text = ' '.join(realtext.split()[:maxwords]) if len(fulltext) > maxwords: text += ' ' + ellipsis else: words = maxwords / len(searchterms) text = [] lowestpos = len(fulltext) highestpos = 0 hilite_terms = [] for searchterm in searchterms: term = re.escape(searchterm) if '?' in term or '*' in term: termq = term.replace('\\?', '.') termq = termq.replace('\\*', '.[^\ ]*') term_found = re.compile(termq).findall(fulltextstr) if term_found: hilite_terms += term_found searchterms.remove(searchterm) term = term_found[0] searchterms.append(term.strip()) else: hilite_terms.append(term) else: hilite_terms.append(term) if not term in fulltext: # term matched probably something in the title # return the first n words: line = ' '.join(fulltext[:words]) text.append(line) lowestpos = 0 highestpos = words continue pos = fulltext.index(term) if pos < lowestpos: lowestpos = pos if pos > highestpos: highestpos = pos start = pos - (words / 2) end = pos + (words / 2) + 1 if start < 0: end += -start start = 0 pre = ' '.join(fulltext[start:pos]) post = ' '.join(fulltext[pos + 1:end]) if not text and start != 0: # we're adding the first (splitted) result # and it's not at the beginning of the fulltext # lets add an ellipsis pre = ellipsis + pre text.append('%s %s %s %s' % (pre, fulltext[pos], post, ellipsis)) # if all the terms that are found are close together, # then use this, otherwise, we would end # up with the same sentence for each searchterm # this code will create a new text result list, which # does not have 'split' results. if lowestpos < highestpos: if highestpos - lowestpos < maxwords: padding = (maxwords - (highestpos - lowestpos)) / 2 lowestpos -= padding highestpos += padding if lowestpos < 0: highestpos += -lowestpos lowestpos = 0 text = fulltext[lowestpos:highestpos] if not lowestpos == 0: text[0] = '%s %s' % (ellipsis, text[0]) if highestpos < len(fulltext) - 1: text[-1] += ' %s' % ellipsis # do some hiliting, use original text # (with punctuation) if this is a silva document text = ' '.join(text) if IVersion.providedBy(content) and hasattr(content, 'fulltext'): realtext = ' '.join(content.fulltext()[2:]) # replace multiple whitespace characters with one space realtext = re.compile('[\ \n\t\xa0]+').sub(' ', realtext) textparts = text.split(ellipsis) new = [] for textpart in textparts: if textpart == '': new.append('') continue textpart = textpart.strip() find = textpart.replace(' ', '[^a-zA-Z0-9]+') textexpr = re.compile(find, re.IGNORECASE) text = textexpr.findall(realtext) if text: text = text[0] else: # somehow we can't find a match in original text # use the one from the catalog text = textpart new.append(text) text = ellipsis.join(new) for term in hilite_terms: if term.startswith('"'): term = term[1:] if term.endswith('"'): term = term[:-1] term = re.escape(term) text = ' ' + text regexp = re.compile( '([^a-zA-Z0-9]+)(%s)([^a-zA-Z0-9]+)' % term.lower(), re.IGNORECASE) sub = ('\g<1><strong class="search-result-snippet-hilite">' '\g<2></strong>\g<3>') text = regexp.sub(sub, text) return '<div class="searchresult-snippet">%s</div>' % text.strip()
def render(self, item): ellipsis = '…' maxwords = 40 searchterm = unicode(self.request.form.get('fulltext', ''), 'utf8') catalog = self.context.service_catalog fulltext = catalog.getIndexDataForRID(item.getRID()).get('fulltext', []) if not fulltext: # no fulltext available, probably an image return '' content = item.getObject() # since fulltext always starts with id and title, lets remove that idstring = content.id if IVersion.providedBy(content): idstring = content.get_silva_object().id skipwords = len(('%s %s' % (idstring, content.get_title())).split(' ')) fulltext = fulltext[skipwords:] fulltextstr = ' '.join(fulltext) searchterms = searchterm.split() if not searchterms: # searchterm is not specified, # return the first 20 words text = ' '.join(fulltext[:maxwords]) if IVersion.providedBy(content) and hasattr(content, 'fulltext'): realtext = ' '.join(content.fulltext()[2:]) # replace multiple whitespace characters with one space realtext = re.compile('[\ \n\t\xa0]+').sub(' ', realtext) text = ' '.join(realtext.split()[:maxwords]) if len(fulltext) > maxwords: text += ' ' + ellipsis else: words = maxwords / len(searchterms) text = [] lowestpos = len(fulltext) highestpos = 0 hilite_terms = [] for searchterm in searchterms: term = re.escape(searchterm) if '?' in term or '*' in term: termq = term.replace('\\?', '.') termq = termq.replace('\\*', '.[^\ ]*') term_found = re.compile(termq).findall(fulltextstr) if term_found: hilite_terms += term_found searchterms.remove(searchterm) term = term_found[0] searchterms.append(term.strip()) else: hilite_terms.append(term) else: hilite_terms.append(term) if not term in fulltext: # term matched probably something in the title # return the first n words: line = ' '.join(fulltext[:words]) text.append(line) lowestpos = 0 highestpos = words continue pos = fulltext.index(term) if pos < lowestpos: lowestpos = pos if pos > highestpos: highestpos = pos start = pos -(words/2) end = pos + (words/2) + 1 if start < 0 : end += -start start = 0 pre = ' '.join(fulltext[start:pos]) post = ' '.join(fulltext[pos+1:end]) if not text and start != 0: # we're adding the first (splitted) result # and it's not at the beginning of the fulltext # lets add an ellipsis pre = ellipsis + pre text.append('%s %s %s %s' % ( pre, fulltext[pos], post, ellipsis) ) # if all the terms that are found are close together, # then use this, otherwise, we would end # up with the same sentence for each searchterm # this code will create a new text result list, which # does not have 'split' results. if lowestpos < highestpos: if highestpos - lowestpos < maxwords: padding = (maxwords-(highestpos - lowestpos ))/2 lowestpos -= padding highestpos += padding if lowestpos < 0: highestpos += -lowestpos lowestpos = 0 text = fulltext[lowestpos:highestpos] if not lowestpos == 0: text[0] = '%s %s' % (ellipsis, text[0]) if highestpos < len(fulltext)-1: text[-1] += ' %s' % ellipsis # do some hiliting, use original text # (with punctuation) if this is a silva document text = ' '.join(text) if IVersion.providedBy(content) and hasattr(content, 'fulltext'): realtext = ' '.join(content.fulltext()[2:]) # replace multiple whitespace characters with one space realtext = re.compile('[\ \n\t\xa0]+').sub(' ', realtext) textparts = text.split(ellipsis) new = [] for textpart in textparts: if textpart == '': new.append('') continue textpart = textpart.strip() find = textpart.replace(' ', '[^a-zA-Z0-9]+') textexpr = re.compile(find, re.IGNORECASE) text = textexpr.findall(realtext) if text: text = text[0] else: # somehow we can't find a match in original text # use the one from the catalog text = textpart new.append(text) text = ellipsis.join(new) for term in hilite_terms: if term.startswith('"'): term = term[1:] if term.endswith('"'): term = term[:-1] term = re.escape(term) text = ' ' + text regexp = re.compile( '([^a-zA-Z0-9]+)(%s)([^a-zA-Z0-9]+)' % term.lower(), re.IGNORECASE) sub = ('\g<1><strong class="search-result-snippet-hilite">' '\g<2></strong>\g<3>') text = regexp.sub(sub, text) return '<div class="searchresult-snippet">%s</div>' % text.strip()
def render(self, item): content = item.getObject() if IVersion.providedBy(content): content = content.get_silva_object() return self.get_icon(content)
def set_markers(content, event): target = content if IVersion.providedBy(content): target = content.get_silva_object() for marker in event.design.markers: alsoProvides(target, marker)
def update(self): super(HTMLInputWidget, self).update() content = self.form.context if IVersion.providedBy(content): content = content.get_silva_object() self.configuration = content.meta_type