| 29 | |
| 30 | @PluginManager.acceptPlugins |
| 31 | class ContentManager(object): |
| 32 | |
| 33 | def __init__(self, site): |
| 34 | self.site = site |
| 35 | self.log = self.site.log |
| 36 | self.contents = ContentDbDict(site) |
| 37 | self.hashfield = PeerHashfield() |
| 38 | self.has_optional_files = False |
| 39 | |
| 40 | # Load all content.json files |
| 41 | def loadContents(self): |
| 42 | if len(self.contents) == 0: |
| 43 | self.log.debug("ContentDb not initialized, load files from filesystem") |
| 44 | self.loadContent(add_bad_files=False, delete_removed_files=False) |
| 45 | self.site.settings["size"], self.site.settings["size_optional"] = self.getTotalSize() |
| 46 | |
| 47 | # Load hashfield cache |
| 48 | if "hashfield" in self.site.settings.get("cache", {}): |
| 49 | self.hashfield.frombytes(base64.b64decode(self.site.settings["cache"]["hashfield"])) |
| 50 | del self.site.settings["cache"]["hashfield"] |
| 51 | elif self.contents.get("content.json") and self.site.settings["size_optional"] > 0: |
| 52 | self.site.storage.updateBadFiles() # No hashfield cache created yet |
| 53 | self.has_optional_files = bool(self.hashfield) |
| 54 | |
| 55 | self.contents.db.initSite(self.site) |
| 56 | |
| 57 | def getFileChanges(self, old_files, new_files): |
| 58 | deleted = {key: val for key, val in old_files.items() if key not in new_files} |
| 59 | deleted_hashes = {val.get("sha512"): key for key, val in old_files.items() if key not in new_files} |
| 60 | added = {key: val for key, val in new_files.items() if key not in old_files} |
| 61 | renamed = {} |
| 62 | for relative_path, node in added.items(): |
| 63 | hash = node.get("sha512") |
| 64 | if hash in deleted_hashes: |
| 65 | relative_path_old = deleted_hashes[hash] |
| 66 | renamed[relative_path_old] = relative_path |
| 67 | del(deleted[relative_path_old]) |
| 68 | return list(deleted), renamed |
| 69 | |
| 70 | # Load content.json to self.content |
| 71 | # Return: Changed files ["index.html", "data/messages.json"], Deleted files ["old.jpg"] |
| 72 | def loadContent(self, content_inner_path="content.json", add_bad_files=True, delete_removed_files=True, load_includes=True, force=False): |
| 73 | content_inner_path = content_inner_path.strip("/") # Remove / from beginning |
| 74 | old_content = self.contents.get(content_inner_path) |
| 75 | content_path = self.site.storage.getPath(content_inner_path) |
| 76 | content_dir = helper.getDirname(self.site.storage.getPath(content_inner_path)) |
| 77 | content_inner_dir = helper.getDirname(content_inner_path) |
| 78 | |
| 79 | if os.path.isfile(content_path): |
| 80 | try: |
| 81 | # Check if file is newer than what we have |
| 82 | if not force and old_content and not self.site.settings.get("own"): |
| 83 | for line in open(content_path): |
| 84 | if '"modified"' not in line: |
| 85 | continue |
| 86 | match = re.search(r"([0-9\.]+),$", line.strip(" \r\n")) |
| 87 | if match and float(match.group(1)) <= old_content.get("modified", 0): |
| 88 | self.log.debug("%s loadContent same json file, skipping" % content_inner_path) |