def update_branch(parent_id): """Recursively updates branch setting correct ids, level, slug and path""" for page in get_pages_by_parent_id(parent_id): db.update( "pages", where="id=$id", vars=page, **unique_path(page, page.id)) update_branch(page.id)
def update_columns(block, sizes): columns = get_blocks_by_parent_id(block.id) edit_len = min(len(columns), len(sizes)) create_len = len(sizes) - len(columns) orphan_blocks = [] for i in range(edit_len): col, size = columns[i], sizes[i] db.update( "blocks", where="id = $id", vars=col, updated_at=web.SQLLiteral("CURRENT_TIMESTAMP"), size=size, css_class=column_css_class(size), position=i + 1, ) if create_len >= 0: # Create columns create_columns(block, sizes[edit_len:], edit_len) else: # Remove columns orphan_blocks = remove_columns(block, columns[create_len:]) return orphan_blocks
def update_page_by_id(page_id, data): page = get_page_by_id(page_id) # Cannot change page type del data["type"] if page.is_system: # Cannot edit slug of the system page del data["slug"] # position can be changed, but not parent_id data.parent_id = page.parent_id data.path = page.path else: data.parent_id = int(data.parent_id) data.update(unique_path(data, page_id)) # if position specified and parent has not changed if data.position and data.parent_id == page.parent_id: data.position = int(data.position) else: data.position = get_last_position("pages", data.parent_id) data.update( description_cached=smarty(sanitize(data.description)), updated_at=web.SQLLiteral("CURRENT_TIMESTAMP"), ) # Set published_at to NOW if data.published_at is None: data.published_at = web.SQLLiteral("CURRENT_TIMESTAMP") with db.transaction(): # Transact changes to positions if (data.position != page.position or data.parent_id != page.parent_id): # Collapse positions for the removed page collapse_tree_siblings("pages", page) # Shift positions to free the space to insert page expand_tree_siblings("pages", data) db.update( "pages", where="id = $page_id", vars=locals(), **data) # TODO: expand this for tree if data.path != page.path: update_branch(page.id) page.update(data) return page
def expand_tree_siblings(table_name, obj): """Expands positions to free the space for @obj insertion""" db.update( table_name, where="parent_id = $parent_id AND position >= $position AND " "NOT is_deleted", vars=obj, position=web.SQLLiteral("position + 1"), ) return obj
def resize_image(image, size): original_name = os.path.join(config.upload_dir, image.filename) destination_name = os.path.join( config.static_dir, "i/" + image.filename + "_" + size + image.extension ) resize_image_file(original_name, destination_name, size) sizes = set(image.sizes.split(",")) if image.sizes else set() sizes.add(size) image.sizes = ",".join(sizes) db.update("documents", where="id = $id", vars=image, sizes=image.sizes) return image
def collapse_tree_siblings(table_name, obj): """Collapses positions at @obj.position eg: if position = 4, then 1 2 3 (4) [5 6 7 8 9] -> 1 2 3 (4) [4 5 6 7 8] @obj should then be deleted or moved away from its parent """ db.update( table_name, where="parent_id = $parent_id AND position > $position AND " "NOT is_deleted", vars=obj, position=web.SQLLiteral("position - 1"), ) return obj
def update_document_by_id(document_id, data): document = get_document_by_id(document_id) # Cannot edit system files and folders if document.is_system: raise flash.error( _("Cannot edit or delete system files and folders.")) parent = get_document_by_id(data.parent_id) # TODO: custom input field that returns integer value data.update( ids=(parent.ids or "") + "," + str(parent.id), level=parent.level + 1, position=int(data.position), parent_id=parent.id, updated_at=web.SQLLiteral("CURRENT_TIMESTAMP"), ) with db.transaction(): # Transact changes to positions if (data.position != document.position or data.parent_id != document.parent_id): # Collapse positions for the removed document collapse_tree_siblings("documents", document) # Shift positions to free the space to insert document expand_tree_siblings("documents", data) # Cannot change documents type and upload del data["type"] del data["upload"] db.update( "documents", where="id = $document_id", vars=locals(), **data) # Update document with data # TODO: fix updated_at document.update(data) return document
def remove_columns(block, columns): # TODO: fix CURRENT_TIMESTAMP # Orphan update data orphan_data = web.storage( updated_at=web.SQLLiteral("CURRENT_TIMESTAMP"), page_id=block.page_id, parent_id=block.parent_id, ids=block.ids, level=block.level, position=block.position + 1, ) orphans = [] for column in columns: orphans += get_blocks_by_parent_id(column.id) delete_block_by_id(column.id, delete_system=True) # Shift positions of the blocks after orphans # Positions before: # 1 2 (3) 4 5 # Positions after (3 orphans): # 1 2 (3) [4 5 6] 7 8 # Blocks 4 5 shifted to 7 8 # db.update( "blocks", where="parent_id = $parent_id AND NOT is_deleted AND " "position > $position", vars=block, position=web.SQLLiteral("position + %d" % len(orphans)), ) # Insert orphans for orphan in orphans: orphan.update(orphan_data) db.update( "blocks", where="id = $id", vars=orphan, **orphan_data) orphan_data.position += 1 return orphans
def update_block_by_id(block_id, data): block = get_block_by_id(block_id) # Cannot edit or delete system blocks if block.is_system: raise flash.error( _("Cannot edit or delete system blocks.")) data.updated_at = web.SQLLiteral("CURRENT_TIMESTAMP") # Cannot change type and template of block del data["template"] del data["type"] if block.type == "wysiwyg": data.content_cached = smarty(sanitize(data.content)) else: data.content_cached = smarty(data.content) # Get column sizes from data sizes = data.pop("sizes") # Don't change block position, it may be wrong # TODO: ensure correct position from the server position = data.pop("position") # TODO: wrap the code below in transaction db.update( "blocks", where="$block_id = id", vars=locals(), **data) # Update block with data # TODO: fix updated_at block.update(data) # Create columns for row block if block.template == "row" and sizes: block.orphans = update_columns(block, sizes) return block
def delete_tree_branch(table_name, parent_obj, func=None): """Recursively deletes document tree branch. Ignores is_system flag, deletes everything.""" db.update( table_name, where="id = $id AND NOT is_deleted", vars=parent_obj, is_deleted=True, deleted_at=web.SQLLiteral("CURRENT_TIMESTAMP"), ) if func is not None: func(parent_obj) for obj in db.select(table_name, where="parent_id = $id AND NOT is_deleted", vars=parent_obj): delete_tree_branch(table_name, obj, func) return parent_obj