(self, name, item, parent, prefix, is_dir, item_inode, hlm)
| 400 | logger.debug("fuse: _process_archive completed in %.1f s for archive %s", duration, archive.name) |
| 401 | |
| 402 | def _process_leaf(self, name, item, parent, prefix, is_dir, item_inode, hlm): |
| 403 | path = item.path |
| 404 | del item.path # save some space |
| 405 | |
| 406 | def file_version(item, path): |
| 407 | if "chunks" in item: |
| 408 | file_id = blake2b_128(path) |
| 409 | current_version, previous_id = self.versions_index.get(file_id, (0, None)) |
| 410 | |
| 411 | contents_id = blake2b_128(b"".join(chunk_id for chunk_id, _ in item.chunks)) |
| 412 | |
| 413 | if contents_id != previous_id: |
| 414 | current_version += 1 |
| 415 | self.versions_index[file_id] = current_version, contents_id |
| 416 | |
| 417 | return current_version |
| 418 | |
| 419 | def make_versioned_name(name, version, add_dir=False): |
| 420 | if add_dir: |
| 421 | # add intermediate directory with same name as filename |
| 422 | path_fname = name.rsplit(b"/", 1) |
| 423 | name += b"/" + path_fname[-1] |
| 424 | # keep original extension at end to avoid confusing tools |
| 425 | name, ext = os.path.splitext(name) |
| 426 | version_enc = os.fsencode(".%05d" % version) |
| 427 | return name + version_enc + ext |
| 428 | |
| 429 | if "hlid" in item: |
| 430 | link_target = hlm.retrieve(id=item.hlid, default=None) |
| 431 | if link_target is not None: |
| 432 | # Hard link was extracted previously, just link |
| 433 | link_target = os.fsencode(link_target) |
| 434 | if self.versions: |
| 435 | # adjust link target name with version |
| 436 | version = self.file_versions[link_target] |
| 437 | link_target = make_versioned_name(link_target, version, add_dir=True) |
| 438 | try: |
| 439 | inode = self.find_inode(link_target, prefix) |
| 440 | except KeyError: |
| 441 | logger.warning("Skipping broken hard link: %s -> %s", path, link_target) |
| 442 | return |
| 443 | item = self.get_item(inode) |
| 444 | item.nlink = item.get("nlink", 1) + 1 |
| 445 | self._items[inode] = item |
| 446 | else: |
| 447 | inode = item_inode |
| 448 | self._items[inode] = item |
| 449 | # remember extracted item path, so that following hard links don't extract twice. |
| 450 | hlm.remember(id=item.hlid, info=path) |
| 451 | else: |
| 452 | inode = item_inode |
| 453 | |
| 454 | if self.versions and not is_dir: |
| 455 | parent = self._process_inner(name, parent) |
| 456 | enc_path = os.fsencode(path) |
| 457 | version = file_version(item, enc_path) |
| 458 | if version is not None: |
| 459 | # regular file, with contents |
no test coverage detected