예제 #1
0
    def _read_attr(self, filename, recover=True):
        """Read a node meta data file"""
        
        try:
            tree = ET.ElementTree(file=filename)
        except Exception as e:
            #if recover:
            #    self._recover_attr(filename)
            #    return self._read_attr(filename, recover=False)
            
            raise ConnectionError(
                _(u"Error reading meta data file '%s'" % filename), e)

        # check root
        root = tree.getroot()
        if root.tag != "node":
            raise ConnectionError(_("Root tag is not 'node'"))
        
        # iterate children
        attr = {}
        version = None
        for child in root:
            if child.tag == "dict":
                attr = plist.load_etree(child)
            if child.tag == "version":
                version = int(child.text)

        if version:
            attr["version"] = version
        
        return attr
예제 #2
0
    def create_node(self, nodeid, attr, _path=None):
        """Create a node"""
        if self._filename is None:
            raise ConnectionError("connect() has not been called")

        # check for creating root
        if self._rootid is None:
            parentids = attr.get("parentids", [])
            if parentids != []:
                raise ConnectionError("root node must have parentids = []")
            _path = self._filename
            is_root = True
        else:
            is_root = False

        # check for existing nodeid
        if self.has_node(nodeid):
            raise NodeExists(nodeid)

        # generate a new nodeid if one is not given
        if nodeid is None:
            nodeid = keepnote.notebook.new_nodeid()

        # TODO: handle case where parent does not currently exist
        # TODO: handle case where parent finally shows up and
        # reunites with its children in the orphans dir

        # Determine parentid.
        # TODO: support multiple parents.
        parentids = attr.get("parentids")
        parentid = parentids[0] if parentids else None

        # Determine path.
        if _path:
            path = _path
        elif parentid:
            # Make path using parent and title.
            parent_path = self._get_node_path(parentid)
            title = attr.get("title", _("New Page"))
            path = get_valid_unique_filename(parent_path, title)
        else:
            # Use an orphandir since no parent exists.
            path = self._get_orphandir(nodeid)

        # Clean attributes.
        self._clean_attr(nodeid, attr)

        # Make directory and write attr
        try:
            attr_file = self._get_node_attr_file(nodeid, path)
            os.makedirs(path)
            self._write_attr(attr_file, nodeid, attr)

        except OSError, e:
            raise ConnectionError(_("Cannot create node"), e)
예제 #3
0
    def _rename_node_dir(self, nodeid, attr, parentid, new_parentid, path):
        """Renames a node directory to resemble attr['title']"""

        if new_parentid is not None:
            # try to pick a path that closely resembles the title
            title = attr.get("title", _("New Page"))
            new_parent_path = self._get_node_path(new_parentid)
            new_path = get_valid_unique_filename(new_parent_path, title)
            basename = os.path.basename(new_path)
        else:
            # make orphan
            new_path = self._get_orphandir(nodeid)
            basename = new_path           

        try:
            os.rename(path, new_path)
        except Exception as e:
            raise ConnectionError(
                _(u"Cannot rename '%s' to '%s'" % (path, new_path)), e)
        
        # update index
        self._path_cache.move(nodeid, basename, new_parentid)
        self._index.add_node(nodeid, new_parentid, basename, attr, 
                             mtime=get_path_mtime(new_path))

        # update parent too
        if parentid:
            self._index.set_node_mtime(
                parentid, get_path_mtime(os.path.dirname(path)))
        if new_parentid and new_parentid != parentid:
            self._index.set_node_mtime(
                new_parentid, get_path_mtime(new_parent_path))
예제 #4
0
    def _read_root(self):
        """Read root node attr"""
        if self._filename is None:
            raise ConnectionError("connect() has not been called")

        attr = self._read_node(None, self._filename)
        self._rootid = attr["nodeid"]
        self._init_root()
        return attr
예제 #5
0
    def _write_attr(self, filename, nodeid, attr):
        """Write a node meta data file"""
        self._attr_mask.set_dict(attr)

        try:
            write_attr(filename, nodeid, self._attr_mask)
        except Exception, e:
            raise
            raise ConnectionError(
                _("Cannot write meta data" + " " + filename + ":" + str(e)), e)
예제 #6
0
    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)
예제 #7
0
def read_attr(filename, set_extra=True):
    """
    Read a node meta data file. Returns an attr dict

    filename -- a filename or stream
    """
    try:
        tree = ET.ElementTree(file=filename)
    except Exception, e:
        raise ConnectionError(
            _(u"Error reading meta data file '%s'" % filename), e)
예제 #8
0
    def delete_node(self, nodeid):
        """Delete node"""

        # TODO: will need code that orphans any children of nodeid
        path = self._get_node_path(nodeid)
        if not os.path.exists(path):
            raise UnknownNode()

        try:
            shutil.rmtree(path)
        except Exception, e:
            raise ConnectionError(_(u"Do not have permission to delete"), e)
예제 #9
0
    def delete_node(self, nodeid):
        """Delete node"""

        # TODO: will need code that orphans any children of nodeid

        try:
            shutil.rmtree(self._get_node_path(nodeid))
        except Exception as e:
            raise ConnectionError(
                _(u"Do not have permission to delete"), e)

        # TODO: remove from index entire subtree

        self._path_cache.remove(nodeid)
        self._index.remove_node(nodeid)
