diff --git a/onionr/communicator2.py b/onionr/communicator2.py index e09b9481..297573dd 100755 --- a/onionr/communicator2.py +++ b/onionr/communicator2.py @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sys, os, core, config, json, onionrblockapi as block, requests, time, logger, threading, onionrplugins as plugins, base64 +import sys, os, core, config, json, onionrblockapi as block, requests, time, logger, threading, onionrplugins as plugins, base64, onionr import onionrexceptions from defusedxml import minidom @@ -50,13 +50,13 @@ class OnionrCommunicatorDaemon: # amount of threads running by name, used to prevent too many self.threadCounts = {} - + # set true when shutdown command recieved self.shutdown = False # list of new blocks to download, added to when new block lists are fetched from peers self.blockQueue = [] - + # Clear the daemon queue for any dead messages if os.path.exists(self._core.queueDB): self._core.clearDaemonQueue() @@ -64,18 +64,17 @@ class OnionrCommunicatorDaemon: # Loads in and starts the enabled plugins plugins.reload() + if debug or developmentMode: + OnionrCommunicatorTimers(self, self.heartbeat, 10) + + # Initalize peer online list + logger.debug('Onionr is not yet ready to recieve commands.') + self.getOnlinePeers() + # Print nice header thing :) if config.get('general.display_header', True): self.header() - if debug or developmentMode: - OnionrCommunicatorTimers(self, self.heartbeat, 10) - - # Initalize peer online list - logger.warn('Onionr is not yet ready to recieve commands.') - self.getOnlinePeers() - logger.info('\033[4mOnionr is ready\033[0m.') - # Set timers, function reference, seconds OnionrCommunicatorTimers(self, self.daemonCommands, 5) OnionrCommunicatorTimers(self, self.detectAPICrash, 5) @@ -93,22 +92,23 @@ class OnionrCommunicatorDaemon: break i.processTimer() time.sleep(self.delay) + logger.info('Goodbye.') self._core._utils.localCommand('shutdown') def lookupKeys(self): '''Lookup new keys''' - logger.info('LOOKING UP NEW KEYS') + logger.debug('Looking up new keys...') tryAmount = 1 for i in range(tryAmount): # Download new key list from random online peers peer = self.pickOnlinePeer() newKeys = self.peerAction(peer, action='kex') self._core._utils.mergeKeys(newKeys) - + self.decrementThreadCount('lookupKeys') return - + def lookupAdders(self): '''Lookup new peer addresses''' logger.info('LOOKING UP NEW ADDRESSES') @@ -118,7 +118,7 @@ class OnionrCommunicatorDaemon: peer = self.pickOnlinePeer() newAdders = self.peerAction(peer, action='pex') self._core._utils.mergeAdders(newAdders) - + self.decrementThreadCount('lookupKeys') def lookupBlocks(self): @@ -149,7 +149,7 @@ class OnionrCommunicatorDaemon: def getBlocks(self): '''download new blocks in queue''' for blockHash in self.blockQueue: - logger.info("ATTEMPTING TO DOWNLOAD " + blockHash) + logger.info("Attempting to download %s..." % blockHash) content = self.peerAction(self.pickOnlinePeer(), 'getData', data=blockHash) # block content from random peer (includes metadata) if content != False: try: @@ -201,7 +201,7 @@ class OnionrCommunicatorDaemon: self.threadCounts[threadName] -= 1 except KeyError: pass - + def clearOfflinePeer(self): '''Removes the longest offline peer to retry later''' try: @@ -209,7 +209,7 @@ class OnionrCommunicatorDaemon: except IndexError: pass else: - logger.debug('removed ' + removed + ' from offline list to try them again.') + logger.debug('Removed ' + removed + ' from offline list, will try them again.') self.decrementThreadCount('clearOfflinePeer') def getOnlinePeers(self): @@ -262,7 +262,7 @@ class OnionrCommunicatorDaemon: tried.append(address) logger.debug('Failed to connect to ' + address) return retData - + def printOnlinePeers(self): '''logs online peer list''' if len(self.onlinePeers) == 0: @@ -349,7 +349,7 @@ class OnionrCommunicatorDaemon: if os.path.exists('static-data/header.txt'): with open('static-data/header.txt', 'rb') as file: # only to stdout, not file or log or anything - print(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n')) + sys.stderr.write(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n').replace('B', logger.colors.bold).replace('V', onionr.ONIONR_VERSION)) logger.info(logger.colors.fg.lightgreen + '-> ' + str(message) + logger.colors.reset + logger.colors.fg.lightgreen + ' <-\n') class OnionrCommunicatorTimers: diff --git a/onionr/core.py b/onionr/core.py index d220953c..b32b0db3 100644 --- a/onionr/core.py +++ b/onionr/core.py @@ -390,7 +390,7 @@ class Core: events.event('queue_pop', data = {'data': retData}, onionr = None) return retData - + def makeDaemonDB(self): '''generate the daemon queue db''' conn = sqlite3.connect(self.queueDB) @@ -669,16 +669,18 @@ class Core: conn.close() return True - def insertBlock(self, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = {}): + def insertBlock(self, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = None): ''' Inserts a block into the network encryptType must be specified to encrypt a block ''' - try: - data.decode() - except AttributeError: - data = data.encode() + if meta is None: + meta = dict() + + if type(data) is bytes: + data = data.decode() + data = str(data) retData = '' signature = '' @@ -686,10 +688,9 @@ class Core: metadata = {} # only use header if not set in provided meta - try: - meta['type'] - except KeyError: - meta['type'] = header # block type + if not header is None: + meta['type'] = header + meta['type'] = str(meta['type']) jsonMeta = json.dumps(meta) @@ -709,7 +710,7 @@ class Core: if len(jsonMeta) > 1000: raise onionrexceptions.InvalidMetadata('meta in json encoded form must not exceed 1000 bytes') - + # encrypt block metadata/sig/content if encryptType == 'sym': if len(symKey) < self.requirements.passwordLength: diff --git a/onionr/logger.py b/onionr/logger.py index c915f2f9..e2e09d03 100644 --- a/onionr/logger.py +++ b/onionr/logger.py @@ -123,18 +123,18 @@ def get_file(): return _outputfile -def raw(data): +def raw(data, fd = sys.stdout): ''' Outputs raw data to console without formatting ''' if get_settings() & OUTPUT_TO_CONSOLE: - print(data) + ts = fd.write('%s\n' % data) if get_settings() & OUTPUT_TO_FILE: with open(_outputfile, "a+") as f: f.write(colors.filter(data) + '\n') -def log(prefix, data, color = '', timestamp=True): +def log(prefix, data, color = '', timestamp=True, fd = sys.stdout): ''' Logs the data prefix : The prefix to the output @@ -149,7 +149,7 @@ def log(prefix, data, color = '', timestamp=True): if not get_settings() & USE_ANSI: output = colors.filter(output) - raw(output) + raw(output, fd = fd) def readline(message = ''): ''' @@ -218,14 +218,14 @@ def warn(data, timestamp=True): # error: when only one function, module, or process of the program encountered a problem and must stop def error(data, error=None, timestamp=True): if get_level() <= LEVEL_ERROR: - log('-', data, colors.fg.red, timestamp=timestamp) + log('-', data, colors.fg.red, timestamp=timestamp, fd = sys.stderr) if not error is None: debug('Error: ' + str(error) + parse_error()) # fatal: when the something so bad has happened that the program must stop def fatal(data, timestamp=True): if get_level() <= LEVEL_FATAL: - log('#', data, colors.bg.red + colors.fg.green + colors.bold, timestamp=timestamp) + log('#', data, colors.bg.red + colors.fg.green + colors.bold, timestamp=timestamp, fd = sys.stderr) # returns a formatted error message def parse_error(): diff --git a/onionr/onionr.py b/onionr/onionr.py index 20cc514e..5f91b576 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -263,7 +263,7 @@ class Onionr: def listConn(self): self.onionrCore.daemonQueueAdd('connectedPeers') - + def listPeers(self): logger.info('Peer transport address list:') for i in self.onionrCore.listAdders(): @@ -335,7 +335,7 @@ class Onionr: logger.info('Running on %s %s' % (platform.platform(), platform.release())) return - + def doKEX(self): '''make communicator do kex''' logger.info('Sending kex to command queue...') @@ -745,5 +745,5 @@ class Onionr: else: logger.error('%s add-file ' % sys.argv[0], timestamp = False) - -Onionr() +if __name__ == "__main__": + Onionr() diff --git a/onionr/onionrblockapi.py b/onionr/onionrblockapi.py index 90a32b9a..ba0c0408 100644 --- a/onionr/onionrblockapi.py +++ b/onionr/onionrblockapi.py @@ -496,7 +496,6 @@ class Block: - child (str/Block): the child Block to be followed - file (str/file): the file to write the content to, instead of returning it - maximumFollows (int): the maximum number of Blocks to follow - ''' # validate data and instantiate Core diff --git a/onionr/static-data/header.txt b/onionr/static-data/header.txt index 045c8aa1..92664951 100644 --- a/onionr/static-data/header.txt +++ b/onionr/static-data/header.txt @@ -18,7 +18,7 @@ P ::: :::: ::::::: :::: :::: W:: :: :: ::: :: :: :: :: :::: ::::: P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: ::: P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: :: P :::: :::::: :::::: :::: -P :::: :::::::::::: :::: +P :::: :::::::::::: :::: GvPBV P ::::: :::::::: :::: P ::::: :::::: P ::::::::::::::::