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