예제 #10
0
    def _move_to_lostdir(self, filename):
        """Moves a file/dir to the lost_found directory"""
        lostdir = self._get_lostdir()
        if not os.path.exists(lostdir):
            os.makedirs(lostdir)

        new_filename = keepnote.notebook.get_unique_filename(
            lostdir, os.path.basename(filename), sep=u"-")

        keepnote.log_message(u"moving data to lostdir '%s' => '%s'\n" %
                             (filename, new_filename))
        try:
            os.rename(filename, new_filename)
        except OSError, e:
            raise ConnectionError(u"unable to store lost file '%s'" % filename,
                                  e)
예제 #11
0
    def _write_attr(self, filename, attr):
        """Write a node meta data file"""

        self._attr_mask.set_dict(attr)

        try:
            out = safefile.open(filename, "w", codec="utf-8")
            out.write(u'<?xml version="1.0" encoding="UTF-8"?>\n'
                      u'<node>\n'
                      u'<version>%d</version>\n' % 
                      attr.get("version", 
                               keepnote.notebook.NOTEBOOK_FORMAT_VERSION))
            plist.dump(self._attr_mask, out, indent=2, depth=0)
            out.write(u'</node>\n')
            out.close()
        except Exception as e:
            raise ConnectionError(
                _("Cannot write meta data" + " " + filename + ":" + str(e)), e)
예제 #12
0
    def _rename_node_dir(self, nodeid, attr, parentid, new_parentid, path):
        """Renames a node directory to resemble attr['title']"""

        if new_parentid is not None:
            # try to pick a path that closely resembles the title
            title = attr.get("title", _("New Page"))
            new_parent_path = self._get_node_path(new_parentid)
            new_path = get_valid_unique_filename(new_parent_path, title)
            basename = os.path.basename(new_path)
        else:
            # make orphan
            new_path = self._get_orphandir(nodeid)
            basename = new_path

        try:
            os.rename(path, new_path)
        except Exception, e:
            raise ConnectionError(
                _(u"Cannot rename '%s' to '%s'" % (path, new_path)), e)
예제 #13
0
    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 as 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 as 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)
예제 #14
0
def read_attr(filename, set_extra=True):
    """
    Read a node meta data file. Returns an attr dict

    filename -- a filename or stream
    """
    try:
        tree = ET.ElementTree(file=filename)
    except Exception, e:
        raise ConnectionError(
            _(u"Error reading meta data file '%s'" % filename), e)

    # check root
    root = tree.getroot()
    if root.tag != "node":
        raise ConnectionError(_("Root tag is not 'node'"))

    # iterate children
    attr = {}
    extra = {}
    for child in root:
        if child.tag == "dict":
            attr = plist.load_etree(child)
        elif child.tag == "version":
            extra['version'] = int(child.text)
        elif child.tag == "id":
            extra['nodeid'] = child.text

    # For backward-compatibility, use attr nodeid to set extra if needed.
    if 'nodeid' not in extra:
        extra['nodeid'] = attr['nodeid']
예제 #15
0
    def create_node(self, nodeid, attr, _path=None):
        """Create a node"""

        # check for creating root
        if self._rootid is None:
            if self._filename is None:
                raise ConnectionError("connect() has not been called")
            parentids = attr.get("parentids", ())
            if parentids != []:
                raise ConnectionError("root node must have parentids = []")
            _path = self._filename
            _root = True
        else:
            _root = False


        # check for existing nodeid
        if self.has_node(nodeid):
            raise NodeExists(nodeid)

        # generate a new nodeid if one is not given
        if nodeid is None:
            nodeid = keepnote.notebook.new_nodeid()

        # TODO: handle case where parent does not currently exist
        # TODO: handle case where parent finally shows up and
        # reunites with its children in the orphans dir

        # determine parentid
        parentids = attr.get("parentids", ())
        if not parentids:
            # if parentids is None or [], it is orphan
            parentid = None
        else:
            parentid = parentids[0]

        # if no path, use title to set path
        if _path is None:
            title = attr.get("title", _("New Page"))
            if parentid is not None:
                # TODO: handle case where parentid is unknown
                # and therefore node is orphan
                parent_path = self._get_node_path(parentid)
                path = get_valid_unique_filename(parent_path, title)
            else:
                path = self._get_orphandir(nodeid)
        else:
            path = _path
        
        # initialize with no children
        attr["childrenids"] = []

        # determine basename
        basename = os.path.basename(path) if parentid else path

        # make directory and write attr
        try:
            os.makedirs(path)
            self._write_attr(self._get_node_attr_file(nodeid, path), attr)
            self._path_cache.add(nodeid, basename, parentid)
        except OSError as e:
            raise ConnectionError(_("Cannot create node"), e)
        
        # finish initializing root
        if _root:
            self._rootid = attr["nodeid"]
            self._init_root()

        # update index
        self._index.add_node(nodeid, parentid, basename, attr, 
                             mtime=get_path_mtime(path))


        return nodeid