def paste_nodes(self): """ Paste nodes view. Paste formerly copied or cutted nodes into the current context. Note that a cutted node can not be pasted into itself. :result: Redirect response to the referrer of the request. :rtype: pyramid.httpexceptions.HTTPFound """ ids, action = self.request.session["kotti.paste"] for count, id in enumerate(ids): item = DBSession.query(Node).get(id) if item is not None: if action == "cut": if not self.request.has_permission("edit", item): raise Forbidden() item.__parent__.children.remove(item) item.name = title_to_name(item.name, blacklist=self.context.keys()) self.context[item.name] = item if count is len(ids) - 1: del self.request.session["kotti.paste"] elif action == "copy": copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=self.context.keys()) copy.name = name self.context[name] = copy self.flash( _("${title} was pasted.", mapping=dict(title=item.title)), "success" ) else: self.flash(_("Could not paste node. It no longer exists."), "error") DBSession.flush() if not self.request.is_xhr: return self.back()
def test_numbering(self): self.setUp() from kotti.util import title_to_name assert title_to_name(u"Report Part 1", blacklist=[]) == u"report-part-1" assert title_to_name(u"Report Part 1", blacklist=["report-part-1"]) == u"report-part-1-1" assert title_to_name(u"Report Part 3", blacklist=["report-part-3"]) == u"report-part-3-1" assert title_to_name(u"Report Part 3", blacklist=["report-part-3", "report-part-3-1"]) == u"report-part-3-2"
def test_numbering(self): self.setUp() from kotti.util import title_to_name assert title_to_name('Report Part 1', blacklist=[]) == 'report-part-1' assert title_to_name('Report Part 1', blacklist=['report-part-1']) == 'report-part-1-1' assert title_to_name('Report Part 3', blacklist=['report-part-3']) == 'report-part-3-1' assert title_to_name('Report Part 3', blacklist=['report-part-3', 'report-part-3-1' ]) == 'report-part-3-2'
def test_numbering(self): self.setUp() from kotti.util import title_to_name assert title_to_name(u'Report Part 1', blacklist=[]) == u'report-part-1' assert title_to_name(u'Report Part 1', blacklist=['report-part-1']) == u'report-part-1-1' assert title_to_name(u'Report Part 3', blacklist=['report-part-3']) == u'report-part-3-1' assert title_to_name( u'Report Part 3', blacklist=['report-part-3', 'report-part-3-1'] ) == u'report-part-3-2'
def paste_nodes(self): """ Paste nodes view. Paste formerly copied or cutted nodes into the current context. Note that a cutted node can not be pasted into itself. :result: Redirect response to the referrer of the request. :rtype: pyramid.httpexceptions.HTTPFound kotti_multilingual override: If you paste objects after a cut action we want to clear all translations (prevent edge case problems) """ def unlink_translation(content): content_id = content.id DBSession.query(Translation).filter( or_(Translation.target_id == content_id, Translation.source_id == content_id) ).delete() ids, action = self.request.session["kotti.paste"] for count, id in enumerate(ids): item = DBSession.query(Node).get(id) if item is not None: if action == "cut": if not has_permission("edit", item, self.request): raise Forbidden() # unlink translations for each child children = self._all_children(item, permission="edit") unlink_translation(item) for child in children: unlink_translation(child) item.__parent__.children.remove(item) item.name = title_to_name(item.name, blacklist=self.context.keys()) self.context.children.append(item) if count is len(ids) - 1: del self.request.session["kotti.paste"] elif action == "copy": copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=self.context.keys()) copy.name = name self.context.children.append(copy) self.flash(_(u"${title} was pasted.", mapping=dict(title=item.title)), "success") else: self.flash(_(u"Could not paste node. It no longer exists."), "error") if not self.request.is_xhr: return self.back()
def test_numbering(self): self.setUp() from kotti.util import title_to_name assert title_to_name("Report Part 1", blacklist=[]) == "report-part-1" assert (title_to_name("Report Part 1", blacklist=["report-part-1" ]) == "report-part-1-1") assert (title_to_name("Report Part 3", blacklist=["report-part-3" ]) == "report-part-3-1") assert (title_to_name("Report Part 3", blacklist=["report-part-3", "report-part-3-1" ]) == "report-part-3-2")
def find_name(self, appstruct): name = appstruct.get('name') if name is None: name = title_to_name(appstruct['title']) while name in self.context.keys(): name = disambiguate_name(name) return name
def process_upload(self): """ Process a single upload. Also see: https://github.com/valums/file-uploader/blob/master/server/readme.md :result: Status object with URL of the created item (on success) or error message on failure. :rtype: dict """ fs = self.request.POST["qqfile"] # We can fail hard, as somebody is trying to cheat on us if that fails. assert isinstance(fs, FieldStorage) try: factory = self.factory_by_name(self.request.POST["content_type"]) except KeyError as e: result = {"success": False, "error": e.message} else: name = title_to_name(fs.filename, blacklist=self.context.keys()) self.context[name] = node = factory.from_field_storage(fs) node.title = fs.filename result = {"success": True, "url": self.request.resource_url(node)} # FineUploader expects JSON with Content-Type 'text/plain' response = Response(json.dumps(result)) response.content_type = "text/plain" return response
def paste_node(context, request): id, action = request.session['kotti.paste'] item = DBSession.query(Node).get(id) if item is not None: if action == 'cut': if not has_permission('edit', item, request): raise Forbidden() item.__parent__.children.remove(item) context.children.append(item) del request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=context.keys()) copy.name = name context.children.append(copy) request.session.flash( _(u'${title} pasted.', mapping=dict(title=item.title)), 'success') else: request.session.flash( _(u'Could not paste node. It does not exist anymore.'), 'error') if not request.is_xhr: location = resource_url(context, request) return HTTPFound(location=location)
def paste_node(context, request): session = DBSession() id, action = request.session['kotti.paste'] item = session.query(Node).get(id) if item is not None: if action == 'cut': if not has_permission('edit', item, request): raise Forbidden() item.__parent__.children.remove(item) context.children.append(item) del request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=context.keys()) copy.name = name context.children.append(copy) request.session.flash(_(u'${title} pasted.', mapping=dict(title=item.title)), 'success') else: request.session.flash(_(u'Could not paste node. It does not exist anymore.'), 'error') if not request.is_xhr: location = resource_url(context, request) return HTTPFound(location=location)
def paste_nodes(self): """ Paste nodes view. Paste formerly copied or cutted nodes into the current context. Note that a cutted node can not be pasted into itself. :result: Redirect response to the referrer of the request. :rtype: pyramid.httpexceptions.HTTPFound """ ids, action = self.request.session['kotti.paste'] for count, id in enumerate(ids): item = DBSession.query(Node).get(id) if item is not None: if action == 'cut': if not has_permission('edit', item, self.request): raise Forbidden() item.__parent__.children.remove(item) self.context.children.append(item) if count is len(ids) - 1: del self.request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=self.context.keys()) copy.name = name self.context.children.append(copy) self.flash( _(u'${title} was pasted.', mapping=dict(title=item.title)), 'success') else: self.flash(_(u'Could not paste node. It no longer exists.'), 'error') if not self.request.is_xhr: return self.back()
def paste_nodes(self): """ Paste nodes view. Paste formerly copied or cutted nodes into the current context. Note that a cutted node can not be pasted into itself. :result: Redirect response to the referrer of the request. :rtype: pyramid.httpexceptions.HTTPFound """ ids, action = self.request.session['kotti.paste'] for count, id in enumerate(ids): item = DBSession.query(Node).get(id) if item is not None: if action == 'cut': if not has_permission('edit', item, self.request): raise Forbidden() item.__parent__.children.remove(item) self.context.children.append(item) if count is len(ids) - 1: del self.request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=self.context.keys()) copy.name = name self.context.children.append(copy) self.flash(_(u'${title} was pasted.', mapping=dict(title=item.title)), 'success') else: self.flash(_(u'Could not paste node. It no longer exists.'), 'error') if not self.request.is_xhr: return self.back()
def upload(context, request): title = request.POST["uploadtitle"] description = request.POST["uploaddescription"] file = request.POST["uploadfile"] if not hasattr(file, "filename"): return Response("""<html><head></head><body onload="window.parent.uploadError('%s');"></body></html>""" % ( "Y U NO FILE???", )) mimetype = file.type filename = file.filename data = file.file.read() size = len(data) title = title or filename if mimetype.startswith("image"): Factory = Image else: Factory = File resource = context[title_to_name(title, blacklist=context.keys())] = Factory( title=title, description=description, data=data, filename=filename, mimetype=mimetype, size=size ) return Response("""<html><head></head><body onload="window.parent.uploadOk('%s', '%s');"></body></html>""" % ( request.resource_url(resource).rstrip("/"), request.resource_url(context).rstrip("/") ))
def process_upload(self): """ Process a single upload. Also see: https://github.com/valums/file-uploader/blob/master/server/readme.md :result: Status object with URL of the created item (on success) or error message on failure. :rtype: dict """ fs = self.request.POST['qqfile'] # We can fail hard, as somebody is trying to cheat on us if that fails. assert isinstance(fs, FieldStorage) try: factory = self.factory_by_name(self.request.POST['content_type']) except KeyError as e: result = { 'success': False, 'error': e.message, } else: name = title_to_name(fs.filename, blacklist=self.context.keys()) self.context[name] = node = factory.from_field_storage(fs) node.title = fs.filename result = { "success": True, "url": self.request.resource_url(node), } # FineUploader expects JSON with Content-Type 'text/plain' response = Response(json.dumps(result)) response.content_type = 'text/plain' return response
def rename_nodes(self): """ Rename nodes view. Renders either a view to change the titles and names for multiple nodes or handle the changes and get back to the referrer of the request. :result: Either a redirect response or a dictionary passed to the template for rendering. :rtype: pyramid.httpexceptions.HTTPFound or dict """ if "rename_nodes" in self.request.POST: ids = self.request.POST.getall("children-to-rename") for id in ids: item = DBSession.query(Node).get(id) name = self.request.POST[id + "-name"] title = self.request.POST[id + "-title"] if not name or not title: self.request.session.flash(_(u"Name and title are required."), "error") location = resource_url(self.context, self.request) + "@@rename_nodes" return HTTPFound(location=location) else: item.name = title_to_name(name, blacklist=self.context.keys()) item.title = title self.request.session.flash(_(u"Your changes have been saved."), "success") return self.back("@@contents") if "cancel" in self.request.POST: self.request.session.flash(_(u"No changes made."), "info") return self.back("@@contents") ids = self._selected_children(add_context=False) items = [] if ids is not None: items = DBSession.query(Node).filter(Node.id.in_(ids)).all() return {"items": items}
def add_item(self, context, request, appstruct): name = appstruct.get('name') if name is None: name = title_to_name(appstruct['title']) while name in context.keys(): name = disambiguate_name(name) item = context[name] = self.add(**appstruct) request.session.flash(self.add_success_msg, 'success') location = resource_url(item, request) + self.success_path return HTTPFound(location=location)
def _create_discussion_inside(obj): discussion = Discussion( title=u'discussion', description=u'discussion for comments', tags=[], creation_date=datetime.datetime.now() ) _id = title_to_name(discussion.title, blacklist=obj.keys()) obj[_id] = discussion return obj[_id]
def create_comment_inside(obj): comment = Comment( title=u'comment', description=u'comment for discussion', tags=[], creation_date=datetime.datetime.now(), # TODO: Current user creator=u'TODOCURRENTUSER', message=u'' ) _id = title_to_name(comment.title, blacklist=obj.keys()) obj[_id] = comment return obj[_id]
def create_columns_from_dbf(data, context): tmp = tempfile.NamedTemporaryFile(suffix='.dbf') tmp.file.write(data) tmp.file.flush() dbt = dbf.Table(tmp.name) for fieldname in dbt.field_names: fieldinfo = dbt.field_info(fieldname) column_type = None column_lenght = 0 if fieldinfo[0] in ['N', 'F', 'B', 'Y']: column_type = 'Float' if fieldinfo[2] == 0: column_type = 'Integer' elif fieldinfo[0] in [ 'I', ]: column_type = 'Integer' elif fieldinfo[0] in ['C']: column_type = 'String' column_lenght = fieldinfo[1] elif fieldinfo[0] in ['D']: column_type = 'Date' elif fieldinfo[0] in ['T']: column_type = 'DateTime' elif fieldinfo[0] in ['L']: column_type = 'Boolean' elif fieldinfo[0] in ['P']: logger.warn('Picture type not suppported') if column_type: name = title_to_name(fieldname, blacklist=context.keys()) if fieldname.endswith('_'): destname = fieldname[:-1] else: destname = fieldname if len(destname) < 2: destname = destname + '0' column = RDBTableColumn(parent=context, name=name, title=fieldname, src_column_name=fieldname, dest_column_name=destname, column_type=column_type, column_lenght=column_lenght, is_pk=False) DBSession.add(column) else: raise TypeError(u'Unsupported type %s' % fieldinfo[0]) dbt.close() tmp.close()
def put(self): # we never accept id, it doesn't conform to jsonapi format data = self.request.json_body['data'] name=_schema_factory_name(type_name=data['type']) schema_factory = self.request.registry.getUtility(ISchemaFactory, name=name) schema = schema_factory(None, self.request) validated = schema.deserialize(data['attributes']) klass = get_factory(self.request, data['type']) name = title_to_name(validated['title'], blacklist=self.context.keys()) new_item = self.context[name] = klass(**validated) return new_item
def put(self): # we never accept id, it doesn't conform to jsonapi format data = self.request.json_body['data'] name = _schema_factory_name(type_name=data['type']) schema_factory = self.request.registry.getUtility(ISchemaFactory, name=name) schema = schema_factory(None, self.request) validated = schema.deserialize(data['attributes']) klass = get_factory(self.request, data['type']) name = title_to_name(validated['title'], blacklist=self.context.keys()) new_item = self.context[name] = klass(**validated) return new_item
def create_columns_from_dbf(data, context): tmp = tempfile.NamedTemporaryFile(suffix='.dbf') tmp.file.write(data) tmp.file.flush() dbt = dbf.Table(tmp.name) for fieldname in dbt.field_names: fieldinfo = dbt.field_info(fieldname) column_type = None column_lenght = 0 if fieldinfo[0] in ['N', 'F', 'B', 'Y']: column_type = 'Float' if fieldinfo[2]==0: column_type = 'Integer' elif fieldinfo[0] in ['I',]: column_type = 'Integer' elif fieldinfo[0] in ['C']: column_type = 'String' column_lenght = fieldinfo[1] elif fieldinfo[0] in ['D']: column_type = 'Date' elif fieldinfo[0] in ['T']: column_type = 'DateTime' elif fieldinfo[0] in ['L']: column_type = 'Boolean' elif fieldinfo[0] in ['P']: logger.warn('Picture type not suppported') if column_type: name = title_to_name(fieldname, blacklist=context.keys()) if fieldname.endswith('_'): destname = fieldname[:-1] else: destname = fieldname if len(destname) < 2: destname = destname + '0' column = RDBTableColumn(parent= context, name= name, title=fieldname, src_column_name=fieldname, dest_column_name=destname, column_type=column_type, column_lenght=column_lenght, is_pk=False) DBSession.add(column) else: raise TypeError(u'Unsupported type %s' % fieldinfo[0]) dbt.close() tmp.close()
def upload(self): title = self.request.POST['uploadtitle'] description = self.request.POST['uploaddescription'] if 'uploadfile' not in self.request.POST: self.request.session.flash( _('Please select a file to upload.'), 'error' ) return self.kottibrowser() file = self.request.POST['uploadfile'] if not hasattr(file, 'filename'): self.request.session.flash( _('Please select a file to upload.'), 'error' ) return self.kottibrowser() mimetype = file.type filename = file.filename data = file.file.read() size = len(data) title = title or filename if has_kotti_image and mimetype.startswith('image'): Factory = Image else: Factory = File id = title_to_name(title, blacklist=self.context.keys()) resource = self.context[id] = Factory( title=title, description=description, data=data, filename=filename, mimetype=mimetype, size=size ) self.request.session.flash(_('Successfully uploaded.'), 'success') location = self.request.resource_url(resource, '@@kottibrowser') return HTTPFound(location=location)
def generate_unique_name_from_realname(real_name): name = title_to_name(real_name).replace('-','') principals = get_principals() principal = principals.get(name) while principal is not None: postfix = name[-1] try: postfix = int(postfix) name = "%s%d" % ( name[:-1], (postfix+1) ) except : name = name + "2" principal = principals.get(name) return name
def upload(self): title = self.request.POST["uploadtitle"] description = self.request.POST["uploaddescription"] if "uploadfile" not in self.request.POST: self.request.session.flash( _("Please select a file to upload."), "error" ) return self.kottibrowser() file = self.request.POST["uploadfile"] if not hasattr(file, "filename"): self.request.session.flash( _("Please select a file to upload."), "error" ) return self.kottibrowser() mimetype = file.type filename = file.filename data = file.file.read() size = len(data) title = title or filename if mimetype.startswith("image"): Factory = Image else: Factory = File id = title_to_name(title, blacklist=self.context.keys()) resource = self.context[id] = Factory( title=title, description=description, data=data, filename=filename, mimetype=mimetype, size=size ) self.request.session.flash(_("Successfully uploaded."), "success") location = self.request.resource_url(resource, "@@kottibrowser") return HTTPFound(location=location)
def post(self): # import pdb; pdb.set_trace() cstruct = self.request.json if 'name' in cstruct: name = cstruct['name'] else: title = cstruct.get('title', None) if not title: self.request.response.status = 400 return {'error': "Object construction require either 'name' or 'title'"} name = title_to_name(title) #TODO: Check name occopuied or not #TODO: Component validation obj = Entity(name=name) for key in cstruct: setattr(obj, key, cstruct[key]) self.context[name] = obj self.request.response.status = 201 return {}
def upload(self): title = self.request.POST["uploadtitle"] description = self.request.POST["uploaddescription"] if "uploadfile" not in self.request.POST: self.request.session.flash(_("Please select a file to upload."), "error") return self.kottibrowser() file = self.request.POST["uploadfile"] if not hasattr(file, "filename"): self.request.session.flash(_("Please select a file to upload."), "error") return self.kottibrowser() mimetype = file.type filename = file.filename data = file.file.read() size = len(data) title = title or filename if mimetype.startswith("image"): Factory = Image else: Factory = File id = title_to_name(title, blacklist=self.context.keys()) resource = self.context[id] = Factory(title=title, description=description, data=data, filename=filename, mimetype=mimetype, size=size) self.request.session.flash(_("Successfully uploaded."), "success") location = self.request.resource_url(resource, "@@kottibrowser") return HTTPFound(location=location)
def rename_nodes(self): """ Rename nodes view. Renders either a view to change the titles and names for multiple nodes or handle the changes and get back to the referrer of the request. :result: Either a redirect response or a dictionary passed to the template for rendering. :rtype: pyramid.httpexceptions.HTTPFound or dict """ if 'rename_nodes' in self.request.POST: ids = self.request.POST.getall('children-to-rename') for id in ids: item = DBSession.query(Node).get(id) name = self.request.POST[id + '-name'] title = self.request.POST[id + '-title'] if not name or not title: self.request.session.flash( _(u'Name and title are required.'), 'error') location = resource_url(self.context, self.request) + '@@rename_nodes' return HTTPFound(location=location) else: item.name = title_to_name(name, blacklist=self.context.keys()) item.title = title self.request.session.flash(_(u'Your changes have been saved.'), 'success') return self.back('@@contents') if 'cancel' in self.request.POST: self.request.session.flash(_(u'No changes made.'), 'info') return self.back('@@contents') ids = self._selected_children(add_context=False) items = [] if ids is not None: items = DBSession.query(Node).filter(Node.id.in_(ids)).all() return {'items': items}
def put(self): # we never accept id, it doesn't conform to jsonapi format data = self.request.json_body['data'] klass = get_content_factory(self.request, data['type']) add_permission = klass.type_info.add_permission if not self.request.has_permission(add_permission, self.context): raise HTTPForbidden() schema_name = _schema_factory_name(type_name=data['type']) schema_factory = self.request.registry.getUtility(ISchemaFactory, name=schema_name) schema = schema_factory(None, self.request) validated = schema.deserialize(data['attributes']) name = title_to_name(validated['title'], blacklist=self.context.keys()) new_item = self.context[name] = klass(**validated) response = HTTPCreated() response.body = render('kotti_jsonp', new_item, self.request) return response
def rename_nodes(self): """ Rename nodes view. Renders either a view to change the titles and names for multiple nodes or handle the changes and get back to the referrer of the request. :result: Either a redirect response or a dictionary passed to the template for rendering. :rtype: pyramid.httpexceptions.HTTPFound or dict """ if 'rename_nodes' in self.request.POST: ids = self.request.POST.getall('children-to-rename') for id in ids: item = DBSession.query(Node).get(id) name = self.request.POST[id + '-name'] title = self.request.POST[id + '-title'] if not name or not title: self.flash(_(u'Name and title are required.'), 'error') location = resource_url(self.context, self.request, '@@rename_nodes') return HTTPFound(location=location) else: item.name = title_to_name(name, blacklist=self.context.keys()) item.title = title self.flash(_(u'Your changes have been saved.'), 'success') return self.back('@@contents') if 'cancel' in self.request.POST: self.flash(_(u'No changes were made.'), 'info') return self.back('@@contents') ids = self._selected_children(add_context=False) items = [] if ids is not None: items = DBSession.query(Node).filter(Node.id.in_(ids)).all() return {'items': items}
def paste_node(context, request): session = DBSession() id, action = request.session['kotti.paste'] item = session.query(Node).get(id) if action == 'cut': if not has_permission('edit', item, request): raise Forbidden() item.__parent__.children.remove(item) context.children.append(item) del request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = title_to_name(copy.title) while name in context.keys(): name = disambiguate_name(name) copy.name = name context.children.append(copy) request.session.flash( _(u'${title} pasted.', mapping=dict(title=item.title)), 'success') if not request.is_xhr: location = resource_url(context, request) return HTTPFound(location=location)
def rename_nodes(self): """ Rename nodes view. Renders either a view to change the titles and names for multiple nodes or handle the changes and get back to the referrer of the request. :result: Either a redirect response or a dictionary passed to the template for rendering. :rtype: pyramid.httpexceptions.HTTPFound or dict """ if "rename_nodes" in self.request.POST: ids = self.request.POST.getall("children-to-rename") for id in ids: item = DBSession.query(Node).get(id) name = self.request.POST[id + "-name"] title = self.request.POST[id + "-title"] if not name or not title: self.flash(_("Name and title are required."), "error") location = resource_url( self.context, self.request, "@@rename_nodes" ) return HTTPFound(location=location) else: item.name = title_to_name(name, blacklist=self.context.keys()) item.title = title self.flash(_("Your changes have been saved."), "success") return self.back("@@contents") if "cancel" in self.request.POST: self.flash(_("No changes were made."), "info") return self.back("@@contents") ids = self._selected_children(add_context=False) items = [] if ids is not None: items = DBSession.query(Node).filter(Node.id.in_(ids)).all() return {"items": items}
def paste_node(context, request): session = DBSession() id, action = request.session['kotti.paste'] item = session.query(Node).get(id) if action == 'cut': if not has_permission('edit', item, request): raise Forbidden() item.__parent__.children.remove(item) context.children.append(item) del request.session['kotti.paste'] elif action == 'copy': copy = item.copy() name = copy.name if not name: # for root name = title_to_name(copy.title) while name in context.keys(): name = disambiguate_name(name) copy.name = name context.children.append(copy) request.session.flash(_(u'${title} pasted.', mapping=dict(title=item.title)), 'success') if not request.is_xhr: location = resource_url(context, request) return HTTPFound(location=location)
def test_max_length_250(self): self.setUp() from kotti.util import title_to_name assert len(title_to_name("a" * 250)) == 240
def test_max_length_40_no_default(self): self.setUp() from kotti.util import title_to_name assert len(title_to_name(u'a' * 50, max_length=40)) == 40
def test_normal(self): self.setUp() from kotti.util import title_to_name assert title_to_name(u'Foo Bar') == u'foo-bar'
def test_max_length_255(self): self.setUp() from kotti.util import title_to_name assert len(title_to_name(u'a' * 255)) == 240
def test_max_length_40(self): self.setUp() from kotti.util import title_to_name assert len(title_to_name(u'a' * 50)) == 50
:rtype: dict """ fs = self.request.POST['qqfile'] # We can fail hard, as somebody is trying to cheat on us if that fails. assert isinstance(fs, FieldStorage) try: factory = self.factory_by_name(self.request.POST['content_type']) except KeyError, e: result = { 'success': False, 'error': e.message, } else: name = title_to_name(fs.filename, blacklist=self.context.keys()) self.context[name] = node = factory.from_field_storage(fs) node.title = fs.filename result = { "success": True, "url": self.request.resource_url(node), } # FineUploader expects JSON with Content-Type 'text/plain' response = Response(json.dumps(result)) response.content_type = 'text/plain' return response
def find_name(self, appstruct): name = appstruct.get('name') if name is None: name = title_to_name( appstruct['title'], blacklist=self.context.keys()) return name
def test_normal(self): self.setUp() from kotti.util import title_to_name assert title_to_name("Foo Bar") == "foo-bar"
def test_max_length(self): from kotti.util import title_to_name assert len(title_to_name(u'a' * 50)) == 40
def find_name(self, appstruct): name = appstruct.get('name') if name is None: name = title_to_name(appstruct['title'], blacklist=self.context.keys()) return name