now it actually works. (But I dont know about milestones yet)
This commit is contained in:
		
							parent
							
								
									c1a2d279ff
								
							
						
					
					
						commit
						072e3dd8ff
					
				
							
								
								
									
										135
									
								
								next.py
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								next.py
									
									
									
									
									
								
							@ -39,13 +39,11 @@ def log(txt):
 | 
				
			|||||||
    print("[-] "+str(txt))
 | 
					    print("[-] "+str(txt))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def sendEmOff(bundles, api):
 | 
					def sendEmOff(bundles, api):
 | 
				
			||||||
    print("SENDING (")
 | 
					    print("[->]")
 | 
				
			||||||
    pprint(bundles)
 | 
					    for bundle in bundles:
 | 
				
			||||||
    print(")")
 | 
					        api.send_trytes(
 | 
				
			||||||
    return
 | 
					            trytes=bundle
 | 
				
			||||||
    api.send_trytes(
 | 
					        )
 | 
				
			||||||
        trytes=bundles
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Atom():
 | 
					class Atom():
 | 
				
			||||||
    def __init__(self, milestone: bool, cont, name: str = None) -> None:
 | 
					    def __init__(self, milestone: bool, cont, name: str = None) -> None:
 | 
				
			||||||
@ -133,7 +131,7 @@ class TangleBlob():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def dumpAllSealed(self):
 | 
					    def dumpAllSealed(self):
 | 
				
			||||||
        bundles = []
 | 
					        bundles = []
 | 
				
			||||||
        for i in range(len(self.chunks)-self.pushedNum):
 | 
					        for i in range(max(0,len(self.chunks)-self.pushedNum)):
 | 
				
			||||||
            c = i + self.pushedNum
 | 
					            c = i + self.pushedNum
 | 
				
			||||||
            chunk = self.chunks[c]
 | 
					            chunk = self.chunks[c]
 | 
				
			||||||
            if chunk.isSealed():
 | 
					            if chunk.isSealed():
 | 
				
			||||||
@ -143,7 +141,8 @@ class TangleBlob():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def sealAndDump(self):
 | 
					    def sealAndDump(self):
 | 
				
			||||||
        # When unmounting / closing / ...
 | 
					        # When unmounting / closing / ...
 | 
				
			||||||
        self.chunks[-1].seal()
 | 
					        if self.chunks:
 | 
				
			||||||
 | 
					            self.chunks[-1].seal()
 | 
				
			||||||
        return self.dumpAllSealed()
 | 
					        return self.dumpAllSealed()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def append(self, data: bytes, newBlock: bool = False) -> None:
 | 
					    def append(self, data: bytes, newBlock: bool = False) -> None:
 | 
				
			||||||
@ -174,6 +173,7 @@ class TangleBlob():
 | 
				
			|||||||
        return self.preChunks
 | 
					        return self.preChunks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def read(self) -> bytes:
 | 
					    def read(self) -> bytes:
 | 
				
			||||||
 | 
					        self._requireFetched()
 | 
				
			||||||
        data = b''
 | 
					        data = b''
 | 
				
			||||||
        for chunk in self.chunks:
 | 
					        for chunk in self.chunks:
 | 
				
			||||||
            data += chunk.getData()
 | 
					            data += chunk.getData()
 | 
				
			||||||
@ -198,7 +198,7 @@ class TangleBlob():
 | 
				
			|||||||
            txHash = self.iotaApi.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"]
 | 
					            txHash = self.iotaApi.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"]
 | 
				
			||||||
            if len(txHash)==0:
 | 
					            if len(txHash)==0:
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
            bundles = self.api.get_bundles(txHash[0])["bundles"]
 | 
					            bundles = self.iotaApi.get_bundles(txHash[0])["bundles"]
 | 
				
			||||||
            for bundle in bundles:
 | 
					            for bundle in bundles:
 | 
				
			||||||
                for tx in bundle.transactions:
 | 
					                for tx in bundle.transactions:
 | 
				
			||||||
                    # TODO: Can we just strip the 9s and call it a day?
 | 
					                    # TODO: Can we just strip the 9s and call it a day?
 | 
				
			||||||
@ -236,7 +236,7 @@ class TangleBlob():
 | 
				
			|||||||
                lines[-1]+=" {+}"
 | 
					                lines[-1]+=" {+}"
 | 
				
			||||||
        return "\n".join(lines)
 | 
					        return "\n".join(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def close(self):
 | 
					    def _close(self):
 | 
				
			||||||
        bundles = self.sealAndDump()
 | 
					        bundles = self.sealAndDump()
 | 
				
			||||||
        if bundles:
 | 
					        if bundles:
 | 
				
			||||||
            sendEmOff(bundles, self.iotaApi)
 | 
					            sendEmOff(bundles, self.iotaApi)
 | 
				
			||||||
@ -260,7 +260,7 @@ class TangleFileTreeElement(TangleBlob):
 | 
				
			|||||||
            return
 | 
					            return
 | 
				
			||||||
        unpacker = msgpack.Unpacker(raw=True)
 | 
					        unpacker = msgpack.Unpacker(raw=True)
 | 
				
			||||||
        unpacker.feed(raw)
 | 
					        unpacker.feed(raw)
 | 
				
			||||||
        for i, elem in enumerate(reversed(unpacker)):
 | 
					        for i, elem in enumerate(reversed(list(unpacker))):
 | 
				
			||||||
            if elem[0]:
 | 
					            if elem[0]:
 | 
				
			||||||
                # Is a milestone
 | 
					                # Is a milestone
 | 
				
			||||||
                # TODO: Update our known milestoneIndex, if we find one
 | 
					                # TODO: Update our known milestoneIndex, if we find one
 | 
				
			||||||
@ -269,12 +269,16 @@ class TangleFileTreeElement(TangleBlob):
 | 
				
			|||||||
                self._applyMilestone(elem[1])
 | 
					                self._applyMilestone(elem[1])
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                if elem[1] in self.inodes: #name
 | 
					                name = elem[1].decode()
 | 
				
			||||||
                    self.inodes[elem[1]].applyDelta(elem[2])
 | 
					                if name in self.inodes: #name
 | 
				
			||||||
 | 
					                    atom = Atom(False, elem[2], name)
 | 
				
			||||||
 | 
					                    self.inodes[name].applyAtom(atom)
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    # new file
 | 
					                    # new inode
 | 
				
			||||||
                    self.inodes[elem[1]] = Inode(elem[1], self.iotaApi)
 | 
					                    type = ["dir","file"][elem[2][b't']]
 | 
				
			||||||
                    self.inodes[elem[1]].applyDelta(elem[2])
 | 
					                    self.inodes[name] = Inode(name, self.iotaApi, self, type)
 | 
				
			||||||
 | 
					                    atom = Atom(False, elem[2], name)
 | 
				
			||||||
 | 
					                    self.inodes[name].applyAtom(atom)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _getSkipChunks(self):
 | 
					    def _getSkipChunks(self):
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
@ -303,6 +307,7 @@ class TangleFileTreeElement(TangleBlob):
 | 
				
			|||||||
        return list(self.inodes.keys())
 | 
					        return list(self.inodes.keys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _tree(self):
 | 
					    def _tree(self):
 | 
				
			||||||
 | 
					        self._requireFetched()
 | 
				
			||||||
        dirs = {}
 | 
					        dirs = {}
 | 
				
			||||||
        files = []
 | 
					        files = []
 | 
				
			||||||
        for inode in self.inodes:
 | 
					        for inode in self.inodes:
 | 
				
			||||||
@ -358,15 +363,14 @@ class TangleFileTreeElement(TangleBlob):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _updateFileSize(self, name: str, size: int) -> None:
 | 
					    def _updateFileSize(self, name: str, size: int) -> None:
 | 
				
			||||||
        self._requireFetched()
 | 
					        self._requireFetched()
 | 
				
			||||||
        self.inodes[name].size = size
 | 
					        atom = self.inodes[name].change(size=size)
 | 
				
			||||||
        self._newAtom(self.inodes[name])
 | 
					        self._newAtom(atom)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _updateFileToken(self, name: str, token: bytes, size: int) -> None:
 | 
					    def _updateFileHash(self, name: str, hash: bytes, size: int) -> None:
 | 
				
			||||||
        log("New FileToken for file '"+name+"' registered")
 | 
					        log("New FileToken for file '"+name+"' registered")
 | 
				
			||||||
        self._requireFetched()
 | 
					        self._requireFetched()
 | 
				
			||||||
        self.inodes[name].token = token
 | 
					        atom = self.inodes[name].change(size=size, hash=hash)
 | 
				
			||||||
        self.inodes[name].size = size
 | 
					        self._newAtom(atom)
 | 
				
			||||||
        self._newAtom(self.inodes[name])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def performMilestone(self) -> None:
 | 
					    def performMilestone(self) -> None:
 | 
				
			||||||
        if isinstance(self.parent, bytes):
 | 
					        if isinstance(self.parent, bytes):
 | 
				
			||||||
@ -375,45 +379,58 @@ class TangleFileTreeElement(TangleBlob):
 | 
				
			|||||||
        for a in self.inodes:
 | 
					        for a in self.inodes:
 | 
				
			||||||
            stones[a] = self.inodes[a].toStone()
 | 
					            stones[a] = self.inodes[a].toStone()
 | 
				
			||||||
        self.atomStack = 0
 | 
					        self.atomStack = 0
 | 
				
			||||||
        # TODO: Delimiter ?
 | 
					 | 
				
			||||||
        # TODO: compression ?
 | 
					 | 
				
			||||||
        milestoneAtom = Atom(True, stones)
 | 
					        milestoneAtom = Atom(True, stones)
 | 
				
			||||||
        data = milestoneAtom.dump()
 | 
					        data = milestoneAtom.dump()
 | 
				
			||||||
        self.milestoneIndex = self.getSize()
 | 
					        self.milestoneIndex = self.getChunkLen()
 | 
				
			||||||
        if self.parent!=None:
 | 
					        if self.parent!=None:
 | 
				
			||||||
            self.parent._updateChildMilestone(self.name, self.milestoneIndex)
 | 
					            self.parent._updateChildMilestone(self.name, self.milestoneIndex)
 | 
				
			||||||
        self.append(data, True)
 | 
					        self.append(data, True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _updateChildMilestone(self, name: str, milestoneIndex: int):
 | 
					    def _updateChildMilestone(self, name: str, milestoneIndex: int):
 | 
				
			||||||
 | 
					        atom = self.inodes[name].change(milestoneIndex = milestoneIndex)
 | 
				
			||||||
        if isinstance(self.parent, bytes):
 | 
					        if isinstance(self.parent, bytes):
 | 
				
			||||||
            # We are the genesis-block
 | 
					            # We are the genesis-block
 | 
				
			||||||
            self.append(milestoneIndex)
 | 
					            self.milestoneIndex = milestoneIndex
 | 
				
			||||||
 | 
					            self.append(msgpack.dumps(milestoneIndex))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            atom = self.inodes[name].change(milestoneIndex = milestoneIndex)
 | 
					 | 
				
			||||||
            self._newAtom(atom)
 | 
					            self._newAtom(atom)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def close(self) -> None:
 | 
				
			||||||
 | 
					        for i in self.inodes:
 | 
				
			||||||
 | 
					            inode = self.inodes[i]
 | 
				
			||||||
 | 
					            if inode.hasRef:
 | 
				
			||||||
 | 
					                ref = inode.getRef()
 | 
				
			||||||
 | 
					                ref.close()
 | 
				
			||||||
 | 
					        self._close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TangleFile():
 | 
					class TangleFile():
 | 
				
			||||||
    def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None:
 | 
					    def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None:
 | 
				
			||||||
        self.api = iotaApi
 | 
					        self.api = iotaApi
 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
        self.parent = parent
 | 
					        self.parent = parent
 | 
				
			||||||
        self.reflexiveAtom = parent.inodes[name]
 | 
					        self.reflexiveInode = parent.inodes[name]
 | 
				
			||||||
        self.size = self.reflexiveAtom.size
 | 
					        self.size = self.reflexiveInode.size
 | 
				
			||||||
        self.hash = self.reflexiveAtom.hash
 | 
					        self.hash = self.reflexiveInode.hash
 | 
				
			||||||
        self.token = hashlib.sha3_384(b'f' + parent.getRef().token + self.hash).digest()
 | 
					        self.token = hashlib.sha3_384(b'f' + parent.token + self.hash).digest()
 | 
				
			||||||
        self.blob = TangleBlob(self.token, iotaApi)
 | 
					        self.blob = TangleBlob(self.token, iotaApi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def write(self, offset: int, data: bytes):
 | 
					    def write(self, offset: int, data: bytes):
 | 
				
			||||||
        if offset == self.size:
 | 
					        if offset == self.size:
 | 
				
			||||||
            self.append(data)
 | 
					            self.blob.append(data)
 | 
				
			||||||
 | 
					            self.size = self.blob.getSize()
 | 
				
			||||||
 | 
					            self.parent._updateFileSize(self.name, self.size)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.token = self.genToken()
 | 
					 | 
				
			||||||
            oldData = self.blob.read()
 | 
					            oldData = self.blob.read()
 | 
				
			||||||
            newData = oldData[:offset] + data + oldData[offset+len(data):]
 | 
					            newData = oldData[:offset] + data + oldData[offset+len(data):]
 | 
				
			||||||
 | 
					            self.hash = hashlib.sha256(newData).digest()
 | 
				
			||||||
 | 
					            self.token = hashlib.sha3_384(b'f' + self.parent.token + self.hash).digest()
 | 
				
			||||||
            self.blob = TangleBlob(self.token)
 | 
					            self.blob = TangleBlob(self.token)
 | 
				
			||||||
            self.blob.append(newData)
 | 
					            self.blob.append(newData)
 | 
				
			||||||
            self.size = self.blob.getSize()
 | 
					            self.size = self.blob.getSize()
 | 
				
			||||||
            self.parent._updateFileToken(self.name, self.token, self.size)
 | 
					            self.parent._updateFileHash(self.name, self.hash, self.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def close(self):
 | 
				
			||||||
 | 
					        self.blob._close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Inode():
 | 
					class Inode():
 | 
				
			||||||
    def __init__(self, name: str, iotaApi: Iota, parent: TangleFileTreeElement = None, type: str = None) -> None:
 | 
					    def __init__(self, name: str, iotaApi: Iota, parent: TangleFileTreeElement = None, type: str = None) -> None:
 | 
				
			||||||
@ -471,11 +488,14 @@ class Inode():
 | 
				
			|||||||
            if self.type=="dir":
 | 
					            if self.type=="dir":
 | 
				
			||||||
                self.ref = TangleFileTreeElement(self.name, self.milestoneIndex, self.parent, self.iotaApi)
 | 
					                self.ref = TangleFileTreeElement(self.name, self.milestoneIndex, self.parent, self.iotaApi)
 | 
				
			||||||
            elif self.type=="file":
 | 
					            elif self.type=="file":
 | 
				
			||||||
                self.ref = TangleFile(self.name, self, self.iotaApi)
 | 
					                self.ref = TangleFile(self.name, self.parent, self.iotaApi)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                raise Exception("Cannot get reference of an inode of type "+self.type)
 | 
					                raise Exception("Cannot get reference of an inode of type "+self.type)
 | 
				
			||||||
        return self.ref
 | 
					        return self.ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def hasRef(self):
 | 
				
			||||||
 | 
					        return not self.ref==None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IotaFs():
 | 
					class IotaFs():
 | 
				
			||||||
    def __init__(self, token) -> None:
 | 
					    def __init__(self, token) -> None:
 | 
				
			||||||
        self.api = Iota('https://nodes.thetangle.org:443', local_pow=True)
 | 
					        self.api = Iota('https://nodes.thetangle.org:443', local_pow=True)
 | 
				
			||||||
@ -491,35 +511,36 @@ class IotaFs():
 | 
				
			|||||||
                              + "Unknown records for no root-directory in Genesis Chain: "+str(self.genesis.getNameList()))
 | 
					                              + "Unknown records for no root-directory in Genesis Chain: "+str(self.genesis.getNameList()))
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                # we dont have a root yet, lets create one...
 | 
					                # we dont have a root yet, lets create one...
 | 
				
			||||||
                log("Unable to reference to root: Creating new root")
 | 
					                log("Unable to find reference to root: Creating new root")
 | 
				
			||||||
                self.genesis.mkdir("/")
 | 
					                self.genesis.mkdir("/")
 | 
				
			||||||
        log("Successfully Mounted!")
 | 
					        log("Successfully Mounted!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def createNewFile(self, name) -> None:
 | 
					    def createNewFile(self, name) -> None:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
api = Iota('https://nodes.thetangle.org:443', local_pow=True)
 | 
					api = Iota('https://nodes.thetangle.org:443', local_pow=True)
 | 
				
			||||||
token = b'testToken'
 | 
					token = b'testToken'
 | 
				
			||||||
genesis = TangleFileTreeElement("*", 0, token, api)
 | 
					genesis = TangleFileTreeElement("*", 0, token, api)
 | 
				
			||||||
genesis.mkdir("/")
 | 
					 | 
				
			||||||
root = genesis.inodes["/"].getRef()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
root.mkdir("dir1")
 | 
					if False:
 | 
				
			||||||
root.mkdir("dir2")
 | 
					    genesis.mkdir("/")
 | 
				
			||||||
root.mkdir("dir3")
 | 
					    root = genesis.inodes["/"].getRef()
 | 
				
			||||||
root.mkdir("dir4")
 | 
					 | 
				
			||||||
root.mkfile("file.txt")
 | 
					 | 
				
			||||||
d2 = root.inodes["dir2"].getRef()
 | 
					 | 
				
			||||||
d2.mkfile("a.txt")
 | 
					 | 
				
			||||||
d3 = root.inodes["dir3"].getRef()
 | 
					 | 
				
			||||||
d3.mkfile("b.txt")
 | 
					 | 
				
			||||||
d3.mkfile("c.txt")
 | 
					 | 
				
			||||||
d3.mkfile("d.txt")
 | 
					 | 
				
			||||||
d3.mkdir("subDir")
 | 
					 | 
				
			||||||
d4 = root.inodes["dir4"].getRef()
 | 
					 | 
				
			||||||
d4.mkdir("sub")
 | 
					 | 
				
			||||||
sub = d4.inodes["sub"].getRef()
 | 
					 | 
				
			||||||
sub.mkdir("subsub")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
print(genesis.tree())
 | 
					    root.mkdir("dir1")
 | 
				
			||||||
 | 
					    root.mkdir("dir2")
 | 
				
			||||||
 | 
					    root.mkdir("dir3")
 | 
				
			||||||
 | 
					    root.mkdir("dir4")
 | 
				
			||||||
 | 
					    root.mkfile("file.txt")
 | 
				
			||||||
 | 
					    d2 = root.inodes["dir2"].getRef()
 | 
				
			||||||
 | 
					    d2.mkfile("a.txt")
 | 
				
			||||||
 | 
					    d3 = root.inodes["dir3"].getRef()
 | 
				
			||||||
 | 
					    d3.mkfile("b.txt")
 | 
				
			||||||
 | 
					    d3.mkfile("c.txt")
 | 
				
			||||||
 | 
					    d3.mkfile("d.txt")
 | 
				
			||||||
 | 
					    d3.mkdir("subDir")
 | 
				
			||||||
 | 
					    d4 = root.inodes["dir4"].getRef()
 | 
				
			||||||
 | 
					    d4.mkdir("sub")
 | 
				
			||||||
 | 
					    sub = d4.inodes["sub"].getRef()
 | 
				
			||||||
 | 
					    sub.mkdir("subsub")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print(genesis.tree())
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user