def delete_slide(loader: Loader, slide_index: int, do_garbage_collection: bool = True): slide_filepath = make_slide_path(slide_index) slide_rels_filepath = make_rels_path(slide_filepath) presentation_rels_filepath = make_rels_path(PRESENTATION_PATH) # delete slide xml try: loader.delete_file(slide_filepath) except KeyError: return loader.delete_file(slide_rels_filepath) # delete relations if do_garbage_collection: delete_unused_media(loader=loader) last_pptx_slide_index = find_last_index_of_content(loader=loader, content_name='slide') for i in range(1, last_pptx_slide_index + 1): delete_mention_in_slide(loader=loader, slide_id=i, slide_id_to_delete=slide_index) # update presentation xml slide_relation_id = find_relation_id_in_rels( loader=loader, rels_filepath=presentation_rels_filepath, filepath=slide_filepath) assert slide_relation_id is not None delete_mention_in_rels(loader=loader, rels_filepath=presentation_rels_filepath, relation_id=slide_relation_id) delete_slide_mention_in_presentation(loader=loader, relation_id=slide_relation_id) # update content type xml delete_mention_in_content_type(loader=loader, filepath=slide_filepath)
def delete_mention_in_slide(loader: Loader, slide_id: int, slide_id_to_delete: int): slide_filepath_to_delete = f'slide{slide_id_to_delete}.xml' slide_filepath = make_slide_path(slide_id) slide_rels_filepath = make_rels_path(slide_filepath) r_id = find_relation_id_in_rels(loader=loader, rels_filepath=slide_rels_filepath, filepath=slide_filepath_to_delete) if r_id is None: return delete_shapes_with_relation(loader=loader, slide_filepath=slide_filepath, r_id_to_delete=r_id) delete_mention_in_rels(loader=loader, rels_filepath=slide_rels_filepath, relation_id=r_id)
def _slide_layout_path(self) -> str: rels_path = make_rels_path(self._xml_path) return find_first_relation_path_with_prefix(self._storage.loader, rels_path, SLIDE_LAYOUTS_PATH_PREFIX)
def rels(self) -> ElementTree: return self._storage.loader.get_file_xml(make_rels_path(self._xml_path))
def _slide_master_path(self) -> str: rels_path = make_rels_path(self._xml_path) return find_first_relation_path_with_prefix(self._storage.loader, rels_path, SLIDE_MASTERS_PATH_PREFIX)
def _theme_path(self) -> str: rels_path = make_rels_path(self._xml_path) return find_first_relation_path_with_prefix(self._storage.loader, rels_path, THEMES_PATH_PREFIX)
def copy_relations_recursively(src_loader: Loader, src_rels_filepath: str, dest_loader: Loader, dest_rels_filepath: str, state: Optional[_CopyRelationState] = None) -> Iterable[str]: """ :return: abs destination paths of what was copied """ if state is None: state = _CopyRelationState() src_xml = src_loader.get_file_xml(src_rels_filepath) dest_xml = dest_loader.get_file_xml(dest_rels_filepath) target_filepaths_queue = list() repeated_target_filepaths_queue = list() for src_rel in src_xml.xpath('r:Relationship', namespaces=pptx_xml_ns): # make dest target filepath relative_src_target = src_rel.get('Target') match_result = _PATH_DIR_CONTENT_NAME_EXT_REGEX.match(relative_src_target) dir_name = match_result.group(1) content_name = match_result.group(2) ext = match_result.group(3) last_target_index = find_last_index_of_content(loader=dest_loader, content_name=content_name, dir_name=dir_name) dest_target_index = last_target_index + 1 relative_dest_target = f'../{dir_name}/{content_name}{dest_target_index}.{ext}' # copy file abs_src_target = absolutize_filepath_relatively_to_content_dirs(relative_src_target) abs_dest_target = absolutize_filepath_relatively_to_content_dirs(relative_dest_target) contents = src_loader.get_file(abs_src_target) dest_loader.save_file(abs_dest_target, contents) # add this file's rels to copy queue src_rel_filepath = make_rels_path(abs_src_target) dest_rel_filepath = make_rels_path(abs_dest_target) if src_loader.does_file_exist(src_rel_filepath): if state.has_src(abs_src_target): repeated_target_filepaths_queue.append((src_rel_filepath, dest_rel_filepath)) else: target_filepaths_queue.append((src_rel_filepath, dest_rel_filepath)) # track state.track(abs_src_target, abs_dest_target) # track in rels dest_item_xml = etree.Element('{%s}Relationship' % pptx_xml_ns['r']) dest_item_xml.set('Id', src_rel.get('Id')) dest_item_xml.set('Type', src_rel.get('Type')) dest_item_xml.set('Target', relative_dest_target) dest_xml.append(dest_item_xml) dest_loader.save_file_xml(dest_rels_filepath, dest_xml) for src_rel_filepath, dest_rel_filepath in target_filepaths_queue: create_blank_rels(loader=dest_loader, filepath=dest_rel_filepath) copy_relations_recursively(src_loader=src_loader, src_rels_filepath=src_rel_filepath, dest_loader=dest_loader, dest_rels_filepath=dest_rel_filepath, state=state) for src_rel_filepath, dest_rel_filepath in repeated_target_filepaths_queue: create_blank_rels(loader=dest_loader, filepath=dest_rel_filepath) _copy_relations_recursively_repeated_case(src_loader=src_loader, src_rels_filepath=src_rel_filepath, dest_loader=dest_loader, dest_rels_filepath=dest_rel_filepath, state=state) return state.dest_filepaths