def list_dir(self, nodeid, filename="/", _path=None): """List data files in node.""" if not filename.endswith("/"): raise FileError("filename '%s' does not end with '/'" % filename) path = self.get_node_path(nodeid) if _path is None else _path path = get_node_filename(path, filename) try: filenames = os.listdir(path) except: raise UnknownFile("cannot file file '%s' '%s'" % (nodeid, filename)) for name in filenames: # TODO: extract this as a documented method. if (name != NODE_META_FILE and not name.startswith("__")): fullname = os.path.join(path, name) node_fullname = path_join(filename, name) if not os.path.exists(get_node_meta_file(fullname)): # ensure directory is not a node if os.path.isdir(fullname): yield node_fullname + "/" else: yield node_fullname
def update_node(self, nodeid, attr): """Write node attr""" # TODO: support mutltiple parents # Clean attributes. self._clean_attr(nodeid, attr) # write attrs path = self._get_node_path(nodeid) self._write_attr(get_node_meta_file(path), nodeid, attr) # Determine possible path changes due to node moves or title renaming. # Get old parentid. parentid = self._get_parentid(nodeid) # Get new parentid if nodeid == self.get_rootid(): parentid2 = None else: parentids2 = attr.get("parentids") parentid2 = parentids2[0] if parentids2 else None # Get old title. title_index = self._index.get_attr(nodeid, "title") if parentid != parentid2: # Move to a new parent. self._rename_node_dir(nodeid, attr, parentid, parentid2, path) elif (parentid and title_index and title_index != attr.get("title", u"")): # Rename node directory, but # do not rename root node dir (parentid is None). self._rename_node_dir(nodeid, attr, parentid, parentid2, path) else: # Update index. basename = os.path.basename(path) self._index.add_node(nodeid, parentid2, basename, attr, mtime=get_path_mtime(path))
def _read_node(self, parentid, path, _full=True, _force_index=False): """ Reads a node from disk. _full -- If True, populate all children ids from filesystem. _force_index -- Index node regardless of mtime. """ metafile = get_node_meta_file(path) attr, extra = self._read_attr(metafile) nodeid = extra['nodeid'] # Clean attr and rewrite them if needed. if not self._clean_attr(nodeid, attr): self._write_attr(metafile, nodeid, attr) # update path cache basename = os.path.basename(path) if parentid else path self._path_cache.add(nodeid, basename, parentid) # check indexing if _force_index: # reindex this node self._index.add_node(nodeid, parentid, basename, attr, get_path_mtime(path)) else: # if node has changed on disk (newer mtime), then re-index it current, mtime = self._node_index_current(nodeid, path) if not current: self._reindex_node(nodeid, parentid, path, attr, mtime) # Supplement parent and child ids # TODO: when cloning is implemented, use filesystem to only supplement # not replace ids if parentid and 'parentids' in attr: attr['parentids'] = [parentid] if _full and 'childrenids' in attr: attr["childrenids"] = list( self._list_children_nodeids(nodeid, path)) return attr
def _read_node(self, parentid, path, _full=True, _force_index=False): """ Reads a node from disk. _full -- If True, populate all children ids from filesystem. _force_index -- Index node regardless of mtime. """ metafile = get_node_meta_file(path) attr, extra = self._read_attr(metafile) nodeid = extra['nodeid'] # Clean attr and rewrite them if needed. if not self._clean_attr(nodeid, attr): self._write_attr(metafile, nodeid, attr) # update path cache basename = os.path.basename(path) if parentid else path self._path_cache.add(nodeid, basename, parentid) # check indexing if _force_index: # reindex this node self._index.add_node( nodeid, parentid, basename, attr, get_path_mtime(path)) else: # if node has changed on disk (newer mtime), then re-index it current, mtime = self._node_index_current(nodeid, path) if not current: self._reindex_node(nodeid, parentid, path, attr, mtime) # Supplement parent and child ids # TODO: when cloning is implemented, use filesystem to only supplement # not replace ids if parentid and 'parentids' in attr: attr['parentids'] = [parentid] if _full and 'childrenids' in attr: attr["childrenids"] = list( self._list_children_nodeids(nodeid, path)) return attr
def _list_children_attr(self, nodeid, _path=None, _full=True): """List attr of children nodes of nodeid""" path = self._path_cache.get_path(nodeid) if _path is None else _path assert path is not None try: files = os.listdir(path) except Exception, e: raise ConnectionError( _(u"Do not have permission to read folder contents: %s") % path, e) for filename in files: path2 = os.path.join(path, filename) if os.path.exists(get_node_meta_file(path2)): try: yield self._read_node(nodeid, path2, _full=_full) except ConnectionError, e: keepnote.log_error(u"error reading %s" % path2) continue # TODO: raise warning, not all children read self._path_cache.set_children_complete(nodeid, True) def _list_children_nodeids(self, nodeid, _path=None, _index=True): """List nodeids of children of node""" # try to use cache first children = self._path_cache.get_children(nodeid) if children is not None: