| 604 | |
| 605 | # Copy this site |
| 606 | def clone(self, address, privatekey=None, address_index=None, root_inner_path="", overwrite=False): |
| 607 | import shutil |
| 608 | new_site = SiteManager.site_manager.need(address, all_file=False) |
| 609 | default_dirs = [] # Dont copy these directories (has -default version) |
| 610 | for dir_name in os.listdir(self.storage.directory): |
| 611 | if "-default" in dir_name: |
| 612 | default_dirs.append(dir_name.replace("-default", "")) |
| 613 | |
| 614 | self.log.debug("Cloning to %s, ignore dirs: %s, root: %s" % (address, default_dirs, root_inner_path)) |
| 615 | |
| 616 | # Copy root content.json |
| 617 | if not new_site.storage.isFile("content.json") and not overwrite: |
| 618 | # New site: Content.json not exist yet, create a new one from source site |
| 619 | if "size_limit" in self.settings: |
| 620 | new_site.settings["size_limit"] = self.settings["size_limit"] |
| 621 | |
| 622 | # Use content.json-default is specified |
| 623 | if self.storage.isFile(root_inner_path + "/content.json-default"): |
| 624 | content_json = self.storage.loadJson(root_inner_path + "/content.json-default") |
| 625 | else: |
| 626 | content_json = self.storage.loadJson("content.json") |
| 627 | |
| 628 | if "domain" in content_json: |
| 629 | del content_json["domain"] |
| 630 | content_json["title"] = "my" + content_json["title"] |
| 631 | content_json["cloned_from"] = self.address |
| 632 | content_json["clone_root"] = root_inner_path |
| 633 | content_json["files"] = {} |
| 634 | if address_index: |
| 635 | content_json["address_index"] = address_index # Site owner's BIP32 index |
| 636 | new_site.storage.writeJson("content.json", content_json) |
| 637 | new_site.content_manager.loadContent( |
| 638 | "content.json", add_bad_files=False, delete_removed_files=False, load_includes=False |
| 639 | ) |
| 640 | |
| 641 | # Copy files |
| 642 | for content_inner_path, content in list(self.content_manager.contents.items()): |
| 643 | file_relative_paths = list(content.get("files", {}).keys()) |
| 644 | |
| 645 | # Sign content.json at the end to make sure every file is included |
| 646 | file_relative_paths.sort() |
| 647 | file_relative_paths.sort(key=lambda key: key.replace("-default", "").endswith("content.json")) |
| 648 | |
| 649 | for file_relative_path in file_relative_paths: |
| 650 | file_inner_path = helper.getDirname(content_inner_path) + file_relative_path # Relative to content.json |
| 651 | file_inner_path = file_inner_path.strip("/") # Strip leading / |
| 652 | if not file_inner_path.startswith(root_inner_path): |
| 653 | self.log.debug("[SKIP] %s (not in clone root)" % file_inner_path) |
| 654 | continue |
| 655 | if file_inner_path.split("/")[0] in default_dirs: # Dont copy directories that has -default postfixed alternative |
| 656 | self.log.debug("[SKIP] %s (has default alternative)" % file_inner_path) |
| 657 | continue |
| 658 | file_path = self.storage.getPath(file_inner_path) |
| 659 | |
| 660 | # Copy the file normally to keep the -default postfixed dir and file to allow cloning later |
| 661 | if root_inner_path: |
| 662 | file_inner_path_dest = re.sub("^%s/" % re.escape(root_inner_path), "", file_inner_path) |
| 663 | file_path_dest = new_site.storage.getPath(file_inner_path_dest) |