Add createChain and mergeChain
parent
6ff3c2c519
commit
9c2acb7099
|
@ -467,7 +467,12 @@ class Onionr:
|
|||
|
||||
os.makedirs(plugins.get_plugins_folder(plugin_name))
|
||||
with open(plugins.get_plugins_folder(plugin_name) + '/main.py', 'a') as main:
|
||||
main.write(open('static-data/default_plugin.py').read().replace('$user', os.getlogin()).replace('$date', datetime.datetime.now().strftime('%Y-%m-%d')).replace('$name', plugin_name))
|
||||
contents = ''
|
||||
with open('static-data/default_plugin.py', 'rb') as file:
|
||||
contents = file.read()
|
||||
|
||||
# TODO: Fix $user. os.getlogin() is B U G G Y
|
||||
main.write(contents.replace('$user', 'some random developer').replace('$date', datetime.datetime.now().strftime('%Y-%m-%d')).replace('$name', plugin_name))
|
||||
|
||||
with open(plugins.get_plugins_folder(plugin_name) + '/info.json', 'a') as main:
|
||||
main.write(json.dumps({'author' : 'anonymous', 'description' : 'the default description of the plugin', 'version' : '1.0'}))
|
||||
|
@ -585,7 +590,7 @@ class Onionr:
|
|||
'Known Peers Count' : str(len(self.onionrCore.listPeers()) - 1),
|
||||
'Enabled Plugins Count' : str(len(config.get('plugins')['enabled'])) + ' / ' + str(len(os.listdir('data/plugins/'))),
|
||||
'Known Blocks Count' : str(totalBlocks),
|
||||
'Percent Blocks Signed' : str(round(100 * signedBlocks / totalBlocks, 2)) + '%'
|
||||
'Percent Blocks Signed' : str(round(100 * signedBlocks / totalBlocks, 2)) + '%' # TODO: div by zero error
|
||||
}
|
||||
|
||||
# color configuration
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
'''
|
||||
|
||||
import core as onionrcore, logger
|
||||
import json, os, datetime
|
||||
import json, os, datetime, base64
|
||||
|
||||
class Block:
|
||||
def __init__(self, hash = None, core = None):
|
||||
|
@ -469,7 +469,7 @@ class Block:
|
|||
|
||||
return list()
|
||||
|
||||
def merge(child, file = None, maximumFollows = 32, core = None):
|
||||
def mergeChain(child, file = None, maximumFollows = 32, core = None):
|
||||
'''
|
||||
Follows a child Block to its root parent Block, merging content
|
||||
|
||||
|
@ -485,6 +485,8 @@ class Block:
|
|||
maximumFollows = max(0, maximumFollows)
|
||||
|
||||
# type conversions
|
||||
if type(child) == list:
|
||||
child = child[-1]
|
||||
if type(child) == str:
|
||||
child = Block(child)
|
||||
if (not file is None) and (type(file) == str):
|
||||
|
@ -521,21 +523,37 @@ class Block:
|
|||
for hash in blocks:
|
||||
block = Block(hash, core = core)
|
||||
contents = block.getContent()
|
||||
contents = base64.b64decode(contents.encode())
|
||||
|
||||
if file is None:
|
||||
buffer += contents
|
||||
buffer += contents.decode()
|
||||
else:
|
||||
file.write(contents)
|
||||
|
||||
return (None if not file is None else buffer)
|
||||
|
||||
def create(data = None, chunksize = 4999000, file = None, type = 'chunk', sign = True):
|
||||
def createChain(data = None, chunksize = 99800, file = None, type = 'chunk', sign = True, encrypt = False, verbose = False):
|
||||
'''
|
||||
Creates a chain of blocks to store larger amounts of data
|
||||
|
||||
The chunksize is set to 4999000 because it provides the least amount of PoW for the most amount of data.
|
||||
The chunksize is set to 99800 because it provides the least amount of PoW for the most amount of data.
|
||||
|
||||
TODO: Add docs
|
||||
Inputs:
|
||||
- data (*): if `file` is None, the data to be stored in blocks
|
||||
- file (file/str): the filename or file object to read from (or None to read `data` instead)
|
||||
- chunksize (int): the number of bytes per block chunk
|
||||
- type (str): the type header for each of the blocks
|
||||
- sign (bool): whether or not to sign each block
|
||||
- encrypt (str): the public key to encrypt to, or False to disable encryption
|
||||
- verbose (bool): whether or not to return a tuple containing more info
|
||||
|
||||
Outputs:
|
||||
- if `verbose`:
|
||||
- (tuple):
|
||||
- (str): the child block hash
|
||||
- (list): all block hashes associated with storing the file
|
||||
- if not `verbose`:
|
||||
- (str): the child block hash
|
||||
'''
|
||||
|
||||
blocks = list()
|
||||
|
@ -547,13 +565,26 @@ class Block:
|
|||
return blocks
|
||||
elif isinstance(file, str):
|
||||
file = open(file, 'rb')
|
||||
if isinstance(data, str):
|
||||
if not isinstance(data, str):
|
||||
data = str(data)
|
||||
|
||||
if not file is None:
|
||||
while True:
|
||||
# read chunksize bytes from the file
|
||||
filesize = os.stat(file.name).st_size
|
||||
offset = filesize % chunksize
|
||||
maxtimes = int(filesize / chunksize)
|
||||
|
||||
for times in range(0, maxtimes + 1):
|
||||
# read chunksize bytes from the file (end -> beginning)
|
||||
if times < maxtimes:
|
||||
file.seek(- ((times + 1) * chunksize), 2)
|
||||
content = file.read(chunksize)
|
||||
else:
|
||||
file.seek(0, 0)
|
||||
content = file.read(offset)
|
||||
|
||||
# encode it- python is really bad at handling certain bytes that
|
||||
# are often present in binaries.
|
||||
content = base64.b64encode(content).decode()
|
||||
|
||||
# if it is the end of the file, exit
|
||||
if not content:
|
||||
|
@ -569,7 +600,10 @@ class Block:
|
|||
# remember the hash in cache
|
||||
blocks.append(hash)
|
||||
elif not data is None:
|
||||
for content in [data[n:n + chunksize] for n in range(0, len(data), chunksize)]:
|
||||
for content in reversed([data[n:n + chunksize] for n in range(0, len(data), chunksize)]):
|
||||
# encode chunk with base64
|
||||
content = base64.b64encode(content.encode()).decode()
|
||||
|
||||
# create block
|
||||
block = Block()
|
||||
block.setType(type)
|
||||
|
@ -580,7 +614,10 @@ class Block:
|
|||
# remember the hash in cache
|
||||
blocks.append(hash)
|
||||
|
||||
return blocks
|
||||
# return different things depending on verbosity
|
||||
if verbose:
|
||||
return (blocks[-1], blocks)
|
||||
return blocks[-1]
|
||||
|
||||
def exists(hash):
|
||||
'''
|
||||
|
|
|
@ -138,24 +138,17 @@ class OnionrTests(unittest.TestCase):
|
|||
logger.info('Running BlockAPI test #2...')
|
||||
|
||||
original_content = 'onionr'
|
||||
contents = [original_content[i:i+2] for i in range(0, len(original_content), 2)]
|
||||
contents.reverse()
|
||||
|
||||
blocks = list()
|
||||
parent = None
|
||||
logger.debug('original: %s' % original_content)
|
||||
|
||||
for content in contents:
|
||||
block = Block('test', content)
|
||||
block.setParent(parent)
|
||||
parent = block
|
||||
print('block "%s": %s' % (content, block.save()))
|
||||
blocks.append(block)
|
||||
blocks = Block.createChain(data = original_content, chunksize = 2, verbose = True)
|
||||
|
||||
child = blocks[-1]
|
||||
logger.debug(blocks[1])
|
||||
|
||||
merged = Block.merge(child)
|
||||
child = blocks[0]
|
||||
merged = Block.mergeChain(child)
|
||||
|
||||
print('merged blocks: %s' % merged)
|
||||
logger.debug('merged blocks (child: %s): %s' % (child, merged))
|
||||
|
||||
if merged != original_content:
|
||||
self.assertTrue(False)
|
||||
|
|
Loading…
Reference in New Issue