def inline_stream(text): """Turn a text into a list of events similar to XML: START_ELEMENT, END_ELEMENT, TEXT. Inline elements (emphasis, strong, reference sources...) are concerned. """ events = [] for event, value in parse_inline(text): if event == XTEXT: events.append((TEXT, value.encode('utf-8'), None)) elif event == XFOOTNOTE: target = checkid(value) attributes = {XTARGET: target} events.append((START_ELEMENT, (rest_uri, event, attributes), None)) events.append((TEXT, value.encode('utf-8'), None)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XREFERENCE: target = checkid(value) attributes = {XTARGET: target} events.append((START_ELEMENT, (rest_uri, event, attributes), None)) events.append((TEXT, value.encode('utf-8'), None)) events.append((END_ELEMENT, (rest_uri, event), None)) else: events.append((START_ELEMENT, (rest_uri, event, {}), None)) events.append((TEXT, value.encode('utf-8'), None)) events.append((END_ELEMENT, (rest_uri, event), None)) return events
def generate_title_and_name(title, used): # The easy case name = checkid(title) if name not in used: return title, name # OK we must search for a free title/name index = 0 while True: title2 = u'%s (%d)' % (title, index) name = checkid(title2) if name not in used: return title2, name index += 1
def get_new_resource_name(self, form): if form.has_key('name') and form['name'].strip(): name = form['name'].strip() elif form.has_key('title'): name = form['title'].strip() else: # Number context = get_context() abspath = context.resource.get_canonical_path() query = AndQuery( get_base_path_query(str(abspath), depth=1), PhraseQuery('format', self.add_cls.class_id)) search = context.root.search(query) if len(search): doc = search.get_documents(sort_by='name', reverse=True)[0] if self.new_resource_name_prefix: start = len(self.new_resource_name_prefix) else: start = 0 name = int(doc.name[start+1:]) + 1 else: name = 1 name = str(name) if self.new_resource_name_prefix: name = '%s-%s' % (self.new_resource_name_prefix, name) return checkid(name)
def action(self, resource, context, form): title = form["title"].strip() name = form["name"] name = checkid(title) if name is None: raise FormError, messages.MSG_BAD_NAME vhosts = [] # We add the default vhost entry site_url = "%s.projects.zmgc.net" % name vhosts.append(site_url) url = "%s" % form["vhosts"] # XXX We need to check the domain name is valid vhosts.append(url) vhosts = [x for x in vhosts if x] # Create the resource class_id = "project" cls = get_resource_class(class_id) container = resource.get_resource("/projects") # check if name is taken if container.get_resource(name, soft=True) is not None: item = container.get_resource(name, soft=True) return context.come_back(MSG_EXISTANT_PROJECT) item = container.make_resource(name, cls) # The metadata metadata = item.metadata language = resource.get_edit_languages(context)[0] metadata.set_property("title", Property(title, lang=language)) metadata.set_property("vhosts", vhosts) metadata.set_property("website_is_open", "community") # TODO we need to make this based on the URL of the # go to the user's profile page goto = "/projects/%s" % item.name return context.come_back(MSG_NEW_RESOURCE, goto=goto)
def _get_form(self, resource, context): form = AutoForm._get_form(self, resource, context) name = self.get_new_resource_name(form) # Check the name if not name: raise FormError, messages.MSG_NAME_MISSING try: name = checkid(name) except UnicodeEncodeError: name = None if name is None: raise FormError, messages.MSG_BAD_NAME # Check the name is free root = context.root category = root.get_resource(form['category']) if category.get_resource(name, soft=True) is not None: raise FormError, messages.MSG_NAME_CLASH # Ok form['name'] = name return form
def generate_bill(self, context): """Creates bill as a pdf.""" # Get template document = self.get_resource('/ui/shop/orders/bill.xml') # Build namespace orders = get_orders(self) namespace = self.get_namespace(context) namespace['logo'] = orders.get_pdf_logo_key(context) signature = orders.get_property('signature') signature = signature.encode('utf-8') namespace['pdf_signature'] = XMLParser(signature.replace('\n', '<br/>')) # Products namespace['products'] = self.get_products_namespace(context) # Company company = orders.get_property('company') company = company.encode('utf-8') namespace['pdf_company'] = XMLParser(company.replace('\n', '<br/>')) # Customer namespace['customer'] = self.get_customer_namespace(context) # VAT total_pre_vat, total_vat = self.get_vat_details(context) total_pre_vat = self.format_price(get_arrondi(total_pre_vat)) total_vat = self.format_price(get_arrondi(total_vat)) namespace['total_pre_vat'] = total_pre_vat namespace['total_vat'] = total_vat # Build pdf try: pdf = stl_pmltopdf(document, namespace=namespace) except Exception: return None title = MSG(u'Bill').gettext() name = checkid(title) metadata = {'title': {'en': title}, 'filename': '%s.pdf' % name} self.del_resource(name, soft=True) return self.make_resource(name, PDF, body=pdf, **metadata)
def _get_form(self, resource, context): form = super(AutoAdd, self)._get_form(resource, context) # 1. The container container = self.get_container(resource, context, form) form['container'] = container # 2. The name name = self.get_new_resource_name(form) if not name: raise FormError, messages.MSG_NAME_MISSING try: name = checkid(name) except UnicodeEncodeError: name = None if name is None: raise FormError, messages.MSG_BAD_NAME # Check the name is free if container.get_resource(name, soft=True) is not None: raise FormError, messages.MSG_NAME_CLASH form['name'] = name # Ok return form
def odt_reference_resolver(resource, reference, context, known_links=[]): path = reference.path if not path.startswith_slash: # Was not resolved raise ValueError, 'page "%s": the link "%s" is broken' % ( resource.name, reference) if path not in known_links: return default_reference_resolver(resource, reference, context) destination = resource.get_resource(path) if not isinstance(destination, resource.__class__): return default_reference_resolver(resource, reference, context) doctree = destination.get_doctree() title = None if reference.fragment: for node in doctree.traverse(condition=nodes.title): if checkid(node.astext()) == reference.fragment: title = node.astext() break if not reference.fragment or title is None: # First title for node in doctree.traverse(condition=nodes.title): title = node.astext() break # No title at all if title is None: return default_reference_resolver(resource, reference, context) return u"#1.%s|outline" % title
def _get_form(self, resource, context): # We cannot call direct parent NewInstance, because we override the # container form = super(NewInstance, self)._get_form(resource, context) # 1. The container container = self._get_container(resource, context) ac = container.get_access_control() if not ac.is_allowed_to_add(context.user, container): path = context.get_link(container) path = '/' if path == '.' else '/%s/' % path msg = ERROR(u'Adding resources to {path} is not allowed.') raise FormError, msg.gettext(path=path) # 2. Strip the title form['title'] = form['title'].strip() # 3. The name name = self.get_new_resource_name(form) if not name: raise FormError, messages.MSG_NAME_MISSING try: name = checkid(name) except UnicodeEncodeError: name = None if name is None: raise FormError, messages.MSG_BAD_NAME # Check the name is free if container.get_resource(name, soft=True) is not None: raise FormError, messages.MSG_NAME_CLASH form['name'] = name # Ok return form
def set_value(self, resource, context, name, form): if name == 'tags': proxy = TagsAware_Edit return proxy.set_value(self, resource, context, name, form) elif name in ('attachment', 'alert_time'): return False if name == 'alert_date': alert_date = form[name] if alert_date: alert_time = form['alert_time'] or time(9, 0) value = datetime.combine(alert_date, alert_time) else: status = form['crm_m_status'] if status not in ('finished', 'nogo'): context.message = ERR_ALERT_MANDATORY return True value = None resource.set_property('crm_m_alert', value) return False elif name == 'crm_m_nextaction': value = form[name] if not value: status = form['crm_m_status'] if status not in ('finished', 'nogo'): context.message = ERR_NEXTACTION_MANDATORY return True resource.set_property('crm_m_nextaction', value) return False elif name == 'comment': value = form[name] # Attachment attachment = form['attachment'] if attachment is None: if not value: return False else: filename, mimetype, body = attachment # Find a non used name attachment = checkid(filename) attachment, extension, language = FileName.decode(attachment) attachment = generate_name(attachment, resource.get_names()) # Add attachment cls = get_resource_class(mimetype) resource.make_resource(attachment, cls, body=body, filename=filename, extension=extension, format=mimetype) if not value: value = DUMMY_COMMENT user = context.user author = user.name if user else None value = Property(value, date=context.timestamp, author=author, attachment=attachment) resource.metadata.set_property(name, value) context.database.change_resource(resource) return False proxy = DBResource_Edit return proxy.set_value(self, resource, context, name, form)
def get_options(cls, iana_root_zone, region, county_name=None): options = [] for row in get_world(): if region == checkid(row.get_value('region')): county = row.get_value('county') name = '%s#%s#%s' % (iana_root_zone, region, checkid(county)) if county_name == checkid(row.get_value('county')): options.append({'name': name, 'value': county, 'selected': True }) else: options.append({'name': name, 'value': county, 'selected': False}) options.sort(key=sort_key) if iana_root_zone: switch = '%s#%s#switch' % (iana_root_zone, region) else: switch = 'none#none#switch' options.insert(0, {'name': switch, 'value': 'Choose different region!', 'selected': False}) return options
def init_resource(self, **kw): super(ConfigMenu, self).init_resource(**kw) # Menu order = [] menus = [('/', u'Home'), ('/;contact', u'Contact')] for path, title in menus: name = checkid(title) order.append(name) self.make_resource(name, MenuItem, path=path, title={'en': title}) self.set_property('order', order)
def action_upload(self, resource, context, form): filename, mimetype, body = form['file'] name, type, language = FileName.decode(filename) # Check the filename is good title = form['title'].strip() name = checkid(title) or checkid(name) if name is None: context.message = messages.MSG_BAD_NAME return # Get the container container = context.root.get_resource(form['target_path']) # Check the name is free if container.get_resource(name, soft=True) is not None: context.message = messages.MSG_NAME_CLASH return # Check it is of the expected type cls = context.database.get_resource_class(mimetype) if not self.can_upload(cls): error = u'The given file is not of the expected type.' context.message = ERROR(error) return kw = {'data': body, 'filename': filename} # Add the image to the resource child = container.make_resource(name, cls, **kw) # The title language = resource.get_edit_languages(context)[0] title = MetadataProperty(title, lang=language) child.metadata.set_property('title', title) # Get the path path = child.abspath action = self.get_resource_action(context) if action: path = '%s%s' % (path, action) # Return javascript scripts = self.get_scripts(context) context.add_script(*scripts) return self.get_javascript_return(context, path)
def init_resource(self, **kw): super(ConfigMenu, self).init_resource(**kw) # Menu order = [] menus = [("/", u"Home"), ("/;contact", u"Contact")] for path, title in menus: name = checkid(title) order.append(name) self.make_resource(name, MenuItem, path=path, title={"en": title}) self.set_property("order", order)
def action_upload(self, resource, context, form): filename, mimetype, body = form['file'] name, type, language = FileName.decode(filename) # Check the filename is good title = form['title'].strip() name = checkid(title) or checkid(name) if name is None: context.message = messages.MSG_BAD_NAME return # Get the container container = context.root.get_resource(form['target_path']) # Check the name is free if container.get_resource(name, soft=True) is not None: context.message = messages.MSG_NAME_CLASH return # Check it is of the expected type cls = context.database.get_resource_class(mimetype) if not self.can_upload(cls): error = u'The given file is not of the expected type.' context.message = ERROR(error) return kw = {'data': body, 'filename': filename} # Add the image to the resource child = container.make_resource(name, cls, **kw) # The title language = resource.get_edit_languages(context)[0] title = Property(title, lang=language) child.metadata.set_property('title', title) # Get the path path = child.abspath action = self.get_resource_action(context) if action: path = '%s%s' % (path, action) # Return javascript scripts = self.get_scripts(context) context.add_script(*scripts) return self.get_javascript_return(context, path)
def action(self, resource, context, form): paths = form['paths'] new_names = form['new_names'] # Check if 2 resources are similary named if len(new_names) > len(set(new_names)): context.message = messages.MSG_NAME_CLASH return paths.sort() paths.reverse() # Clean the copy cookie if needed cut, cp_paths = context.get_cookie('ikaaro_cp', datatype=CopyCookie) renamed = [] referenced = [] # Process input data abspath = resource.abspath for i, path in enumerate(paths): new_name = new_names[i] new_name = checkid(new_name) if new_name is None: context.message = messages.MSG_BAD_NAME return # Split the path if '/' in path: parent_path, old_name = path.rsplit('/', 1) container = resource.get_resource(parent_path) else: old_name = path container = resource # Check the name really changed if new_name == old_name: continue # Check there is not another resource with the same name if container.get_resource(new_name, soft=True) is not None: context.message = messages.MSG_EXISTANT_FILENAME return # Clean cookie (FIXME Do not clean the cookie, update it) if cp_paths and str(abspath.resolve2(path)) in cp_paths: context.del_cookie('ikaaro_cp') cp_paths = [] # Rename try: container.move_resource(old_name, new_name) except ConsistencyError: referenced.append(old_name) continue else: renamed.append(old_name) if referenced and not renamed: resources = ', '.join(referenced) message = messages.MSG_RESOURCES_REFERENCED.gettext( resources=resources) else: message = messages.MSG_RENAMED return context.come_back(message, goto=self.goto_after)
def run(self): self.assert_has_content() # Default values options = self.options for option in ('title', 'comments', 'subject', 'keywords'): if options.get(option) is None: options[option] = u"" if options.get('language') is None: # The website language, not the content language # because the wiki is not multilingual anyway context = get_context() languages = context.site_root.get_property('website_languages') language = context.accept_language.select_language(languages) options['language'] = language # Cover page if self.arguments: # Push cover as an option cover_uri = checkid(self.arguments[0][1:-2]) options['cover'] = directives.uri(cover_uri) # Metadata metadata = ['Book:'] for key in ('toc-depth', 'ignore-missing-pages', 'title', 'comments', 'subject', 'keywords', 'language', 'filename'): value = options.get(key) if not value: continue metadata.append(' %s: %s' % (key, value)) template = options.get('template') if template is not None: metadata.append(' template: ') meta_node = nodes.literal_block('Book Metadata', '\n'.join(metadata)) meta_node.append(nodes.reference(refuri=template, text=template, name=template, wiki_template=True)) else: meta_node = nodes.literal_block('Book Metadata', '\n'.join(metadata)) book_node = book(self.block_text, **options) if self.arguments: # Display the cover cover_text = self.arguments.pop(0) textnodes, messages = self.state.inline_text(cover_text, self.lineno) book_node += nodes.title(cover_text, '', *textnodes) book_node += messages # Parse inner list self.state.nested_parse(self.content, self.content_offset, book_node) # Automatically number pages for bullet_list in book_node.traverse(condition=nodes.bullet_list): bullet_list.__class__ = nodes.enumerated_list bullet_list.tagname = 'enumerated_list' return [meta_node, book_node]
def action(self, resource, context, form): paths = form['paths'] new_names = form['new_names'] paths.sort() paths.reverse() # Clean the copy cookie if needed cut, cp_paths = context.get_cookie('ikaaro_cp', datatype=CopyCookie) renamed = [] referenced = [] # Process input data abspath = resource.abspath for i, path in enumerate(paths): new_name = new_names[i] new_name = checkid(new_name) if new_name is None: context.message = messages.MSG_BAD_NAME return # Split the path if '/' in path: parent_path, old_name = path.rsplit('/', 1) container = resource.get_resource(parent_path) else: old_name = path container = resource # Check the name really changed if new_name == old_name: continue # Check there is not another resource with the same name if container.get_resource(new_name, soft=True) is not None: context.message = messages.MSG_EXISTANT_FILENAME return # Clean cookie (FIXME Do not clean the cookie, update it) if cp_paths and str(abspath.resolve2(path)) in cp_paths: context.del_cookie('ikaaro_cp') cp_paths = [] # Rename try: container.move_resource(old_name, new_name) except ConsistencyError: referenced.append(old_name) continue else: renamed.append(old_name) if referenced and not renamed: resources = ', '.join(referenced) message = messages.MSG_RESOURCES_REFERENCED(resources=resources) else: message = messages.MSG_RENAMED return context.come_back(message, goto=self.goto_after)
def get_options(cls): ''' return JSON ser ''' list_countries = set() for row in get_world(): country = row.get_value('country') iana_root_zone = row.get_value('iana_root_zone') list_countries.add((iana_root_zone, country)) options = [] for index, row in enumerate(list_countries): options.append({'name': row[0], 'value': MSG(row[1]), 'title': checkid(row[1]), 'selected': None}) return sorted(options, key=itemgetter('title'))
def _format_meta(form, template_name, toc_depth, language, document): """Format the metadata of a rst book from a lpod document. """ content = [] content.append(u' :toc-depth: %s' % toc_depth) content.append(u' :template: %s' % template_name) content.append(u' :ignore-missing-pages: no') for key in ['title', 'comments', 'subject', 'keywords']: content.append(u' :%s: %s' % (key, form[key])) content.append(u' :language: %s' % language) # Compute a default filename title = document.get_part('meta').get_title() if title is None or not title.strip(): filename, _, _ = form['file'] filename = checkid(filename) else: filename = checkid(title.strip()) + '.odt' content.append(u' :filename: %s' % filename) content.append(u'') return u"\n".join(content)
def POST(self, resource, context): name, class_id, changes = self.json # 1. Make the resource if name is not None: name = checkid(name) cls = context.database.get_resource_class(class_id) child = resource.make_resource(name, cls) # 2. Modify the resource update_resource(child, changes) # 3. Return the URL of the new resource return self.created(child)
def set_new_resource_link(self, node): node['classes'].append('nowiki') prefix = self.get_pathto(self.parent) title = node['name'] title_encoded = title.encode('utf_8') if node.attributes.get('wiki_template'): new_type = 'application/vnd.oasis.opendocument.text' else: new_type = self.__class__.__name__ params = {'type': new_type, 'title': title_encoded, 'name': checkid(title) or title_encoded} refuri = "%s/;new_resource?%s" % (prefix, urlencode(params)) node['refuri'] = refuri
def process_name(name): for encoding in encodings: try: title = unicode(name, encoding) checkid_name = checkid(title, soft=False) break except UnicodeError: pass else: raise ValueError, name if checkid_name is None: raise ValueError, name # Ok return checkid_name, title
def get_links(self): base = self.abspath try: doctree = self.get_doctree() except SystemMessage: # The doctree is in a incoherent state return set() # Links links = set() for node in doctree.traverse(condition=nodes.reference): refname = node.get('wiki_name') if refname is False: # Wiki link not found title = node['name'] path = checkid(title) or title path = base.resolve(path) elif refname: # Wiki link found, "refname" is the path path = base.resolve2(refname) else: # Regular link, include internal ones refuri = node.get('refuri') if refuri is None: continue reference = get_reference(refuri.encode('utf_8')) # Skip external if is_external(reference): continue path = base.resolve2(reference.path) path = str(path) links.add(path) # Images for node in doctree.traverse(condition=nodes.image): reference = get_reference(node['uri'].encode('utf_8')) # Skip external image if is_external(reference): continue # Resolve the path path = base.resolve(reference.path) path = str(path) links.add(path) return links
def get_options(cls, iana_root_zone): list_regions = set() country_name = [] for row in get_world(): if row.get_value('iana_root_zone') == iana_root_zone: list_regions.add(row.get_value('region')) if country_name == []: country_name.append(row.get_value('country')) options = [] for index, row in enumerate(list_regions): name = '%s#%s' % (iana_root_zone, checkid(row)) options.append({'name': name, 'value': row, 'selected': False}) options.sort(key=sort_key) options.insert(0, {'name': 'switch', 'value': '* not from ' + country_name[0] + ' *', 'selected': False}) return options
def block_stream(text): """Turn a text into a list of events similar to XML: START_ELEMENT, END_ELEMENT, TEXT. Block elements (lists, literal blocks, paragraphs, titles...) are concerned. Inline elements are loaded as well where applicable. """ if isinstance(text, str): text = unicode(text, 'utf-8') events = [] for event, value in parse_everything(text): if event == XTITLE: overline, title, underline = value target = checkid(title) attributes = { (rest_uri, 'overline'): overline, (rest_uri, 'underline'): underline, (rest_uri, XTARGET): target } events.append((START_ELEMENT, (rest_uri, event, attributes), None)) events.extend(inline_stream(title)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XPARAGRAPH: events.append((START_ELEMENT, (rest_uri, event, {}), None)) events.extend(inline_stream(value)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XLITERAL_BLOCK: events.append((START_ELEMENT, (rest_uri, event, {}), None)) events.append((TEXT, value.encode('utf-8'), None)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XLIST_BEGIN: events.append((START_ELEMENT, (rest_uri, 'list', { (rest_uri, 'item'): value }), None)) elif event == XLIST_END: events.append((END_ELEMENT, (rest_uri, 'list'), None)) elif event == XLIST_ITEM_BEGIN: events.append((START_ELEMENT, (rest_uri, 'list_item', {}), None)) elif event == XLIST_ITEM_END: events.append((END_ELEMENT, (rest_uri, 'list_item'), None)) else: raise NotImplementedError, event return events
def resolve_link(self, title): parent = self.parent # Try regular resource name or path try: name = str(title) except UnicodeEncodeError: pass else: resource = parent.get_resource(name, soft=True) if resource is not None: return resource # Convert wiki name to resource name name = checkid(title) if name is None: return None return parent.get_resource(name, soft=True)
def block_stream(text): """Turn a text into a list of events similar to XML: START_ELEMENT, END_ELEMENT, TEXT. Block elements (lists, literal blocks, paragraphs, titles...) are concerned. Inline elements are loaded as well where applicable. """ if isinstance(text, str): text = unicode(text, 'utf-8') events = [] for event, value in parse_everything(text): if event == XTITLE: overline, title, underline = value target = checkid(title) attributes = {(rest_uri, 'overline'): overline, (rest_uri, 'underline'): underline, (rest_uri, XTARGET): target} events.append((START_ELEMENT, (rest_uri, event, attributes), None)) events.extend(inline_stream(title)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XPARAGRAPH: events.append((START_ELEMENT, (rest_uri, event, {}), None)) events.extend(inline_stream(value)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XLITERAL_BLOCK: events.append((START_ELEMENT, (rest_uri, event, {}), None)) events.append((TEXT, value.encode('utf-8'), None)) events.append((END_ELEMENT, (rest_uri, event), None)) elif event == XLIST_BEGIN: events.append((START_ELEMENT, (rest_uri, 'list', {(rest_uri, 'item'): value}), None)) elif event == XLIST_END: events.append((END_ELEMENT, (rest_uri, 'list'), None)) elif event == XLIST_ITEM_BEGIN: events.append((START_ELEMENT, (rest_uri, 'list_item', {}), None)) elif event == XLIST_ITEM_END: events.append((END_ELEMENT, (rest_uri, 'list_item'), None)) else: raise NotImplementedError, event return events
def _add_image(filename, document, resource): if type(filename) is unicode: filename = filename.encode('UTF-8') data = document.get_part('Pictures/%s' % filename) name, a_type, language = FileName.decode(filename) # Check the filename is good name = checkid(name) if name is None: return None # XXX If the resource exists, we assume it's the good resource if resource.get_resource(name, soft=True) is None: # Get mimetype / class mimetype = get_mimetype(filename) cls = get_context().database.get_resource_class(mimetype) # Add the image resource.make_resource(name, cls, body=data, format=mimetype, filename=filename, extension=a_type) # All OK return name
def action_add_resource(self, resource, context, form): mode = form['mode'] name = checkid(form['title']) # Check name validity if name is None: context.message = MSG(u"Invalid title.") return # Get the container root = context.root container = root.get_resource(context.get_form_value('target_path')) # Check the name is free if container.get_resource(name, soft=True) is not None: context.message = messages.MSG_NAME_CLASH return # Get the type of resource to add cls = self.get_page_type(mode) # Create the resource child = container.make_resource(name, cls) scripts = self.get_scripts(context) context.add_script(*scripts) return self.get_javascript_return(context, child.abspath)
def get_namespace(self, resource, context): namespace = {} table = resource.get_resource(resource.order_path) handler = table.handler title = resource.get_title() namespace['title'] = title namespace['width'] = resource.get_property('width') namespace['height'] = resource.get_property('height') namespace['border'] = resource.get_property('border') namespace['show_border'] = resource.get_property('show_border') namespace['show_title'] = resource.get_property('show_title') img_ids = list(handler.get_record_ids()) if not img_ids: return {'images': {}, 'title': title, 'show_title': True} get_value = handler.get_record_value namespace['cssid'] = "%s-%s" % (checkid(title.replace('.','-')), self.uid) namespace['images'] = [] for record in handler.get_records_in_order(): img_path = get_value(record, 'img_path') img_path_resource = table.get_resource(str(img_path), soft=True) if img_path_resource: img_path = context.get_link(img_path_resource) namespace['images'].append({ 'description': get_value(record, 'description'), 'title': get_value(record, 'title'), 'img_link': get_value(record, 'img_link'), # TODO: Get a ./ link instead of a /section/page/img/ 'img_path': img_path, '__id__': get_value(record, '__id__'), 'target': get_value(record, 'target') }) self.uid += 1 return namespace
def _save_template(context, a_file, target_path): """Save the imported template. """ filename, mimetype, body = a_file name, type, language = FileName.decode(filename) # Check the filename is good name = checkid(name) if name is None: context.message = MSG_BAD_NAME return # Get the container container = context.root.get_resource(target_path) # Search for a free name names = container.get_names() name = generate_name(name, names) # Add the image to the resource cls = context.database.get_resource_class(mimetype) container.make_resource(name, cls, body=body, format=mimetype, filename=filename, extension=type) return name
def extract_archive(self, handler, default_language, filter=None, postproc=None, update=False): change_resource = self.database.change_resource for path_str in handler.get_contents(): # 1. Skip folders clean_path = "/".join([ checkid(x) or 'file' if x else 'file' for x in path_str.split("/")]) path = Path(clean_path) if path.endswith_slash: continue # Skip the owner file (garbage produced by microsoft) filename = path[-1] if filename.startswith('~$'): continue # 2. Create parent folders if needed folder = self for name in path[:-1]: name, title = process_name(name) subfolder = folder.get_resource(name, soft=True) if subfolder is None: folder = folder.make_resource(name, Folder) folder.set_value('title', title, default_language) elif not isinstance(subfolder, Folder): raise RuntimeError, MSG_NAME_CLASH else: folder = subfolder # 3. Find out the resource name and title, the file mimetype and # language mimetype = guess_mimetype(filename, 'application/octet-stream') name, extension, language = FileName.decode(filename) name, title = process_name(name) language = language or default_language # Keep the filename extension (except in webpages) if mimetype not in ('application/xhtml+xml', 'text/html'): name = FileName.encode((name, extension, None)) # 4. The body body = handler.get_file(path_str) if filter: body = filter(path_str, mimetype, body) if body is None: continue # 5. Update or make file file = folder.get_resource(name, soft=True) if file: if update is False: msg = 'unexpected resource at {path}' raise RuntimeError, msg.format(path=path_str) if mimetype == 'text/html': body = tidy_html(body) file_handler = file.get_handler(language) else: file_handler = file.get_handler() old_body = file.handler.to_str() file_handler.load_state_from_string(body) if postproc: postproc(file) # FIXME Comparing the bytes does not work for XML, so we use # this weak heuristic if len(old_body) != len(file.handler.to_str()): change_resource(file) else: # Case 1: the resource does not exist file = folder._make_file(name, filename, mimetype, body, language) file.set_value('title', title, language=language) if postproc: postproc(file)
def get_namespace(self, resource, context): root = context.root here = context.resource site_root = here.get_site_root() site_root_abspath = site_root.get_abspath() shop = site_root.get_resource('shop') categories_abspath = str(site_root_abspath.resolve2('categories')) show_nb_products = resource.get_property('show_nb_products') show_first_category = resource.get_property('show_first_category') show_second_level = resource.get_property('show_second_level') here_abspath = here.get_abspath() here_real_abspath = str(here_abspath) here_parent_abspath = here_abspath.resolve2('..') current_level = here_real_abspath.count('/') if here.metadata.format == 'category': here_abspath = str(here.get_abspath()) # Max level deploy = count '/' + 1 # here_abspath at level 1 does not contain '/' here_abspath_level = here_abspath.count('/') max_level_deploy = here_abspath_level + 1 else: if here.metadata.format == 'product': # Special case for the product, here_* values are compute # with here = parent category parent_category = here.parent parent_category_abspath = parent_category.get_abspath() here_abspath = str(parent_category_abspath) here_abspath_level = here_abspath.count('/') max_level_deploy = here_abspath_level + 1 here_parent_abspath = parent_category_abspath.resolve2('..') else: # Tweak here_abspath here_abspath = categories_abspath here_abspath_level = here_abspath.count('/') max_level_deploy = categories_abspath.count('/') + 1 here_abspath_p = Path(here_abspath) # Get search with all publics products all_products = root.search( AndQuery(PhraseQuery('format', shop.product_class.class_id), PhraseQuery('workflow_state', 'public'))) # Get search with all categories all_categories = root.search( AndQuery(PhraseQuery('parent_paths', categories_abspath), PhraseQuery('format', 'category'))) # Build a dict with brains by level cat_per_level = {} for index, cat in enumerate( all_categories.get_documents(sort_by='abspath')): # Skip first category --> /categories if index == 0 and show_first_category is False: continue level = cat.abspath.count('/') # Skip second level (if we are not on level /categories/') if (show_second_level is False and current_level > 2 and level == 3 and not here_real_abspath == cat.abspath and not here_parent_abspath == cat.abspath): continue # Skip bad level if level > max_level_deploy: continue diff_level = here_abspath_level - level path_to_resolve = ['..' for x in range(diff_level)] path_to_resolve = '/'.join(path_to_resolve) # Path uses to compute the prefix with the current category here_prefix = here_abspath_p.resolve2(path_to_resolve) # Compute the prefix prefix = here_prefix.get_prefix(cat.abspath) if prefix == here_prefix: # special case when prefix equals here_prefix pass elif len(prefix) != level - 1: # bad, not in the same arborescence continue # Get the product number in the category sub_results = all_products.search( PhraseQuery('parent_paths', cat.abspath)) cats = cat_per_level.setdefault(level, []) cats.append({'doc': cat, 'nb_products': len(sub_results)}) # Build the tree starting with the higher level tree_template = resource.get_resource(self.tree_template) levels = sorted(cat_per_level.keys(), reverse=True) tree = None for level in levels: items = [] for data in cat_per_level[level]: doc = data['doc'] if here_abspath.startswith(doc.abspath): sub_tree = tree css = 'in-path ' else: sub_tree = None css = '' css = 'active ' if here_abspath == doc.abspath else css # Href (get_link emulation) href = str(site_root_abspath.get_pathto(doc.abspath)) css += checkid(href) css = css.replace('.', '-dot-') if resource.get_property('use_small_title'): title = doc.m_breadcrumb_title or doc.m_title or doc.name else: title = doc.m_title or doc.name d = { 'title': title, 'href': '/%s' % href, 'sub_tree': sub_tree, 'nb_products': data['nb_products'], 'css': css } items.append(d) tree = stl(tree_template, { 'items': items, 'show_nb_products': show_nb_products, 'css': None }) return {'title': resource.get_title(), 'tree': tree}
def action_add_or_edit(self, resource, context, record): record['name'] = checkid(record['title'].value) resource.handler.add_record(record)