def upload(self): # Move uploaded files to their permanent location try: for member in self.upload_members: if schema.get(self.data, member) is None: continue value = schema.get(self.instance, member) if isinstance(member, schema.Collection): files = value else: files = (value, ) for i, file in enumerate(files): temp_file = self.temp_paths[file] if os.path.exists(temp_file): dest = file.file_path if os.path.exists(dest): os.remove(dest) move(temp_file, dest) # Remove the temporary folder finally: rmtree(self.temp_upload_folder)
def adapt_object(self, context): context.consume("upload") upload = context.get("upload", None) if upload: context.set("file_name", schema.get(upload, "file_name")) context.set("mime_type", schema.get(upload, "mime_type")) context.set("file_size", schema.get(upload, "file_size")) context.set("file_hash", schema.get(upload, "file_hash"))
def test_reference_relation_constraints(self): from cocktail.schema import Reference, Integer, exceptions, get foreign_field = Integer("foo") ref = Reference(relation_constraints=[ foreign_field.not_equal(None), foreign_field.greater(3), foreign_field.lower(8), lambda owner, related: get(related, "foo", None) is None or get( related, "foo", None) % 5 != 0 ]) self._test_validation(ref, [None, {"foo": 4}, {"foo": 6}, {"foo": 7}]) self._test_validation( ref, None, [{}, { "foo": None }], exceptions.RelationConstraintError, error_count=2 # Note that x > None is always True ) self._test_validation(ref, None, [{ "foo": -6 }, { "foo": 1 }, { "foo": 3 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[1]}) self._test_validation(ref, None, [{ "foo": 8 }, { "foo": 12 }, { "foo": 134 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[2]}) self._test_validation(ref, None, [{ "foo": 5 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[3]})
def get_item_id(self, item): pm = self.schema.primary_member if pm is None: raise ValueError( "Selectable tables must have a schema with a primary member " "defined or override their get_item_id() method") return get(item, pm)
def handle_processed(cls, event): controller = event.source rel = cherrypy.request.params.get("relation-select") # Open the item selector if rel: pos = rel.find("-") root_content_type_name = rel[:pos] selection_parameter = rel[pos + 1:] key = selection_parameter[len(controller.form_prefix):] # Push the relation as a new stack node current_node = controller.stack_node rel_node = RelationNode() rel_node.member = current_node.content_type[key] controller.edit_stack.push(rel_node) value = schema.get(current_node.form_data, key) raise cherrypy.HTTPRedirect( controller.context["cms"].contextual_uri("content") + "?" + view_state( selection=value.id if value is not None else None, edit_stack=controller.edit_stack.to_param(), client_side_scripting=controller.client_side_scripting) + "#default") # Open an editor for a new nested item new = cherrypy.request.params.get("relation-new") if new: pos = new.find("-") member_name = new[:pos] content_type_name = new[pos + 1:] # Push the relation as a new stack node current_node = controller.stack_node rel_node = RelationNode() rel_node.member = current_node.content_type[member_name] controller.edit_stack.push(rel_node) raise cherrypy.HTTPRedirect( controller.context["cms"].contextual_uri( "content", "new", item_type=content_type_name, edit_stack=controller.edit_stack.to_param())) # Open an editor for an existing nested item edit = cherrypy.request.params.get("relation-edit") if edit: raise cherrypy.HTTPRedirect( controller.edit_uri(controller.stack_node.form_data[edit]))
def iter_changes(self, source=None): for member, language in EditNode.iter_changes(self, source): # Ignore differences on the upload field if no file has been # uploaded if member.name == "upload": upload = schema.get(self.form_data, "upload", None) if (upload is None or upload.get("file_hash") == self.item.file_hash): continue yield (member, language)
def _read_schema(self, member, target, languages, path): if target is None: if isinstance(member, type): target = member() else: target = {} path.append(member) try: for child_member in member.members().values(): if child_member.editable != schema.EDITABLE: continue if self._is_schema(child_member): nested_target = schema.get(target, child_member, None) if nested_target is None: nested_target = self.create_nested_target( member, child_member, target) schema.set(target, child_member.name, nested_target) else: nested_target = target value = self.read( child_member, nested_target, languages if child_member.translated else None, path) # Validate child members *after* all members have read their values # (this allows conditional validations based on other members in # the schema) if self.errors != "ignore": invalid_members = set() for error in member.get_errors(target): error_member = error.member if (error_member not in invalid_members and error_member.editable == schema.EDITABLE): invalid_members.add(error_member) error_target = error.context.get_object() fixed_value = self._fix_value(error_target, error_member, error.value, error) if error_member.name: schema.set(error_target, error_member.name, fixed_value) finally: path.pop() return target
def unrelate(self, member, item): """Breaks the relation between the edited item and one of its related items. @param member: The member describing the relation between the two items. It should be the end nearer to the edited item. @type member: L{RelationMember<cocktail.schema.RelationMember>} @param item: The item to unrelate. @type item: L{Item<woost.models.item.Item>} """ if isinstance(member, schema.Collection): collection = schema.get(self.form_data, member) schema.remove(collection, item) else: schema.set(self.form_data, member, None)
def relate(self, member, item): """Adds a relation between the edited item and another item. @param member: The member describing the relation between the two items. It should be the end nearer to the edited item. @type member: L{RelationMember<cocktail.schema.RelationMember>} @param item: The item to relate. @type item: L{Item<woost.models.item.Item>} """ if isinstance(member, schema.Collection): collection = schema.get(self.form_data, member) # Editing collections with duplicate entries is not allowed if item in collection: raise ValueError( "Collections with duplicate entries are not allowed") schema.add(collection, item) else: schema.set(self.form_data, member, item)
def _synchronize(self): cmp = self.comparision get_param = cherrypy.request.params.get file_downloads = set() selection = self.sync_selection with changeset_context(get_current_user()): for obj in cmp["incomming"]: if obj.global_id in selection: obj.insert() if isinstance(obj, File): file_downloads.add(obj) for global_id, change in cmp["modified"].iteritems(): if global_id in selection: local = change["local"] remote = change["remote"] for member, lang in change["diff"]: value = schema.get(remote, member, language=lang) local.set(member, value, lang) if member in (File.file_hash, File.file_size): file_downloads.add(local) # Download files from the remote copy for file in file_downloads: self.synchronization.download_file(file) # Find importable content again self.comparision = self.synchronization.compare_content() notify_user( translations( "woost.controllers.InstallationSyncController.success"), "success")
def collection(self): return schema.get(self.edit_node.form_data, self.member)
def _handle_form_data(self): stack_node = self.stack_node form_data = stack_node.form_data translations = stack_node.translations section = self.params.read(schema.String("section", default="fields")) added_translation = self.params.read( schema.String("add_translation", enumeration=self.available_languages)) deleted_translation = self.params.read( schema.String("delete_translation", enumeration=translations)) # Remove translations if deleted_translation: translations.remove(deleted_translation) for key, member in self.fields_schema.members().iteritems(): if member.translated: values = form_data.get(key) if values: values.pop(deleted_translation, None) get_method = cherrypy.request.method.upper() == "GET" # Load form data from the request get_parameter(self.fields_schema, target=form_data, languages=translations, prefix=self.form_prefix, errors="ignore", implicit_booleans=not get_method, undefined="skip" if get_method else "set_none") # Add translations if added_translation and added_translation not in translations: translations.append(added_translation) # Try to copy an existing fallback translation for fallback_language in iter_language_chain(added_translation, include_self=False): if fallback_language in translations: for key, member in self.fields_schema.members().iteritems( ): if member.translated: value = schema.get(form_data, key, language=fallback_language) schema.set(form_data, key, value, language=added_translation) break # If there's no fallback translation to use, create a new # translation from scratch else: translation_data = {} stack_node.content_type.translation.init_instance( translation_data) for key, value in translation_data.iteritems(): schema.set(form_data, key, value, language=added_translation) # Drop references unlink = cherrypy.request.params.get("relation-unlink") if unlink: form_data[unlink] = None return form_data
def user_collection(self): user_collection = BackOfficeUserCollection(self.root_content_type) if self.root_content_type: user = get_current_user() for role in user.roles: if role.default_content_type: if issubclass(role.default_content_type, self.root_content_type): user_collection.default_type = role.default_content_type break if self.edit_stack and isinstance(self.stack_node, RelationNode): user_collection.default_type = \ self.stack_node.member.selector_default_type user_collection.available_languages = self.available_languages user_collection.selection_mode = self.selection_mode user_collection.default_order = \ [NegativeExpression(Item.last_update_time)] # Parameter persistence prefix = self.persistence_prefix duration = self.persistence_duration user_collection.set_parameter_source( "type", SessionParameterSource(key_prefix=prefix)) type_prefix = user_collection.type.full_name if prefix: type_prefix += "-" + prefix user_collection.persistence_prefix = type_prefix user_collection.persistent_source = psource = SessionParameterSource( key_prefix=type_prefix) user_collection.set_parameter_source("content_view", psource) user_collection.set_parameter_source("members", psource) user_collection.set_parameter_source("order", psource) user_collection.set_parameter_source("grouping", psource) user_collection.set_parameter_source("filter", psource) user_collection.set_parameter_source("page", psource) user_collection.set_parameter_source("page_size", psource) user_collection.set_parameter_source("expanded", psource) user_collection.set_parameter_source( "language", CookieParameterSource(cookie_naming="visible_languages", cookie_duration=duration)) # Exclude instances of invisible types def hide_invisible_types(content_type): if not content_type.visible: exclusion = ExclusionExpression(Self, content_type.keys) exclusion.by_key = True user_collection.add_base_filter(exclusion) else: for descendant_type \ in content_type.derived_schemas(recursive = False): hide_invisible_types(descendant_type) hide_invisible_types(user_collection.type) node = self.stack_node if node and isinstance(node, RelationNode): relation = node.member is_collection = isinstance(relation, schema.Collection) edit_node = self.edit_stack[-2] excluded_items = set() # Exclude items that are already contained on an edited collection if is_collection: excluded_items.update(schema.get(edit_node.form_data, relation)) if excluded_items: user_collection.add_base_filter( ExclusionExpression(Self, excluded_items)) # Add relation constraints if relation.enumeration: enumeration = relation.resolve_constraint( relation.enumeration, ValidationContext(edit_node.item.__class__, edit_node.item, persistent_object=edit_node.item)) user_collection.add_base_filter( InclusionExpression(Self, enumeration)) for constraint in relation.get_constraint_filters(edit_node.item): user_collection.add_base_filter(constraint) # Filter unauthorized items user_collection.add_base_filter( PermissionExpression(get_current_user(), ReadPermission)) return user_collection