diff --git a/docs/html/index.html b/docs/html/index.html index f739a8aa..d2d28cf7 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/docs/html/onionr/apiservers/private/index.html b/docs/html/onionr/apiservers/private/index.html deleted file mode 100644 index 5f157ef0..00000000 --- a/docs/html/onionr/apiservers/private/index.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - -onionr.apiservers.private API documentation - - - - - - - - - -
-
-
-

Module onionr.apiservers.private

-
-
-

Onionr - Private P2P Communication

-

This file handles all incoming http requests to the client, using Flask

-
-Source code -
'''
-    Onionr - Private P2P Communication
-
-    This file handles all incoming http requests to the client, using Flask
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import base64, os, time
-import flask
-from gevent.pywsgi import WSGIServer
-from onionrutils import epoch
-import httpapi, filepaths, logger
-from . import register_private_blueprints
-from etc import waitforsetvar
-import serializeddata, config
-from .. import public
-class PrivateAPI:
-    '''
-        Client HTTP api
-    '''
-
-    callbacks = {'public' : {}, 'private' : {}}
-
-    def __init__(self):
-        '''
-            Initialize the api server, preping variables for later use
-
-            This initialization defines all of the API entry points and handlers for the endpoints and errors
-            This also saves the used host (random localhost IP address) to the data folder in host.txt
-        '''
-        self.config = config
-        self.startTime = epoch.get_epoch()
-        app = flask.Flask(__name__)
-        bindPort = int(config.get('client.client.port', 59496))
-        self.bindPort = bindPort
-
-        self.clientToken = config.get('client.webpassword')
-        self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
-
-        self.host = httpapi.apiutils.setbindip.set_bind_IP(filepaths.private_API_host_file)
-        logger.info('Running api on %s:%s' % (self.host, self.bindPort))
-        self.httpServer = ''
-
-        self.queueResponse = {}
-        self.get_block_data = httpapi.apiutils.GetBlockData(self)
-        register_private_blueprints.register_private_blueprints(self, app)
-        httpapi.load_plugin_blueprints(app)
-        self.app = app
-    
-    def start(self):
-        waitforsetvar.wait_for_set_var(self, "_too_many")
-        self.publicAPI = self._too_many.get(public.PublicAPI)
-        self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler)
-        self.httpServer.serve_forever()
-
-    def setPublicAPIInstance(self, inst):
-        self.publicAPI = inst
-
-    def validateToken(self, token):
-        '''
-            Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration
-        '''
-        if not self.clientToken:
-            logger.error("client password needs to be set")
-            return False
-        try:
-            if not hmac.compare_digest(self.clientToken, token):
-                return False
-            else:
-                return True
-        except TypeError:
-            return False
-
-    def getUptime(self):
-        while True:
-            try:
-                return epoch.get_epoch() - self.startTime
-            except (AttributeError, NameError):
-                # Don't error on race condition with startup
-                pass
-
-    def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False):
-        return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly)
-
-
-
-

Sub-modules

-
-
onionr.apiservers.private.register_private_blueprints
-
-

Onionr - Private P2P Communication …

-
-
-
-
-
-
-
-
-

Classes

-
-
-class PrivateAPI -
-
-

Client HTTP api

-

Initialize the api server, preping variables for later use

-

This initialization defines all of the API entry points and handlers for the endpoints and errors -This also saves the used host (random localhost IP address) to the data folder in host.txt

-
-Source code -
class PrivateAPI:
-    '''
-        Client HTTP api
-    '''
-
-    callbacks = {'public' : {}, 'private' : {}}
-
-    def __init__(self):
-        '''
-            Initialize the api server, preping variables for later use
-
-            This initialization defines all of the API entry points and handlers for the endpoints and errors
-            This also saves the used host (random localhost IP address) to the data folder in host.txt
-        '''
-        self.config = config
-        self.startTime = epoch.get_epoch()
-        app = flask.Flask(__name__)
-        bindPort = int(config.get('client.client.port', 59496))
-        self.bindPort = bindPort
-
-        self.clientToken = config.get('client.webpassword')
-        self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
-
-        self.host = httpapi.apiutils.setbindip.set_bind_IP(filepaths.private_API_host_file)
-        logger.info('Running api on %s:%s' % (self.host, self.bindPort))
-        self.httpServer = ''
-
-        self.queueResponse = {}
-        self.get_block_data = httpapi.apiutils.GetBlockData(self)
-        register_private_blueprints.register_private_blueprints(self, app)
-        httpapi.load_plugin_blueprints(app)
-        self.app = app
-    
-    def start(self):
-        waitforsetvar.wait_for_set_var(self, "_too_many")
-        self.publicAPI = self._too_many.get(public.PublicAPI)
-        self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler)
-        self.httpServer.serve_forever()
-
-    def setPublicAPIInstance(self, inst):
-        self.publicAPI = inst
-
-    def validateToken(self, token):
-        '''
-            Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration
-        '''
-        if not self.clientToken:
-            logger.error("client password needs to be set")
-            return False
-        try:
-            if not hmac.compare_digest(self.clientToken, token):
-                return False
-            else:
-                return True
-        except TypeError:
-            return False
-
-    def getUptime(self):
-        while True:
-            try:
-                return epoch.get_epoch() - self.startTime
-            except (AttributeError, NameError):
-                # Don't error on race condition with startup
-                pass
-
-    def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False):
-        return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly)
-
-

Class variables

-
-
var callbacks
-
-
-
-
-

Methods

-
-
-def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False) -
-
-
-
-Source code -
def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False):
-    return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly)
-
-
-
-def getUptime(self) -
-
-
-
-Source code -
def getUptime(self):
-    while True:
-        try:
-            return epoch.get_epoch() - self.startTime
-        except (AttributeError, NameError):
-            # Don't error on race condition with startup
-            pass
-
-
-
-def setPublicAPIInstance(self, inst) -
-
-
-
-Source code -
def setPublicAPIInstance(self, inst):
-    self.publicAPI = inst
-
-
-
-def start(self) -
-
-
-
-Source code -
def start(self):
-    waitforsetvar.wait_for_set_var(self, "_too_many")
-    self.publicAPI = self._too_many.get(public.PublicAPI)
-    self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler)
-    self.httpServer.serve_forever()
-
-
-
-def validateToken(self, token) -
-
-

Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration

-
-Source code -
def validateToken(self, token):
-    '''
-        Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration
-    '''
-    if not self.clientToken:
-        logger.error("client password needs to be set")
-        return False
-    try:
-        if not hmac.compare_digest(self.clientToken, token):
-            return False
-        else:
-            return True
-    except TypeError:
-        return False
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/communicator/index.html b/docs/html/onionr/communicator/index.html deleted file mode 100644 index fd2c8ad7..00000000 --- a/docs/html/onionr/communicator/index.html +++ /dev/null @@ -1,743 +0,0 @@ - - - - - - -onionr.communicator API documentation - - - - - - - - - -
-
-
-

Module onionr.communicator

-
-
-

Onionr - Private P2P Communication

-

This file contains both the OnionrCommunicate class for communcating with peers -and code to operate as a daemon, getting commands from the command queue database (see core.Core.daemonQueue)

-
-Source code -
'''
-    Onionr - Private P2P Communication
-
-    This file contains both the OnionrCommunicate class for communcating with peers
-    and code to operate as a daemon, getting commands from the command queue database (see core.Core.daemonQueue)
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sys, os, time
-import config, logger
-import onionrexceptions, onionrpeers
-from onionrblocks import onionrblockapi as block
-from onionrplugins import onionrevents as events
-import onionrplugins as plugins
-from . import onlinepeers, uploadqueue
-from communicatorutils import servicecreator, onionrcommunicatortimers
-from communicatorutils import downloadblocks, lookupblocks, lookupadders
-from communicatorutils import servicecreator, connectnewpeers
-from communicatorutils import uploadblocks
-from communicatorutils import daemonqueuehandler, announcenode, deniableinserts
-from communicatorutils import cooldownpeer, housekeeping, netcheck
-from onionrutils import localcommand, epoch
-from etc import humanreadabletime
-import onionrservices, filepaths
-from onionrblocks import storagecounter
-from coredb import daemonqueue, dbfiles
-from utils import gettransports
-from netcontroller import NetController
-OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
-
-config.reload()
-class OnionrCommunicatorDaemon:
-    def __init__(self, shared_state, developmentMode=config.get('general.dev_mode', False)):
-        # configure logger and stuff
-        self.config = config
-        self.storage_counter = storagecounter.StorageCounter()
-        self.isOnline = True # Assume we're connected to the internet
-        self.shared_state = shared_state # TooManyObjects module
-
-        # list of timer instances
-        self.timers = []
-
-        # initialize core with Tor socks port being 3rd argument
-        self.proxyPort = shared_state.get(NetController).socksPort
-
-        # Upload information, list of blocks to upload
-        self.blocksToUpload = []
-        self.upload_session_manager = self.shared_state.get(uploadblocks.sessionmanager.BlockUploadSessionManager)
-        self.shared_state.share_object()
-
-        # loop time.sleep delay in seconds
-        self.delay = 1
-
-        # lists of connected peers and peers we know we can't reach currently
-        self.onlinePeers = []
-        self.offlinePeers = []
-        self.cooldownPeer = {}
-        self.connectTimes = {}
-        self.peerProfiles = [] # list of peer's profiles (onionrpeers.PeerProfile instances)
-        self.newPeers = [] # Peers merged to us. Don't add to db until we know they're reachable
-        self.announceProgress = {}
-        self.announceCache = {}
-
-        self.generating_blocks = []
-
-        # amount of threads running by name, used to prevent too many
-        self.threadCounts = {}
-
-        # set true when shutdown command received
-        self.shutdown = False
-
-        # list of new blocks to download, added to when new block lists are fetched from peers
-        self.blockQueue = {}
-
-        # list of blocks currently downloading, avoid s
-        self.currentDownloading = []
-
-        # timestamp when the last online node was seen
-        self.lastNodeSeen = None
-
-        # Dict of time stamps for peer's block list lookup times, to avoid downloading full lists all the time
-        self.dbTimestamps = {}
-
-        # Clear the daemon queue for any dead messages
-        if os.path.exists(dbfiles.daemon_queue_db):
-            daemonqueue.clear_daemon_queue()
-
-        # Loads in and starts the enabled plugins
-        plugins.reload()
-
-        # time app started running for info/statistics purposes
-        self.startTime = epoch.get_epoch()
-
-        uploadqueue.UploadQueue(self) # extends our upload list and saves our list when Onionr exits
-
-        if developmentMode:
-            OnionrCommunicatorTimers(self, self.heartbeat, 30)
-
-        # Set timers, function reference, seconds
-        # requires_peer True means the timer function won't fire if we have no connected peers
-        peerPoolTimer = OnionrCommunicatorTimers(self, onlinepeers.get_online_peers, 60, max_threads=1, my_args=[self])
-        OnionrCommunicatorTimers(self, self.runCheck, 2, max_threads=1)
-
-        # Timers to periodically lookup new blocks and download them
-        lookup_blocks_timer = OnionrCommunicatorTimers(self, lookupblocks.lookup_blocks_from_communicator, config.get('timers.lookupBlocks', 25), my_args=[self], requires_peer=True, max_threads=1)
-        # The block download timer is accessed by the block lookup function to trigger faster download starts
-        self.download_blocks_timer = OnionrCommunicatorTimers(self, self.getBlocks, config.get('timers.getBlocks', 10), requires_peer=True, max_threads=5)
-
-        # Timer to reset the longest offline peer so contact can be attempted again
-        OnionrCommunicatorTimers(self, onlinepeers.clear_offline_peer, 58, my_args=[self])
-
-        # Timer to cleanup old blocks
-        blockCleanupTimer = OnionrCommunicatorTimers(self, housekeeping.clean_old_blocks, 20, my_args=[self])
-
-        # Timer to discover new peers
-        OnionrCommunicatorTimers(self, lookupadders.lookup_new_peer_transports_with_communicator, 60, requires_peer=True, my_args=[self], max_threads=2)
-
-        # Timer for adjusting which peers we actively communicate to at any given time, to avoid over-using peers
-        OnionrCommunicatorTimers(self, cooldownpeer.cooldown_peer, 30, my_args=[self], requires_peer=True)
-
-        # Timer to read the upload queue and upload the entries to peers
-        OnionrCommunicatorTimers(self, uploadblocks.upload_blocks_from_communicator, 5, my_args=[self], requires_peer=True, max_threads=1)
-
-        # Timer to process the daemon command queue
-        OnionrCommunicatorTimers(self, daemonqueuehandler.handle_daemon_commands, 6, my_args=[self], max_threads=3)
-
-        # Setup direct connections
-        if config.get('general.socket_servers', False):
-            self.services = onionrservices.OnionrServices()
-            self.active_services = []
-            self.service_greenlets = []
-            OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, max_threads=50, my_args=[self])
-        else:
-            self.services = None
-        
-        # {peer_pubkey: ephemeral_address}, the address to reach them
-        self.direct_connection_clients = {}
-        
-        # This timer creates deniable blocks, in an attempt to further obfuscate block insertion metadata
-        if config.get('general.insert_deniable_blocks', True):
-            deniableBlockTimer = OnionrCommunicatorTimers(self, deniableinserts.insert_deniable_block, 180, my_args=[self], requires_peer=True, max_threads=1)
-            deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
-
-        # Timer to check for connectivity, through Tor to various high-profile onion services
-        netCheckTimer = OnionrCommunicatorTimers(self, netcheck.net_check, 500, my_args=[self], max_threads=1)
-
-        # Announce the public API server transport address to other nodes if security level allows
-        if config.get('general.security_level', 1) == 0 and config.get('general.announce_node', True):
-            # Default to high security level incase config breaks
-            announceTimer = OnionrCommunicatorTimers(self, announcenode.announce_node, 3600, my_args=[self], requires_peer=True, max_threads=1)
-            announceTimer.count = (announceTimer.frequency - 120)
-        else:
-            logger.debug('Will not announce node.')
-        
-        # Timer to delete malfunctioning or long-dead peers
-        cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requires_peer=True)
-
-        # Timer to cleanup dead ephemeral forward secrecy keys 
-        forwardSecrecyTimer = OnionrCommunicatorTimers(self, housekeeping.clean_keys, 15, my_args=[self], max_threads=1)
-
-        # Adjust initial timer triggers
-        peerPoolTimer.count = (peerPoolTimer.frequency - 1)
-        cleanupTimer.count = (cleanupTimer.frequency - 60)
-        blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
-        lookup_blocks_timer = (lookup_blocks_timer.frequency - 2)
-
-        shared_state.add(self)
-
-        # Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking
-        try:
-            while not self.shutdown:
-                for i in self.timers:
-                    if self.shutdown:
-                        break
-                    i.processTimer()
-                time.sleep(self.delay)
-                # Debug to print out used FDs (regular and net)
-                #proc = psutil.Process()
-                #print(proc.open_files(), len(psutil.net_connections()))
-        except KeyboardInterrupt:
-            self.shutdown = True
-            pass
-
-        logger.info('Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
-        try:
-            self.service_greenlets
-        except AttributeError:
-            pass
-        else:
-            for server in self.service_greenlets:
-                server.stop()
-        localcommand.local_command('shutdown') # shutdown the api
-        try:
-            time.sleep(0.5)
-        except KeyboardInterrupt:
-            pass
-
-    def getBlocks(self):
-        '''download new blocks in queue'''
-        downloadblocks.download_blocks_from_communicator(self)
-
-    def decrementThreadCount(self, threadName):
-        '''Decrement amount of a thread name if more than zero, called when a function meant to be run in a thread ends'''
-        try:
-            if self.threadCounts[threadName] > 0:
-                self.threadCounts[threadName] -= 1
-        except KeyError:
-            pass
-
-    def connectNewPeer(self, peer='', useBootstrap=False):
-        '''Adds a new random online peer to self.onlinePeers'''
-        connectnewpeers.connect_new_peer_to_communicator(self, peer, useBootstrap)
-
-    def peerCleanup(self):
-        '''This just calls onionrpeers.cleanupPeers, which removes dead or bad peers (offline too long, too slow)'''
-        onionrpeers.peer_cleanup()
-        self.decrementThreadCount('peerCleanup')
-
-    def getPeerProfileInstance(self, peer):
-        '''Gets a peer profile instance from the list of profiles, by address name'''
-        for i in self.peerProfiles:
-            # if the peer's profile is already loaded, return that
-            if i.address == peer:
-                retData = i
-                break
-        else:
-            # if the peer's profile is not loaded, return a new one. connectNewPeer also adds it to the list on connect
-            retData = onionrpeers.PeerProfiles(peer)
-            self.peerProfiles.append(retData)
-        return retData
-
-    def getUptime(self):
-        return epoch.get_epoch() - self.startTime
-
-    def heartbeat(self):
-        '''Show a heartbeat debug message'''
-        logger.debug('Heartbeat. Node running for %s.' % humanreadabletime.human_readable_time(self.getUptime()))
-        self.decrementThreadCount('heartbeat')
-
-    def runCheck(self):
-        if run_file_exists(self):
-            logger.debug('Status check; looks good.')
-
-        self.decrementThreadCount('runCheck')
-
-def startCommunicator(shared_state):
-    OnionrCommunicatorDaemon(shared_state)
-
-def run_file_exists(daemon):
-    if os.path.isfile(filepaths.run_check_file):
-        os.remove(filepaths.run_check_file)
-        return True
-    return False
-
-
-
-

Sub-modules

-
-
onionr.communicator.bootstrappeers
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicator.onlinepeers
-
-
-
-
onionr.communicator.peeraction
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicator.uploadqueue
-
-

Onionr - Private P2P Communication …

-
-
-
-
-
-
-

Functions

-
-
-def run_file_exists(daemon) -
-
-
-
-Source code -
def run_file_exists(daemon):
-    if os.path.isfile(filepaths.run_check_file):
-        os.remove(filepaths.run_check_file)
-        return True
-    return False
-
-
-
-def startCommunicator(shared_state) -
-
-
-
-Source code -
def startCommunicator(shared_state):
-    OnionrCommunicatorDaemon(shared_state)
-
-
-
-
-
-

Classes

-
-
-class OnionrCommunicatorDaemon -(shared_state, developmentMode=True) -
-
-
-
-Source code -
class OnionrCommunicatorDaemon:
-    def __init__(self, shared_state, developmentMode=config.get('general.dev_mode', False)):
-        # configure logger and stuff
-        self.config = config
-        self.storage_counter = storagecounter.StorageCounter()
-        self.isOnline = True # Assume we're connected to the internet
-        self.shared_state = shared_state # TooManyObjects module
-
-        # list of timer instances
-        self.timers = []
-
-        # initialize core with Tor socks port being 3rd argument
-        self.proxyPort = shared_state.get(NetController).socksPort
-
-        # Upload information, list of blocks to upload
-        self.blocksToUpload = []
-        self.upload_session_manager = self.shared_state.get(uploadblocks.sessionmanager.BlockUploadSessionManager)
-        self.shared_state.share_object()
-
-        # loop time.sleep delay in seconds
-        self.delay = 1
-
-        # lists of connected peers and peers we know we can't reach currently
-        self.onlinePeers = []
-        self.offlinePeers = []
-        self.cooldownPeer = {}
-        self.connectTimes = {}
-        self.peerProfiles = [] # list of peer's profiles (onionrpeers.PeerProfile instances)
-        self.newPeers = [] # Peers merged to us. Don't add to db until we know they're reachable
-        self.announceProgress = {}
-        self.announceCache = {}
-
-        self.generating_blocks = []
-
-        # amount of threads running by name, used to prevent too many
-        self.threadCounts = {}
-
-        # set true when shutdown command received
-        self.shutdown = False
-
-        # list of new blocks to download, added to when new block lists are fetched from peers
-        self.blockQueue = {}
-
-        # list of blocks currently downloading, avoid s
-        self.currentDownloading = []
-
-        # timestamp when the last online node was seen
-        self.lastNodeSeen = None
-
-        # Dict of time stamps for peer's block list lookup times, to avoid downloading full lists all the time
-        self.dbTimestamps = {}
-
-        # Clear the daemon queue for any dead messages
-        if os.path.exists(dbfiles.daemon_queue_db):
-            daemonqueue.clear_daemon_queue()
-
-        # Loads in and starts the enabled plugins
-        plugins.reload()
-
-        # time app started running for info/statistics purposes
-        self.startTime = epoch.get_epoch()
-
-        uploadqueue.UploadQueue(self) # extends our upload list and saves our list when Onionr exits
-
-        if developmentMode:
-            OnionrCommunicatorTimers(self, self.heartbeat, 30)
-
-        # Set timers, function reference, seconds
-        # requires_peer True means the timer function won't fire if we have no connected peers
-        peerPoolTimer = OnionrCommunicatorTimers(self, onlinepeers.get_online_peers, 60, max_threads=1, my_args=[self])
-        OnionrCommunicatorTimers(self, self.runCheck, 2, max_threads=1)
-
-        # Timers to periodically lookup new blocks and download them
-        lookup_blocks_timer = OnionrCommunicatorTimers(self, lookupblocks.lookup_blocks_from_communicator, config.get('timers.lookupBlocks', 25), my_args=[self], requires_peer=True, max_threads=1)
-        # The block download timer is accessed by the block lookup function to trigger faster download starts
-        self.download_blocks_timer = OnionrCommunicatorTimers(self, self.getBlocks, config.get('timers.getBlocks', 10), requires_peer=True, max_threads=5)
-
-        # Timer to reset the longest offline peer so contact can be attempted again
-        OnionrCommunicatorTimers(self, onlinepeers.clear_offline_peer, 58, my_args=[self])
-
-        # Timer to cleanup old blocks
-        blockCleanupTimer = OnionrCommunicatorTimers(self, housekeeping.clean_old_blocks, 20, my_args=[self])
-
-        # Timer to discover new peers
-        OnionrCommunicatorTimers(self, lookupadders.lookup_new_peer_transports_with_communicator, 60, requires_peer=True, my_args=[self], max_threads=2)
-
-        # Timer for adjusting which peers we actively communicate to at any given time, to avoid over-using peers
-        OnionrCommunicatorTimers(self, cooldownpeer.cooldown_peer, 30, my_args=[self], requires_peer=True)
-
-        # Timer to read the upload queue and upload the entries to peers
-        OnionrCommunicatorTimers(self, uploadblocks.upload_blocks_from_communicator, 5, my_args=[self], requires_peer=True, max_threads=1)
-
-        # Timer to process the daemon command queue
-        OnionrCommunicatorTimers(self, daemonqueuehandler.handle_daemon_commands, 6, my_args=[self], max_threads=3)
-
-        # Setup direct connections
-        if config.get('general.socket_servers', False):
-            self.services = onionrservices.OnionrServices()
-            self.active_services = []
-            self.service_greenlets = []
-            OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, max_threads=50, my_args=[self])
-        else:
-            self.services = None
-        
-        # {peer_pubkey: ephemeral_address}, the address to reach them
-        self.direct_connection_clients = {}
-        
-        # This timer creates deniable blocks, in an attempt to further obfuscate block insertion metadata
-        if config.get('general.insert_deniable_blocks', True):
-            deniableBlockTimer = OnionrCommunicatorTimers(self, deniableinserts.insert_deniable_block, 180, my_args=[self], requires_peer=True, max_threads=1)
-            deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
-
-        # Timer to check for connectivity, through Tor to various high-profile onion services
-        netCheckTimer = OnionrCommunicatorTimers(self, netcheck.net_check, 500, my_args=[self], max_threads=1)
-
-        # Announce the public API server transport address to other nodes if security level allows
-        if config.get('general.security_level', 1) == 0 and config.get('general.announce_node', True):
-            # Default to high security level incase config breaks
-            announceTimer = OnionrCommunicatorTimers(self, announcenode.announce_node, 3600, my_args=[self], requires_peer=True, max_threads=1)
-            announceTimer.count = (announceTimer.frequency - 120)
-        else:
-            logger.debug('Will not announce node.')
-        
-        # Timer to delete malfunctioning or long-dead peers
-        cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requires_peer=True)
-
-        # Timer to cleanup dead ephemeral forward secrecy keys 
-        forwardSecrecyTimer = OnionrCommunicatorTimers(self, housekeeping.clean_keys, 15, my_args=[self], max_threads=1)
-
-        # Adjust initial timer triggers
-        peerPoolTimer.count = (peerPoolTimer.frequency - 1)
-        cleanupTimer.count = (cleanupTimer.frequency - 60)
-        blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
-        lookup_blocks_timer = (lookup_blocks_timer.frequency - 2)
-
-        shared_state.add(self)
-
-        # Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking
-        try:
-            while not self.shutdown:
-                for i in self.timers:
-                    if self.shutdown:
-                        break
-                    i.processTimer()
-                time.sleep(self.delay)
-                # Debug to print out used FDs (regular and net)
-                #proc = psutil.Process()
-                #print(proc.open_files(), len(psutil.net_connections()))
-        except KeyboardInterrupt:
-            self.shutdown = True
-            pass
-
-        logger.info('Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
-        try:
-            self.service_greenlets
-        except AttributeError:
-            pass
-        else:
-            for server in self.service_greenlets:
-                server.stop()
-        localcommand.local_command('shutdown') # shutdown the api
-        try:
-            time.sleep(0.5)
-        except KeyboardInterrupt:
-            pass
-
-    def getBlocks(self):
-        '''download new blocks in queue'''
-        downloadblocks.download_blocks_from_communicator(self)
-
-    def decrementThreadCount(self, threadName):
-        '''Decrement amount of a thread name if more than zero, called when a function meant to be run in a thread ends'''
-        try:
-            if self.threadCounts[threadName] > 0:
-                self.threadCounts[threadName] -= 1
-        except KeyError:
-            pass
-
-    def connectNewPeer(self, peer='', useBootstrap=False):
-        '''Adds a new random online peer to self.onlinePeers'''
-        connectnewpeers.connect_new_peer_to_communicator(self, peer, useBootstrap)
-
-    def peerCleanup(self):
-        '''This just calls onionrpeers.cleanupPeers, which removes dead or bad peers (offline too long, too slow)'''
-        onionrpeers.peer_cleanup()
-        self.decrementThreadCount('peerCleanup')
-
-    def getPeerProfileInstance(self, peer):
-        '''Gets a peer profile instance from the list of profiles, by address name'''
-        for i in self.peerProfiles:
-            # if the peer's profile is already loaded, return that
-            if i.address == peer:
-                retData = i
-                break
-        else:
-            # if the peer's profile is not loaded, return a new one. connectNewPeer also adds it to the list on connect
-            retData = onionrpeers.PeerProfiles(peer)
-            self.peerProfiles.append(retData)
-        return retData
-
-    def getUptime(self):
-        return epoch.get_epoch() - self.startTime
-
-    def heartbeat(self):
-        '''Show a heartbeat debug message'''
-        logger.debug('Heartbeat. Node running for %s.' % humanreadabletime.human_readable_time(self.getUptime()))
-        self.decrementThreadCount('heartbeat')
-
-    def runCheck(self):
-        if run_file_exists(self):
-            logger.debug('Status check; looks good.')
-
-        self.decrementThreadCount('runCheck')
-
-

Methods

-
-
-def connectNewPeer(self, peer='', useBootstrap=False) -
-
-

Adds a new random online peer to self.onlinePeers

-
-Source code -
def connectNewPeer(self, peer='', useBootstrap=False):
-    '''Adds a new random online peer to self.onlinePeers'''
-    connectnewpeers.connect_new_peer_to_communicator(self, peer, useBootstrap)
-
-
-
-def decrementThreadCount(self, threadName) -
-
-

Decrement amount of a thread name if more than zero, called when a function meant to be run in a thread ends

-
-Source code -
def decrementThreadCount(self, threadName):
-    '''Decrement amount of a thread name if more than zero, called when a function meant to be run in a thread ends'''
-    try:
-        if self.threadCounts[threadName] > 0:
-            self.threadCounts[threadName] -= 1
-    except KeyError:
-        pass
-
-
-
-def getBlocks(self) -
-
-

download new blocks in queue

-
-Source code -
def getBlocks(self):
-    '''download new blocks in queue'''
-    downloadblocks.download_blocks_from_communicator(self)
-
-
-
-def getPeerProfileInstance(self, peer) -
-
-

Gets a peer profile instance from the list of profiles, by address name

-
-Source code -
def getPeerProfileInstance(self, peer):
-    '''Gets a peer profile instance from the list of profiles, by address name'''
-    for i in self.peerProfiles:
-        # if the peer's profile is already loaded, return that
-        if i.address == peer:
-            retData = i
-            break
-    else:
-        # if the peer's profile is not loaded, return a new one. connectNewPeer also adds it to the list on connect
-        retData = onionrpeers.PeerProfiles(peer)
-        self.peerProfiles.append(retData)
-    return retData
-
-
-
-def getUptime(self) -
-
-
-
-Source code -
def getUptime(self):
-    return epoch.get_epoch() - self.startTime
-
-
-
-def heartbeat(self) -
-
-

Show a heartbeat debug message

-
-Source code -
def heartbeat(self):
-    '''Show a heartbeat debug message'''
-    logger.debug('Heartbeat. Node running for %s.' % humanreadabletime.human_readable_time(self.getUptime()))
-    self.decrementThreadCount('heartbeat')
-
-
-
-def peerCleanup(self) -
-
-

This just calls onionrpeers.cleanupPeers, which removes dead or bad peers (offline too long, too slow)

-
-Source code -
def peerCleanup(self):
-    '''This just calls onionrpeers.cleanupPeers, which removes dead or bad peers (offline too long, too slow)'''
-    onionrpeers.peer_cleanup()
-    self.decrementThreadCount('peerCleanup')
-
-
-
-def runCheck(self) -
-
-
-
-Source code -
def runCheck(self):
-    if run_file_exists(self):
-        logger.debug('Status check; looks good.')
-
-    self.decrementThreadCount('runCheck')
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/communicatorutils/daemonqueuehandler.html b/docs/html/onionr/communicatorutils/daemonqueuehandler.html deleted file mode 100644 index 3dcd7dcc..00000000 --- a/docs/html/onionr/communicatorutils/daemonqueuehandler.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - -onionr.communicatorutils.daemonqueuehandler API documentation - - - - - - - - - -
-
-
-

Module onionr.communicatorutils.daemonqueuehandler

-
-
-

Onionr - P2P Anonymous Storage Network

-

Handle daemon queue commands in the communicator

-
-Source code -
'''
-    Onionr - P2P Anonymous Storage Network
-
-    Handle daemon queue commands in the communicator
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import logger
-from onionrplugins import onionrevents as events
-from onionrutils import localcommand
-from coredb import daemonqueue
-import filepaths
-from . import restarttor
-def handle_daemon_commands(comm_inst):
-    cmd = daemonqueue.daemon_queue()
-    response = ''
-    if cmd is not False:
-        events.event('daemon_command', data = {'cmd' : cmd})
-        if cmd[0] == 'shutdown':
-            comm_inst.shutdown = True
-        elif cmd[0] == 'remove_from_insert_list':
-            try:
-                comm_inst.generating_blocks.remove(cmd[1])
-            except ValueError:
-                pass
-        elif cmd[0] == 'announceNode':
-            if len(comm_inst.onlinePeers) > 0:
-                comm_inst.announce(cmd[1])
-            else:
-                logger.debug("No nodes connected. Will not introduce node.")
-        elif cmd[0] == 'runCheck': # deprecated
-            logger.debug('Status check; looks good.')
-            open(filepaths.run_check_file + '.runcheck', 'w+').close()
-        elif cmd[0] == 'connectedPeers':
-            response = '\n'.join(list(comm_inst.onlinePeers)).strip()
-            if response == '':
-                response = 'none'
-        elif cmd[0] == 'localCommand':
-            response = localcommand.local_command(cmd[1])
-        elif cmd[0] == 'clearOffline':
-            comm_inst.offlinePeers = []
-        elif cmd[0] == 'restartTor':
-            restarttor.restart(comm_inst)
-            comm_inst.offlinePeers = []
-        elif cmd[0] == 'pex':
-            for i in comm_inst.timers:
-                if i.timerFunction.__name__ == 'lookupAdders':
-                    i.count = (i.frequency - 1)
-        elif cmd[0] == 'uploadBlock':
-            comm_inst.blocksToUpload.append(cmd[1])
-        else:
-            logger.debug('Received daemon queue command unable to be handled: %s' % (cmd[0],))
-
-        if cmd[0] not in ('', None):
-            if response != '':
-                localcommand.local_command('queueResponseAdd/' + cmd[4], post=True, postData={'data': response})
-        response = ''
-
-    comm_inst.decrementThreadCount('handle_daemon_commands')
-
-
-
-
-
-
-
-

Functions

-
-
-def handle_daemon_commands(comm_inst) -
-
-
-
-Source code -
def handle_daemon_commands(comm_inst):
-    cmd = daemonqueue.daemon_queue()
-    response = ''
-    if cmd is not False:
-        events.event('daemon_command', data = {'cmd' : cmd})
-        if cmd[0] == 'shutdown':
-            comm_inst.shutdown = True
-        elif cmd[0] == 'remove_from_insert_list':
-            try:
-                comm_inst.generating_blocks.remove(cmd[1])
-            except ValueError:
-                pass
-        elif cmd[0] == 'announceNode':
-            if len(comm_inst.onlinePeers) > 0:
-                comm_inst.announce(cmd[1])
-            else:
-                logger.debug("No nodes connected. Will not introduce node.")
-        elif cmd[0] == 'runCheck': # deprecated
-            logger.debug('Status check; looks good.')
-            open(filepaths.run_check_file + '.runcheck', 'w+').close()
-        elif cmd[0] == 'connectedPeers':
-            response = '\n'.join(list(comm_inst.onlinePeers)).strip()
-            if response == '':
-                response = 'none'
-        elif cmd[0] == 'localCommand':
-            response = localcommand.local_command(cmd[1])
-        elif cmd[0] == 'clearOffline':
-            comm_inst.offlinePeers = []
-        elif cmd[0] == 'restartTor':
-            restarttor.restart(comm_inst)
-            comm_inst.offlinePeers = []
-        elif cmd[0] == 'pex':
-            for i in comm_inst.timers:
-                if i.timerFunction.__name__ == 'lookupAdders':
-                    i.count = (i.frequency - 1)
-        elif cmd[0] == 'uploadBlock':
-            comm_inst.blocksToUpload.append(cmd[1])
-        else:
-            logger.debug('Received daemon queue command unable to be handled: %s' % (cmd[0],))
-
-        if cmd[0] not in ('', None):
-            if response != '':
-                localcommand.local_command('queueResponseAdd/' + cmd[4], post=True, postData={'data': response})
-        response = ''
-
-    comm_inst.decrementThreadCount('handle_daemon_commands')
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/communicatorutils/index.html b/docs/html/onionr/communicatorutils/index.html deleted file mode 100644 index 4b265539..00000000 --- a/docs/html/onionr/communicatorutils/index.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - -onionr.communicatorutils API documentation - - - - - - - - - -
-
-
-

Module onionr.communicatorutils

-
-
-
-
-

Sub-modules

-
-
onionr.communicatorutils.announcenode
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.connectnewpeers
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.cooldownpeer
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.daemonqueuehandler
-
-

Onionr - P2P Anonymous Storage Network …

-
-
onionr.communicatorutils.deniableinserts
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.downloadblocks
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.housekeeping
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.lookupadders
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.lookupblocks
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.netcheck
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.onionrcommunicatortimers
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.proxypicker
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.restarttor
-
-
-
-
onionr.communicatorutils.servicecreator
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils.uploadblocks
-
-

Onionr - Private P2P Communication …

-
-
-
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/communicatorutils/uploadblocks/sessionmanager.html b/docs/html/onionr/communicatorutils/uploadblocks/sessionmanager.html deleted file mode 100644 index 1db7b4db..00000000 --- a/docs/html/onionr/communicatorutils/uploadblocks/sessionmanager.html +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - -onionr.communicatorutils.uploadblocks.sessionmanager API documentation - - - - - - - - - -
-
-
-

Module onionr.communicatorutils.uploadblocks.sessionmanager

-
-
-

Onionr - Private P2P Communication

-

Manager for upload 'sessions'

-
-Source code -
"""
-    Onionr - Private P2P Communication
-
-    Manager for upload 'sessions'
-"""
-from __future__ import annotations
-"""
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-"""
-from typing import Iterable, Union
-
-from onionrutils import bytesconverter
-from onionrutils import localcommand
-from etc import onionrvalues
-from etc import waitforsetvar
-from utils import reconstructhash
-
-from . import session
-
-class BlockUploadSessionManager:
-    """Holds block UploadSession instances. Optionally accepts iterable of sessions to added on init
-
-    Arguments: old_session: iterable of old UploadSession objects"""
-    def __init__(self, old_sessions:Iterable=None):
-        #self._too_many: TooMany = None
-        if old_sessions is None:
-            self.sessions = []
-        else:
-            self.sessions = old_session
-    
-    def add_session(self, session_or_block: Union(str, bytes, session.UploadSession))->session.UploadSession:
-        """Create (or add existing) block upload session from a str/bytes block hex hash, existing UploadSession"""
-        if isinstance(session_or_block, session.UploadSession): 
-            if not session_or_block in self.sessions:
-                self.sessions.append(session_or_block)
-            return session_or_block
-        try:
-            return self.get_session(session_or_block)
-        except KeyError:
-            pass
-        # convert bytes hash to str
-        if isinstance(session_or_block, bytes): session_or_block = bytesconverter.bytes_to_str(session_or_block)
-        # intentionally not elif
-        if isinstance(session_or_block, str):
-            new_session = session.UploadSession(session_or_block)
-            self.sessions.append(new_session)
-            return new_session
-
-    def get_session(self, block_hash: Union(str, bytes))->session.UploadSession:
-        block_hash = reconstructhash.deconstruct_hash(bytesconverter.bytes_to_str(block_hash))
-        for session in self.sessions:
-            if session.block_hash == block_hash: return session
-        raise KeyError
-
-    def clean_session(self, specific_session: Union[str, UploadSession]=None):
-        comm_inst: OnionrCommunicatorDaemon = self._too_many.get_by_string("OnionrCommunicatorDaemon")
-        sessions_to_delete = []
-        if comm_inst.getUptime() < 120: return
-        for session in self.sessions:
-            if (session.total_success_count / len(comm_inst.onlinePeers)) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
-                sessions_to_delete.append(session)
-        for session in sessions_to_delete:
-            self.sessions.remove(session)
-            # TODO cleanup to one round of search
-            # Remove the blocks from the sessions, upload list, and waitforshare list
-            try:
-                comm_inst.blocksToUpload.remove(reconstructhash.reconstruct_hash(session.block_hash))
-            except ValueError:
-                pass
-            try:
-                comm_inst.blocksToUpload.remove(session.block_hash)
-            except ValueError:
-                pass
-            localcommand.local_command('waitforshare/{session.block_hash}')
-
-
-
-
-
-
-
-
-
-

Classes

-
-
-class BlockUploadSessionManager -(old_sessions=None) -
-
-

Holds block UploadSession instances. Optionally accepts iterable of sessions to added on init

-

Arguments: old_session: iterable of old UploadSession objects

-
-Source code -
class BlockUploadSessionManager:
-    """Holds block UploadSession instances. Optionally accepts iterable of sessions to added on init
-
-    Arguments: old_session: iterable of old UploadSession objects"""
-    def __init__(self, old_sessions:Iterable=None):
-        #self._too_many: TooMany = None
-        if old_sessions is None:
-            self.sessions = []
-        else:
-            self.sessions = old_session
-    
-    def add_session(self, session_or_block: Union(str, bytes, session.UploadSession))->session.UploadSession:
-        """Create (or add existing) block upload session from a str/bytes block hex hash, existing UploadSession"""
-        if isinstance(session_or_block, session.UploadSession): 
-            if not session_or_block in self.sessions:
-                self.sessions.append(session_or_block)
-            return session_or_block
-        try:
-            return self.get_session(session_or_block)
-        except KeyError:
-            pass
-        # convert bytes hash to str
-        if isinstance(session_or_block, bytes): session_or_block = bytesconverter.bytes_to_str(session_or_block)
-        # intentionally not elif
-        if isinstance(session_or_block, str):
-            new_session = session.UploadSession(session_or_block)
-            self.sessions.append(new_session)
-            return new_session
-
-    def get_session(self, block_hash: Union(str, bytes))->session.UploadSession:
-        block_hash = reconstructhash.deconstruct_hash(bytesconverter.bytes_to_str(block_hash))
-        for session in self.sessions:
-            if session.block_hash == block_hash: return session
-        raise KeyError
-
-    def clean_session(self, specific_session: Union[str, UploadSession]=None):
-        comm_inst: OnionrCommunicatorDaemon = self._too_many.get_by_string("OnionrCommunicatorDaemon")
-        sessions_to_delete = []
-        if comm_inst.getUptime() < 120: return
-        for session in self.sessions:
-            if (session.total_success_count / len(comm_inst.onlinePeers)) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
-                sessions_to_delete.append(session)
-        for session in sessions_to_delete:
-            self.sessions.remove(session)
-            # TODO cleanup to one round of search
-            # Remove the blocks from the sessions, upload list, and waitforshare list
-            try:
-                comm_inst.blocksToUpload.remove(reconstructhash.reconstruct_hash(session.block_hash))
-            except ValueError:
-                pass
-            try:
-                comm_inst.blocksToUpload.remove(session.block_hash)
-            except ValueError:
-                pass
-            localcommand.local_command('waitforshare/{session.block_hash}')
-
-

Methods

-
-
-def add_session(self, session_or_block) -
-
-

Create (or add existing) block upload session from a str/bytes block hex hash, existing UploadSession

-
-Source code -
def add_session(self, session_or_block: Union(str, bytes, session.UploadSession))->session.UploadSession:
-    """Create (or add existing) block upload session from a str/bytes block hex hash, existing UploadSession"""
-    if isinstance(session_or_block, session.UploadSession): 
-        if not session_or_block in self.sessions:
-            self.sessions.append(session_or_block)
-        return session_or_block
-    try:
-        return self.get_session(session_or_block)
-    except KeyError:
-        pass
-    # convert bytes hash to str
-    if isinstance(session_or_block, bytes): session_or_block = bytesconverter.bytes_to_str(session_or_block)
-    # intentionally not elif
-    if isinstance(session_or_block, str):
-        new_session = session.UploadSession(session_or_block)
-        self.sessions.append(new_session)
-        return new_session
-
-
-
-def clean_session(self, specific_session=None) -
-
-
-
-Source code -
def clean_session(self, specific_session: Union[str, UploadSession]=None):
-    comm_inst: OnionrCommunicatorDaemon = self._too_many.get_by_string("OnionrCommunicatorDaemon")
-    sessions_to_delete = []
-    if comm_inst.getUptime() < 120: return
-    for session in self.sessions:
-        if (session.total_success_count / len(comm_inst.onlinePeers)) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
-            sessions_to_delete.append(session)
-    for session in sessions_to_delete:
-        self.sessions.remove(session)
-        # TODO cleanup to one round of search
-        # Remove the blocks from the sessions, upload list, and waitforshare list
-        try:
-            comm_inst.blocksToUpload.remove(reconstructhash.reconstruct_hash(session.block_hash))
-        except ValueError:
-            pass
-        try:
-            comm_inst.blocksToUpload.remove(session.block_hash)
-        except ValueError:
-            pass
-        localcommand.local_command('waitforshare/{session.block_hash}')
-
-
-
-def get_session(self, block_hash) -
-
-
-
-Source code -
def get_session(self, block_hash: Union(str, bytes))->session.UploadSession:
-    block_hash = reconstructhash.deconstruct_hash(bytesconverter.bytes_to_str(block_hash))
-    for session in self.sessions:
-        if session.block_hash == block_hash: return session
-    raise KeyError
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/coredb/daemonqueue/index.html b/docs/html/onionr/coredb/daemonqueue/index.html deleted file mode 100644 index 08de235a..00000000 --- a/docs/html/onionr/coredb/daemonqueue/index.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - -onionr.coredb.daemonqueue API documentation - - - - - - - - - -
-
-
-

Module onionr.coredb.daemonqueue

-
-
-

Onionr - Private P2P Communication

-

Write and read the daemon queue, which is how messages are passed into the onionr daemon in a more -direct way than the http api

-
-Source code -
'''
-    Onionr - Private P2P Communication
-
-    Write and read the daemon queue, which is how messages are passed into the onionr daemon in a more
-    direct way than the http api
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sqlite3, os
-from onionrplugins import onionrevents as events
-from onionrutils import localcommand, epoch
-from .. import dbfiles
-from onionrsetup import dbcreator
-
-def daemon_queue()->str:
-    '''
-        Gives commands to the communication proccess/daemon by reading an sqlite3 database
-
-        This function intended to be used by the client. Queue to exchange data between "client" and server.
-    '''
-
-    retData = False
-    if not os.path.exists(dbfiles.daemon_queue_db):
-        dbcreator.createDaemonDB()
-    else:
-        conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-        c = conn.cursor()
-        try:
-            for row in c.execute('SELECT command, data, date, min(ID), responseID FROM commands group by id'):
-                retData = row
-                break
-        except sqlite3.OperationalError:
-            dbcreator.createDaemonDB()
-        else:
-            if retData != False:
-                c.execute('DELETE FROM commands WHERE id=?;', (retData[3],))
-        conn.commit()
-        conn.close()
-
-    return retData
-
-def daemon_queue_add(command: str, data='', responseID: str =''):
-    '''
-        Add a command to the daemon queue, used by the communication daemon (communicator.py)
-    '''
-
-    retData = True
-
-    date = epoch.get_epoch()
-    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-    c = conn.cursor()
-    t = (command, data, date, responseID)
-    try:
-        c.execute('INSERT INTO commands (command, data, date, responseID) VALUES(?, ?, ?, ?)', t)
-        conn.commit()
-    except sqlite3.OperationalError:
-        retData = False
-        daemon_queue()
-    conn.close()
-    return retData
-
-def daemon_queue_get_response(responseID=''):
-    '''
-        Get a response sent by communicator to the API, by requesting to the API
-    '''
-    if len(responseID) == 0: raise ValueError('ResponseID should not be empty')
-    resp = localcommand.local_command(dbfiles.daemon_queue_db, 'queueResponse/' + responseID)
-    return resp
-
-def clear_daemon_queue():
-    '''
-        Clear the daemon queue (somewhat dangerous)
-    '''
-    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-    c = conn.cursor()
-
-    c.execute('DELETE FROM commands;')
-    conn.commit()
-
-    conn.close()
-
-
-
-
-
-
-
-

Functions

-
-
-def clear_daemon_queue() -
-
-

Clear the daemon queue (somewhat dangerous)

-
-Source code -
def clear_daemon_queue():
-    '''
-        Clear the daemon queue (somewhat dangerous)
-    '''
-    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-    c = conn.cursor()
-
-    c.execute('DELETE FROM commands;')
-    conn.commit()
-
-    conn.close()
-
-
-
-def daemon_queue() -
-
-

Gives commands to the communication proccess/daemon by reading an sqlite3 database

-

This function intended to be used by the client. Queue to exchange data between "client" and server.

-
-Source code -
def daemon_queue()->str:
-    '''
-        Gives commands to the communication proccess/daemon by reading an sqlite3 database
-
-        This function intended to be used by the client. Queue to exchange data between "client" and server.
-    '''
-
-    retData = False
-    if not os.path.exists(dbfiles.daemon_queue_db):
-        dbcreator.createDaemonDB()
-    else:
-        conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-        c = conn.cursor()
-        try:
-            for row in c.execute('SELECT command, data, date, min(ID), responseID FROM commands group by id'):
-                retData = row
-                break
-        except sqlite3.OperationalError:
-            dbcreator.createDaemonDB()
-        else:
-            if retData != False:
-                c.execute('DELETE FROM commands WHERE id=?;', (retData[3],))
-        conn.commit()
-        conn.close()
-
-    return retData
-
-
-
-def daemon_queue_add(command, data='', responseID='') -
-
-

Add a command to the daemon queue, used by the communication daemon (communicator.py)

-
-Source code -
def daemon_queue_add(command: str, data='', responseID: str =''):
-    '''
-        Add a command to the daemon queue, used by the communication daemon (communicator.py)
-    '''
-
-    retData = True
-
-    date = epoch.get_epoch()
-    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30)
-    c = conn.cursor()
-    t = (command, data, date, responseID)
-    try:
-        c.execute('INSERT INTO commands (command, data, date, responseID) VALUES(?, ?, ?, ?)', t)
-        conn.commit()
-    except sqlite3.OperationalError:
-        retData = False
-        daemon_queue()
-    conn.close()
-    return retData
-
-
-
-def daemon_queue_get_response(responseID='') -
-
-

Get a response sent by communicator to the API, by requesting to the API

-
-Source code -
def daemon_queue_get_response(responseID=''):
-    '''
-        Get a response sent by communicator to the API, by requesting to the API
-    '''
-    if len(responseID) == 0: raise ValueError('ResponseID should not be empty')
-    resp = localcommand.local_command(dbfiles.daemon_queue_db, 'queueResponse/' + responseID)
-    return resp
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/index.html b/docs/html/onionr/index.html deleted file mode 100644 index 439ddbcd..00000000 --- a/docs/html/onionr/index.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - -onionr API documentation - - - - - - - - - -
-
-
-

Module onionr

-
-
-

Onionr - Private P2P Communication

-

This file initializes Onionr when ran to be a daemon or with commands

-

Run with 'help' for usage.

-
-Source code -
#!/usr/bin/env python3
-'''
-    Onionr - Private P2P Communication
-
-    This file initializes Onionr when ran to be a daemon or with commands
-
-    Run with 'help' for usage.
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-
-# Set the user's locale for encoding reasons
-import locale 
-locale.setlocale(locale.LC_ALL, '')
-
-# Import standard libraries
-import sys
-
-# 3rd party lib imports
-# Ensure that PySocks is installed
-try:
-    from urllib3.contrib.socks import SOCKSProxyManager
-except ModuleNotFoundError:
-    raise ModuleNotFoundError("You need the PySocks module (for use with socks5 proxy to use Tor)")
-
-# Onionr imports
-from etc import onionrvalues # For different Onionr related constants such as versions
-import onionrsetup as setup
-
-# Ensure we have at least the minimum python version
-if sys.version_info[0] == 2 or sys.version_info[1] < onionrvalues.MIN_PY_VERSION:
-    sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (onionrvalues.MIN_PY_VERSION,))
-    sys.exit(1)
-
-# Create Onionr data directories, must be done before most imports
-from utils import createdirs
-createdirs.create_dirs()
-
-from onionrcommands import parser
-from onionrplugins import onionrevents as events
-
-setup.setup_config()
-setup.setup_default_plugins()
-
-def onionr_main():
-    parser.register()
-    return
-
-if __name__ == "__main__":
-    onionr_main()
-
-
-
-

Sub-modules

-
-
onionr.apiservers
-
-
-
-
onionr.communicator
-
-

Onionr - Private P2P Communication …

-
-
onionr.communicatorutils
-
-
-
-
onionr.config
-
-

Onionr - Private P2P Communication …

-
-
onionr.coredb
-
-
-
-
onionr.etc
-
-
-
-
onionr.filepaths
-
-
-
-
onionr.httpapi
-
-

Onionr - Private P2P Communication …

-
-
onionr.keymanager
-
-

Onionr - Private P2P Communication …

-
-
onionr.logger
-
-

Onionr - Private P2P Communication …

-
-
onionr.netcontroller
-
-
-
-
onionr.notifier
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrblocks
-
-
-
-
onionr.onionrcommands
-
-
-
-
onionr.onionrcrypto
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrexceptions
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrpeers
-
-
-
-
onionr.onionrplugins
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrproofs
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrservices
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrsetup
-
-
-
-
onionr.onionrstorage
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrusers
-
-
-
-
onionr.onionrutils
-
-
-
-
onionr.serializeddata
-
-

Onionr - Private P2P Communication …

-
-
onionr.utils
-
-
-
-
-
-
-
-
-

Functions

-
-
-def onionr_main() -
-
-
-
-Source code -
def onionr_main():
-    parser.register()
-    return
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/daemonlaunch.html b/docs/html/onionr/onionrcommands/daemonlaunch.html deleted file mode 100644 index 4c12fb64..00000000 --- a/docs/html/onionr/onionrcommands/daemonlaunch.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - - -onionr.onionrcommands.daemonlaunch API documentation - - - - - - - - - -
-
-
-

Module onionr.onionrcommands.daemonlaunch

-
-
-

Onionr - Private P2P Communication

-

launch the api servers and communicator

-
-Source code -
'''
-    Onionr - Private P2P Communication
-
-    launch the api servers and communicator
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-
-import os, time, sys, platform, sqlite3, signal
-from threading import Thread
-
-import toomanyobjs
-
-import config, apiservers, logger, communicator
-from onionrplugins import onionrevents as events
-from netcontroller import NetController
-from onionrutils import localcommand
-import filepaths
-from coredb import daemonqueue
-from etc import onionrvalues, cleanup
-from onionrcrypto import getourkeypair
-from utils import hastor, logoheader
-from . import version
-import serializeddata
-
-def _proper_shutdown():
-    localcommand.local_command('shutdown')
-    sys.exit(1)
-
-def daemon():
-    '''
-        Starts the Onionr communication daemon
-    '''
-    if not hastor.has_tor():
-        logger.error("Tor is not present in system path or Onionr directory", terminal=True)
-        sys.exit(1)
-
-    # remove runcheck if it exists
-    if os.path.isfile(filepaths.run_check_file):
-        logger.debug('Runcheck file found on daemon start, deleting in advance.')
-        os.remove(filepaths.run_check_file)
-    
-    # Create shared object
-
-    shared_state = toomanyobjs.TooMany()
-
-    Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start()
-    Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start()
-    shared_state.get(serializeddata.SerializedData)
-    shared_state.share_object() # share the parent object to the threads
-
-    apiHost = ''
-    while apiHost == '':
-        try:
-            with open(filepaths.public_API_host_file, 'r') as hostFile:
-                apiHost = hostFile.read()
-        except FileNotFoundError:
-            pass
-        time.sleep(0.5)
-
-    logger.raw('', terminal=True)
-    # print nice header thing :)
-    if config.get('general.display_header', True):
-        logoheader.header()
-    version.version(verbosity = 5, function = logger.info)
-    logger.debug('Python version %s' % platform.python_version())
-
-    if onionrvalues.DEVELOPMENT_MODE:
-        logger.warn('Development mode enabled', timestamp = False, terminal=True)
-
-    net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost)
-    shared_state.add(net)
-
-    logger.info('Tor is starting...', terminal=True)
-    if not net.startTor():
-        localcommand.local_command('shutdown')
-        sys.exit(1)
-    if len(net.myID) > 0 and config.get('general.security_level', 1) == 0:
-        logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID))
-    else:
-        logger.debug('.onion service disabled')
-    logger.info('Using public key: %s' % (logger.colors.underline + getourkeypair.get_keypair()[0][:52]))
-
-    try:
-        time.sleep(1)
-    except KeyboardInterrupt:
-        _proper_shutdown()
-    events.event('init', threaded = False)
-    events.event('daemon_start')
-    communicator.startCommunicator(shared_state)
-
-    localcommand.local_command('shutdown')
-
-    net.killTor()
-    try:
-        time.sleep(5) # Time to allow threads to finish, if not any "daemon" threads will be slaughtered http://docs.python.org/library/threading.html#threading.Thread.daemon
-    except KeyboardInterrupt:
-        pass
-    cleanup.delete_run_files()
-
-def _ignore_sigint(sig, frame):
-    '''This space intentionally left blank'''
-    return
-
-def kill_daemon():
-    '''
-        Shutdown the Onionr daemon (communicator)
-    '''
-
-    logger.warn('Stopping the running daemon...', timestamp = False, terminal=True)
-    try:
-        events.event('daemon_stop')
-        net = NetController(config.get('client.port', 59496))
-        try:
-            daemonqueue.daemon_queue_add('shutdown')
-        except sqlite3.OperationalError:
-            pass
-
-        net.killTor()
-    except Exception as e:
-        logger.error('Failed to shutdown daemon: ' + str(e), error = e, timestamp = False, terminal=True)
-    return
-
-kill_daemon.onionr_help = "Gracefully stops the Onionr API servers"
-
-def start(input: bool = False, override: bool = False):
-    """If no lock file, make one and start onionr, error if there is and its not overridden"""
-    if os.path.exists('.onionr-lock') and not override:
-        logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete .onionr-lock & try again).', terminal=True)
-    else:
-        if not onionrvalues.DEVELOPMENT_MODE:
-            lockFile = open('.onionr-lock', 'w')
-            lockFile.write('')
-            lockFile.close()
-        daemon()
-        if not onionrvalues.DEVELOPMENT_MODE:
-            try:
-                os.remove('.onionr-lock')
-            except FileNotFoundError:
-                pass
-
-start.onionr_help = "Start Onionr node (public and clients API servers)"
-
-
-
-
-
-
-
-

Functions

-
-
-def daemon() -
-
-

Starts the Onionr communication daemon

-
-Source code -
def daemon():
-    '''
-        Starts the Onionr communication daemon
-    '''
-    if not hastor.has_tor():
-        logger.error("Tor is not present in system path or Onionr directory", terminal=True)
-        sys.exit(1)
-
-    # remove runcheck if it exists
-    if os.path.isfile(filepaths.run_check_file):
-        logger.debug('Runcheck file found on daemon start, deleting in advance.')
-        os.remove(filepaths.run_check_file)
-    
-    # Create shared object
-
-    shared_state = toomanyobjs.TooMany()
-
-    Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start()
-    Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start()
-    shared_state.get(serializeddata.SerializedData)
-    shared_state.share_object() # share the parent object to the threads
-
-    apiHost = ''
-    while apiHost == '':
-        try:
-            with open(filepaths.public_API_host_file, 'r') as hostFile:
-                apiHost = hostFile.read()
-        except FileNotFoundError:
-            pass
-        time.sleep(0.5)
-
-    logger.raw('', terminal=True)
-    # print nice header thing :)
-    if config.get('general.display_header', True):
-        logoheader.header()
-    version.version(verbosity = 5, function = logger.info)
-    logger.debug('Python version %s' % platform.python_version())
-
-    if onionrvalues.DEVELOPMENT_MODE:
-        logger.warn('Development mode enabled', timestamp = False, terminal=True)
-
-    net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost)
-    shared_state.add(net)
-
-    logger.info('Tor is starting...', terminal=True)
-    if not net.startTor():
-        localcommand.local_command('shutdown')
-        sys.exit(1)
-    if len(net.myID) > 0 and config.get('general.security_level', 1) == 0:
-        logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID))
-    else:
-        logger.debug('.onion service disabled')
-    logger.info('Using public key: %s' % (logger.colors.underline + getourkeypair.get_keypair()[0][:52]))
-
-    try:
-        time.sleep(1)
-    except KeyboardInterrupt:
-        _proper_shutdown()
-    events.event('init', threaded = False)
-    events.event('daemon_start')
-    communicator.startCommunicator(shared_state)
-
-    localcommand.local_command('shutdown')
-
-    net.killTor()
-    try:
-        time.sleep(5) # Time to allow threads to finish, if not any "daemon" threads will be slaughtered http://docs.python.org/library/threading.html#threading.Thread.daemon
-    except KeyboardInterrupt:
-        pass
-    cleanup.delete_run_files()
-
-
-
-def kill_daemon() -
-
-

Shutdown the Onionr daemon (communicator)

-
-Source code -
def kill_daemon():
-    '''
-        Shutdown the Onionr daemon (communicator)
-    '''
-
-    logger.warn('Stopping the running daemon...', timestamp = False, terminal=True)
-    try:
-        events.event('daemon_stop')
-        net = NetController(config.get('client.port', 59496))
-        try:
-            daemonqueue.daemon_queue_add('shutdown')
-        except sqlite3.OperationalError:
-            pass
-
-        net.killTor()
-    except Exception as e:
-        logger.error('Failed to shutdown daemon: ' + str(e), error = e, timestamp = False, terminal=True)
-    return
-
-
-
-def start(input=False, override=False) -
-
-

If no lock file, make one and start onionr, error if there is and its not overridden

-
-Source code -
def start(input: bool = False, override: bool = False):
-    """If no lock file, make one and start onionr, error if there is and its not overridden"""
-    if os.path.exists('.onionr-lock') and not override:
-        logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete .onionr-lock & try again).', terminal=True)
-    else:
-        if not onionrvalues.DEVELOPMENT_MODE:
-            lockFile = open('.onionr-lock', 'w')
-            lockFile.write('')
-            lockFile.close()
-        daemon()
-        if not onionrvalues.DEVELOPMENT_MODE:
-            try:
-                os.remove('.onionr-lock')
-            except FileNotFoundError:
-                pass
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/onionrstatistics.html b/docs/html/onionr/onionrcommands/onionrstatistics.html deleted file mode 100644 index d0419977..00000000 --- a/docs/html/onionr/onionrcommands/onionrstatistics.html +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - -onionr.onionrcommands.onionrstatistics API documentation - - - - - - - - - -
-
-
-

Module onionr.onionrcommands.onionrstatistics

-
-
-

Onionr - Private P2P Communication

-

This module defines commands to show stats/details about the local node

-
-Source code -
'''
-    Onionr - Private P2P Communication
-
-    This module defines commands to show stats/details about the local node
-'''
-'''
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os, uuid, time
-import logger
-from onionrblocks import onionrblockapi
-from onionrutils import checkcommunicator, mnemonickeys
-from utils import sizeutils, gethostname, getconsolewidth, identifyhome
-from coredb import blockmetadb, daemonqueue, keydb
-import onionrcrypto, config
-from etc import onionrvalues
-def show_stats():
-    try:
-        # define stats messages here
-        totalBlocks = len(blockmetadb.get_block_list())
-        home = identifyhome.identify_home()
-        signedBlocks = len(onionrblockapi.Block.getBlocks(signed = True))
-        messages = {
-            # info about local client
-            'Onionr Daemon Status' : ((logger.colors.fg.green + 'Online') if checkcommunicator.is_communicator_running(timeout = 9) else logger.colors.fg.red + 'Offline'),
-
-            # file and folder size stats
-            'div1' : True, # this creates a solid line across the screen, a div
-            'Total Block Size' : sizeutils.human_size(sizeutils.size(home + 'blocks/')),
-            'Total Plugin Size' : sizeutils.human_size(sizeutils.size(home + 'plugins/')),
-            'Log File Size' : sizeutils.human_size(sizeutils.size(home + 'output.log')),
-
-            # count stats
-            'div2' : True,
-            'Known Peers (nodes)' : str(max(len(keydb.listkeys.list_adders()) - 1, 0)),
-            'Enabled Plugins' : str(len(config.get('plugins.enabled', list()))) + ' / ' + str(len(os.listdir(home + 'plugins/'))),
-            'Stored Blocks' : str(totalBlocks),
-            'Percent Blocks Signed' : str(round(100 * signedBlocks / max(totalBlocks, 1), 2)) + '%'
-        }
-
-        # color configuration
-        colors = {
-            'title' : logger.colors.bold,
-            'key' : logger.colors.fg.lightgreen,
-            'val' : logger.colors.fg.green,
-            'border' : logger.colors.fg.lightblue,
-
-            'reset' : logger.colors.reset
-        }
-
-        # pre-processing
-        maxlength = 0
-        width = getconsolewidth.get_console_width()
-        for key, val in messages.items():
-            if not (type(val) is bool and val is True):
-                maxlength = max(len(key), maxlength)
-        prewidth = maxlength + len(' | ')
-        groupsize = width - prewidth - len('[+] ')
-
-        # generate stats table
-        logger.info(colors['title'] + 'Onionr v%s Statistics' % onionrvalues.ONIONR_VERSION + colors['reset'], terminal=True)
-        logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-        for key, val in messages.items():
-            if not (type(val) is bool and val is True):
-                val = [str(val)[i:i + groupsize] for i in range(0, len(str(val)), groupsize)]
-
-                logger.info(colors['key'] + str(key).rjust(maxlength) + colors['reset'] + colors['border'] + ' | ' + colors['reset'] + colors['val'] + str(val.pop(0)) + colors['reset'], terminal=True)
-
-                for value in val:
-                    logger.info(' ' * maxlength + colors['border'] + ' | ' + colors['reset'] + colors['val'] + str(value) + colors['reset'], terminal=True)
-            else:
-                logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-        logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-    except Exception as e:
-        logger.error('Failed to generate statistics table. ' + str(e), error = e, timestamp = False, terminal=True)
-
-def show_details():
-    details = {
-        'Node Address' : gethostname.get_hostname(),
-        'Web Password' : config.get('client.webpassword'),
-        'Public Key' : onionrcrypto.pub_key,
-        'Human-readable Public Key' : mnemonickeys.get_human_readable_ID()
-    }
-
-    for detail in details:
-        logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), terminal = True)
-
-show_details.onionr_help = "Shows relevant information for your Onionr install: note address, web password and active public key."
-show_stats.onionr_help = "Shows statistics for your Onionr node. Slow if Onionr is not running"
-
-
-
-
-
-
-
-

Functions

-
-
-def show_details() -
-
-
-
-Source code -
def show_details():
-    details = {
-        'Node Address' : gethostname.get_hostname(),
-        'Web Password' : config.get('client.webpassword'),
-        'Public Key' : onionrcrypto.pub_key,
-        'Human-readable Public Key' : mnemonickeys.get_human_readable_ID()
-    }
-
-    for detail in details:
-        logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), terminal = True)
-
-
-
-def show_stats() -
-
-
-
-Source code -
def show_stats():
-    try:
-        # define stats messages here
-        totalBlocks = len(blockmetadb.get_block_list())
-        home = identifyhome.identify_home()
-        signedBlocks = len(onionrblockapi.Block.getBlocks(signed = True))
-        messages = {
-            # info about local client
-            'Onionr Daemon Status' : ((logger.colors.fg.green + 'Online') if checkcommunicator.is_communicator_running(timeout = 9) else logger.colors.fg.red + 'Offline'),
-
-            # file and folder size stats
-            'div1' : True, # this creates a solid line across the screen, a div
-            'Total Block Size' : sizeutils.human_size(sizeutils.size(home + 'blocks/')),
-            'Total Plugin Size' : sizeutils.human_size(sizeutils.size(home + 'plugins/')),
-            'Log File Size' : sizeutils.human_size(sizeutils.size(home + 'output.log')),
-
-            # count stats
-            'div2' : True,
-            'Known Peers (nodes)' : str(max(len(keydb.listkeys.list_adders()) - 1, 0)),
-            'Enabled Plugins' : str(len(config.get('plugins.enabled', list()))) + ' / ' + str(len(os.listdir(home + 'plugins/'))),
-            'Stored Blocks' : str(totalBlocks),
-            'Percent Blocks Signed' : str(round(100 * signedBlocks / max(totalBlocks, 1), 2)) + '%'
-        }
-
-        # color configuration
-        colors = {
-            'title' : logger.colors.bold,
-            'key' : logger.colors.fg.lightgreen,
-            'val' : logger.colors.fg.green,
-            'border' : logger.colors.fg.lightblue,
-
-            'reset' : logger.colors.reset
-        }
-
-        # pre-processing
-        maxlength = 0
-        width = getconsolewidth.get_console_width()
-        for key, val in messages.items():
-            if not (type(val) is bool and val is True):
-                maxlength = max(len(key), maxlength)
-        prewidth = maxlength + len(' | ')
-        groupsize = width - prewidth - len('[+] ')
-
-        # generate stats table
-        logger.info(colors['title'] + 'Onionr v%s Statistics' % onionrvalues.ONIONR_VERSION + colors['reset'], terminal=True)
-        logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-        for key, val in messages.items():
-            if not (type(val) is bool and val is True):
-                val = [str(val)[i:i + groupsize] for i in range(0, len(str(val)), groupsize)]
-
-                logger.info(colors['key'] + str(key).rjust(maxlength) + colors['reset'] + colors['border'] + ' | ' + colors['reset'] + colors['val'] + str(val.pop(0)) + colors['reset'], terminal=True)
-
-                for value in val:
-                    logger.info(' ' * maxlength + colors['border'] + ' | ' + colors['reset'] + colors['val'] + str(value) + colors['reset'], terminal=True)
-            else:
-                logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-        logger.info(colors['border'] + '-' * (maxlength + 1) + '+' + colors['reset'], terminal=True)
-    except Exception as e:
-        logger.error('Failed to generate statistics table. ' + str(e), error = e, timestamp = False, terminal=True)
-
-
-
-
-
-
-
- -
- - - - - \ No newline at end of file diff --git a/docs/html/src/apiservers/index.html b/docs/html/src/apiservers/index.html new file mode 100644 index 00000000..a7288ecb --- /dev/null +++ b/docs/html/src/apiservers/index.html @@ -0,0 +1,88 @@ + + + + + + +src.apiservers API documentation + + + + + + + + + +
+
+
+

Module src.apiservers

+
+
+

Flask WSGI apps for the public and private API servers.

+

Public is net-facing server meant for other nodes +Private is meant for controlling and accessing this node

+
+ +Expand source code + +
"""Flask WSGI apps for the public and private API servers.
+
+Public is net-facing server meant for other nodes
+Private is meant for controlling and accessing this node
+"""
+
+from . import public, private
+
+PublicAPI = public.PublicAPI
+ClientAPI = private.PrivateAPI
+
+
+
+

Sub-modules

+
+
src.apiservers.private
+
+

Onionr - Private P2P Communication …

+
+
src.apiservers.public
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/apiservers/private/index.html b/docs/html/src/apiservers/private/index.html new file mode 100644 index 00000000..cc4ef6ab --- /dev/null +++ b/docs/html/src/apiservers/private/index.html @@ -0,0 +1,411 @@ + + + + + + +src.apiservers.private API documentation + + + + + + + + + +
+
+
+

Module src.apiservers.private

+
+
+

Onionr - Private P2P Communication.

+

This file handles all incoming http requests to the client, using Flask

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This file handles all incoming http requests to the client, using Flask
+"""
+from typing import Dict
+import hmac
+
+import flask
+from gevent.pywsgi import WSGIServer
+
+from onionrutils import epoch
+import httpapi
+from filepaths import private_API_host_file
+import logger
+
+from etc import waitforsetvar
+from . import register_private_blueprints
+import config
+from .. import public
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class PrivateAPI:
+    """Client HTTP api for controlling onionr and using UI."""
+
+    callbacks: Dict[str, Dict] = {'public': {}, 'private': {}}
+
+    def __init__(self):
+        """Initialize the api server, preping variables for later use.
+
+        This initialization defines all of the API entry points
+        and handlers for the endpoints and errors
+        This also saves the used host (random localhost IP address)
+        to the data folder in host.txt
+        """
+        self.config = config
+
+        self.startTime = epoch.get_epoch()
+        app = flask.Flask(__name__)
+        bind_port = int(config.get('client.client.port', 59496))
+        self.bindPort = bind_port
+
+        self.clientToken = config.get('client.webpassword')
+
+        self.host = httpapi.apiutils.setbindip.set_bind_IP(
+            private_API_host_file)
+        logger.info('Running api on %s:%s' % (self.host, self.bindPort))
+        self.httpServer = ''
+
+        self.queueResponse = {}
+        self.get_block_data = httpapi.apiutils.GetBlockData(self)
+        register_private_blueprints.register_private_blueprints(self, app)
+        httpapi.load_plugin_blueprints(app)
+        self.app = app
+
+    def start(self):
+        """Start client gevent API web server with flask client app."""
+        waitforsetvar.wait_for_set_var(self, "_too_many")
+        fd_handler = httpapi.fdsafehandler.FDSafeHandler
+        self.publicAPI = self._too_many.get(  # pylint: disable=E1101
+            public.PublicAPI)
+        self.httpServer = WSGIServer((self.host, self.bindPort),
+                                     self.app, log=None,
+                                     handler_class=fd_handler)
+        self.httpServer.serve_forever()
+
+    def setPublicAPIInstance(self, inst):
+        """Dynamically set public API instance."""
+        self.publicAPI = inst
+
+    def validateToken(self, token):
+        """Validate that the client token matches the given token.
+
+        Used to prevent CSRF and other attacks.
+        """
+        if not self.clientToken:
+            logger.error("client password needs to be set")
+            return False
+        try:
+            return hmac.compare_digest(self.clientToken, token)
+        except TypeError:
+            return False
+
+    def getUptime(self) -> int:
+        """Safely wait for uptime to be set and return it."""
+        while True:
+            try:
+                return epoch.get_epoch() - self.startTime
+            except (AttributeError, NameError):
+                # Don't error on race condition with startup
+                pass
+
+    def getBlockData(self, bHash, decrypt=False, raw=False,
+                     headerOnly=False) -> bytes:
+        """Returns block data bytes."""
+        return self.get_block_data.get_block_data(bHash,
+                                                  decrypt=decrypt,
+                                                  raw=raw,
+                                                  headerOnly=headerOnly)
+
+
+
+

Sub-modules

+
+
src.apiservers.private.register_private_blueprints
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+
+
+

Classes

+
+
+class PrivateAPI +
+
+

Client HTTP api for controlling onionr and using UI.

+

Initialize the api server, preping variables for later use.

+

This initialization defines all of the API entry points +and handlers for the endpoints and errors +This also saves the used host (random localhost IP address) +to the data folder in host.txt

+
+ +Expand source code + +
class PrivateAPI:
+    """Client HTTP api for controlling onionr and using UI."""
+
+    callbacks: Dict[str, Dict] = {'public': {}, 'private': {}}
+
+    def __init__(self):
+        """Initialize the api server, preping variables for later use.
+
+        This initialization defines all of the API entry points
+        and handlers for the endpoints and errors
+        This also saves the used host (random localhost IP address)
+        to the data folder in host.txt
+        """
+        self.config = config
+
+        self.startTime = epoch.get_epoch()
+        app = flask.Flask(__name__)
+        bind_port = int(config.get('client.client.port', 59496))
+        self.bindPort = bind_port
+
+        self.clientToken = config.get('client.webpassword')
+
+        self.host = httpapi.apiutils.setbindip.set_bind_IP(
+            private_API_host_file)
+        logger.info('Running api on %s:%s' % (self.host, self.bindPort))
+        self.httpServer = ''
+
+        self.queueResponse = {}
+        self.get_block_data = httpapi.apiutils.GetBlockData(self)
+        register_private_blueprints.register_private_blueprints(self, app)
+        httpapi.load_plugin_blueprints(app)
+        self.app = app
+
+    def start(self):
+        """Start client gevent API web server with flask client app."""
+        waitforsetvar.wait_for_set_var(self, "_too_many")
+        fd_handler = httpapi.fdsafehandler.FDSafeHandler
+        self.publicAPI = self._too_many.get(  # pylint: disable=E1101
+            public.PublicAPI)
+        self.httpServer = WSGIServer((self.host, self.bindPort),
+                                     self.app, log=None,
+                                     handler_class=fd_handler)
+        self.httpServer.serve_forever()
+
+    def setPublicAPIInstance(self, inst):
+        """Dynamically set public API instance."""
+        self.publicAPI = inst
+
+    def validateToken(self, token):
+        """Validate that the client token matches the given token.
+
+        Used to prevent CSRF and other attacks.
+        """
+        if not self.clientToken:
+            logger.error("client password needs to be set")
+            return False
+        try:
+            return hmac.compare_digest(self.clientToken, token)
+        except TypeError:
+            return False
+
+    def getUptime(self) -> int:
+        """Safely wait for uptime to be set and return it."""
+        while True:
+            try:
+                return epoch.get_epoch() - self.startTime
+            except (AttributeError, NameError):
+                # Don't error on race condition with startup
+                pass
+
+    def getBlockData(self, bHash, decrypt=False, raw=False,
+                     headerOnly=False) -> bytes:
+        """Returns block data bytes."""
+        return self.get_block_data.get_block_data(bHash,
+                                                  decrypt=decrypt,
+                                                  raw=raw,
+                                                  headerOnly=headerOnly)
+
+

Class variables

+
+
var callbacks
+
+

dict() -> new empty dictionary +dict(mapping) -> new dictionary initialized from a mapping object's +(key, value) pairs +dict(iterable) -> new dictionary initialized as if via: +d = {} +for k, v in iterable: +d[k] = v +dict(**kwargs) -> new dictionary initialized with the name=value pairs +in the keyword argument list. +For example: +dict(one=1, two=2)

+
+
+

Methods

+
+
+def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False) +
+
+

Returns block data bytes.

+
+ +Expand source code + +
def getBlockData(self, bHash, decrypt=False, raw=False,
+                 headerOnly=False) -> bytes:
+    """Returns block data bytes."""
+    return self.get_block_data.get_block_data(bHash,
+                                              decrypt=decrypt,
+                                              raw=raw,
+                                              headerOnly=headerOnly)
+
+
+
+def getUptime(self) +
+
+

Safely wait for uptime to be set and return it.

+
+ +Expand source code + +
def getUptime(self) -> int:
+    """Safely wait for uptime to be set and return it."""
+    while True:
+        try:
+            return epoch.get_epoch() - self.startTime
+        except (AttributeError, NameError):
+            # Don't error on race condition with startup
+            pass
+
+
+
+def setPublicAPIInstance(self, inst) +
+
+

Dynamically set public API instance.

+
+ +Expand source code + +
def setPublicAPIInstance(self, inst):
+    """Dynamically set public API instance."""
+    self.publicAPI = inst
+
+
+
+def start(self) +
+
+

Start client gevent API web server with flask client app.

+
+ +Expand source code + +
def start(self):
+    """Start client gevent API web server with flask client app."""
+    waitforsetvar.wait_for_set_var(self, "_too_many")
+    fd_handler = httpapi.fdsafehandler.FDSafeHandler
+    self.publicAPI = self._too_many.get(  # pylint: disable=E1101
+        public.PublicAPI)
+    self.httpServer = WSGIServer((self.host, self.bindPort),
+                                 self.app, log=None,
+                                 handler_class=fd_handler)
+    self.httpServer.serve_forever()
+
+
+
+def validateToken(self, token) +
+
+

Validate that the client token matches the given token.

+

Used to prevent CSRF and other attacks.

+
+ +Expand source code + +
def validateToken(self, token):
+    """Validate that the client token matches the given token.
+
+    Used to prevent CSRF and other attacks.
+    """
+    if not self.clientToken:
+        logger.error("client password needs to be set")
+        return False
+    try:
+        return hmac.compare_digest(self.clientToken, token)
+    except TypeError:
+        return False
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/apiservers/private/register_private_blueprints.html b/docs/html/src/apiservers/private/register_private_blueprints.html similarity index 63% rename from docs/html/onionr/apiservers/private/register_private_blueprints.html rename to docs/html/src/apiservers/private/register_private_blueprints.html index fc08e473..ed32d92b 100644 --- a/docs/html/onionr/apiservers/private/register_private_blueprints.html +++ b/docs/html/src/apiservers/private/register_private_blueprints.html @@ -3,13 +3,13 @@ - -onionr.apiservers.private.register_private_blueprints API documentation + +src.apiservers.private.register_private_blueprints API documentation - + @@ -17,19 +17,30 @@
-

Module onionr.apiservers.private.register_private_blueprints

+

Module src.apiservers.private.register_private_blueprints

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This file registers blueprints for the private api server

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file registers blueprints for the private api server
-'''
-'''
+This file registers blueprints for the private api server
+"""
+from threading import Thread
+from gevent import spawn
+from gevent import sleep
+
+from httpapi import security, friendsapi, profilesapi, configapi, insertblock
+from httpapi import miscclientapi, onionrsitesapi, apiutils
+from httpapi import directconnections
+from httpapi import themeapi
+from httpapi.sse.private import private_sse_blueprint
+
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,22 +53,41 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os
-from httpapi import security, friendsapi, profilesapi, configapi, insertblock, miscclientapi, onionrsitesapi, apiutils
-from httpapi import directconnections
+"""
+
+
 def register_private_blueprints(private_api, app):
-    app.register_blueprint(security.client.ClientAPISecurity(private_api).client_api_security_bp)
+    """Register private API plask blueprints."""
+    app.register_blueprint(security.client.ClientAPISecurity(
+        private_api).client_api_security_bp)
     app.register_blueprint(friendsapi.friends)
     app.register_blueprint(profilesapi.profile_BP)
     app.register_blueprint(configapi.config_BP)
     app.register_blueprint(insertblock.ib)
     app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
-    app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(private_api).private_endpoints_bp)
+    app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(
+        private_api).private_endpoints_bp)
+    app.register_blueprint(miscclientapi.motd.bp)
     app.register_blueprint(onionrsitesapi.site_api)
     app.register_blueprint(apiutils.shutdown.shutdown_bp)
     app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
-    app.register_blueprint(directconnections.DirectConnectionManagement(private_api).direct_conn_management_bp)
+    app.register_blueprint(directconnections.DirectConnectionManagement(
+        private_api).direct_conn_management_bp)
+    app.register_blueprint(themeapi.theme_blueprint)
+    app.register_blueprint(private_sse_blueprint)
+
+    def _add_events_bp():
+        while True:
+            try:
+                private_api._too_many
+                break
+            except AttributeError:
+                sleep(0.2)
+        app.register_blueprint(
+            private_api._too_many.get_by_string('DaemonEventsBP').flask_bp)
+
+    Thread(target=_add_events_bp).start()
+
     return app
@@ -68,25 +98,47 @@ def register_private_blueprints(private_api, app):

Functions

-
+
def register_private_blueprints(private_api, app)
-
+

Register private API plask blueprints.

-Source code + +Expand source code +
def register_private_blueprints(private_api, app):
-    app.register_blueprint(security.client.ClientAPISecurity(private_api).client_api_security_bp)
+    """Register private API plask blueprints."""
+    app.register_blueprint(security.client.ClientAPISecurity(
+        private_api).client_api_security_bp)
     app.register_blueprint(friendsapi.friends)
     app.register_blueprint(profilesapi.profile_BP)
     app.register_blueprint(configapi.config_BP)
     app.register_blueprint(insertblock.ib)
     app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
-    app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(private_api).private_endpoints_bp)
+    app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(
+        private_api).private_endpoints_bp)
+    app.register_blueprint(miscclientapi.motd.bp)
     app.register_blueprint(onionrsitesapi.site_api)
     app.register_blueprint(apiutils.shutdown.shutdown_bp)
     app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
-    app.register_blueprint(directconnections.DirectConnectionManagement(private_api).direct_conn_management_bp)
+    app.register_blueprint(directconnections.DirectConnectionManagement(
+        private_api).direct_conn_management_bp)
+    app.register_blueprint(themeapi.theme_blueprint)
+    app.register_blueprint(private_sse_blueprint)
+
+    def _add_events_bp():
+        while True:
+            try:
+                private_api._too_many
+                break
+            except AttributeError:
+                sleep(0.2)
+        app.register_blueprint(
+            private_api._too_many.get_by_string('DaemonEventsBP').flask_bp)
+
+    Thread(target=_add_events_bp).start()
+
     return app
@@ -103,19 +155,19 @@ def register_private_blueprints(private_api, app):
diff --git a/docs/html/onionr/apiservers/public/index.html b/docs/html/src/apiservers/public/index.html similarity index 63% rename from docs/html/onionr/apiservers/public/index.html rename to docs/html/src/apiservers/public/index.html index 8148baf4..df9046f7 100644 --- a/docs/html/onionr/apiservers/public/index.html +++ b/docs/html/src/apiservers/public/index.html @@ -3,13 +3,13 @@ - -onionr.apiservers.public API documentation + +src.apiservers.public API documentation - + @@ -17,19 +17,32 @@
-

Module onionr.apiservers.public

+

Module src.apiservers.public

-

Onionr - Private P2P Communication

-

This file handles all incoming http requests to the public api server, using Flask

+

Onionr - Private P2P Communication.

+

This file handles all incoming http requests +to the public api server, using Flask

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file handles all incoming http requests to the public api server, using Flask
-'''
-'''
+This file handles all incoming http requests
+to the public api server, using Flask
+"""
+import time
+import threading
+import flask
+from gevent.pywsgi import WSGIServer
+from httpapi import apiutils, security, fdsafehandler, miscpublicapi
+import logger
+import config
+import filepaths
+from utils import gettransports
+from etc import onionrvalues, waitforsetvar
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,15 +55,8 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import time
-import threading
-import flask
-from gevent.pywsgi import WSGIServer
-from httpapi import apiutils, security, fdsafehandler, miscpublicapi
-import logger, config, filepaths
-from utils import gettransports
-from etc import onionrvalues, waitforsetvar
+"""
+
 
 def _get_tor_adder(pub_api):
     transports = []
@@ -59,34 +65,43 @@ def _get_tor_adder(pub_api):
         time.sleep(0.3)
     pub_api.torAdder = transports[0]
 
+
 class PublicAPI:
-    '''
-        The new client api server, isolated from the public api
-    '''
+    """The new client api server, isolated from the public api."""
+
     def __init__(self):
+        """Setup the public api app."""
         app = flask.Flask('PublicAPI')
         app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
         self.i2pEnabled = config.get('i2p.host', False)
-        self.hideBlocks = [] # Blocks to be denied sharing
-        self.host = apiutils.setbindip.set_bind_IP(filepaths.public_API_host_file)
+        self.hideBlocks = []  # Blocks to be denied sharing
+        self.host = apiutils.setbindip.set_bind_IP(
+            filepaths.public_API_host_file)
 
-        threading.Thread(target=_get_tor_adder, args=[self], daemon=True).start()
+        threading.Thread(target=_get_tor_adder,
+                         args=[self], daemon=True).start()
 
         self.torAdder = ""
         self.bindPort = config.get('client.public.port')
         self.lastRequest = 0
-        self.hitCount = 0 # total rec requests to public api since server started
+        # total rec requests to public api since server started
+        self.hitCount = 0
         self.config = config
         self.API_VERSION = onionrvalues.API_VERSION
         logger.info('Running public api on %s:%s' % (self.host, self.bindPort))
 
-        app.register_blueprint(security.public.PublicAPISecurity(self).public_api_security_bp)
-        app.register_blueprint(miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp)
+        app.register_blueprint(
+            security.public.PublicAPISecurity(self).public_api_security_bp)
+        app.register_blueprint(
+            miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp)
         self.app = app
 
     def start(self):
+        """Start the Public API server."""
         waitforsetvar.wait_for_set_var(self, "_too_many")
-        self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=fdsafehandler.FDSafeHandler)
+        self.httpServer = WSGIServer((self.host, self.bindPort),
+                                     self.app, log=None,
+                                     handler_class=fdsafehandler.FDSafeHandler)
         self.httpServer.serve_forever()
@@ -99,55 +114,71 @@ class PublicAPI:

Classes

-
+
class PublicAPI
-

The new client api server, isolated from the public api

+

The new client api server, isolated from the public api.

+

Setup the public api app.

-Source code + +Expand source code +
class PublicAPI:
-    '''
-        The new client api server, isolated from the public api
-    '''
+    """The new client api server, isolated from the public api."""
+
     def __init__(self):
+        """Setup the public api app."""
         app = flask.Flask('PublicAPI')
         app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
         self.i2pEnabled = config.get('i2p.host', False)
-        self.hideBlocks = [] # Blocks to be denied sharing
-        self.host = apiutils.setbindip.set_bind_IP(filepaths.public_API_host_file)
+        self.hideBlocks = []  # Blocks to be denied sharing
+        self.host = apiutils.setbindip.set_bind_IP(
+            filepaths.public_API_host_file)
 
-        threading.Thread(target=_get_tor_adder, args=[self], daemon=True).start()
+        threading.Thread(target=_get_tor_adder,
+                         args=[self], daemon=True).start()
 
         self.torAdder = ""
         self.bindPort = config.get('client.public.port')
         self.lastRequest = 0
-        self.hitCount = 0 # total rec requests to public api since server started
+        # total rec requests to public api since server started
+        self.hitCount = 0
         self.config = config
         self.API_VERSION = onionrvalues.API_VERSION
         logger.info('Running public api on %s:%s' % (self.host, self.bindPort))
 
-        app.register_blueprint(security.public.PublicAPISecurity(self).public_api_security_bp)
-        app.register_blueprint(miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp)
+        app.register_blueprint(
+            security.public.PublicAPISecurity(self).public_api_security_bp)
+        app.register_blueprint(
+            miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp)
         self.app = app
 
     def start(self):
+        """Start the Public API server."""
         waitforsetvar.wait_for_set_var(self, "_too_many")
-        self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=fdsafehandler.FDSafeHandler)
+        self.httpServer = WSGIServer((self.host, self.bindPort),
+                                     self.app, log=None,
+                                     handler_class=fdsafehandler.FDSafeHandler)
         self.httpServer.serve_forever()

Methods

-
+
def start(self)
-
+

Start the Public API server.

-Source code + +Expand source code +
def start(self):
+    """Start the Public API server."""
     waitforsetvar.wait_for_set_var(self, "_too_many")
-    self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=fdsafehandler.FDSafeHandler)
+    self.httpServer = WSGIServer((self.host, self.bindPort),
+                                 self.app, log=None,
+                                 handler_class=fdsafehandler.FDSafeHandler)
     self.httpServer.serve_forever()
@@ -164,15 +195,15 @@ class PublicAPI:
diff --git a/docs/html/src/bigbrother/index.html b/docs/html/src/bigbrother/index.html new file mode 100644 index 00000000..44586f09 --- /dev/null +++ b/docs/html/src/bigbrother/index.html @@ -0,0 +1,166 @@ + + + + + + +src.bigbrother API documentation + + + + + + + + + +
+
+
+

Module src.bigbrother

+
+
+

Onionr - Private P2P Communication.

+

Processes interpreter hook events to detect security leaks

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Processes interpreter hook events to detect security leaks
+"""
+import sys
+from typing import Iterable
+
+from onionrexceptions import PythonVersion
+from . import ministry
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def _auditing_supported():
+    try:
+        sys.audit
+        sys.addaudithook
+    except AttributeError:
+        raise PythonVersion('Auditing not supported interpreter')
+
+
+def sys_hook_entrypoint(event, info):
+    """Entrypoint for big brother sys auditors."""
+    if event == 'socket.connect':
+        ministry.ofcommunication.detect_socket_leaks(info)
+    elif event == 'exec':
+        # logs and block both exec and eval
+        ministry.ofexec.block_exec(event, info)
+    elif event == 'system':
+        ministry.ofexec.block_system(info)
+
+
+def enable_ministries(disable_hooks: Iterable = None):
+    """Enable auditors."""
+    disable_hooks = disable_hooks or []
+    _auditing_supported()  # raises PythonVersion exception if <3.8
+    sys.addaudithook(sys_hook_entrypoint)
+
+
+
+

Sub-modules

+
+
src.bigbrother.ministry
+
+
+
+
+
+
+
+
+

Functions

+
+
+def enable_ministries(disable_hooks=None) +
+
+

Enable auditors.

+
+ +Expand source code + +
def enable_ministries(disable_hooks: Iterable = None):
+    """Enable auditors."""
+    disable_hooks = disable_hooks or []
+    _auditing_supported()  # raises PythonVersion exception if <3.8
+    sys.addaudithook(sys_hook_entrypoint)
+
+
+
+def sys_hook_entrypoint(event, info) +
+
+

Entrypoint for big brother sys auditors.

+
+ +Expand source code + +
def sys_hook_entrypoint(event, info):
+    """Entrypoint for big brother sys auditors."""
+    if event == 'socket.connect':
+        ministry.ofcommunication.detect_socket_leaks(info)
+    elif event == 'exec':
+        # logs and block both exec and eval
+        ministry.ofexec.block_exec(event, info)
+    elif event == 'system':
+        ministry.ofexec.block_system(info)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/bigbrother/ministry/index.html b/docs/html/src/bigbrother/ministry/index.html new file mode 100644 index 00000000..f0abed47 --- /dev/null +++ b/docs/html/src/bigbrother/ministry/index.html @@ -0,0 +1,77 @@ + + + + + + +src.bigbrother.ministry API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/bigbrother/ministry/ofcommunication.html b/docs/html/src/bigbrother/ministry/ofcommunication.html new file mode 100644 index 00000000..22540253 --- /dev/null +++ b/docs/html/src/bigbrother/ministry/ofcommunication.html @@ -0,0 +1,149 @@ + + + + + + +src.bigbrother.ministry.ofcommunication API documentation + + + + + + + + + +
+
+
+

Module src.bigbrother.ministry.ofcommunication

+
+
+

Onionr - Private P2P Communication.

+

Ensure sockets don't get made to non localhost

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Ensure sockets don't get made to non localhost
+"""
+import ipaddress
+
+import logger
+from onionrexceptions import NetworkLeak
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def detect_socket_leaks(socket_event):
+    """Is called by the big brother broker whenever.
+
+    a socket connection happens.
+    raises exception & logs if not to loopback
+    """
+    ip_address = socket_event[1][0]
+
+    # validate is valid ip address (no hostname, etc)
+    # raises NetworkLeak if not
+    try:
+        ipaddress.ip_address(ip_address)
+    except ValueError:
+        logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
+        raise \
+            NetworkLeak('Conn to host/non local IP, this is a privacy issue!')
+
+    # Validate that the IP is localhost ipv4
+
+    if not ip_address.startswith('127'):
+        logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
+        raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
+
+
+
+
+
+
+
+

Functions

+
+
+def detect_socket_leaks(socket_event) +
+
+

Is called by the big brother broker whenever.

+

a socket connection happens. +raises exception & logs if not to loopback

+
+ +Expand source code + +
def detect_socket_leaks(socket_event):
+    """Is called by the big brother broker whenever.
+
+    a socket connection happens.
+    raises exception & logs if not to loopback
+    """
+    ip_address = socket_event[1][0]
+
+    # validate is valid ip address (no hostname, etc)
+    # raises NetworkLeak if not
+    try:
+        ipaddress.ip_address(ip_address)
+    except ValueError:
+        logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
+        raise \
+            NetworkLeak('Conn to host/non local IP, this is a privacy issue!')
+
+    # Validate that the IP is localhost ipv4
+
+    if not ip_address.startswith('127'):
+        logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
+        raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/bigbrother/ministry/ofexec.html b/docs/html/src/bigbrother/ministry/ofexec.html new file mode 100644 index 00000000..933e3915 --- /dev/null +++ b/docs/html/src/bigbrother/ministry/ofexec.html @@ -0,0 +1,227 @@ + + + + + + +src.bigbrother.ministry.ofexec API documentation + + + + + + + + + +
+
+
+

Module src.bigbrother.ministry.ofexec

+
+
+

Onionr - Private P2P Communication.

+

Prevent eval/exec/os.system and log it

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Prevent eval/exec/os.system and log it
+"""
+import base64
+import platform
+
+import logger
+from utils import identifyhome
+from onionrexceptions import ArbitraryCodeExec
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def block_system(cmd):
+    """Prevent os.system except for whitelisted commands+contexts."""
+    allowed = 'taskkill /PID '
+    is_ok = False
+    if platform.system() == 'Windows':
+        if cmd.startswith(allowed):
+            for c in cmd.split(allowed)[1]:
+                if not c.isalnum() or c not in ('/', 'F', ' '):
+                    break
+            else:
+                is_ok = True
+    if not is_ok:
+        logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
+        logger.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
+        raise ArbitraryCodeExec('os.system command not in whitelist')
+
+
+def block_exec(event, info):
+    """Prevent arbitrary code execution in eval/exec and log it."""
+    # because libraries have stupid amounts of compile/exec/eval,
+    # We have to use a whitelist where it can be tolerated
+    # Generally better than nothing, not a silver bullet
+    whitelisted_code = [
+                        'netrc.py',
+                        'shlex.py',
+                        'gzip.py',
+                        '<werkzeug routing>',
+                        'werkzeug/test.py',
+                        'multiprocessing/popen_fork.py',
+                        'multiprocessing/util.py',
+                        'multiprocessing/connection.py',
+                        'onionrutils/escapeansi.py',
+                        'stem/connection.py',
+                        'stem/response/add_onion.py',
+                        'stem/response/authchallenge.py',
+                        'stem/response/getinfo.py',
+                        'stem/response/getconf.py',
+                        'stem/response/mapaddress.py',
+                        'stem/response/protocolinfo.py'
+                       ]
+    home = identifyhome.identify_home()
+
+    code_b64 = base64.b64encode(info[0].co_code).decode()
+
+    for source in whitelisted_code:
+        if info[0].co_filename.endswith(source):
+            return
+
+    if home + 'plugins/' in info[0].co_filename:
+        return
+
+    logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
+    logger.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
+    logger.warn('Prevented exec/eval. Report this with the sample below')
+    logger.warn(f'{event} code in base64 format: {code_b64}')
+    raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
+
+
+
+
+
+
+
+

Functions

+
+
+def block_exec(event, info) +
+
+

Prevent arbitrary code execution in eval/exec and log it.

+
+ +Expand source code + +
def block_exec(event, info):
+    """Prevent arbitrary code execution in eval/exec and log it."""
+    # because libraries have stupid amounts of compile/exec/eval,
+    # We have to use a whitelist where it can be tolerated
+    # Generally better than nothing, not a silver bullet
+    whitelisted_code = [
+                        'netrc.py',
+                        'shlex.py',
+                        'gzip.py',
+                        '<werkzeug routing>',
+                        'werkzeug/test.py',
+                        'multiprocessing/popen_fork.py',
+                        'multiprocessing/util.py',
+                        'multiprocessing/connection.py',
+                        'onionrutils/escapeansi.py',
+                        'stem/connection.py',
+                        'stem/response/add_onion.py',
+                        'stem/response/authchallenge.py',
+                        'stem/response/getinfo.py',
+                        'stem/response/getconf.py',
+                        'stem/response/mapaddress.py',
+                        'stem/response/protocolinfo.py'
+                       ]
+    home = identifyhome.identify_home()
+
+    code_b64 = base64.b64encode(info[0].co_code).decode()
+
+    for source in whitelisted_code:
+        if info[0].co_filename.endswith(source):
+            return
+
+    if home + 'plugins/' in info[0].co_filename:
+        return
+
+    logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
+    logger.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
+    logger.warn('Prevented exec/eval. Report this with the sample below')
+    logger.warn(f'{event} code in base64 format: {code_b64}')
+    raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
+
+
+
+def block_system(cmd) +
+
+

Prevent os.system except for whitelisted commands+contexts.

+
+ +Expand source code + +
def block_system(cmd):
+    """Prevent os.system except for whitelisted commands+contexts."""
+    allowed = 'taskkill /PID '
+    is_ok = False
+    if platform.system() == 'Windows':
+        if cmd.startswith(allowed):
+            for c in cmd.split(allowed)[1]:
+                if not c.isalnum() or c not in ('/', 'F', ' '):
+                    break
+            else:
+                is_ok = True
+    if not is_ok:
+        logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
+        logger.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
+        raise ArbitraryCodeExec('os.system command not in whitelist')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/communicator/bootstrappeers.html b/docs/html/src/communicator/bootstrappeers.html similarity index 69% rename from docs/html/onionr/communicator/bootstrappeers.html rename to docs/html/src/communicator/bootstrappeers.html index de2d8d74..c1e7cf93 100644 --- a/docs/html/onionr/communicator/bootstrappeers.html +++ b/docs/html/src/communicator/bootstrappeers.html @@ -3,13 +3,13 @@ - -onionr.communicator.bootstrappeers API documentation + +src.communicator.bootstrappeers API documentation - + @@ -17,19 +17,22 @@
-

Module onionr.communicator.bootstrappeers

+

Module src.communicator.bootstrappeers

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

add bootstrap peers to the communicator peer list

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    add bootstrap peers to the communicator peer list
-'''
-'''
+add bootstrap peers to the communicator peer list
+"""
+from utils import readstatic, gettransports
+from coredb import keydb
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,17 +45,18 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from utils import readstatic, gettransports
-from coredb import keydb
+"""
+
 bootstrap_peers = readstatic.read_static('bootstrap-nodes.txt').split(',')
-def add_bootstrap_list_to_peer_list(comm_inst, peerList):
-    '''
-        Add the bootstrap list to the peer list (no duplicates)
-    '''
+
+
+def add_bootstrap_list_to_peer_list(comm_inst, peerList, db_only=False):
+    """Add the bootstrap list to the peer list (no duplicates)."""
     for i in bootstrap_peers:
-        if i not in peerList and i not in comm_inst.offlinePeers and not i in gettransports.get() and len(str(i).strip()) > 0:
-            peerList.append(i)
+        if i not in peerList and i not in comm_inst.offlinePeers \
+                and i not in gettransports.get() and len(str(i).strip()) > 0:
+            if not db_only:
+                peerList.append(i)
             keydb.addkeys.add_address(i)
@@ -63,20 +67,22 @@ def add_bootstrap_list_to_peer_list(comm_inst, peerList):

Functions

-
-def add_bootstrap_list_to_peer_list(comm_inst, peerList) +
+def add_bootstrap_list_to_peer_list(comm_inst, peerList, db_only=False)
-

Add the bootstrap list to the peer list (no duplicates)

+

Add the bootstrap list to the peer list (no duplicates).

-Source code -
def add_bootstrap_list_to_peer_list(comm_inst, peerList):
-    '''
-        Add the bootstrap list to the peer list (no duplicates)
-    '''
+
+Expand source code
+
+
def add_bootstrap_list_to_peer_list(comm_inst, peerList, db_only=False):
+    """Add the bootstrap list to the peer list (no duplicates)."""
     for i in bootstrap_peers:
-        if i not in peerList and i not in comm_inst.offlinePeers and not i in gettransports.get() and len(str(i).strip()) > 0:
-            peerList.append(i)
+        if i not in peerList and i not in comm_inst.offlinePeers \
+                and i not in gettransports.get() and len(str(i).strip()) > 0:
+            if not db_only:
+                peerList.append(i)
             keydb.addkeys.add_address(i)
@@ -93,19 +99,19 @@ def add_bootstrap_list_to_peer_list(comm_inst, peerList):
diff --git a/docs/html/src/communicator/daemoneventhooks/index.html b/docs/html/src/communicator/daemoneventhooks/index.html new file mode 100644 index 00000000..0c105683 --- /dev/null +++ b/docs/html/src/communicator/daemoneventhooks/index.html @@ -0,0 +1,210 @@ + + + + + + +src.communicator.daemoneventhooks API documentation + + + + + + + + + +
+
+
+

Module src.communicator.daemoneventhooks

+
+
+

Onionr - Private P2P Communication.

+

Hooks to handle daemon events

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Hooks to handle daemon events
+"""
+from threading import Thread
+
+from .removefrominsertqueue import remove_from_insert_queue
+
+from typing import TYPE_CHECKING
+
+from gevent import sleep
+
+from communicatorutils.uploadblocks import mixmate
+from communicatorutils import restarttor
+
+if TYPE_CHECKING:
+    from toomanyobjs import TooMany
+    from communicator import OnionrCommunicatorDaemon
+    from httpapi.daemoneventsapi import DaemonEventsBP
+    from onionrtypes import BlockHash
+    from apiservers import PublicAPI
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def daemon_event_handlers(shared_state: 'TooMany'):
+    def _get_inst(class_name: str):
+        while True:
+            try:
+                return shared_state.get_by_string(class_name)
+            except KeyError:
+                sleep(0.2)
+    comm_inst = _get_inst('OnionrCommunicatorDaemon')
+    public_api: 'PublicAPI' = _get_inst('PublicAPI')
+    events_api: 'DaemonEventsBP' = _get_inst('DaemonEventsBP')
+
+    def remove_from_insert_queue_wrapper(block_hash: 'BlockHash'):
+        remove_from_insert_queue(comm_inst, block_hash)
+        return "removed"
+
+    def print_test(text=''):
+        print("It works!", text)
+        return f"It works! {text}"
+
+    def upload_event(block: 'BlockHash' = ''):
+        if not block:
+            raise ValueError
+        public_api.hideBlocks.append(block)
+        try:
+            mixmate.block_mixer(comm_inst.blocksToUpload, block)
+        except ValueError:
+            pass
+        return "removed"
+
+    def restart_tor():
+        restarttor.restart(comm_inst)
+        comm_inst.offlinePeers = []
+
+    def test_runtime():
+        Thread(target=comm_inst.shared_state.get_by_string(
+            "OnionrRunTestManager").run_tests).start()
+
+    events_api.register_listener(remove_from_insert_queue_wrapper)
+    events_api.register_listener(print_test)
+    events_api.register_listener(upload_event)
+    events_api.register_listener(test_runtime)
+
+
+
+

Sub-modules

+
+
src.communicator.daemoneventhooks.removefrominsertqueue
+
+

Onionr - P2P Anonymous Storage Network …

+
+
+
+
+
+
+

Functions

+
+
+def daemon_event_handlers(shared_state) +
+
+
+
+ +Expand source code + +
def daemon_event_handlers(shared_state: 'TooMany'):
+    def _get_inst(class_name: str):
+        while True:
+            try:
+                return shared_state.get_by_string(class_name)
+            except KeyError:
+                sleep(0.2)
+    comm_inst = _get_inst('OnionrCommunicatorDaemon')
+    public_api: 'PublicAPI' = _get_inst('PublicAPI')
+    events_api: 'DaemonEventsBP' = _get_inst('DaemonEventsBP')
+
+    def remove_from_insert_queue_wrapper(block_hash: 'BlockHash'):
+        remove_from_insert_queue(comm_inst, block_hash)
+        return "removed"
+
+    def print_test(text=''):
+        print("It works!", text)
+        return f"It works! {text}"
+
+    def upload_event(block: 'BlockHash' = ''):
+        if not block:
+            raise ValueError
+        public_api.hideBlocks.append(block)
+        try:
+            mixmate.block_mixer(comm_inst.blocksToUpload, block)
+        except ValueError:
+            pass
+        return "removed"
+
+    def restart_tor():
+        restarttor.restart(comm_inst)
+        comm_inst.offlinePeers = []
+
+    def test_runtime():
+        Thread(target=comm_inst.shared_state.get_by_string(
+            "OnionrRunTestManager").run_tests).start()
+
+    events_api.register_listener(remove_from_insert_queue_wrapper)
+    events_api.register_listener(print_test)
+    events_api.register_listener(upload_event)
+    events_api.register_listener(test_runtime)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/communicator/daemoneventhooks/removefrominsertqueue.html b/docs/html/src/communicator/daemoneventhooks/removefrominsertqueue.html new file mode 100644 index 00000000..11e8f70d --- /dev/null +++ b/docs/html/src/communicator/daemoneventhooks/removefrominsertqueue.html @@ -0,0 +1,117 @@ + + + + + + +src.communicator.daemoneventhooks.removefrominsertqueue API documentation + + + + + + + + + +
+
+
+

Module src.communicator.daemoneventhooks.removefrominsertqueue

+
+
+

Onionr - P2P Anonymous Storage Network.

+

Remove block hash from daemon's upload list.

+
+ +Expand source code + +
"""Onionr - P2P Anonymous Storage Network.
+
+Remove block hash from daemon's upload list.
+"""
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
+    from onionrtypes import BlockHash
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def remove_from_insert_queue(comm_inst: "OnionrCommunicatorDaemon",
+                             b_hash: "BlockHash"):
+    """Remove block hash from daemon's upload list."""
+    try:
+        comm_inst.generating_blocks.remove(b_hash)
+    except ValueError:
+        pass
+
+
+
+
+
+
+
+

Functions

+
+
+def remove_from_insert_queue(comm_inst, b_hash) +
+
+

Remove block hash from daemon's upload list.

+
+ +Expand source code + +
def remove_from_insert_queue(comm_inst: "OnionrCommunicatorDaemon",
+                             b_hash: "BlockHash"):
+    """Remove block hash from daemon's upload list."""
+    try:
+        comm_inst.generating_blocks.remove(b_hash)
+    except ValueError:
+        pass
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/communicator/index.html b/docs/html/src/communicator/index.html new file mode 100644 index 00000000..111010db --- /dev/null +++ b/docs/html/src/communicator/index.html @@ -0,0 +1,866 @@ + + + + + + +src.communicator API documentation + + + + + + + + + +
+
+
+

Module src.communicator

+
+
+

Onionr - Private P2P Communication.

+

This file contains both the OnionrCommunicate class for +communcating with peers and code to operate as a daemon, +getting commands from the command queue database +(see core.Core.daemonQueue)

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This file contains both the OnionrCommunicate class for
+communcating with peers and code to operate as a daemon,
+getting commands from the command queue database
+(see core.Core.daemonQueue)
+"""
+import os
+import time
+
+import config
+import logger
+import onionrpeers
+import onionrplugins as plugins
+from . import onlinepeers, uploadqueue
+from communicatorutils import servicecreator
+from communicatorutils import onionrcommunicatortimers
+from communicatorutils import downloadblocks
+from communicatorutils import lookupblocks
+from communicatorutils import lookupadders
+from communicatorutils import connectnewpeers
+from communicatorutils import uploadblocks
+from communicatorutils import announcenode, deniableinserts
+from communicatorutils import cooldownpeer
+from communicatorutils import housekeeping
+from communicatorutils import netcheck
+from onionrutils import localcommand
+from onionrutils import epoch
+from etc import humanreadabletime
+import onionrservices
+import filepaths
+from onionrblocks import storagecounter
+from coredb import dbfiles
+from netcontroller import NetController
+from . import bootstrappeers
+from . import daemoneventhooks
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
+
+config.reload()
+
+
+class OnionrCommunicatorDaemon:
+    def __init__(self, shared_state, developmentMode=None):
+        if developmentMode is None:
+            developmentMode = config.get('general.dev_mode', False)
+
+        # configure logger and stuff
+        self.config = config
+        self.storage_counter = storagecounter.StorageCounter()
+        self.isOnline = True  # Assume we're connected to the internet
+        self.shared_state = shared_state  # TooManyObjects module
+
+        if config.get('general.offline_mode', False):
+            self.isOnline = False
+
+        # list of timer instances
+        self.timers = []
+
+        # initialize core with Tor socks port being 3rd argument
+        self.proxyPort = shared_state.get(NetController).socksPort
+
+        # Upload information, list of blocks to upload
+        self.blocksToUpload = []
+        self.upload_session_manager = self.shared_state.get(
+            uploadblocks.sessionmanager.BlockUploadSessionManager)
+        self.shared_state.share_object()
+
+        # loop time.sleep delay in seconds
+        self.delay = 1
+
+        # lists of connected peers and peers we know we can't reach currently
+        self.onlinePeers = []
+        self.offlinePeers = []
+        self.cooldownPeer = {}
+        self.connectTimes = {}
+        # list of peer's profiles (onionrpeers.PeerProfile instances)
+        self.peerProfiles = []
+        # Peers merged to us. Don't add to db until we know they're reachable
+        self.newPeers = []
+        self.announceProgress = {}
+        self.announceCache = {}
+
+        self.generating_blocks = []
+
+        # amount of threads running by name, used to prevent too many
+        self.threadCounts = {}
+
+        # set true when shutdown command received
+        self.shutdown = False
+
+        # list of new blocks to download
+        # added to when new block lists are fetched from peers
+        self.blockQueue = {}
+
+        # list of blocks currently downloading, avoid s
+        self.currentDownloading = []
+
+        # timestamp when the last online node was seen
+        self.lastNodeSeen = None
+
+        # Dict of time stamps for peer's block list lookup times,
+        # to avoid downloading full lists all the time
+        self.dbTimestamps = {}
+
+        # Loads in and starts the enabled plugins
+        plugins.reload()
+
+        # time app started running for info/statistics purposes
+        self.startTime = epoch.get_epoch()
+
+        # extends our upload list and saves our list when Onionr exits
+        uploadqueue.UploadQueue(self)
+
+        if developmentMode:
+            OnionrCommunicatorTimers(self, self.heartbeat, 30)
+
+        # Set timers, function reference, seconds
+        # requires_peer True means the timer function won't fire if we
+        # have no connected peers
+        peerPoolTimer = OnionrCommunicatorTimers(
+            self, onlinepeers.get_online_peers, 60, max_threads=1,
+            my_args=[self])
+
+        # Timers to periodically lookup new blocks and download them
+        lookup_blocks_timer = OnionrCommunicatorTimers(
+            self,
+            lookupblocks.lookup_blocks_from_communicator,
+            config.get('timers.lookupBlocks', 25),
+            my_args=[self], requires_peer=True, max_threads=1)
+
+        """The block download timer is accessed by the block lookup function
+        to trigger faster download starts"""
+        self.download_blocks_timer = OnionrCommunicatorTimers(
+            self, self.getBlocks, config.get('timers.getBlocks', 10),
+            requires_peer=True, max_threads=5)
+
+        # Timer to reset the longest offline peer
+        # so contact can be attempted again
+        OnionrCommunicatorTimers(
+            self, onlinepeers.clear_offline_peer, 58, my_args=[self])
+
+        # Timer to cleanup old blocks
+        blockCleanupTimer = OnionrCommunicatorTimers(
+            self, housekeeping.clean_old_blocks, 20, my_args=[self])
+
+        # Timer to discover new peers
+        OnionrCommunicatorTimers(
+            self, lookupadders.lookup_new_peer_transports_with_communicator,
+            60, requires_peer=True, my_args=[self], max_threads=2)
+
+        # Timer for adjusting which peers
+        # we actively communicate to at any given time,
+        # to avoid over-using peers
+        OnionrCommunicatorTimers(
+            self, cooldownpeer.cooldown_peer, 30,
+            my_args=[self], requires_peer=True)
+
+        # Timer to read the upload queue and upload the entries to peers
+        OnionrCommunicatorTimers(
+            self, uploadblocks.upload_blocks_from_communicator,
+            5, my_args=[self], requires_peer=True, max_threads=1)
+
+        # Setup direct connections
+        if config.get('general.socket_servers', False):
+            self.services = onionrservices.OnionrServices()
+            self.active_services = []
+            self.service_greenlets = []
+            OnionrCommunicatorTimers(
+                self, servicecreator.service_creator, 5,
+                max_threads=50, my_args=[self])
+        else:
+            self.services = None
+
+        # {peer_pubkey: ephemeral_address}, the address to reach them
+        self.direct_connection_clients = {}
+
+        # This timer creates deniable blocks,
+        # in an attempt to further obfuscate block insertion metadata
+        if config.get('general.insert_deniable_blocks', True):
+            deniableBlockTimer = OnionrCommunicatorTimers(
+                self, deniableinserts.insert_deniable_block,
+                180, my_args=[self], requires_peer=True, max_threads=1)
+            deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
+
+        # Timer to check for connectivity,
+        # through Tor to various high-profile onion services
+        OnionrCommunicatorTimers(self, netcheck.net_check, 500,
+                                 my_args=[self], max_threads=1)
+
+        # Announce the public API server transport address
+        # to other nodes if security level allows
+        if config.get('general.security_level', 1) == 0 \
+                and config.get('general.announce_node', True):
+            # Default to high security level incase config breaks
+            announceTimer = OnionrCommunicatorTimers(
+                self,
+                announcenode.announce_node,
+                3600, my_args=[self], requires_peer=True, max_threads=1)
+            announceTimer.count = (announceTimer.frequency - 60)
+        else:
+            logger.debug('Will not announce node.')
+
+        # Timer to delete malfunctioning or long-dead peers
+        cleanupTimer = OnionrCommunicatorTimers(
+            self, self.peerCleanup, 300, requires_peer=True)
+
+        # Timer to cleanup dead ephemeral forward secrecy keys
+        OnionrCommunicatorTimers(
+            self, housekeeping.clean_keys, 15, my_args=[self], max_threads=1)
+
+        # Adjust initial timer triggers
+        peerPoolTimer.count = (peerPoolTimer.frequency - 1)
+        cleanupTimer.count = (cleanupTimer.frequency - 60)
+        blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
+        lookup_blocks_timer = (lookup_blocks_timer.frequency - 2)
+
+        shared_state.add(self)
+
+        if config.get('general.use_bootstrap_list', True):
+            bootstrappeers.add_bootstrap_list_to_peer_list(
+                self, [], db_only=True)
+
+        daemoneventhooks.daemon_event_handlers(shared_state)
+
+        if not config.get('onboarding.done', True):
+            logger.info(
+                'First run detected. Run openhome to get setup.',
+                terminal=True)
+
+            while not config.get('onboarding.done', True):
+                time.sleep(5)
+
+        # Main daemon loop, mainly for calling timers,
+        # don't do any complex operations here to avoid locking
+        try:
+            while not self.shutdown:
+                for i in self.timers:
+                    if self.shutdown:
+                        break
+                    i.processTimer()
+                time.sleep(self.delay)
+        except KeyboardInterrupt:
+            self.shutdown = True
+
+        logger.info(
+            'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
+        try:
+            self.service_greenlets
+        except AttributeError:
+            pass
+        else:
+            # Stop onionr direct connection services
+            for server in self.service_greenlets:
+                server.stop()
+        try:
+            time.sleep(0.5)
+        except KeyboardInterrupt:
+            pass
+
+    def getBlocks(self):
+        """Download new blocks in queue."""
+        downloadblocks.download_blocks_from_communicator(self)
+
+    def decrementThreadCount(self, threadName):
+        """Decrement amount of a thread name if more than zero.
+
+        called when a function meant to be run in a thread ends
+        """
+        try:
+            if self.threadCounts[threadName] > 0:
+                self.threadCounts[threadName] -= 1
+        except KeyError:
+            pass
+
+    def connectNewPeer(self, peer='', useBootstrap=False):
+        """Adds a new random online peer to self.onlinePeers"""
+        connectnewpeers.connect_new_peer_to_communicator(
+            self, peer, useBootstrap)
+
+    def peerCleanup(self):
+        """This just calls onionrpeers.cleanupPeers.
+
+        Remove dead or bad peers (offline too long, too slow)"""
+        onionrpeers.peer_cleanup()
+        self.decrementThreadCount('peerCleanup')
+
+    def getPeerProfileInstance(self, peer):
+        """Gets a peer profile instance from the list of profiles"""
+        for i in self.peerProfiles:
+            # if the peer's profile is already loaded, return that
+            if i.address == peer:
+                retData = i
+                break
+        else:
+            # if the peer's profile is not loaded, return a new one.
+            # connectNewPeer also adds it to the list on connect
+            retData = onionrpeers.PeerProfiles(peer)
+            self.peerProfiles.append(retData)
+        return retData
+
+    def getUptime(self):
+        return epoch.get_epoch() - self.startTime
+
+    def heartbeat(self):
+        """Show a heartbeat debug message."""
+        logger.debug('Heartbeat. Node running for %s.' %
+                     humanreadabletime.human_readable_time(self.getUptime()))
+        self.decrementThreadCount('heartbeat')
+
+
+def startCommunicator(shared_state):
+    OnionrCommunicatorDaemon(shared_state)
+
+
+
+

Sub-modules

+
+
src.communicator.bootstrappeers
+
+

Onionr - Private P2P Communication …

+
+
src.communicator.daemoneventhooks
+
+

Onionr - Private P2P Communication …

+
+
src.communicator.onlinepeers
+
+
+
+
src.communicator.peeraction
+
+

Onionr - Private P2P Communication …

+
+
src.communicator.uploadqueue
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+

Functions

+
+
+def startCommunicator(shared_state) +
+
+
+
+ +Expand source code + +
def startCommunicator(shared_state):
+    OnionrCommunicatorDaemon(shared_state)
+
+
+
+
+
+

Classes

+
+
+class OnionrCommunicatorDaemon +(shared_state, developmentMode=None) +
+
+
+
+ +Expand source code + +
class OnionrCommunicatorDaemon:
+    def __init__(self, shared_state, developmentMode=None):
+        if developmentMode is None:
+            developmentMode = config.get('general.dev_mode', False)
+
+        # configure logger and stuff
+        self.config = config
+        self.storage_counter = storagecounter.StorageCounter()
+        self.isOnline = True  # Assume we're connected to the internet
+        self.shared_state = shared_state  # TooManyObjects module
+
+        if config.get('general.offline_mode', False):
+            self.isOnline = False
+
+        # list of timer instances
+        self.timers = []
+
+        # initialize core with Tor socks port being 3rd argument
+        self.proxyPort = shared_state.get(NetController).socksPort
+
+        # Upload information, list of blocks to upload
+        self.blocksToUpload = []
+        self.upload_session_manager = self.shared_state.get(
+            uploadblocks.sessionmanager.BlockUploadSessionManager)
+        self.shared_state.share_object()
+
+        # loop time.sleep delay in seconds
+        self.delay = 1
+
+        # lists of connected peers and peers we know we can't reach currently
+        self.onlinePeers = []
+        self.offlinePeers = []
+        self.cooldownPeer = {}
+        self.connectTimes = {}
+        # list of peer's profiles (onionrpeers.PeerProfile instances)
+        self.peerProfiles = []
+        # Peers merged to us. Don't add to db until we know they're reachable
+        self.newPeers = []
+        self.announceProgress = {}
+        self.announceCache = {}
+
+        self.generating_blocks = []
+
+        # amount of threads running by name, used to prevent too many
+        self.threadCounts = {}
+
+        # set true when shutdown command received
+        self.shutdown = False
+
+        # list of new blocks to download
+        # added to when new block lists are fetched from peers
+        self.blockQueue = {}
+
+        # list of blocks currently downloading, avoid s
+        self.currentDownloading = []
+
+        # timestamp when the last online node was seen
+        self.lastNodeSeen = None
+
+        # Dict of time stamps for peer's block list lookup times,
+        # to avoid downloading full lists all the time
+        self.dbTimestamps = {}
+
+        # Loads in and starts the enabled plugins
+        plugins.reload()
+
+        # time app started running for info/statistics purposes
+        self.startTime = epoch.get_epoch()
+
+        # extends our upload list and saves our list when Onionr exits
+        uploadqueue.UploadQueue(self)
+
+        if developmentMode:
+            OnionrCommunicatorTimers(self, self.heartbeat, 30)
+
+        # Set timers, function reference, seconds
+        # requires_peer True means the timer function won't fire if we
+        # have no connected peers
+        peerPoolTimer = OnionrCommunicatorTimers(
+            self, onlinepeers.get_online_peers, 60, max_threads=1,
+            my_args=[self])
+
+        # Timers to periodically lookup new blocks and download them
+        lookup_blocks_timer = OnionrCommunicatorTimers(
+            self,
+            lookupblocks.lookup_blocks_from_communicator,
+            config.get('timers.lookupBlocks', 25),
+            my_args=[self], requires_peer=True, max_threads=1)
+
+        """The block download timer is accessed by the block lookup function
+        to trigger faster download starts"""
+        self.download_blocks_timer = OnionrCommunicatorTimers(
+            self, self.getBlocks, config.get('timers.getBlocks', 10),
+            requires_peer=True, max_threads=5)
+
+        # Timer to reset the longest offline peer
+        # so contact can be attempted again
+        OnionrCommunicatorTimers(
+            self, onlinepeers.clear_offline_peer, 58, my_args=[self])
+
+        # Timer to cleanup old blocks
+        blockCleanupTimer = OnionrCommunicatorTimers(
+            self, housekeeping.clean_old_blocks, 20, my_args=[self])
+
+        # Timer to discover new peers
+        OnionrCommunicatorTimers(
+            self, lookupadders.lookup_new_peer_transports_with_communicator,
+            60, requires_peer=True, my_args=[self], max_threads=2)
+
+        # Timer for adjusting which peers
+        # we actively communicate to at any given time,
+        # to avoid over-using peers
+        OnionrCommunicatorTimers(
+            self, cooldownpeer.cooldown_peer, 30,
+            my_args=[self], requires_peer=True)
+
+        # Timer to read the upload queue and upload the entries to peers
+        OnionrCommunicatorTimers(
+            self, uploadblocks.upload_blocks_from_communicator,
+            5, my_args=[self], requires_peer=True, max_threads=1)
+
+        # Setup direct connections
+        if config.get('general.socket_servers', False):
+            self.services = onionrservices.OnionrServices()
+            self.active_services = []
+            self.service_greenlets = []
+            OnionrCommunicatorTimers(
+                self, servicecreator.service_creator, 5,
+                max_threads=50, my_args=[self])
+        else:
+            self.services = None
+
+        # {peer_pubkey: ephemeral_address}, the address to reach them
+        self.direct_connection_clients = {}
+
+        # This timer creates deniable blocks,
+        # in an attempt to further obfuscate block insertion metadata
+        if config.get('general.insert_deniable_blocks', True):
+            deniableBlockTimer = OnionrCommunicatorTimers(
+                self, deniableinserts.insert_deniable_block,
+                180, my_args=[self], requires_peer=True, max_threads=1)
+            deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
+
+        # Timer to check for connectivity,
+        # through Tor to various high-profile onion services
+        OnionrCommunicatorTimers(self, netcheck.net_check, 500,
+                                 my_args=[self], max_threads=1)
+
+        # Announce the public API server transport address
+        # to other nodes if security level allows
+        if config.get('general.security_level', 1) == 0 \
+                and config.get('general.announce_node', True):
+            # Default to high security level incase config breaks
+            announceTimer = OnionrCommunicatorTimers(
+                self,
+                announcenode.announce_node,
+                3600, my_args=[self], requires_peer=True, max_threads=1)
+            announceTimer.count = (announceTimer.frequency - 60)
+        else:
+            logger.debug('Will not announce node.')
+
+        # Timer to delete malfunctioning or long-dead peers
+        cleanupTimer = OnionrCommunicatorTimers(
+            self, self.peerCleanup, 300, requires_peer=True)
+
+        # Timer to cleanup dead ephemeral forward secrecy keys
+        OnionrCommunicatorTimers(
+            self, housekeeping.clean_keys, 15, my_args=[self], max_threads=1)
+
+        # Adjust initial timer triggers
+        peerPoolTimer.count = (peerPoolTimer.frequency - 1)
+        cleanupTimer.count = (cleanupTimer.frequency - 60)
+        blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
+        lookup_blocks_timer = (lookup_blocks_timer.frequency - 2)
+
+        shared_state.add(self)
+
+        if config.get('general.use_bootstrap_list', True):
+            bootstrappeers.add_bootstrap_list_to_peer_list(
+                self, [], db_only=True)
+
+        daemoneventhooks.daemon_event_handlers(shared_state)
+
+        if not config.get('onboarding.done', True):
+            logger.info(
+                'First run detected. Run openhome to get setup.',
+                terminal=True)
+
+            while not config.get('onboarding.done', True):
+                time.sleep(5)
+
+        # Main daemon loop, mainly for calling timers,
+        # don't do any complex operations here to avoid locking
+        try:
+            while not self.shutdown:
+                for i in self.timers:
+                    if self.shutdown:
+                        break
+                    i.processTimer()
+                time.sleep(self.delay)
+        except KeyboardInterrupt:
+            self.shutdown = True
+
+        logger.info(
+            'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
+        try:
+            self.service_greenlets
+        except AttributeError:
+            pass
+        else:
+            # Stop onionr direct connection services
+            for server in self.service_greenlets:
+                server.stop()
+        try:
+            time.sleep(0.5)
+        except KeyboardInterrupt:
+            pass
+
+    def getBlocks(self):
+        """Download new blocks in queue."""
+        downloadblocks.download_blocks_from_communicator(self)
+
+    def decrementThreadCount(self, threadName):
+        """Decrement amount of a thread name if more than zero.
+
+        called when a function meant to be run in a thread ends
+        """
+        try:
+            if self.threadCounts[threadName] > 0:
+                self.threadCounts[threadName] -= 1
+        except KeyError:
+            pass
+
+    def connectNewPeer(self, peer='', useBootstrap=False):
+        """Adds a new random online peer to self.onlinePeers"""
+        connectnewpeers.connect_new_peer_to_communicator(
+            self, peer, useBootstrap)
+
+    def peerCleanup(self):
+        """This just calls onionrpeers.cleanupPeers.
+
+        Remove dead or bad peers (offline too long, too slow)"""
+        onionrpeers.peer_cleanup()
+        self.decrementThreadCount('peerCleanup')
+
+    def getPeerProfileInstance(self, peer):
+        """Gets a peer profile instance from the list of profiles"""
+        for i in self.peerProfiles:
+            # if the peer's profile is already loaded, return that
+            if i.address == peer:
+                retData = i
+                break
+        else:
+            # if the peer's profile is not loaded, return a new one.
+            # connectNewPeer also adds it to the list on connect
+            retData = onionrpeers.PeerProfiles(peer)
+            self.peerProfiles.append(retData)
+        return retData
+
+    def getUptime(self):
+        return epoch.get_epoch() - self.startTime
+
+    def heartbeat(self):
+        """Show a heartbeat debug message."""
+        logger.debug('Heartbeat. Node running for %s.' %
+                     humanreadabletime.human_readable_time(self.getUptime()))
+        self.decrementThreadCount('heartbeat')
+
+

Methods

+
+
+def connectNewPeer(self, peer='', useBootstrap=False) +
+
+

Adds a new random online peer to self.onlinePeers

+
+ +Expand source code + +
def connectNewPeer(self, peer='', useBootstrap=False):
+    """Adds a new random online peer to self.onlinePeers"""
+    connectnewpeers.connect_new_peer_to_communicator(
+        self, peer, useBootstrap)
+
+
+
+def decrementThreadCount(self, threadName) +
+
+

Decrement amount of a thread name if more than zero.

+

called when a function meant to be run in a thread ends

+
+ +Expand source code + +
def decrementThreadCount(self, threadName):
+    """Decrement amount of a thread name if more than zero.
+
+    called when a function meant to be run in a thread ends
+    """
+    try:
+        if self.threadCounts[threadName] > 0:
+            self.threadCounts[threadName] -= 1
+    except KeyError:
+        pass
+
+
+
+def getBlocks(self) +
+
+

Download new blocks in queue.

+
+ +Expand source code + +
def getBlocks(self):
+    """Download new blocks in queue."""
+    downloadblocks.download_blocks_from_communicator(self)
+
+
+
+def getPeerProfileInstance(self, peer) +
+
+

Gets a peer profile instance from the list of profiles

+
+ +Expand source code + +
def getPeerProfileInstance(self, peer):
+    """Gets a peer profile instance from the list of profiles"""
+    for i in self.peerProfiles:
+        # if the peer's profile is already loaded, return that
+        if i.address == peer:
+            retData = i
+            break
+    else:
+        # if the peer's profile is not loaded, return a new one.
+        # connectNewPeer also adds it to the list on connect
+        retData = onionrpeers.PeerProfiles(peer)
+        self.peerProfiles.append(retData)
+    return retData
+
+
+
+def getUptime(self) +
+
+
+
+ +Expand source code + +
def getUptime(self):
+    return epoch.get_epoch() - self.startTime
+
+
+
+def heartbeat(self) +
+
+

Show a heartbeat debug message.

+
+ +Expand source code + +
def heartbeat(self):
+    """Show a heartbeat debug message."""
+    logger.debug('Heartbeat. Node running for %s.' %
+                 humanreadabletime.human_readable_time(self.getUptime()))
+    self.decrementThreadCount('heartbeat')
+
+
+
+def peerCleanup(self) +
+
+

This just calls onionrpeers.cleanupPeers.

+

Remove dead or bad peers (offline too long, too slow)

+
+ +Expand source code + +
def peerCleanup(self):
+    """This just calls onionrpeers.cleanupPeers.
+
+    Remove dead or bad peers (offline too long, too slow)"""
+    onionrpeers.peer_cleanup()
+    self.decrementThreadCount('peerCleanup')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/communicator/onlinepeers/clearofflinepeer.html b/docs/html/src/communicator/onlinepeers/clearofflinepeer.html similarity index 67% rename from docs/html/onionr/communicator/onlinepeers/clearofflinepeer.html rename to docs/html/src/communicator/onlinepeers/clearofflinepeer.html index a7e8be99..e8997c7c 100644 --- a/docs/html/onionr/communicator/onlinepeers/clearofflinepeer.html +++ b/docs/html/src/communicator/onlinepeers/clearofflinepeer.html @@ -3,13 +3,13 @@ - -onionr.communicator.onlinepeers.clearofflinepeer API documentation + +src.communicator.onlinepeers.clearofflinepeer API documentation - + @@ -17,19 +17,25 @@
-

Module onionr.communicator.onlinepeers.clearofflinepeer

+

Module src.communicator.onlinepeers.clearofflinepeer

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

clear offline peer in a communicator instance

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    clear offline peer in a communicator instance
-'''
-'''
+clear offline peer in a communicator instance
+"""
+from typing import TYPE_CHECKING
+
+import logger
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,16 +48,18 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import logger
-def clear_offline_peer(comm_inst):
-    '''Removes the longest offline peer to retry later'''
+"""
+
+
+def clear_offline_peer(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Remove the longest offline peer to retry later."""
     try:
         removed = comm_inst.offlinePeers.pop(0)
     except IndexError:
         pass
     else:
-        logger.debug('Removed ' + removed + ' from offline list, will try them again.')
+        logger.debug('Removed ' + removed +
+                     ' from offline list, will try them again.')
     comm_inst.decrementThreadCount('clear_offline_peer')
@@ -62,21 +70,24 @@ def clear_offline_peer(comm_inst):

Functions

-
+
def clear_offline_peer(comm_inst)
-

Removes the longest offline peer to retry later

+

Remove the longest offline peer to retry later.

-Source code -
def clear_offline_peer(comm_inst):
-    '''Removes the longest offline peer to retry later'''
+
+Expand source code
+
+
def clear_offline_peer(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Remove the longest offline peer to retry later."""
     try:
         removed = comm_inst.offlinePeers.pop(0)
     except IndexError:
         pass
     else:
-        logger.debug('Removed ' + removed + ' from offline list, will try them again.')
+        logger.debug('Removed ' + removed +
+                     ' from offline list, will try them again.')
     comm_inst.decrementThreadCount('clear_offline_peer')
@@ -93,19 +104,19 @@ def clear_offline_peer(comm_inst):
diff --git a/docs/html/onionr/communicator/onlinepeers/index.html b/docs/html/src/communicator/onlinepeers/index.html similarity index 66% rename from docs/html/onionr/communicator/onlinepeers/index.html rename to docs/html/src/communicator/onlinepeers/index.html index 5e94f0b7..2ee17c2f 100644 --- a/docs/html/onionr/communicator/onlinepeers/index.html +++ b/docs/html/src/communicator/onlinepeers/index.html @@ -3,13 +3,13 @@ - -onionr.communicator.onlinepeers API documentation + +src.communicator.onlinepeers API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.communicator.onlinepeers

+

Module src.communicator.onlinepeers

-Source code + +Expand source code +
from . import clearofflinepeer, onlinepeers, pickonlinepeers, removeonlinepeer
 
 clear_offline_peer = clearofflinepeer.clear_offline_peer
@@ -33,19 +35,19 @@ remove_online_peer = removeonlinepeer.remove_online_peer

Sub-modules

-
onionr.communicator.onlinepeers.clearofflinepeer
+
src.communicator.onlinepeers.clearofflinepeer

Onionr - Private P2P Communication …

-
onionr.communicator.onlinepeers.onlinepeers
+
src.communicator.onlinepeers.onlinepeers

Onionr - Private P2P Communication …

-
onionr.communicator.onlinepeers.pickonlinepeers
+
src.communicator.onlinepeers.pickonlinepeers

Onionr - Private P2P Communication …

-
onionr.communicator.onlinepeers.removeonlinepeer
+
src.communicator.onlinepeers.removeonlinepeer

Onionr - Private P2P Communication …

@@ -66,22 +68,22 @@ remove_online_peer = removeonlinepeer.remove_online_peer
diff --git a/docs/html/onionr/communicator/onlinepeers/onlinepeers.html b/docs/html/src/communicator/onlinepeers/onlinepeers.html similarity index 63% rename from docs/html/onionr/communicator/onlinepeers/onlinepeers.html rename to docs/html/src/communicator/onlinepeers/onlinepeers.html index 900a6393..53a6c692 100644 --- a/docs/html/onionr/communicator/onlinepeers/onlinepeers.html +++ b/docs/html/src/communicator/onlinepeers/onlinepeers.html @@ -3,13 +3,13 @@ - -onionr.communicator.onlinepeers.onlinepeers API documentation + +src.communicator.onlinepeers.onlinepeers API documentation - + @@ -17,19 +17,27 @@
-

Module onionr.communicator.onlinepeers.onlinepeers

+

Module src.communicator.onlinepeers.onlinepeers

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

get online peers in a communicator instance

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    get online peers in a communicator instance
-'''
-'''
+get online peers in a communicator instance
+"""
+import time
+from typing import TYPE_CHECKING
+
+from etc import humanreadabletime
+import logger
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,20 +50,28 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import time
-from etc import humanreadabletime
-import logger
-def get_online_peers(comm_inst):
-    '''
-        Manages the comm_inst.onlinePeers attribute list, connects to more peers if we have none connected
-    '''
-    config = comm_inst.config
-    logger.debug('Refreshing peer pool...')
-    maxPeers = int(config.get('peers.max_connect', 10))
-    needed = maxPeers - len(comm_inst.onlinePeers)
+"""
 
-    for i in range(needed):
+
+def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Manage the comm_inst.onlinePeers attribute list.
+
+    Connect to more peers if we have none connected
+    """
+    config = comm_inst.config
+    if config.get('general.offline_mode', False):
+        comm_inst.decrementThreadCount('get_online_peers')
+        return
+    logger.debug('Refreshing peer pool...')
+    max_peers = int(config.get('peers.max_connect', 10))
+    needed = max_peers - len(comm_inst.onlinePeers)
+
+    last_seen = 'never'
+    if not isinstance(comm_inst.lastNodeSeen, type(None)):
+        last_seen = humanreadabletime.human_readable_time(
+            comm_inst.lastNodeSeen)
+
+    for _ in range(needed):
         if len(comm_inst.onlinePeers) == 0:
             comm_inst.connectNewPeer(useBootstrap=True)
         else:
@@ -65,7 +81,8 @@ def get_online_peers(comm_inst):
             break
     else:
         if len(comm_inst.onlinePeers) == 0:
-            logger.debug('Couldn\'t connect to any peers.' + (' Last node seen %s ago.' % humanreadabletime.human_readable_time(time.time() - comm_inst.lastNodeSeen) if not comm_inst.lastNodeSeen is None else ''), terminal=True)
+            logger.debug('Couldn\'t connect to any peers.' +
+                         f' Last node seen {last_seen}  ago.')
         else:
             comm_inst.lastNodeSeen = time.time()
     comm_inst.decrementThreadCount('get_online_peers')
@@ -78,23 +95,35 @@ def get_online_peers(comm_inst):

Functions

-
+
def get_online_peers(comm_inst)
-

Manages the comm_inst.onlinePeers attribute list, connects to more peers if we have none connected

+

Manage the comm_inst.onlinePeers attribute list.

+

Connect to more peers if we have none connected

-Source code -
def get_online_peers(comm_inst):
-    '''
-        Manages the comm_inst.onlinePeers attribute list, connects to more peers if we have none connected
-    '''
-    config = comm_inst.config
-    logger.debug('Refreshing peer pool...')
-    maxPeers = int(config.get('peers.max_connect', 10))
-    needed = maxPeers - len(comm_inst.onlinePeers)
+
+Expand source code
+
+
def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Manage the comm_inst.onlinePeers attribute list.
 
-    for i in range(needed):
+    Connect to more peers if we have none connected
+    """
+    config = comm_inst.config
+    if config.get('general.offline_mode', False):
+        comm_inst.decrementThreadCount('get_online_peers')
+        return
+    logger.debug('Refreshing peer pool...')
+    max_peers = int(config.get('peers.max_connect', 10))
+    needed = max_peers - len(comm_inst.onlinePeers)
+
+    last_seen = 'never'
+    if not isinstance(comm_inst.lastNodeSeen, type(None)):
+        last_seen = humanreadabletime.human_readable_time(
+            comm_inst.lastNodeSeen)
+
+    for _ in range(needed):
         if len(comm_inst.onlinePeers) == 0:
             comm_inst.connectNewPeer(useBootstrap=True)
         else:
@@ -104,7 +133,8 @@ def get_online_peers(comm_inst):
             break
     else:
         if len(comm_inst.onlinePeers) == 0:
-            logger.debug('Couldn\'t connect to any peers.' + (' Last node seen %s ago.' % humanreadabletime.human_readable_time(time.time() - comm_inst.lastNodeSeen) if not comm_inst.lastNodeSeen is None else ''), terminal=True)
+            logger.debug('Couldn\'t connect to any peers.' +
+                         f' Last node seen {last_seen}  ago.')
         else:
             comm_inst.lastNodeSeen = time.time()
     comm_inst.decrementThreadCount('get_online_peers')
@@ -123,19 +153,19 @@ def get_online_peers(comm_inst):
diff --git a/docs/html/onionr/communicator/onlinepeers/pickonlinepeers.html b/docs/html/src/communicator/onlinepeers/pickonlinepeers.html similarity index 69% rename from docs/html/onionr/communicator/onlinepeers/pickonlinepeers.html rename to docs/html/src/communicator/onlinepeers/pickonlinepeers.html index 021befc8..eab5fa39 100644 --- a/docs/html/onionr/communicator/onlinepeers/pickonlinepeers.html +++ b/docs/html/src/communicator/onlinepeers/pickonlinepeers.html @@ -3,13 +3,13 @@ - -onionr.communicator.onlinepeers.pickonlinepeers API documentation + +src.communicator.onlinepeers.pickonlinepeers API documentation - + @@ -17,19 +17,24 @@
-

Module onionr.communicator.onlinepeers.pickonlinepeers

+

Module src.communicator.onlinepeers.pickonlinepeers

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

pick online peers in a communicator instance

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""
+Onionr - Private P2P Communication.
 
-    pick online peers in a communicator instance
-'''
-'''
+pick online peers in a communicator instance
+"""
+import secrets
+
+import onionrexceptions
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,17 +47,22 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import secrets
+"""
+
+
 def pick_online_peer(comm_inst):
-    '''randomly picks peer from pool without bias (using secrets module)'''
+    """Randomly picks peer from pool without bias (using secrets module)."""
     ret_data = ''
+    peer_length = len(comm_inst.onlinePeers)
+    if peer_length <= 0:
+        raise onionrexceptions.OnlinePeerNeeded
+
     while True:
         peer_length = len(comm_inst.onlinePeers)
-        if peer_length <= 0:
-            break
+
         try:
-            # get a random online peer, securely. May get stuck in loop if network is lost or if all peers in pool magically disconnect at once
+            # Get a random online peer, securely.
+            # May get stuck in loop if network is lost
             ret_data = comm_inst.onlinePeers[secrets.randbelow(peer_length)]
         except IndexError:
             pass
@@ -68,22 +78,28 @@ def pick_online_peer(comm_inst):
 

Functions

-
+
def pick_online_peer(comm_inst)
-

randomly picks peer from pool without bias (using secrets module)

+

Randomly picks peer from pool without bias (using secrets module).

-Source code + +Expand source code +
def pick_online_peer(comm_inst):
-    '''randomly picks peer from pool without bias (using secrets module)'''
+    """Randomly picks peer from pool without bias (using secrets module)."""
     ret_data = ''
+    peer_length = len(comm_inst.onlinePeers)
+    if peer_length <= 0:
+        raise onionrexceptions.OnlinePeerNeeded
+
     while True:
         peer_length = len(comm_inst.onlinePeers)
-        if peer_length <= 0:
-            break
+
         try:
-            # get a random online peer, securely. May get stuck in loop if network is lost or if all peers in pool magically disconnect at once
+            # Get a random online peer, securely.
+            # May get stuck in loop if network is lost
             ret_data = comm_inst.onlinePeers[secrets.randbelow(peer_length)]
         except IndexError:
             pass
@@ -105,19 +121,19 @@ def pick_online_peer(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicator/onlinepeers/removeonlinepeer.html b/docs/html/src/communicator/onlinepeers/removeonlinepeer.html similarity index 73% rename from docs/html/onionr/communicator/onlinepeers/removeonlinepeer.html rename to docs/html/src/communicator/onlinepeers/removeonlinepeer.html index fe6d3250..b27c1f53 100644 --- a/docs/html/onionr/communicator/onlinepeers/removeonlinepeer.html +++ b/docs/html/src/communicator/onlinepeers/removeonlinepeer.html @@ -3,13 +3,13 @@ - -onionr.communicator.onlinepeers.removeonlinepeer API documentation + +src.communicator.onlinepeers.removeonlinepeer API documentation - + @@ -17,19 +17,20 @@
-

Module onionr.communicator.onlinepeers.removeonlinepeer

+

Module src.communicator.onlinepeers.removeonlinepeer

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

remove an online peer from the pool in a communicator instance

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    remove an online peer from the pool in a communicator instance
-'''
-'''
+remove an online peer from the pool in a communicator instance
+"""
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,9 +43,11 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
+"""
+
+
 def remove_online_peer(comm_inst, peer):
-    '''Remove an online peer'''
+    """Remove an online peer."""
     try:
         del comm_inst.connectTimes[peer]
     except KeyError:
@@ -66,15 +69,17 @@ def remove_online_peer(comm_inst, peer):
 

Functions

-
+
def remove_online_peer(comm_inst, peer)
-

Remove an online peer

+

Remove an online peer.

-Source code + +Expand source code +
def remove_online_peer(comm_inst, peer):
-    '''Remove an online peer'''
+    """Remove an online peer."""
     try:
         del comm_inst.connectTimes[peer]
     except KeyError:
@@ -102,19 +107,19 @@ def remove_online_peer(comm_inst, peer):
 
 
 
diff --git a/docs/html/onionr/communicator/peeraction.html b/docs/html/src/communicator/peeraction.html similarity index 70% rename from docs/html/onionr/communicator/peeraction.html rename to docs/html/src/communicator/peeraction.html index 4e7dff99..e6d48149 100644 --- a/docs/html/onionr/communicator/peeraction.html +++ b/docs/html/src/communicator/peeraction.html @@ -3,13 +3,13 @@ - -onionr.communicator.peeraction API documentation + +src.communicator.peeraction API documentation - + @@ -17,19 +17,25 @@
-

Module onionr.communicator.peeraction

+

Module src.communicator.peeraction

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This file implements logic for performing requests to Onionr peers

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file implements logic for performing requests to Onionr peers
-'''
-'''
+This file implements logic for performing requests to Onionr peers
+"""
+import streamedrequests
+import logger
+from onionrutils import epoch, basicrequests
+from coredb import keydb
+from . import onlinepeers
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,15 +48,12 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import streamedrequests
-import logger
-from onionrutils import epoch, basicrequests
-from coredb import keydb
-from . import onlinepeers
+"""
 
-def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242880):
-    '''Perform a get request to a peer'''
+
+def peer_action(comm_inst, peer, action,
+                returnHeaders=False, max_resp_size=5242880):
+    """Perform a get request to a peer."""
     penalty_score = -10
     if len(peer) == 0:
         return False
@@ -60,25 +63,31 @@ def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242
         ret_data = basicrequests.do_get_request(url, port=comm_inst.proxyPort,
                                                 max_size=max_resp_size)
     except streamedrequests.exceptions.ResponseLimitReached:
-        logger.warn('Request failed due to max response size being overflowed', terminal=True)
+        logger.warn(
+            'Request failed due to max response size being overflowed',
+            terminal=True)
         ret_data = False
         penalty_score = -100
     # if request failed, (error), mark peer offline
-    if ret_data == False: # For some reason "if not" breaks this. Prob has to do with empty string.
+    if ret_data is False:
         try:
             comm_inst.getPeerProfileInstance(peer).addScore(penalty_score)
             onlinepeers.remove_online_peer(comm_inst, peer)
-            keydb.transportinfo.set_address_info(peer, 'lastConnectAttempt', epoch.get_epoch())
+            keydb.transportinfo.set_address_info(
+                peer, 'lastConnectAttempt', epoch.get_epoch())
             if action != 'ping' and not comm_inst.shutdown:
                 logger.warn(f'Lost connection to {peer}', terminal=True)
-                onlinepeers.get_online_peers(comm_inst) # Will only add a new peer to pool if needed
+                # Will only add a new peer to pool if needed
+                onlinepeers.get_online_peers(comm_inst)
         except ValueError:
             pass
     else:
         peer_profile = comm_inst.getPeerProfileInstance(peer)
         peer_profile.update_connect_time()
         peer_profile.addScore(1)
-    return ret_data # If returnHeaders, returns tuple of data, headers. if not, just data string
+ # If returnHeaders, returns tuple of data, headers. + # If not, just data string + return ret_data
@@ -88,15 +97,18 @@ def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242

Functions

-
+
def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242880)
-

Perform a get request to a peer

+

Perform a get request to a peer.

-Source code -
def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242880):
-    '''Perform a get request to a peer'''
+
+Expand source code
+
+
def peer_action(comm_inst, peer, action,
+                returnHeaders=False, max_resp_size=5242880):
+    """Perform a get request to a peer."""
     penalty_score = -10
     if len(peer) == 0:
         return False
@@ -106,25 +118,31 @@ def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242
         ret_data = basicrequests.do_get_request(url, port=comm_inst.proxyPort,
                                                 max_size=max_resp_size)
     except streamedrequests.exceptions.ResponseLimitReached:
-        logger.warn('Request failed due to max response size being overflowed', terminal=True)
+        logger.warn(
+            'Request failed due to max response size being overflowed',
+            terminal=True)
         ret_data = False
         penalty_score = -100
     # if request failed, (error), mark peer offline
-    if ret_data == False: # For some reason "if not" breaks this. Prob has to do with empty string.
+    if ret_data is False:
         try:
             comm_inst.getPeerProfileInstance(peer).addScore(penalty_score)
             onlinepeers.remove_online_peer(comm_inst, peer)
-            keydb.transportinfo.set_address_info(peer, 'lastConnectAttempt', epoch.get_epoch())
+            keydb.transportinfo.set_address_info(
+                peer, 'lastConnectAttempt', epoch.get_epoch())
             if action != 'ping' and not comm_inst.shutdown:
                 logger.warn(f'Lost connection to {peer}', terminal=True)
-                onlinepeers.get_online_peers(comm_inst) # Will only add a new peer to pool if needed
+                # Will only add a new peer to pool if needed
+                onlinepeers.get_online_peers(comm_inst)
         except ValueError:
             pass
     else:
         peer_profile = comm_inst.getPeerProfileInstance(peer)
         peer_profile.update_connect_time()
         peer_profile.addScore(1)
-    return ret_data # If returnHeaders, returns tuple of data, headers. if not, just data string
+ # If returnHeaders, returns tuple of data, headers. + # If not, just data string + return ret_data
@@ -140,19 +158,19 @@ def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242
diff --git a/docs/html/onionr/communicator/uploadqueue/index.html b/docs/html/src/communicator/uploadqueue/index.html similarity index 62% rename from docs/html/onionr/communicator/uploadqueue/index.html rename to docs/html/src/communicator/uploadqueue/index.html index d7382195..3b5314f1 100644 --- a/docs/html/onionr/communicator/uploadqueue/index.html +++ b/docs/html/src/communicator/uploadqueue/index.html @@ -3,13 +3,13 @@ - -onionr.communicator.uploadqueue API documentation + +src.communicator.uploadqueue API documentation - + @@ -17,18 +17,31 @@
-

Module onionr.communicator.uploadqueue

+

Module src.communicator.uploadqueue

-

Onionr - Private P2P Communication

-

Class to remember blocks that need to be uploaded and not shared on startup/shutdown

+

Onionr - Private P2P Communication.

+

Class to remember blocks that need to be uploaded +and not shared on startup/shutdown

-Source code -
"""
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Class to remember blocks that need to be uploaded and not shared on startup/shutdown
+Class to remember blocks that need to be uploaded
+and not shared on startup/shutdown
 """
+import atexit
+import os
+from typing import TYPE_CHECKING
+
+import deadsimplekv
+
+import filepaths
+from onionrutils import localcommand
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
 """
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -44,46 +57,46 @@
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
 
-import atexit
-import json
-
-import deadsimplekv
-
-import filepaths
-from onionrutils import localcommand
-
 UPLOAD_MEMORY_FILE = filepaths.upload_list
 
+
 def _add_to_hidden_blocks(cache):
     for bl in cache:
         localcommand.local_command('waitforshare/' + bl, post=True)
 
+
 class UploadQueue:
-    """
-        Saves and loads block upload info from json file
-    """
+    """Saves and loads block upload info from json file."""
 
     def __init__(self, communicator: 'OnionrCommunicatorDaemon'):
-        """Start the UploadQueue object, loading left over uploads into queue 
-        and registering save shutdown function
+        """Start the UploadQueue object, loading left over uploads into queue.
+
+        register save shutdown function
         """
         self.communicator = communicator
-        cache = deadsimplekv.DeadSimpleKV(UPLOAD_MEMORY_FILE)
+        cache: deadsimplekv.DeadSimpleKV = deadsimplekv.DeadSimpleKV(
+            UPLOAD_MEMORY_FILE)
         self.store_obj = cache
-        cache: list = cache.get('uploads')
-        if cache == None:
+        cache = cache.get('uploads')
+        if cache is None:
             cache = []
-        
+
         _add_to_hidden_blocks(cache)
         self.communicator.blocksToUpload.extend(cache)
 
         atexit.register(self.save)
 
     def save(self):
-        """Saves to disk on shutdown or if called manually"""
-        bl: list = self.communicator.blocksToUpload
-        self.store_obj.put('uploads', bl)
-        self.store_obj.flush()
+ """Save to disk on shutdown or if called manually.""" + bl: deadsimplekv.DeadSimpleKV = self.communicator.blocksToUpload + if len(bl) == 0: + try: + os.remove(UPLOAD_MEMORY_FILE) + except FileNotFoundError: + pass + else: + self.store_obj.put('uploads', bl) + self.store_obj.flush()
@@ -95,57 +108,73 @@ class UploadQueue:

Classes

-
+
class UploadQueue (communicator)
-

Saves and loads block upload info from json file

-

Start the UploadQueue object, loading left over uploads into queue -and registering save shutdown function

+

Saves and loads block upload info from json file.

+

Start the UploadQueue object, loading left over uploads into queue.

+

register save shutdown function

-Source code + +Expand source code +
class UploadQueue:
-    """
-        Saves and loads block upload info from json file
-    """
+    """Saves and loads block upload info from json file."""
 
     def __init__(self, communicator: 'OnionrCommunicatorDaemon'):
-        """Start the UploadQueue object, loading left over uploads into queue 
-        and registering save shutdown function
+        """Start the UploadQueue object, loading left over uploads into queue.
+
+        register save shutdown function
         """
         self.communicator = communicator
-        cache = deadsimplekv.DeadSimpleKV(UPLOAD_MEMORY_FILE)
+        cache: deadsimplekv.DeadSimpleKV = deadsimplekv.DeadSimpleKV(
+            UPLOAD_MEMORY_FILE)
         self.store_obj = cache
-        cache: list = cache.get('uploads')
-        if cache == None:
+        cache = cache.get('uploads')
+        if cache is None:
             cache = []
-        
+
         _add_to_hidden_blocks(cache)
         self.communicator.blocksToUpload.extend(cache)
 
         atexit.register(self.save)
 
     def save(self):
-        """Saves to disk on shutdown or if called manually"""
-        bl: list = self.communicator.blocksToUpload
-        self.store_obj.put('uploads', bl)
-        self.store_obj.flush()
+ """Save to disk on shutdown or if called manually.""" + bl: deadsimplekv.DeadSimpleKV = self.communicator.blocksToUpload + if len(bl) == 0: + try: + os.remove(UPLOAD_MEMORY_FILE) + except FileNotFoundError: + pass + else: + self.store_obj.put('uploads', bl) + self.store_obj.flush()

Methods

-
+
def save(self)
-

Saves to disk on shutdown or if called manually

+

Save to disk on shutdown or if called manually.

-Source code + +Expand source code +
def save(self):
-    """Saves to disk on shutdown or if called manually"""
-    bl: list = self.communicator.blocksToUpload
-    self.store_obj.put('uploads', bl)
-    self.store_obj.flush()
+ """Save to disk on shutdown or if called manually.""" + bl: deadsimplekv.DeadSimpleKV = self.communicator.blocksToUpload + if len(bl) == 0: + try: + os.remove(UPLOAD_MEMORY_FILE) + except FileNotFoundError: + pass + else: + self.store_obj.put('uploads', bl) + self.store_obj.flush()
@@ -161,15 +190,15 @@ and registering save shutdown function

diff --git a/docs/html/onionr/communicatorutils/announcenode.html b/docs/html/src/communicatorutils/announcenode.html similarity index 51% rename from docs/html/onionr/communicatorutils/announcenode.html rename to docs/html/src/communicatorutils/announcenode.html index feb47b3f..10b7a332 100644 --- a/docs/html/onionr/communicatorutils/announcenode.html +++ b/docs/html/src/communicatorutils/announcenode.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.announcenode API documentation + +src.communicatorutils.announcenode API documentation - + @@ -17,19 +17,33 @@
-

Module onionr.communicatorutils.announcenode

+

Module src.communicatorutils.announcenode

-

Onionr - Private P2P Communication

-

Use a communicator instance to announce our transport address to connected nodes

+

Onionr - Private P2P Communication.

+

Use a communicator instance to announce +our transport address to connected nodes

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""
+    Onionr - Private P2P Communication.
 
-    Use a communicator instance to announce our transport address to connected nodes
-'''
-'''
+Use a communicator instance to announce
+our transport address to connected nodes
+"""
+import base64
+import onionrproofs
+import logger
+from etc import onionrvalues
+from onionrutils import basicrequests, bytesconverter
+from utils import gettransports
+from netcontroller import NetController
+from communicator import onlinepeers
+from coredb import keydb
+import onionrexceptions
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,20 +56,14 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import base64
-import onionrproofs, logger
-from etc import onionrvalues
-from onionrutils import basicrequests, bytesconverter
-from utils import gettransports
-from netcontroller import NetController
-from communicator import onlinepeers
-from coredb import keydb
+"""
+
+
 def announce_node(daemon):
-    '''Announce our node to our peers'''
+    """Announce our node to our peers."""
     ret_data = False
     announce_fail = False
-    
+
     # Do not let announceCache get too large
     if len(daemon.announceCache) >= 10000:
         daemon.announceCache.popitem()
@@ -63,51 +71,37 @@ def announce_node(daemon):
     if daemon.config.get('general.security_level', 0) == 0:
         # Announce to random online peers
         for i in daemon.onlinePeers:
-            if not i in daemon.announceCache and not i in daemon.announceProgress:
+            if i not in daemon.announceCache and\
+                    i not in daemon.announceProgress:
                 peer = i
                 break
         else:
-            peer = onlinepeers.pick_online_peer(daemon)
-
-        for x in range(1):
             try:
-                ourID = gettransports.get()[0]
-            except IndexError:
-                break
+                peer = onlinepeers.pick_online_peer(daemon)
+            except onionrexceptions.OnlinePeerNeeded:
+                peer = ""
 
+        try:
+            ourID = gettransports.get()[0]
+            if not peer:
+                raise onionrexceptions.OnlinePeerNeeded
+        except (IndexError, onionrexceptions.OnlinePeerNeeded):
+            pass
+        else:
             url = 'http://' + peer + '/announce'
             data = {'node': ourID}
 
-            combinedNodes = ourID + peer
-            if ourID != 1:
-                existingRand = bytesconverter.bytes_to_str(keydb.transportinfo.get_address_info(peer, 'powValue'))
-                # Reset existingRand if it no longer meets the minimum POW
-                if type(existingRand) is type(None) or not existingRand.endswith('0' * onionrvalues.ANNOUNCE_POW):
-                    existingRand = ''
+            logger.info('Announcing node to ' + url)
+            if basicrequests.do_post_request(
+                    url,
+                    data,
+                    port=daemon.shared_state.get(NetController).socksPort)\
+                    == 'Success':
+                logger.info('Successfully introduced node to ' + peer,
+                            terminal=True)
+                ret_data = True
+                keydb.transportinfo.set_address_info(peer, 'introduced', 1)
 
-            if peer in daemon.announceCache:
-                data['random'] = daemon.announceCache[peer]
-            elif len(existingRand) > 0:
-                data['random'] = existingRand
-            else:
-                daemon.announceProgress[peer] = True
-                proof = onionrproofs.DataPOW(combinedNodes, minDifficulty=onionrvalues.ANNOUNCE_POW)
-                del daemon.announceProgress[peer]
-                try:
-                    data['random'] = base64.b64encode(proof.waitForResult()[1])
-                except TypeError:
-                    # Happens when we failed to produce a proof
-                    logger.error("Failed to produce a pow for announcing to " + peer)
-                    announce_fail = True
-                else:
-                    daemon.announceCache[peer] = data['random']
-            if not announce_fail:
-                logger.info('Announcing node to ' + url)
-                if basicrequests.do_post_request(url, data, port=daemon.shared_state.get(NetController).socksPort) == 'Success':
-                    logger.info('Successfully introduced node to ' + peer, terminal=True)
-                    ret_data = True
-                    keydb.transportinfo.set_address_info(peer, 'introduced', 1)
-                    keydb.transportinfo.set_address_info(peer, 'powValue', data['random'])
     daemon.decrementThreadCount('announce_node')
     return ret_data
@@ -119,18 +113,20 @@ def announce_node(daemon):

Functions

-
+
def announce_node(daemon)
-

Announce our node to our peers

+

Announce our node to our peers.

-Source code + +Expand source code +
def announce_node(daemon):
-    '''Announce our node to our peers'''
+    """Announce our node to our peers."""
     ret_data = False
     announce_fail = False
-    
+
     # Do not let announceCache get too large
     if len(daemon.announceCache) >= 10000:
         daemon.announceCache.popitem()
@@ -138,51 +134,37 @@ def announce_node(daemon):
     if daemon.config.get('general.security_level', 0) == 0:
         # Announce to random online peers
         for i in daemon.onlinePeers:
-            if not i in daemon.announceCache and not i in daemon.announceProgress:
+            if i not in daemon.announceCache and\
+                    i not in daemon.announceProgress:
                 peer = i
                 break
         else:
-            peer = onlinepeers.pick_online_peer(daemon)
-
-        for x in range(1):
             try:
-                ourID = gettransports.get()[0]
-            except IndexError:
-                break
+                peer = onlinepeers.pick_online_peer(daemon)
+            except onionrexceptions.OnlinePeerNeeded:
+                peer = ""
 
+        try:
+            ourID = gettransports.get()[0]
+            if not peer:
+                raise onionrexceptions.OnlinePeerNeeded
+        except (IndexError, onionrexceptions.OnlinePeerNeeded):
+            pass
+        else:
             url = 'http://' + peer + '/announce'
             data = {'node': ourID}
 
-            combinedNodes = ourID + peer
-            if ourID != 1:
-                existingRand = bytesconverter.bytes_to_str(keydb.transportinfo.get_address_info(peer, 'powValue'))
-                # Reset existingRand if it no longer meets the minimum POW
-                if type(existingRand) is type(None) or not existingRand.endswith('0' * onionrvalues.ANNOUNCE_POW):
-                    existingRand = ''
+            logger.info('Announcing node to ' + url)
+            if basicrequests.do_post_request(
+                    url,
+                    data,
+                    port=daemon.shared_state.get(NetController).socksPort)\
+                    == 'Success':
+                logger.info('Successfully introduced node to ' + peer,
+                            terminal=True)
+                ret_data = True
+                keydb.transportinfo.set_address_info(peer, 'introduced', 1)
 
-            if peer in daemon.announceCache:
-                data['random'] = daemon.announceCache[peer]
-            elif len(existingRand) > 0:
-                data['random'] = existingRand
-            else:
-                daemon.announceProgress[peer] = True
-                proof = onionrproofs.DataPOW(combinedNodes, minDifficulty=onionrvalues.ANNOUNCE_POW)
-                del daemon.announceProgress[peer]
-                try:
-                    data['random'] = base64.b64encode(proof.waitForResult()[1])
-                except TypeError:
-                    # Happens when we failed to produce a proof
-                    logger.error("Failed to produce a pow for announcing to " + peer)
-                    announce_fail = True
-                else:
-                    daemon.announceCache[peer] = data['random']
-            if not announce_fail:
-                logger.info('Announcing node to ' + url)
-                if basicrequests.do_post_request(url, data, port=daemon.shared_state.get(NetController).socksPort) == 'Success':
-                    logger.info('Successfully introduced node to ' + peer, terminal=True)
-                    ret_data = True
-                    keydb.transportinfo.set_address_info(peer, 'introduced', 1)
-                    keydb.transportinfo.set_address_info(peer, 'powValue', data['random'])
     daemon.decrementThreadCount('announce_node')
     return ret_data
@@ -200,19 +182,19 @@ def announce_node(daemon):
diff --git a/docs/html/onionr/communicatorutils/connectnewpeers.html b/docs/html/src/communicatorutils/connectnewpeers.html similarity index 87% rename from docs/html/onionr/communicatorutils/connectnewpeers.html rename to docs/html/src/communicatorutils/connectnewpeers.html index ce33a512..0dd8129d 100644 --- a/docs/html/onionr/communicatorutils/connectnewpeers.html +++ b/docs/html/src/communicatorutils/connectnewpeers.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.connectnewpeers API documentation + +src.communicatorutils.connectnewpeers API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.connectnewpeers

+

Module src.communicatorutils.connectnewpeers

Onionr - Private P2P Communication

Connect a new peer to our communicator instance. Does so randomly if no peer is specified

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -81,6 +83,8 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=Fa
             bootstrappeers.add_bootstrap_list_to_peer_list(comm_inst, peerList)
 
     for address in peerList:
+        address = address.strip()
+
         if not config.get('tor.v3onions') and len(address) == 62:
             continue
         # Don't connect to our own address
@@ -125,13 +129,15 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=Fa
 

Functions

-
+
def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=False)
-Source code + +Expand source code +
def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=False):
     config = comm_inst.config
     retData = False
@@ -164,6 +170,8 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=Fa
             bootstrappeers.add_bootstrap_list_to_peer_list(comm_inst, peerList)
 
     for address in peerList:
+        address = address.strip()
+
         if not config.get('tor.v3onions') and len(address) == 62:
             continue
         # Don't connect to our own address
@@ -214,19 +222,19 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=Fa
 
 
 
diff --git a/docs/html/onionr/communicatorutils/cooldownpeer.html b/docs/html/src/communicatorutils/cooldownpeer.html similarity index 84% rename from docs/html/onionr/communicatorutils/cooldownpeer.html rename to docs/html/src/communicatorutils/cooldownpeer.html index d19f96e3..a96f4345 100644 --- a/docs/html/onionr/communicatorutils/cooldownpeer.html +++ b/docs/html/src/communicatorutils/cooldownpeer.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.cooldownpeer API documentation + +src.communicatorutils.cooldownpeer API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.cooldownpeer

+

Module src.communicatorutils.cooldownpeer

Onionr - Private P2P Communication

Select a random online peer in a communicator instance and have them "cool down"

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -87,13 +89,15 @@ def cooldown_peer(comm_inst):
 

Functions

-
+
def cooldown_peer(comm_inst)

Randomly add an online peer to cooldown, so we can connect a new one

-Source code + +Expand source code +
def cooldown_peer(comm_inst):
     '''Randomly add an online peer to cooldown, so we can connect a new one'''
     config = comm_inst.config
@@ -142,19 +146,19 @@ def cooldown_peer(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/deniableinserts.html b/docs/html/src/communicatorutils/deniableinserts.html similarity index 79% rename from docs/html/onionr/communicatorutils/deniableinserts.html rename to docs/html/src/communicatorutils/deniableinserts.html index 183303ec..22e188df 100644 --- a/docs/html/onionr/communicatorutils/deniableinserts.html +++ b/docs/html/src/communicatorutils/deniableinserts.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.deniableinserts API documentation + +src.communicatorutils.deniableinserts API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.deniableinserts

+

Module src.communicatorutils.deniableinserts

Onionr - Private P2P Communication

Use the communicator to insert fake mail messages

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -53,7 +55,7 @@ def insert_deniable_block(comm_inst):
     if secrets.randbelow(chance) == (chance - 1):
         # This assumes on the libsodium primitives to have key-privacy
         fakePeer = onionrvalues.DENIABLE_PEER_ADDRESS
-        data = secrets.token_hex(secrets.randbelow(1024) + 1)
+        data = secrets.token_hex(secrets.randbelow(5120) + 1)
         onionrblocks.insert(data, header='pm', encryptType='asym', asymPeer=fakePeer, disableForward=True, meta={'subject': 'foo'})
     comm_inst.decrementThreadCount('insert_deniable_block')
@@ -65,13 +67,15 @@ def insert_deniable_block(comm_inst):

Functions

-
+
def insert_deniable_block(comm_inst)

Insert a fake block in order to make it more difficult to track real blocks

-Source code + +Expand source code +
def insert_deniable_block(comm_inst):
     '''Insert a fake block in order to make it more difficult to track real blocks'''
     fakePeer = ''
@@ -79,7 +83,7 @@ def insert_deniable_block(comm_inst):
     if secrets.randbelow(chance) == (chance - 1):
         # This assumes on the libsodium primitives to have key-privacy
         fakePeer = onionrvalues.DENIABLE_PEER_ADDRESS
-        data = secrets.token_hex(secrets.randbelow(1024) + 1)
+        data = secrets.token_hex(secrets.randbelow(5120) + 1)
         onionrblocks.insert(data, header='pm', encryptType='asym', asymPeer=fakePeer, disableForward=True, meta={'subject': 'foo'})
     comm_inst.decrementThreadCount('insert_deniable_block')
@@ -97,19 +101,19 @@ def insert_deniable_block(comm_inst):
diff --git a/docs/html/onionr/communicatorutils/downloadblocks/index.html b/docs/html/src/communicatorutils/downloadblocks/index.html similarity index 76% rename from docs/html/onionr/communicatorutils/downloadblocks/index.html rename to docs/html/src/communicatorutils/downloadblocks/index.html index 25c40534..a4800994 100644 --- a/docs/html/onionr/communicatorutils/downloadblocks/index.html +++ b/docs/html/src/communicatorutils/downloadblocks/index.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.downloadblocks API documentation + +src.communicatorutils.downloadblocks API documentation - + @@ -17,19 +17,42 @@
-

Module onionr.communicatorutils.downloadblocks

+

Module src.communicatorutils.downloadblocks

Onionr - Private P2P Communication

Download blocks using the communicator instance

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
     Download blocks using the communicator instance
-'''
-'''
+"""
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
+
+from gevent import spawn
+
+import onionrexceptions
+import logger
+import onionrpeers
+import communicator
+from communicator import peeraction
+from communicator import onlinepeers
+from onionrutils import blockmetadata
+from onionrutils import validatemetadata
+from coredb import blockmetadb
+from onionrutils.localcommand import local_command
+import onionrcrypto
+import onionrstorage
+from onionrblocks import onionrblacklist
+from onionrblocks import storagecounter
+from . import shoulddownload
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,18 +65,11 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import communicator, onionrexceptions
-import logger, onionrpeers
-from onionrutils import blockmetadata, stringvalidators, validatemetadata
-from coredb import blockmetadb
-from . import shoulddownload
-from communicator import peeraction, onlinepeers
-import onionrcrypto, onionrstorage
-from onionrblocks import onionrblacklist, storagecounter
-def download_blocks_from_communicator(comm_inst):
-    '''Use Onionr communicator instance to download blocks in the communicator's queue'''
-    assert isinstance(comm_inst, communicator.OnionrCommunicatorDaemon)
+"""
+
+
+def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"):
+    """Use communicator instance to download blocks in the comms's queue"""
     blacklist = onionrblacklist.OnionrBlackList()
     storage_counter = storagecounter.StorageCounter()
     LOG_SKIP_COUNT = 50 # for how many iterations we skip logging the counter
@@ -62,8 +78,7 @@ def download_blocks_from_communicator(comm_inst):
     # Iterate the block queue in the communicator
     for blockHash in list(comm_inst.blockQueue):
         count += 1
-        if len(comm_inst.onlinePeers) == 0:
-            break
+
         triedQueuePeers = [] # List of peers we've tried for a block
         try:
             blockPeers = list(comm_inst.blockQueue[blockHash])
@@ -79,12 +94,17 @@ def download_blocks_from_communicator(comm_inst):
             break
         # Do not download blocks being downloaded
         if blockHash in comm_inst.currentDownloading:
-            #logger.debug('Already downloading block %s...' % blockHash)
             continue
 
+        if len(comm_inst.onlinePeers) == 0:
+            break
+
         comm_inst.currentDownloading.append(blockHash) # So we can avoid concurrent downloading in other threads of same block
         if len(blockPeers) == 0:
-            peerUsed = onlinepeers.pick_online_peer(comm_inst)
+            try:
+                peerUsed = onlinepeers.pick_online_peer(comm_inst)
+            except onionrexceptions.OnlinePeerNeeded:
+                continue
         else:
             blockPeers = onionrcrypto.cryptoutils.random_shuffle(blockPeers)
             peerUsed = blockPeers.pop(0)
@@ -93,7 +113,7 @@ def download_blocks_from_communicator(comm_inst):
             logger.info("Attempting to download %s from %s..." % (blockHash[:12], peerUsed))
         content = peeraction.peer_action(comm_inst, peerUsed, 'getdata/' + blockHash, max_resp_size=3000000) # block content from random peer (includes metadata)
 
-        if content != False and len(content) > 0:
+        if content is not False and len(content) > 0:
             try:
                 content = content.encode()
             except AttributeError:
@@ -109,7 +129,8 @@ def download_blocks_from_communicator(comm_inst):
                 metas = blockmetadata.get_block_metadata_from_data(content) # returns tuple(metadata, meta), meta is also in metadata
                 metadata = metas[0]
                 try:
-                    metadata_validation_result = validatemetadata.validate_metadata(metadata, metas[2])
+                    metadata_validation_result = \
+                        validatemetadata.validate_metadata(metadata, metas[2])
                 except onionrexceptions.DataExists:
                     metadata_validation_result = False
                 if metadata_validation_result: # check if metadata is valid, and verify nonce
@@ -124,6 +145,14 @@ def download_blocks_from_communicator(comm_inst):
                             removeFromQueue = False
                         else:
                             blockmetadb.add_to_block_DB(blockHash, dataSaved=True) # add block to meta db
+                            spawn(
+                                local_command,
+                                f'/daemon-event/upload_event',
+                                post=True,
+                                is_json=True,
+                                postData={'block': blockHash}
+                            )
+
                             blockmetadata.process_block_metadata(blockHash) # caches block metadata values to block database
                     else:
                         logger.warn('POW failed for block %s.' % (blockHash,))
@@ -144,14 +173,17 @@ def download_blocks_from_communicator(comm_inst):
                 onionrpeers.PeerProfiles(peerUsed).addScore(-50)
                 if tempHash != 'ed55e34cb828232d6c14da0479709bfa10a0923dca2b380496e6b2ed4f7a0253':
                     # Dumb hack for 404 response from peer. Don't log it if 404 since its likely not malicious or a critical error.
-                    logger.warn('Block hash validation failed for ' + blockHash + ' got ' + tempHash)
+                    logger.warn(
+                        'Block hash validation failed for ' +
+                        blockHash + ' got ' + tempHash)
                 else:
                     removeFromQueue = False # Don't remove from queue if 404
             if removeFromQueue:
                 try:
                     del comm_inst.blockQueue[blockHash] # remove from block queue both if success or false
                     if count == LOG_SKIP_COUNT:
-                        logger.info('%s blocks remaining in queue' % [len(comm_inst.blockQueue)], terminal=True)
+                        logger.info('%s blocks remaining in queue' %
+                        [len(comm_inst.blockQueue)], terminal=True)
                         count = 0
                 except KeyError:
                     pass
@@ -162,7 +194,7 @@ def download_blocks_from_communicator(comm_inst):
 

Sub-modules

-
onionr.communicatorutils.downloadblocks.shoulddownload
+
src.communicatorutils.downloadblocks.shoulddownload

Onionr - Private P2P Communication …

@@ -173,16 +205,17 @@ def download_blocks_from_communicator(comm_inst):

Functions

-
+
def download_blocks_from_communicator(comm_inst)
-

Use Onionr communicator instance to download blocks in the communicator's queue

+

Use communicator instance to download blocks in the comms's queue

-Source code -
def download_blocks_from_communicator(comm_inst):
-    '''Use Onionr communicator instance to download blocks in the communicator's queue'''
-    assert isinstance(comm_inst, communicator.OnionrCommunicatorDaemon)
+
+Expand source code
+
+
def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"):
+    """Use communicator instance to download blocks in the comms's queue"""
     blacklist = onionrblacklist.OnionrBlackList()
     storage_counter = storagecounter.StorageCounter()
     LOG_SKIP_COUNT = 50 # for how many iterations we skip logging the counter
@@ -191,8 +224,7 @@ def download_blocks_from_communicator(comm_inst):
     # Iterate the block queue in the communicator
     for blockHash in list(comm_inst.blockQueue):
         count += 1
-        if len(comm_inst.onlinePeers) == 0:
-            break
+
         triedQueuePeers = [] # List of peers we've tried for a block
         try:
             blockPeers = list(comm_inst.blockQueue[blockHash])
@@ -208,12 +240,17 @@ def download_blocks_from_communicator(comm_inst):
             break
         # Do not download blocks being downloaded
         if blockHash in comm_inst.currentDownloading:
-            #logger.debug('Already downloading block %s...' % blockHash)
             continue
 
+        if len(comm_inst.onlinePeers) == 0:
+            break
+
         comm_inst.currentDownloading.append(blockHash) # So we can avoid concurrent downloading in other threads of same block
         if len(blockPeers) == 0:
-            peerUsed = onlinepeers.pick_online_peer(comm_inst)
+            try:
+                peerUsed = onlinepeers.pick_online_peer(comm_inst)
+            except onionrexceptions.OnlinePeerNeeded:
+                continue
         else:
             blockPeers = onionrcrypto.cryptoutils.random_shuffle(blockPeers)
             peerUsed = blockPeers.pop(0)
@@ -222,7 +259,7 @@ def download_blocks_from_communicator(comm_inst):
             logger.info("Attempting to download %s from %s..." % (blockHash[:12], peerUsed))
         content = peeraction.peer_action(comm_inst, peerUsed, 'getdata/' + blockHash, max_resp_size=3000000) # block content from random peer (includes metadata)
 
-        if content != False and len(content) > 0:
+        if content is not False and len(content) > 0:
             try:
                 content = content.encode()
             except AttributeError:
@@ -238,7 +275,8 @@ def download_blocks_from_communicator(comm_inst):
                 metas = blockmetadata.get_block_metadata_from_data(content) # returns tuple(metadata, meta), meta is also in metadata
                 metadata = metas[0]
                 try:
-                    metadata_validation_result = validatemetadata.validate_metadata(metadata, metas[2])
+                    metadata_validation_result = \
+                        validatemetadata.validate_metadata(metadata, metas[2])
                 except onionrexceptions.DataExists:
                     metadata_validation_result = False
                 if metadata_validation_result: # check if metadata is valid, and verify nonce
@@ -253,6 +291,14 @@ def download_blocks_from_communicator(comm_inst):
                             removeFromQueue = False
                         else:
                             blockmetadb.add_to_block_DB(blockHash, dataSaved=True) # add block to meta db
+                            spawn(
+                                local_command,
+                                f'/daemon-event/upload_event',
+                                post=True,
+                                is_json=True,
+                                postData={'block': blockHash}
+                            )
+
                             blockmetadata.process_block_metadata(blockHash) # caches block metadata values to block database
                     else:
                         logger.warn('POW failed for block %s.' % (blockHash,))
@@ -273,14 +319,17 @@ def download_blocks_from_communicator(comm_inst):
                 onionrpeers.PeerProfiles(peerUsed).addScore(-50)
                 if tempHash != 'ed55e34cb828232d6c14da0479709bfa10a0923dca2b380496e6b2ed4f7a0253':
                     # Dumb hack for 404 response from peer. Don't log it if 404 since its likely not malicious or a critical error.
-                    logger.warn('Block hash validation failed for ' + blockHash + ' got ' + tempHash)
+                    logger.warn(
+                        'Block hash validation failed for ' +
+                        blockHash + ' got ' + tempHash)
                 else:
                     removeFromQueue = False # Don't remove from queue if 404
             if removeFromQueue:
                 try:
                     del comm_inst.blockQueue[blockHash] # remove from block queue both if success or false
                     if count == LOG_SKIP_COUNT:
-                        logger.info('%s blocks remaining in queue' % [len(comm_inst.blockQueue)], terminal=True)
+                        logger.info('%s blocks remaining in queue' %
+                        [len(comm_inst.blockQueue)], terminal=True)
                         count = 0
                 except KeyError:
                     pass
@@ -301,24 +350,24 @@ def download_blocks_from_communicator(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/downloadblocks/shoulddownload.html b/docs/html/src/communicatorutils/downloadblocks/shoulddownload.html similarity index 63% rename from docs/html/onionr/communicatorutils/downloadblocks/shoulddownload.html rename to docs/html/src/communicatorutils/downloadblocks/shoulddownload.html index a69a4374..bccea6e2 100644 --- a/docs/html/onionr/communicatorutils/downloadblocks/shoulddownload.html +++ b/docs/html/src/communicatorutils/downloadblocks/shoulddownload.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.downloadblocks.shoulddownload API documentation + +src.communicatorutils.downloadblocks.shoulddownload API documentation - + @@ -17,19 +17,24 @@
-

Module onionr.communicatorutils.downloadblocks.shoulddownload

+

Module src.communicatorutils.downloadblocks.shoulddownload

-

Onionr - Private P2P Communication

-

Check if a block should be downloaded (if we already have it or its blacklisted or not)

+

Onionr - Private P2P Communication.

+

Check if a block should be downloaded +(if we already have it or its blacklisted or not)

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Check if a block should be downloaded (if we already have it or its blacklisted or not)
-'''
-'''
+Check if a block should be downloaded
+(if we already have it or its blacklisted or not)
+"""
+from coredb import blockmetadb
+from onionrblocks import onionrblacklist
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,25 +47,27 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from coredb import blockmetadb
-from onionrblocks import onionrblacklist
+"""
 
-def should_download(comm_inst, block_hash):
+
+def should_download(comm_inst, block_hash) -> bool:
+    """Return bool for if a (assumed to exist) block should be downloaded."""
     blacklist = onionrblacklist.OnionrBlackList()
-    ret_data = True
-    if block_hash in blockmetadb.get_block_list(): # Dont download block we have
-        ret_data = False
+    should = True
+    if block_hash in blockmetadb.get_block_list():
+        # Don't download block we have
+        should = False
     else:
-        if blacklist.inBlacklist(block_hash): # Dont download blacklisted block
-            ret_data = False
-    if ret_data is False:
-        # Remove block from communicator queue if it shouldnt be downloaded
+        if blacklist.inBlacklist(block_hash):
+            # Don't download blacklisted block
+            should = False
+    if should is False:
+        # Remove block from communicator queue if it shouldn't be downloaded
         try:
             del comm_inst.blockQueue[block_hash]
         except KeyError:
             pass
-    return ret_data
+ return should
@@ -70,28 +77,33 @@ def should_download(comm_inst, block_hash):

Functions

-
+
def should_download(comm_inst, block_hash)
-
+

Return bool for if a (assumed to exist) block should be downloaded.

-Source code -
def should_download(comm_inst, block_hash):
+
+Expand source code
+
+
def should_download(comm_inst, block_hash) -> bool:
+    """Return bool for if a (assumed to exist) block should be downloaded."""
     blacklist = onionrblacklist.OnionrBlackList()
-    ret_data = True
-    if block_hash in blockmetadb.get_block_list(): # Dont download block we have
-        ret_data = False
+    should = True
+    if block_hash in blockmetadb.get_block_list():
+        # Don't download block we have
+        should = False
     else:
-        if blacklist.inBlacklist(block_hash): # Dont download blacklisted block
-            ret_data = False
-    if ret_data is False:
-        # Remove block from communicator queue if it shouldnt be downloaded
+        if blacklist.inBlacklist(block_hash):
+            # Don't download blacklisted block
+            should = False
+    if should is False:
+        # Remove block from communicator queue if it shouldn't be downloaded
         try:
             del comm_inst.blockQueue[block_hash]
         except KeyError:
             pass
-    return ret_data
+ return should
@@ -107,19 +119,19 @@ def should_download(comm_inst, block_hash):
diff --git a/docs/html/onionr/communicatorutils/housekeeping.html b/docs/html/src/communicatorutils/housekeeping.html similarity index 83% rename from docs/html/onionr/communicatorutils/housekeeping.html rename to docs/html/src/communicatorutils/housekeeping.html index 6d8e7976..ca728136 100644 --- a/docs/html/onionr/communicatorutils/housekeeping.html +++ b/docs/html/src/communicatorutils/housekeeping.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.housekeeping API documentation + +src.communicatorutils.housekeeping API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.housekeeping

+

Module src.communicatorutils.housekeeping

Onionr - Private P2P Communication

Cleanup old Onionr blocks and forward secrecy keys using the communicator. Ran from a timer usually

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -108,13 +110,15 @@ def clean_keys(comm_inst):
 

Functions

-
+
def clean_keys(comm_inst)

Delete expired forward secrecy keys

-Source code + +Expand source code +
def clean_keys(comm_inst):
     '''Delete expired forward secrecy keys'''
     conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10)
@@ -137,13 +141,15 @@ def clean_keys(comm_inst):
     comm_inst.decrementThreadCount('clean_keys')
-
+
def clean_old_blocks(comm_inst)

Delete old blocks if our disk allocation is full/near full, and also expired blocks

-Source code + +Expand source code +
def clean_old_blocks(comm_inst):
     '''Delete old blocks if our disk allocation is full/near full, and also expired blocks'''
     blacklist = onionrblacklist.OnionrBlackList()
@@ -179,20 +185,20 @@ def clean_keys(comm_inst):
 
 
 
diff --git a/docs/html/onionr/onionrcommands/index.html b/docs/html/src/communicatorutils/index.html similarity index 52% rename from docs/html/onionr/onionrcommands/index.html rename to docs/html/src/communicatorutils/index.html index 6fac25e2..c6ceade3 100644 --- a/docs/html/onionr/onionrcommands/index.html +++ b/docs/html/src/communicatorutils/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands API documentation + +src.communicatorutils API documentation - + @@ -17,69 +17,69 @@
-

Module onionr.onionrcommands

+

Module src.communicatorutils

Sub-modules

-
onionr.onionrcommands.banblocks
+
src.communicatorutils.announcenode

Onionr - Private P2P Communication …

-
onionr.onionrcommands.daemonlaunch
+
src.communicatorutils.connectnewpeers

Onionr - Private P2P Communication …

-
onionr.onionrcommands.exportblocks
+
src.communicatorutils.cooldownpeer

Onionr - Private P2P Communication …

-
onionr.onionrcommands.filecommands
+
src.communicatorutils.deniableinserts

Onionr - Private P2P Communication …

-
onionr.onionrcommands.keyadders
+
src.communicatorutils.downloadblocks

Onionr - Private P2P Communication …

-
onionr.onionrcommands.onionrstatistics
+
src.communicatorutils.housekeeping

Onionr - Private P2P Communication …

-
onionr.onionrcommands.openwebinterface
+
src.communicatorutils.lookupadders

Onionr - Private P2P Communication …

-
onionr.onionrcommands.parser
+
src.communicatorutils.lookupblocks

Onionr - Private P2P Communication …

-
onionr.onionrcommands.pubkeymanager
+
src.communicatorutils.netcheck

Onionr - Private P2P Communication …

-
onionr.onionrcommands.resetplugins
+
src.communicatorutils.onionrcommunicatortimers

Onionr - Private P2P Communication …

-
onionr.onionrcommands.resettor
+
src.communicatorutils.proxypicker

Onionr - Private P2P Communication …

-
onionr.onionrcommands.restartonionr
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrcommands.softreset
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrcommands.version
+
src.communicatorutils.restarttor
+
src.communicatorutils.servicecreator
+
+

Onionr - Private P2P Communication …

+
+
src.communicatorutils.uploadblocks
+
+

Onionr - Private P2P Communication …

+
@@ -97,32 +97,32 @@
diff --git a/docs/html/onionr/communicatorutils/lookupadders.html b/docs/html/src/communicatorutils/lookupadders.html similarity index 78% rename from docs/html/onionr/communicatorutils/lookupadders.html rename to docs/html/src/communicatorutils/lookupadders.html index 1d9bf029..b944c6ca 100644 --- a/docs/html/onionr/communicatorutils/lookupadders.html +++ b/docs/html/src/communicatorutils/lookupadders.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.lookupadders API documentation + +src.communicatorutils.lookupadders API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.lookupadders

+

Module src.communicatorutils.lookupadders

Onionr - Private P2P Communication

Lookup new peer transport addresses using the communicator

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -47,6 +49,7 @@ import logger
 from onionrutils import stringvalidators
 from communicator import peeraction, onlinepeers
 from utils import gettransports
+import onionrexceptions
 def lookup_new_peer_transports_with_communicator(comm_inst):
     logger.info('Looking up new addresses...')
     tryAmount = 1
@@ -58,8 +61,11 @@ def lookup_new_peer_transports_with_communicator(comm_inst):
         if len(newPeers) > 10000:
             # Don't get new peers if we have too many queued up
             break
-        peer = onlinepeers.pick_online_peer(comm_inst)
-        newAdders = peeraction.peer_action(comm_inst, peer, action='pex')
+        try:
+            peer = onlinepeers.pick_online_peer(comm_inst)
+            newAdders = peeraction.peer_action(comm_inst, peer, action='pex')
+        except onionrexceptions.OnlinePeerNeeded:
+            continue
         try:
             newPeers = newAdders.split(',')
         except AttributeError:
@@ -88,13 +94,15 @@ def lookup_new_peer_transports_with_communicator(comm_inst):
 

Functions

-
+
def lookup_new_peer_transports_with_communicator(comm_inst)
-Source code + +Expand source code +
def lookup_new_peer_transports_with_communicator(comm_inst):
     logger.info('Looking up new addresses...')
     tryAmount = 1
@@ -106,8 +114,11 @@ def lookup_new_peer_transports_with_communicator(comm_inst):
         if len(newPeers) > 10000:
             # Don't get new peers if we have too many queued up
             break
-        peer = onlinepeers.pick_online_peer(comm_inst)
-        newAdders = peeraction.peer_action(comm_inst, peer, action='pex')
+        try:
+            peer = onlinepeers.pick_online_peer(comm_inst)
+            newAdders = peeraction.peer_action(comm_inst, peer, action='pex')
+        except onionrexceptions.OnlinePeerNeeded:
+            continue
         try:
             newPeers = newAdders.split(',')
         except AttributeError:
@@ -142,19 +153,19 @@ def lookup_new_peer_transports_with_communicator(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/lookupblocks.html b/docs/html/src/communicatorutils/lookupblocks.html similarity index 85% rename from docs/html/onionr/communicatorutils/lookupblocks.html rename to docs/html/src/communicatorutils/lookupblocks.html index 9f74b529..cf3b3aff 100644 --- a/docs/html/onionr/communicatorutils/lookupblocks.html +++ b/docs/html/src/communicatorutils/lookupblocks.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.lookupblocks API documentation + +src.communicatorutils.lookupblocks API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.lookupblocks

+

Module src.communicatorutils.lookupblocks

Onionr - Private P2P Communication

Lookup new blocks with the communicator using a random connected peer

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -43,12 +45,15 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
+from gevent import time
+
 import logger, onionrproofs
 from onionrutils import stringvalidators, epoch
 from communicator import peeraction, onlinepeers
 from coredb import blockmetadb
 from utils import reconstructhash
 from onionrblocks import onionrblacklist
+import onionrexceptions
 blacklist = onionrblacklist.OnionrBlackList()
 def lookup_blocks_from_communicator(comm_inst):
     logger.info('Looking up new blocks')
@@ -69,7 +74,12 @@ def lookup_blocks_from_communicator(comm_inst):
         if comm_inst.storage_counter.is_full():
             logger.debug('Not looking up new blocks due to maximum amount of allowed disk space used')
             break
-        peer = onlinepeers.pick_online_peer(comm_inst) # select random online peer
+        try:
+            # select random online peer
+            peer = onlinepeers.pick_online_peer(comm_inst)
+        except onionrexceptions.OnlinePeerNeeded:
+            time.sleep(1)
+            continue
         # if we've already tried all the online peers this time around, stop
         if peer in triedPeers:
             if len(comm_inst.onlinePeers) == len(triedPeers):
@@ -127,13 +137,15 @@ def lookup_blocks_from_communicator(comm_inst):
 

Functions

-
+
def lookup_blocks_from_communicator(comm_inst)
-Source code + +Expand source code +
def lookup_blocks_from_communicator(comm_inst):
     logger.info('Looking up new blocks')
     tryAmount = 2
@@ -153,7 +165,12 @@ def lookup_blocks_from_communicator(comm_inst):
         if comm_inst.storage_counter.is_full():
             logger.debug('Not looking up new blocks due to maximum amount of allowed disk space used')
             break
-        peer = onlinepeers.pick_online_peer(comm_inst) # select random online peer
+        try:
+            # select random online peer
+            peer = onlinepeers.pick_online_peer(comm_inst)
+        except onionrexceptions.OnlinePeerNeeded:
+            time.sleep(1)
+            continue
         # if we've already tried all the online peers this time around, stop
         if peer in triedPeers:
             if len(comm_inst.onlinePeers) == len(triedPeers):
@@ -217,19 +234,19 @@ def lookup_blocks_from_communicator(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/netcheck.html b/docs/html/src/communicatorutils/netcheck.html similarity index 67% rename from docs/html/onionr/communicatorutils/netcheck.html rename to docs/html/src/communicatorutils/netcheck.html index fa091a4c..dca80ddd 100644 --- a/docs/html/onionr/communicatorutils/netcheck.html +++ b/docs/html/src/communicatorutils/netcheck.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.netcheck API documentation + +src.communicatorutils.netcheck API documentation - + @@ -17,21 +17,29 @@
-

Module onionr.communicatorutils.netcheck

+

Module src.communicatorutils.netcheck

Onionr - Private P2P Communication

-

Determine if our node is able to use Tor based on the status of a communicator instance +

Determine if our node is able to use Tor based +on the status of a communicator instance and the result of pinging onion http servers

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
-    Determine if our node is able to use Tor based on the status of a communicator instance
+    Determine if our node is able to use Tor based
+    on the status of a communicator instance
     and the result of pinging onion http servers
-'''
-'''
+"""
+import logger
+from utils import netutils
+from onionrutils import localcommand, epoch
+from . import restarttor
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -44,26 +52,30 @@ and the result of pinging onion http servers

You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. -''' -import logger -from utils import netutils -from onionrutils import localcommand, epoch -from . import restarttor +""" + + def net_check(comm_inst): - '''Check if we are connected to the internet or not when we can't connect to any peers''' - rec = False # for detecting if we have received incoming connections recently + """Check if we are connected to the internet + or not when we can't connect to any peers""" + # for detecting if we have received incoming connections recently + rec = False if len(comm_inst.onlinePeers) == 0: try: - if (epoch.get_epoch() - int(localcommand.local_command('/lastconnect'))) <= 60: + if (epoch.get_epoch() - int(localcommand.local_command + ('/lastconnect'))) <= 60: comm_inst.isOnline = True rec = True except ValueError: pass if not rec and not netutils.checkNetwork(torPort=comm_inst.proxyPort): if not comm_inst.shutdown: - logger.warn('Network check failed, are you connected to the Internet, and is Tor working?', terminal=True) - restarttor.restart(comm_inst) - comm_inst.offlinePeers = [] + if not comm_inst.config.get('general.offline_mode', False): + logger.warn('Network check failed, are you connected to ' + + 'the Internet, and is Tor working?', + terminal=True) + restarttor.restart(comm_inst) + comm_inst.offlinePeers = [] comm_inst.isOnline = False else: comm_inst.isOnline = True @@ -77,28 +89,37 @@ def net_check(comm_inst):

Functions

-
+
def net_check(comm_inst)
-

Check if we are connected to the internet or not when we can't connect to any peers

+

Check if we are connected to the internet +or not when we can't connect to any peers

-Source code + +Expand source code +
def net_check(comm_inst):
-    '''Check if we are connected to the internet or not when we can't connect to any peers'''
-    rec = False # for detecting if we have received incoming connections recently
+    """Check if we are connected to the internet
+    or not when we can't connect to any peers"""
+    # for detecting if we have received incoming connections recently
+    rec = False
     if len(comm_inst.onlinePeers) == 0:
         try:
-            if (epoch.get_epoch() - int(localcommand.local_command('/lastconnect'))) <= 60:
+            if (epoch.get_epoch() - int(localcommand.local_command
+                                        ('/lastconnect'))) <= 60:
                 comm_inst.isOnline = True
                 rec = True
         except ValueError:
             pass
         if not rec and not netutils.checkNetwork(torPort=comm_inst.proxyPort):
             if not comm_inst.shutdown:
-                logger.warn('Network check failed, are you connected to the Internet, and is Tor working?', terminal=True)
-                restarttor.restart(comm_inst)
-                comm_inst.offlinePeers = []
+                if not comm_inst.config.get('general.offline_mode', False):
+                    logger.warn('Network check failed, are you connected to ' +
+                                'the Internet, and is Tor working?',
+                                terminal=True)
+                    restarttor.restart(comm_inst)
+                    comm_inst.offlinePeers = []
             comm_inst.isOnline = False
         else:
             comm_inst.isOnline = True
@@ -118,19 +139,19 @@ def net_check(comm_inst):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/onionrcommunicatortimers.html b/docs/html/src/communicatorutils/onionrcommunicatortimers.html similarity index 85% rename from docs/html/onionr/communicatorutils/onionrcommunicatortimers.html rename to docs/html/src/communicatorutils/onionrcommunicatortimers.html index 4d399de5..bd9eb693 100644 --- a/docs/html/onionr/communicatorutils/onionrcommunicatortimers.html +++ b/docs/html/src/communicatorutils/onionrcommunicatortimers.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.onionrcommunicatortimers API documentation + +src.communicatorutils.onionrcommunicatortimers API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.onionrcommunicatortimers

+

Module src.communicatorutils.onionrcommunicatortimers

Onionr - Private P2P Communication

This file contains timer control for the communicator

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -93,7 +95,7 @@ class OnionrCommunicatorTimers:
                 if self.make_thread:
                     for i in range(self.thread_amount):
                         if self.daemon_inst.threadCounts[self.timer_function.__name__] >= self.max_threads:
-                            logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__, terminal=True)
+                            logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__)
                         else:
                             self.daemon_inst.threadCounts[self.timer_function.__name__] += 1
                             newThread = threading.Thread(target=self.timer_function, args=self.args, daemon=True, 
@@ -114,14 +116,16 @@ class OnionrCommunicatorTimers:
 

Classes

-
+
class OnionrCommunicatorTimers (daemon_inst, timer_function, frequency, make_thread=True, thread_amount=1, max_threads=5, requires_peer=False, my_args=[])
-Source code + +Expand source code +
class OnionrCommunicatorTimers:
     def __init__(self, daemon_inst: OnionrCommunicatorDaemon, 
                 timer_function: Callable, frequency: CallFreqSeconds, 
@@ -158,7 +162,7 @@ class OnionrCommunicatorTimers:
                 if self.make_thread:
                     for i in range(self.thread_amount):
                         if self.daemon_inst.threadCounts[self.timer_function.__name__] >= self.max_threads:
-                            logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__, terminal=True)
+                            logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__)
                         else:
                             self.daemon_inst.threadCounts[self.timer_function.__name__] += 1
                             newThread = threading.Thread(target=self.timer_function, args=self.args, daemon=True, 
@@ -171,13 +175,15 @@ class OnionrCommunicatorTimers:
 

Methods

-
+
def processTimer(self)
-Source code + +Expand source code +
def processTimer(self):
 
     # mark how many instances of a thread we have (decremented at thread end)
@@ -197,7 +203,7 @@ class OnionrCommunicatorTimers:
             if self.make_thread:
                 for i in range(self.thread_amount):
                     if self.daemon_inst.threadCounts[self.timer_function.__name__] >= self.max_threads:
-                        logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__, terminal=True)
+                        logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timer_function.__name__)
                     else:
                         self.daemon_inst.threadCounts[self.timer_function.__name__] += 1
                         newThread = threading.Thread(target=self.timer_function, args=self.args, daemon=True, 
@@ -222,15 +228,15 @@ class OnionrCommunicatorTimers:
 
diff --git a/docs/html/onionr/communicatorutils/proxypicker.html b/docs/html/src/communicatorutils/proxypicker.html similarity index 76% rename from docs/html/onionr/communicatorutils/proxypicker.html rename to docs/html/src/communicatorutils/proxypicker.html index fb18a7d4..66f47e26 100644 --- a/docs/html/onionr/communicatorutils/proxypicker.html +++ b/docs/html/src/communicatorutils/proxypicker.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.proxypicker API documentation + +src.communicatorutils.proxypicker API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.proxypicker

+

Module src.communicatorutils.proxypicker

Onionr - Private P2P Communication

Just picks a proxy to use based on a peer's address

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -49,7 +51,7 @@ def pick_proxy(peer_address):
         return 'tor'
     elif peer_address.endswith('.i2p'):
         return 'i2p'
-    raise ValueError("Peer address was not string ending with acceptable value")
+ raise ValueError(f"Peer address was not string ending with acceptable value: {peer_address}")
@@ -59,19 +61,21 @@ def pick_proxy(peer_address):

Functions

-
+
def pick_proxy(peer_address)
-Source code + +Expand source code +
def pick_proxy(peer_address):
     if peer_address.endswith('.onion'):
         return 'tor'
     elif peer_address.endswith('.i2p'):
         return 'i2p'
-    raise ValueError("Peer address was not string ending with acceptable value")
+ raise ValueError(f"Peer address was not string ending with acceptable value: {peer_address}")
@@ -87,19 +91,19 @@ def pick_proxy(peer_address):
diff --git a/docs/html/onionr/communicatorutils/restarttor.html b/docs/html/src/communicatorutils/restarttor.html similarity index 70% rename from docs/html/onionr/communicatorutils/restarttor.html rename to docs/html/src/communicatorutils/restarttor.html index 02688945..136d230f 100644 --- a/docs/html/onionr/communicatorutils/restarttor.html +++ b/docs/html/src/communicatorutils/restarttor.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.restarttor API documentation + +src.communicatorutils.restarttor API documentation - + @@ -17,16 +17,21 @@
-

Module onionr.communicatorutils.restarttor

+

Module src.communicatorutils.restarttor

-Source code + +Expand source code +
import netcontroller
+import config
+
 def restart(comm_inst):
-    net = comm_inst.shared_state.get(netcontroller.NetController)
-    net.killTor()
-    net.startTor()
+ if not config.get('tor.use_existing_tor', False): + net = comm_inst.shared_state.get(netcontroller.NetController) + net.killTor() + net.startTor()
@@ -36,17 +41,20 @@ def restart(comm_inst):

Functions

-
+
def restart(comm_inst)
-Source code + +Expand source code +
def restart(comm_inst):
-    net = comm_inst.shared_state.get(netcontroller.NetController)
-    net.killTor()
-    net.startTor()
+ if not config.get('tor.use_existing_tor', False): + net = comm_inst.shared_state.get(netcontroller.NetController) + net.killTor() + net.startTor()
@@ -62,19 +70,19 @@ def restart(comm_inst):
diff --git a/docs/html/onionr/communicatorutils/servicecreator.html b/docs/html/src/communicatorutils/servicecreator.html similarity index 83% rename from docs/html/onionr/communicatorutils/servicecreator.html rename to docs/html/src/communicatorutils/servicecreator.html index 93b6f909..61077a81 100644 --- a/docs/html/onionr/communicatorutils/servicecreator.html +++ b/docs/html/src/communicatorutils/servicecreator.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.servicecreator API documentation + +src.communicatorutils.servicecreator API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.communicatorutils.servicecreator

+

Module src.communicatorutils.servicecreator

Onionr - Private P2P Communication

Creates an onionr direct connection service by scanning all connection blocks

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -78,13 +80,15 @@ def service_creator(daemon):
 

Functions

-
+
def service_creator(daemon)
-Source code + +Expand source code +
def service_creator(daemon):
     assert isinstance(daemon, communicator.OnionrCommunicatorDaemon)
     
@@ -120,19 +124,19 @@ def service_creator(daemon):
 
 
 
diff --git a/docs/html/onionr/communicatorutils/uploadblocks/index.html b/docs/html/src/communicatorutils/uploadblocks/index.html similarity index 58% rename from docs/html/onionr/communicatorutils/uploadblocks/index.html rename to docs/html/src/communicatorutils/uploadblocks/index.html index d83db240..8869c154 100644 --- a/docs/html/onionr/communicatorutils/uploadblocks/index.html +++ b/docs/html/src/communicatorutils/uploadblocks/index.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.uploadblocks API documentation + +src.communicatorutils.uploadblocks API documentation - + @@ -17,20 +17,36 @@
-

Module onionr.communicatorutils.uploadblocks

+

Module src.communicatorutils.uploadblocks

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Upload blocks in the upload queue to peers from the communicator

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Upload blocks in the upload queue to peers from the communicator
-'''
-from __future__ import annotations
-'''
+Upload blocks in the upload queue to peers from the communicator
+"""
+from typing import TYPE_CHECKING
+from time import sleep
+from threading import Thread
+
+from . import sessionmanager
+
+from onionrtypes import UserID
+import logger
+from communicatorutils import proxypicker
+import onionrexceptions
+from onionrblocks import onionrblockapi as block
+from onionrutils import stringvalidators, basicrequests
+import onionrcrypto
+from communicator import onlinepeers
+if TYPE_CHECKING:
+    from communicator import OnionrCommunicatorDaemon
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -43,27 +59,31 @@ from __future__ import annotations
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from typing import Union, TYPE_CHECKING
-import logger
-from communicatorutils import proxypicker
-import onionrexceptions
-from onionrblocks import onionrblockapi as block
-from onionrutils import localcommand, stringvalidators, basicrequests
-from communicator import onlinepeers
-import onionrcrypto
-from . import sessionmanager
+"""
 
-def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
-    """Accepts a communicator instance and uploads blocks from its upload queue"""
+
+def upload_blocks_from_communicator(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Accept a communicator instance + upload blocks from its upload queue."""
     """when inserting a block, we try to upload
      it to a few peers to add some deniability & increase functionality"""
     TIMER_NAME = "upload_blocks_from_communicator"
 
-    session_manager: sessionmanager.BlockUploadSessionManager = comm_inst.shared_state.get(sessionmanager.BlockUploadSessionManager)
-    triedPeers = []
+    session_manager: sessionmanager.BlockUploadSessionManager
+    session_manager = comm_inst.shared_state.get(
+        sessionmanager.BlockUploadSessionManager)
+    tried_peers: UserID = []
     finishedUploads = []
-    comm_inst.blocksToUpload = onionrcrypto.cryptoutils.random_shuffle(comm_inst.blocksToUpload)
+    comm_inst.blocksToUpload = onionrcrypto.cryptoutils.random_shuffle(
+        comm_inst.blocksToUpload)
+
+    def remove_from_hidden(bl):
+        sleep(60)
+        try:
+            comm_inst.shared_state.get_by_string(
+                'PublicAPI').hideBlocks.remove(bl)
+        except ValueError:
+            pass
+
     if len(comm_inst.blocksToUpload) != 0:
         for bl in comm_inst.blocksToUpload:
             if not stringvalidators.validate_hash(bl):
@@ -71,30 +91,40 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
                 comm_inst.decrementThreadCount(TIMER_NAME)
                 return
             session = session_manager.add_session(bl)
-            for i in range(min(len(comm_inst.onlinePeers), 6)):
-                peer = onlinepeers.pick_online_peer(comm_inst)
+            for _ in range(min(len(comm_inst.onlinePeers), 6)):
+                try:
+                    peer = onlinepeers.pick_online_peer(comm_inst)
+                except onionrexceptions.OnlinePeerNeeded:
+                    continue
                 try:
                     session.peer_exists[peer]
                     continue
                 except KeyError:
                     pass
                 try:
-                    if session.peer_fails[peer] > 3: continue
+                    if session.peer_fails[peer] > 3:
+                        continue
                 except KeyError:
                     pass
-                if peer in triedPeers: continue
-                triedPeers.append(peer)
+                if peer in tried_peers:
+                    continue
+                tried_peers.append(peer)
                 url = f'http://{peer}/upload'
                 try:
                     data = block.Block(bl).getRaw()
                 except onionrexceptions.NoDataAvailable:
                     finishedUploads.append(bl)
                     break
-                proxyType = proxypicker.pick_proxy(peer)
-                logger.info(f"Uploading block {bl[:8]} to {peer}", terminal=True)
-                resp = basicrequests.do_post_request(url, data=data, proxyType=proxyType, content_type='application/octet-stream')
-                if not resp == False:
+                proxy_type = proxypicker.pick_proxy(peer)
+                logger.info(
+                    f"Uploading block {bl[:8]} to {peer}", terminal=True)
+                resp = basicrequests.do_post_request(
+                    url, data=data, proxyType=proxy_type,
+                    content_type='application/octet-stream')
+                if resp is not False:
                     if resp == 'success':
+                        Thread(target=remove_from_hidden,
+                               args=[bl], daemon=True).start()
                         session.success()
                         session.peer_exists[peer] = True
                     elif resp == 'exists':
@@ -104,13 +134,19 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
                         session.fail()
                         session.fail_peer(peer)
                         comm_inst.getPeerProfileInstance(peer).addScore(-5)
-                        logger.warn(f'Failed to upload {bl[:8]}, reason: {resp[:15]}', terminal=True)
+                        logger.warn(
+                           f'Failed to upload {bl[:8]}, reason: {resp}',
+                           terminal=True)
                 else:
                     session.fail()
         session_manager.clean_session()
     for x in finishedUploads:
         try:
             comm_inst.blocksToUpload.remove(x)
+
+            comm_inst.shared_state.get_by_string(
+                'PublicAPI').hideBlocks.remove(x)
+
         except ValueError:
             pass
     comm_inst.decrementThreadCount(TIMER_NAME)
@@ -119,11 +155,15 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):

Sub-modules

-
onionr.communicatorutils.uploadblocks.session
+
src.communicatorutils.uploadblocks.mixmate

Onionr - Private P2P Communication …

-
onionr.communicatorutils.uploadblocks.sessionmanager
+
src.communicatorutils.uploadblocks.session
+
+

Onionr - Private P2P Communication …

+
+
src.communicatorutils.uploadblocks.sessionmanager

Onionr - Private P2P Communication …

@@ -134,23 +174,37 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):

Functions

-
+
def upload_blocks_from_communicator(comm_inst)
-

Accepts a communicator instance and uploads blocks from its upload queue

+

Accept a communicator instance + upload blocks from its upload queue.

-Source code -
def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
-    """Accepts a communicator instance and uploads blocks from its upload queue"""
+
+Expand source code
+
+
def upload_blocks_from_communicator(comm_inst: 'OnionrCommunicatorDaemon'):
+    """Accept a communicator instance + upload blocks from its upload queue."""
     """when inserting a block, we try to upload
      it to a few peers to add some deniability & increase functionality"""
     TIMER_NAME = "upload_blocks_from_communicator"
 
-    session_manager: sessionmanager.BlockUploadSessionManager = comm_inst.shared_state.get(sessionmanager.BlockUploadSessionManager)
-    triedPeers = []
+    session_manager: sessionmanager.BlockUploadSessionManager
+    session_manager = comm_inst.shared_state.get(
+        sessionmanager.BlockUploadSessionManager)
+    tried_peers: UserID = []
     finishedUploads = []
-    comm_inst.blocksToUpload = onionrcrypto.cryptoutils.random_shuffle(comm_inst.blocksToUpload)
+    comm_inst.blocksToUpload = onionrcrypto.cryptoutils.random_shuffle(
+        comm_inst.blocksToUpload)
+
+    def remove_from_hidden(bl):
+        sleep(60)
+        try:
+            comm_inst.shared_state.get_by_string(
+                'PublicAPI').hideBlocks.remove(bl)
+        except ValueError:
+            pass
+
     if len(comm_inst.blocksToUpload) != 0:
         for bl in comm_inst.blocksToUpload:
             if not stringvalidators.validate_hash(bl):
@@ -158,30 +212,40 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
                 comm_inst.decrementThreadCount(TIMER_NAME)
                 return
             session = session_manager.add_session(bl)
-            for i in range(min(len(comm_inst.onlinePeers), 6)):
-                peer = onlinepeers.pick_online_peer(comm_inst)
+            for _ in range(min(len(comm_inst.onlinePeers), 6)):
+                try:
+                    peer = onlinepeers.pick_online_peer(comm_inst)
+                except onionrexceptions.OnlinePeerNeeded:
+                    continue
                 try:
                     session.peer_exists[peer]
                     continue
                 except KeyError:
                     pass
                 try:
-                    if session.peer_fails[peer] > 3: continue
+                    if session.peer_fails[peer] > 3:
+                        continue
                 except KeyError:
                     pass
-                if peer in triedPeers: continue
-                triedPeers.append(peer)
+                if peer in tried_peers:
+                    continue
+                tried_peers.append(peer)
                 url = f'http://{peer}/upload'
                 try:
                     data = block.Block(bl).getRaw()
                 except onionrexceptions.NoDataAvailable:
                     finishedUploads.append(bl)
                     break
-                proxyType = proxypicker.pick_proxy(peer)
-                logger.info(f"Uploading block {bl[:8]} to {peer}", terminal=True)
-                resp = basicrequests.do_post_request(url, data=data, proxyType=proxyType, content_type='application/octet-stream')
-                if not resp == False:
+                proxy_type = proxypicker.pick_proxy(peer)
+                logger.info(
+                    f"Uploading block {bl[:8]} to {peer}", terminal=True)
+                resp = basicrequests.do_post_request(
+                    url, data=data, proxyType=proxy_type,
+                    content_type='application/octet-stream')
+                if resp is not False:
                     if resp == 'success':
+                        Thread(target=remove_from_hidden,
+                               args=[bl], daemon=True).start()
                         session.success()
                         session.peer_exists[peer] = True
                     elif resp == 'exists':
@@ -191,13 +255,19 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
                         session.fail()
                         session.fail_peer(peer)
                         comm_inst.getPeerProfileInstance(peer).addScore(-5)
-                        logger.warn(f'Failed to upload {bl[:8]}, reason: {resp[:15]}', terminal=True)
+                        logger.warn(
+                           f'Failed to upload {bl[:8]}, reason: {resp}',
+                           terminal=True)
                 else:
                     session.fail()
         session_manager.clean_session()
     for x in finishedUploads:
         try:
             comm_inst.blocksToUpload.remove(x)
+
+            comm_inst.shared_state.get_by_string(
+                'PublicAPI').hideBlocks.remove(x)
+
         except ValueError:
             pass
     comm_inst.decrementThreadCount(TIMER_NAME)
@@ -216,25 +286,26 @@ def upload_blocks_from_communicator(comm_inst: OnionrCommunicatorDaemon):
diff --git a/docs/html/src/communicatorutils/uploadblocks/mixmate/index.html b/docs/html/src/communicatorutils/uploadblocks/mixmate/index.html new file mode 100644 index 00000000..d46a4b35 --- /dev/null +++ b/docs/html/src/communicatorutils/uploadblocks/mixmate/index.html @@ -0,0 +1,151 @@ + + + + + + +src.communicatorutils.uploadblocks.mixmate API documentation + + + + + + + + + +
+
+
+

Module src.communicatorutils.uploadblocks.mixmate

+
+
+

Onionr - Private P2P Communication.

+

Perform block mixing

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Perform block mixing
+"""
+import time
+from typing import List
+
+import onionrtypes
+from onionrblocks import onionrblockapi
+
+from .pool import UploadPool
+from .pool import PoolFullException
+
+from etc import onionrvalues
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+upload_pool = UploadPool(4)
+
+
+def block_mixer(upload_list: List[onionrtypes.BlockHash],
+                block_to_mix: onionrtypes.BlockHash):
+    """Delay and mix block inserts.
+
+    Take a block list and a received/created block and add it
+    to the said block list
+    """
+    bl = onionrblockapi.Block(block_to_mix)
+
+    if time.time() - bl.claimedTime > onionrvalues.BLOCK_POOL_MAX_AGE:
+        raise ValueError
+    if block_to_mix:
+        upload_list.append(block_to_mix)
+
+
+
+

Sub-modules

+
+
src.communicatorutils.uploadblocks.mixmate.pool
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+

Functions

+
+
+def block_mixer(upload_list, block_to_mix) +
+
+

Delay and mix block inserts.

+

Take a block list and a received/created block and add it +to the said block list

+
+ +Expand source code + +
def block_mixer(upload_list: List[onionrtypes.BlockHash],
+                block_to_mix: onionrtypes.BlockHash):
+    """Delay and mix block inserts.
+
+    Take a block list and a received/created block and add it
+    to the said block list
+    """
+    bl = onionrblockapi.Block(block_to_mix)
+
+    if time.time() - bl.claimedTime > onionrvalues.BLOCK_POOL_MAX_AGE:
+        raise ValueError
+    if block_to_mix:
+        upload_list.append(block_to_mix)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/communicatorutils/uploadblocks/mixmate/pool.html b/docs/html/src/communicatorutils/uploadblocks/mixmate/pool.html new file mode 100644 index 00000000..a3162bf2 --- /dev/null +++ b/docs/html/src/communicatorutils/uploadblocks/mixmate/pool.html @@ -0,0 +1,300 @@ + + + + + + +src.communicatorutils.uploadblocks.mixmate.pool API documentation + + + + + + + + + +
+
+
+

Module src.communicatorutils.uploadblocks.mixmate.pool

+
+
+

Onionr - Private P2P Communication.

+

Upload pool

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Upload pool
+"""
+from typing import List
+
+import onionrutils
+import onionrtypes
+from onionrcrypto import cryptoutils
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class PoolFullException(Exception):
+    """For when the UploadPool is full.
+
+    Raise when a new hash is attempted to be added
+    """
+
+
+class PoolNotReady(Exception):
+    """Raise when UploadPool pool access is attempted without it being full."""
+
+
+class AlreadyInPool(Exception):
+    """Raise when a hash already in pool is attempted to be added again."""
+
+
+class UploadPool:
+    """Upload pool for mixing blocks together and delaying uploads."""
+
+    def __init__(self, pool_size: int):
+        """Create a new pool with a specified max size.
+
+        Uses private var and getter to avoid direct adding
+        """
+        self._pool: List[onionrtypes.BlockHash] = []
+        self._pool_size = pool_size
+        self.birthday = onionrutils.epoch.get_epoch()
+
+    def add_to_pool(self, item: List[onionrtypes.BlockHash]):
+        """Add a new hash to the pool. Raise PoolFullException if full."""
+        if len(self._pool) >= self._pool_size:
+            raise PoolFullException
+        if not onionrutils.stringvalidators.validate_hash(item):
+            raise ValueError
+        self._pool.append(item)
+
+    def get_pool(self) -> List[onionrtypes.BlockHash]:
+        """Get the hash pool in secure random order."""
+        if len(self._pool) != self._pool_size:
+            raise PoolNotReady
+        final_pool: List[onionrtypes.BlockHash] = cryptoutils.random_shuffle(
+            list(self._pool))
+
+        self._pool.clear()
+        self.birthday = onionrutils.epoch.get_epoch()
+        return final_pool
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class AlreadyInPool +(...) +
+
+

Raise when a hash already in pool is attempted to be added again.

+
+ +Expand source code + +
class AlreadyInPool(Exception):
+    """Raise when a hash already in pool is attempted to be added again."""
+
+

Ancestors

+
    +
  • builtins.Exception
  • +
  • builtins.BaseException
  • +
+
+
+class PoolFullException +(...) +
+
+

For when the UploadPool is full.

+

Raise when a new hash is attempted to be added

+
+ +Expand source code + +
class PoolFullException(Exception):
+    """For when the UploadPool is full.
+
+    Raise when a new hash is attempted to be added
+    """
+
+

Ancestors

+
    +
  • builtins.Exception
  • +
  • builtins.BaseException
  • +
+
+
+class PoolNotReady +(...) +
+
+

Raise when UploadPool pool access is attempted without it being full.

+
+ +Expand source code + +
class PoolNotReady(Exception):
+    """Raise when UploadPool pool access is attempted without it being full."""
+
+

Ancestors

+
    +
  • builtins.Exception
  • +
  • builtins.BaseException
  • +
+
+
+class UploadPool +(pool_size) +
+
+

Upload pool for mixing blocks together and delaying uploads.

+

Create a new pool with a specified max size.

+

Uses private var and getter to avoid direct adding

+
+ +Expand source code + +
class UploadPool:
+    """Upload pool for mixing blocks together and delaying uploads."""
+
+    def __init__(self, pool_size: int):
+        """Create a new pool with a specified max size.
+
+        Uses private var and getter to avoid direct adding
+        """
+        self._pool: List[onionrtypes.BlockHash] = []
+        self._pool_size = pool_size
+        self.birthday = onionrutils.epoch.get_epoch()
+
+    def add_to_pool(self, item: List[onionrtypes.BlockHash]):
+        """Add a new hash to the pool. Raise PoolFullException if full."""
+        if len(self._pool) >= self._pool_size:
+            raise PoolFullException
+        if not onionrutils.stringvalidators.validate_hash(item):
+            raise ValueError
+        self._pool.append(item)
+
+    def get_pool(self) -> List[onionrtypes.BlockHash]:
+        """Get the hash pool in secure random order."""
+        if len(self._pool) != self._pool_size:
+            raise PoolNotReady
+        final_pool: List[onionrtypes.BlockHash] = cryptoutils.random_shuffle(
+            list(self._pool))
+
+        self._pool.clear()
+        self.birthday = onionrutils.epoch.get_epoch()
+        return final_pool
+
+

Methods

+
+
+def add_to_pool(self, item) +
+
+

Add a new hash to the pool. Raise PoolFullException if full.

+
+ +Expand source code + +
def add_to_pool(self, item: List[onionrtypes.BlockHash]):
+    """Add a new hash to the pool. Raise PoolFullException if full."""
+    if len(self._pool) >= self._pool_size:
+        raise PoolFullException
+    if not onionrutils.stringvalidators.validate_hash(item):
+        raise ValueError
+    self._pool.append(item)
+
+
+
+def get_pool(self) +
+
+

Get the hash pool in secure random order.

+
+ +Expand source code + +
def get_pool(self) -> List[onionrtypes.BlockHash]:
+    """Get the hash pool in secure random order."""
+    if len(self._pool) != self._pool_size:
+        raise PoolNotReady
+    final_pool: List[onionrtypes.BlockHash] = cryptoutils.random_shuffle(
+        list(self._pool))
+
+    self._pool.clear()
+    self.birthday = onionrutils.epoch.get_epoch()
+    return final_pool
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/communicatorutils/uploadblocks/session.html b/docs/html/src/communicatorutils/uploadblocks/session.html similarity index 67% rename from docs/html/onionr/communicatorutils/uploadblocks/session.html rename to docs/html/src/communicatorutils/uploadblocks/session.html index d6d7c652..64e9f63f 100644 --- a/docs/html/onionr/communicatorutils/uploadblocks/session.html +++ b/docs/html/src/communicatorutils/uploadblocks/session.html @@ -3,13 +3,13 @@ - -onionr.communicatorutils.uploadblocks.session API documentation + +src.communicatorutils.uploadblocks.session API documentation - + @@ -17,19 +17,26 @@
-

Module onionr.communicatorutils.uploadblocks.session

+

Module src.communicatorutils.uploadblocks.session

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Virtual upload "sessions" for blocks

-Source code -
"""
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Virtual upload "sessions" for blocks
+Virtual upload "sessions" for blocks
 """
-from __future__ import annotations
+from typing import Union, Dict
+
+from onionrtypes import UserID
+from onionrutils import stringvalidators
+from onionrutils import bytesconverter
+from onionrutils import epoch
+from utils import reconstructhash
 """
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -44,38 +51,36 @@ from __future__ import annotations
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
-from typing import Union
 
-from onionrutils import stringvalidators
-from onionrutils import bytesconverter
-from onionrutils import epoch
-from utils import reconstructhash
 
 class UploadSession:
-    """Manages statistics for an Onionr block upload session
-    
-    accepting a block hash (incl. unpadded) as an argument""" 
+    """Manage statistics for an Onionr block upload session.
+
+    accept a block hash (incl. unpadded) as an argument
+    """
+
     def __init__(self, block_hash: Union[str, bytes]):
         block_hash = bytesconverter.bytes_to_str(block_hash)
         block_hash = reconstructhash.reconstruct_hash(block_hash)
-        if not stringvalidators.validate_hash(block_hash): raise ValueError
+        if not stringvalidators.validate_hash(block_hash):
+            raise ValueError
 
         self.start_time = epoch.get_epoch()
         self.block_hash = reconstructhash.deconstruct_hash(block_hash)
         self.total_fail_count: int = 0
         self.total_success_count: int = 0
-        self.peer_fails = {}
-        self.peer_exists = {}
-    
+        self.peer_fails: Dict[UserID, int] = {}
+        self.peer_exists: Dict[UserID, bool] = {}
+
     def fail_peer(self, peer):
         try:
             self.peer_fails[peer] += 1
         except KeyError:
             self.peer_fails[peer] = 0
-    
+
     def fail(self):
         self.total_fail_count += 1
-    
+
     def success(self):
         self.total_success_count += 1
@@ -89,63 +94,72 @@ class UploadSession:

Classes

-
+
class UploadSession (block_hash)
-

Manages statistics for an Onionr block upload session

-

accepting a block hash (incl. unpadded) as an argument

+

Manage statistics for an Onionr block upload session.

+

accept a block hash (incl. unpadded) as an argument

-Source code + +Expand source code +
class UploadSession:
-    """Manages statistics for an Onionr block upload session
-    
-    accepting a block hash (incl. unpadded) as an argument""" 
+    """Manage statistics for an Onionr block upload session.
+
+    accept a block hash (incl. unpadded) as an argument
+    """
+
     def __init__(self, block_hash: Union[str, bytes]):
         block_hash = bytesconverter.bytes_to_str(block_hash)
         block_hash = reconstructhash.reconstruct_hash(block_hash)
-        if not stringvalidators.validate_hash(block_hash): raise ValueError
+        if not stringvalidators.validate_hash(block_hash):
+            raise ValueError
 
         self.start_time = epoch.get_epoch()
         self.block_hash = reconstructhash.deconstruct_hash(block_hash)
         self.total_fail_count: int = 0
         self.total_success_count: int = 0
-        self.peer_fails = {}
-        self.peer_exists = {}
-    
+        self.peer_fails: Dict[UserID, int] = {}
+        self.peer_exists: Dict[UserID, bool] = {}
+
     def fail_peer(self, peer):
         try:
             self.peer_fails[peer] += 1
         except KeyError:
             self.peer_fails[peer] = 0
-    
+
     def fail(self):
         self.total_fail_count += 1
-    
+
     def success(self):
         self.total_success_count += 1

Methods

-
+
def fail(self)
-Source code + +Expand source code +
def fail(self):
     self.total_fail_count += 1
-
+
def fail_peer(self, peer)
-Source code + +Expand source code +
def fail_peer(self, peer):
     try:
         self.peer_fails[peer] += 1
@@ -153,13 +167,15 @@ class UploadSession:
         self.peer_fails[peer] = 0
-
+
def success(self)
-Source code + +Expand source code +
def success(self):
     self.total_success_count += 1
@@ -177,17 +193,17 @@ class UploadSession:
diff --git a/docs/html/src/communicatorutils/uploadblocks/sessionmanager.html b/docs/html/src/communicatorutils/uploadblocks/sessionmanager.html new file mode 100644 index 00000000..788ed714 --- /dev/null +++ b/docs/html/src/communicatorutils/uploadblocks/sessionmanager.html @@ -0,0 +1,422 @@ + + + + + + +src.communicatorutils.uploadblocks.sessionmanager API documentation + + + + + + + + + +
+
+
+

Module src.communicatorutils.uploadblocks.sessionmanager

+
+
+

Onionr - Private P2P Communication.

+

Manager for upload 'sessions'

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Manager for upload 'sessions'
+"""
+from typing import List, Union, TYPE_CHECKING
+if TYPE_CHECKING:
+    from session import UploadSession
+
+from onionrutils import bytesconverter
+from etc import onionrvalues
+from utils import reconstructhash
+
+from . import session
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class BlockUploadSessionManager:
+    """Holds block UploadSession instances.
+
+    Optionally accepts iterable of sessions to added on init
+    Arguments: old_session: iterable of old UploadSession objects
+    """
+
+    def __init__(self, old_sessions: List = None):
+        if old_sessions is None:
+            self.sessions = []
+        else:
+            self.sessions = old_sessions
+
+    def add_session(self,
+                    session_or_block: Union[str,
+                                            bytes,
+                                            session.UploadSession
+                                            ]
+                    ) -> session.UploadSession:
+        """Create (or add existing) block upload session.
+
+        from a str/bytes block hex hash, existing UploadSession
+        """
+        if isinstance(session_or_block, session.UploadSession):
+            if session_or_block not in self.sessions:
+                self.sessions.append(session_or_block)
+            return session_or_block
+        try:
+            return self.get_session(session_or_block)
+        except KeyError:
+            pass
+        # convert bytes hash to str
+        if isinstance(session_or_block, bytes):
+            session_or_block = bytesconverter.bytes_to_str(session_or_block)
+        # intentionally not elif
+        if isinstance(session_or_block, str):
+            new_session = session.UploadSession(session_or_block)
+            self.sessions.append(new_session)
+            return new_session
+        raise ValueError
+
+    def get_session(self,
+                    block_hash: Union[str, bytes]
+                    ) -> session.UploadSession:
+        block_hash = reconstructhash.deconstruct_hash(
+            bytesconverter.bytes_to_str(block_hash))
+        for sess in self.sessions:
+            if sess.block_hash == block_hash:
+                return sess
+        raise KeyError
+
+    def clean_session(self,
+                      specific_session: Union[str, 'UploadSession'] = None):
+
+        comm_inst: 'OnionrCommunicatorDaemon'  # type: ignore
+        comm_inst = self._too_many.get_by_string(  # pylint: disable=E1101 type: ignore
+        "OnionrCommunicatorDaemon")
+        sessions_to_delete = []
+        if comm_inst.getUptime() < 120:
+            return
+        onlinePeerCount = len(comm_inst.onlinePeers)
+
+        # If we have no online peers right now,
+        if onlinePeerCount == 0:
+            return
+
+        for sess in self.sessions:
+            # if over 50% of peers that were online for a session have
+            # become unavailable, don't kill sessions
+            if sess.total_success_count > onlinePeerCount:
+                if onlinePeerCount / sess.total_success_count >= 0.5:
+                    return
+            # Clean sessions if they have uploaded to enough online peers
+            if sess.total_success_count <= 0:
+                continue
+            if (sess.total_success_count / onlinePeerCount) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
+                sessions_to_delete.append(sess)
+        for sess in sessions_to_delete:
+            try:
+                self.sessions.remove(session)
+            except ValueError:
+                pass
+            # TODO cleanup to one round of search
+            # Remove the blocks from the sessions, upload list,
+            # and waitforshare list
+            try:
+                comm_inst.blocksToUpload.remove(
+                    reconstructhash.reconstruct_hash(sess.block_hash))
+            except ValueError:
+                pass
+            try:
+                comm_inst.blocksToUpload.remove(sess.block_hash)
+            except ValueError:
+                pass
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class BlockUploadSessionManager +(old_sessions=None) +
+
+

Holds block UploadSession instances.

+

Optionally accepts iterable of sessions to added on init +Arguments: old_session: iterable of old UploadSession objects

+
+ +Expand source code + +
class BlockUploadSessionManager:
+    """Holds block UploadSession instances.
+
+    Optionally accepts iterable of sessions to added on init
+    Arguments: old_session: iterable of old UploadSession objects
+    """
+
+    def __init__(self, old_sessions: List = None):
+        if old_sessions is None:
+            self.sessions = []
+        else:
+            self.sessions = old_sessions
+
+    def add_session(self,
+                    session_or_block: Union[str,
+                                            bytes,
+                                            session.UploadSession
+                                            ]
+                    ) -> session.UploadSession:
+        """Create (or add existing) block upload session.
+
+        from a str/bytes block hex hash, existing UploadSession
+        """
+        if isinstance(session_or_block, session.UploadSession):
+            if session_or_block not in self.sessions:
+                self.sessions.append(session_or_block)
+            return session_or_block
+        try:
+            return self.get_session(session_or_block)
+        except KeyError:
+            pass
+        # convert bytes hash to str
+        if isinstance(session_or_block, bytes):
+            session_or_block = bytesconverter.bytes_to_str(session_or_block)
+        # intentionally not elif
+        if isinstance(session_or_block, str):
+            new_session = session.UploadSession(session_or_block)
+            self.sessions.append(new_session)
+            return new_session
+        raise ValueError
+
+    def get_session(self,
+                    block_hash: Union[str, bytes]
+                    ) -> session.UploadSession:
+        block_hash = reconstructhash.deconstruct_hash(
+            bytesconverter.bytes_to_str(block_hash))
+        for sess in self.sessions:
+            if sess.block_hash == block_hash:
+                return sess
+        raise KeyError
+
+    def clean_session(self,
+                      specific_session: Union[str, 'UploadSession'] = None):
+
+        comm_inst: 'OnionrCommunicatorDaemon'  # type: ignore
+        comm_inst = self._too_many.get_by_string(  # pylint: disable=E1101 type: ignore
+        "OnionrCommunicatorDaemon")
+        sessions_to_delete = []
+        if comm_inst.getUptime() < 120:
+            return
+        onlinePeerCount = len(comm_inst.onlinePeers)
+
+        # If we have no online peers right now,
+        if onlinePeerCount == 0:
+            return
+
+        for sess in self.sessions:
+            # if over 50% of peers that were online for a session have
+            # become unavailable, don't kill sessions
+            if sess.total_success_count > onlinePeerCount:
+                if onlinePeerCount / sess.total_success_count >= 0.5:
+                    return
+            # Clean sessions if they have uploaded to enough online peers
+            if sess.total_success_count <= 0:
+                continue
+            if (sess.total_success_count / onlinePeerCount) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
+                sessions_to_delete.append(sess)
+        for sess in sessions_to_delete:
+            try:
+                self.sessions.remove(session)
+            except ValueError:
+                pass
+            # TODO cleanup to one round of search
+            # Remove the blocks from the sessions, upload list,
+            # and waitforshare list
+            try:
+                comm_inst.blocksToUpload.remove(
+                    reconstructhash.reconstruct_hash(sess.block_hash))
+            except ValueError:
+                pass
+            try:
+                comm_inst.blocksToUpload.remove(sess.block_hash)
+            except ValueError:
+                pass
+
+

Methods

+
+
+def add_session(self, session_or_block) +
+
+

Create (or add existing) block upload session.

+

from a str/bytes block hex hash, existing UploadSession

+
+ +Expand source code + +
def add_session(self,
+                session_or_block: Union[str,
+                                        bytes,
+                                        session.UploadSession
+                                        ]
+                ) -> session.UploadSession:
+    """Create (or add existing) block upload session.
+
+    from a str/bytes block hex hash, existing UploadSession
+    """
+    if isinstance(session_or_block, session.UploadSession):
+        if session_or_block not in self.sessions:
+            self.sessions.append(session_or_block)
+        return session_or_block
+    try:
+        return self.get_session(session_or_block)
+    except KeyError:
+        pass
+    # convert bytes hash to str
+    if isinstance(session_or_block, bytes):
+        session_or_block = bytesconverter.bytes_to_str(session_or_block)
+    # intentionally not elif
+    if isinstance(session_or_block, str):
+        new_session = session.UploadSession(session_or_block)
+        self.sessions.append(new_session)
+        return new_session
+    raise ValueError
+
+
+
+def clean_session(self, specific_session=None) +
+
+
+
+ +Expand source code + +
def clean_session(self,
+                  specific_session: Union[str, 'UploadSession'] = None):
+
+    comm_inst: 'OnionrCommunicatorDaemon'  # type: ignore
+    comm_inst = self._too_many.get_by_string(  # pylint: disable=E1101 type: ignore
+    "OnionrCommunicatorDaemon")
+    sessions_to_delete = []
+    if comm_inst.getUptime() < 120:
+        return
+    onlinePeerCount = len(comm_inst.onlinePeers)
+
+    # If we have no online peers right now,
+    if onlinePeerCount == 0:
+        return
+
+    for sess in self.sessions:
+        # if over 50% of peers that were online for a session have
+        # become unavailable, don't kill sessions
+        if sess.total_success_count > onlinePeerCount:
+            if onlinePeerCount / sess.total_success_count >= 0.5:
+                return
+        # Clean sessions if they have uploaded to enough online peers
+        if sess.total_success_count <= 0:
+            continue
+        if (sess.total_success_count / onlinePeerCount) >= onionrvalues.MIN_BLOCK_UPLOAD_PEER_PERCENT:
+            sessions_to_delete.append(sess)
+    for sess in sessions_to_delete:
+        try:
+            self.sessions.remove(session)
+        except ValueError:
+            pass
+        # TODO cleanup to one round of search
+        # Remove the blocks from the sessions, upload list,
+        # and waitforshare list
+        try:
+            comm_inst.blocksToUpload.remove(
+                reconstructhash.reconstruct_hash(sess.block_hash))
+        except ValueError:
+            pass
+        try:
+            comm_inst.blocksToUpload.remove(sess.block_hash)
+        except ValueError:
+            pass
+
+
+
+def get_session(self, block_hash) +
+
+
+
+ +Expand source code + +
def get_session(self,
+                block_hash: Union[str, bytes]
+                ) -> session.UploadSession:
+    block_hash = reconstructhash.deconstruct_hash(
+        bytesconverter.bytes_to_str(block_hash))
+    for sess in self.sessions:
+        if sess.block_hash == block_hash:
+            return sess
+    raise KeyError
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/config.html b/docs/html/src/config/index.html similarity index 68% rename from docs/html/onionr/config.html rename to docs/html/src/config/index.html index ccc061e9..f6afa708 100644 --- a/docs/html/onionr/config.html +++ b/docs/html/src/config/index.html @@ -3,13 +3,13 @@ - -onionr.config API documentation + +src.config API documentation - + @@ -17,19 +17,24 @@
-

Module onionr.config

+

Module src.config

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This file deals with configuration management.

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file deals with configuration management.
-'''
-'''
+This file deals with configuration management.
+"""
+import os, json, logger
+import filepaths
+
+from . import onboarding
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,18 +47,14 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-
-import os, json, logger
-import filepaths
+"""
 
 _configfile = filepaths.config_file
 _config = {}
 
+
 def get(key, default = None, save = False):
-    '''
-        Gets the key from configuration, or returns `default`
-    '''
+    """Gets the key from configuration, or returns `default`"""
 
     key = str(key).split('.')
     data = _config
@@ -65,20 +66,20 @@ def get(key, default = None, save = False):
             return default
         data = data[item]
 
-    if not last in data:
+    if last not in data:
         if save:
             set(key, default, savefile = True)
         return default
 
     return data[last]
 
+
 def set(key, value = None, savefile = False):
-    '''
-        Sets the key in configuration to `value`
-    '''
+    """Sets the key in configuration to `value`"""
 
     global _config
 
+    whole_key = key
     key = str(key).split('.')
     data = _config
 
@@ -97,6 +98,7 @@ def set(key, value = None, savefile = False):
     if savefile:
         save()
 
+
 def is_set(key):
     key = str(key).split('.')
     data = _config
@@ -113,18 +115,16 @@ def is_set(key):
 
     return True
 
+
 def check():
-    '''
-        Checks if the configuration file exists, creates it if not
-    '''
+    """Checks if the configuration file exists, creates it if not"""
 
     if not os.path.exists(os.path.dirname(get_config_file())):
         os.makedirs(os.path.dirname(get_config_file()))
 
+
 def save():
-    '''
-        Saves the configuration data to the configuration file
-    '''
+    """Saves the configuration data to the configuration file"""
 
     check()
     try:
@@ -133,10 +133,9 @@ def save():
     except json.JSONDecodeError:
         logger.warn('Failed to write to configuration file.')
 
+
 def reload():
-    '''
-        Reloads the configuration data in memory from the file
-    '''
+    """Reloads the configuration data in memory from the file"""
     check()
     try:
         with open(get_config_file(), 'r', encoding="utf8") as configfile:
@@ -145,67 +144,70 @@ def reload():
         pass
         #logger.debug('Failed to parse configuration file.')
 
+
 def get_config():
-    '''
-        Gets the entire configuration as an array
-    '''
+    """Gets the entire configuration as an array"""
     return _config
 
+
 def set_config(config):
-    '''
-        Sets the configuration to the array in arguments
-    '''
+    """Sets the configuration to the array in arguments"""
     global _config
     _config = config
 
+
 def get_config_file():
-    '''
-        Returns the absolute path to the configuration file
-    '''
+    """Returns the absolute path to the configuration file"""
     return _configfile
 
+
 def set_config_file(configfile):
-    '''
-        Sets the path to the configuration file
-    '''
+    """Sets the path to the configuration file."""
     global _configfile
     _configfile = os.abs.abspath(configfile)
+

Sub-modules

+
+
src.config.onboarding
+
+

Onionr - Private P2P Communication …

+
+

Functions

-
+
def check()

Checks if the configuration file exists, creates it if not

-Source code + +Expand source code +
def check():
-    '''
-        Checks if the configuration file exists, creates it if not
-    '''
+    """Checks if the configuration file exists, creates it if not"""
 
     if not os.path.exists(os.path.dirname(get_config_file())):
         os.makedirs(os.path.dirname(get_config_file()))
-
+
def get(key, default=None, save=False)

Gets the key from configuration, or returns default

-Source code + +Expand source code +
def get(key, default = None, save = False):
-    '''
-        Gets the key from configuration, or returns `default`
-    '''
+    """Gets the key from configuration, or returns `default`"""
 
     key = str(key).split('.')
     data = _config
@@ -217,7 +219,7 @@ def set_config_file(configfile):
             return default
         data = data[item]
 
-    if not last in data:
+    if last not in data:
         if save:
             set(key, default, savefile = True)
         return default
@@ -225,41 +227,43 @@ def set_config_file(configfile):
     return data[last]
-
+
def get_config()

Gets the entire configuration as an array

-Source code + +Expand source code +
def get_config():
-    '''
-        Gets the entire configuration as an array
-    '''
+    """Gets the entire configuration as an array"""
     return _config
-
+
def get_config_file()

Returns the absolute path to the configuration file

-Source code + +Expand source code +
def get_config_file():
-    '''
-        Returns the absolute path to the configuration file
-    '''
+    """Returns the absolute path to the configuration file"""
     return _configfile
-
+
def is_set(key)
-Source code + +Expand source code +
def is_set(key):
     key = str(key).split('.')
     data = _config
@@ -277,17 +281,17 @@ def set_config_file(configfile):
     return True
-
+
def reload()

Reloads the configuration data in memory from the file

-Source code + +Expand source code +
def reload():
-    '''
-        Reloads the configuration data in memory from the file
-    '''
+    """Reloads the configuration data in memory from the file"""
     check()
     try:
         with open(get_config_file(), 'r', encoding="utf8") as configfile:
@@ -296,17 +300,17 @@ def set_config_file(configfile):
         pass
-
+
def save()

Saves the configuration data to the configuration file

-Source code + +Expand source code +
def save():
-    '''
-        Saves the configuration data to the configuration file
-    '''
+    """Saves the configuration data to the configuration file"""
 
     check()
     try:
@@ -316,20 +320,21 @@ def set_config_file(configfile):
         logger.warn('Failed to write to configuration file.')
-
+
def set(key, value=None, savefile=False)

Sets the key in configuration to value

-Source code + +Expand source code +
def set(key, value = None, savefile = False):
-    '''
-        Sets the key in configuration to `value`
-    '''
+    """Sets the key in configuration to `value`"""
 
     global _config
 
+    whole_key = key
     key = str(key).split('.')
     data = _config
 
@@ -349,32 +354,32 @@ def set_config_file(configfile):
         save()
-
+
def set_config(config)

Sets the configuration to the array in arguments

-Source code + +Expand source code +
def set_config(config):
-    '''
-        Sets the configuration to the array in arguments
-    '''
+    """Sets the configuration to the array in arguments"""
     global _config
     _config = config
-
+
def set_config_file(configfile)
-

Sets the path to the configuration file

+

Sets the path to the configuration file.

-Source code + +Expand source code +
def set_config_file(configfile):
-    '''
-        Sets the path to the configuration file
-    '''
+    """Sets the path to the configuration file."""
     global _configfile
     _configfile = os.abs.abspath(configfile)
@@ -392,28 +397,33 @@ def set_config_file(configfile):
diff --git a/docs/html/src/config/onboarding.html b/docs/html/src/config/onboarding.html new file mode 100644 index 00000000..49a96da8 --- /dev/null +++ b/docs/html/src/config/onboarding.html @@ -0,0 +1,213 @@ + + + + + + +src.config.onboarding API documentation + + + + + + + + + +
+
+
+

Module src.config.onboarding

+
+
+

Onionr - Private P2P Communication.

+

Setup config from onboarding choices

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Setup config from onboarding choices
+"""
+from pathlib import Path
+from typing import Union
+
+from filepaths import onboarding_mark_file
+from onionrtypes import JSONSerializable
+from onionrtypes import OnboardingConfig
+import config
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def _get_val_or_none(json: dict, key: str) -> Union[None, JSONSerializable]:
+    try:
+        return json['configInfo'][key]
+    except KeyError:
+        return None
+
+
+def set_config_from_onboarding(config_settings: OnboardingConfig):
+    get = _get_val_or_none
+
+    config.reload()
+
+    if get(config_settings, 'stateTarget') or not get(config_settings,
+                                                      'networkContrib'):
+        config.set('general.security_level', 1)
+
+    if get(config_settings, 'localThreat'):
+        config.set('general.security_level', 3)
+
+    config.set('ui.theme', 'light')
+    if get(config_settings, 'useDark'):
+        config.set('ui.theme', 'dark')
+
+    disabled = config.get('plugins.disabled', [])
+
+    if not get(config_settings, 'circles') or \
+            config.get('general.security_level') > 0:
+        disabled.append('flow')
+
+    if not get(config_settings, 'mail'):
+        disabled.append('pms')
+
+    config.set('plugins.disabled', disabled)
+
+    config.set('general.store_plaintext_blocks',
+               get(config_settings, 'plainContrib'))
+
+    config.set('onboarding.done', True, savefile=True)
+
+
+def set_onboarding_finished():
+    """Create the onboarding completed setting file"""
+    Path(onboarding_mark_file).touch()
+
+
+def is_onboarding_finished() -> bool:
+    return True
+
+
+
+
+
+
+
+

Functions

+
+
+def is_onboarding_finished() +
+
+
+
+ +Expand source code + +
def is_onboarding_finished() -> bool:
+    return True
+
+
+
+def set_config_from_onboarding(config_settings) +
+
+
+
+ +Expand source code + +
def set_config_from_onboarding(config_settings: OnboardingConfig):
+    get = _get_val_or_none
+
+    config.reload()
+
+    if get(config_settings, 'stateTarget') or not get(config_settings,
+                                                      'networkContrib'):
+        config.set('general.security_level', 1)
+
+    if get(config_settings, 'localThreat'):
+        config.set('general.security_level', 3)
+
+    config.set('ui.theme', 'light')
+    if get(config_settings, 'useDark'):
+        config.set('ui.theme', 'dark')
+
+    disabled = config.get('plugins.disabled', [])
+
+    if not get(config_settings, 'circles') or \
+            config.get('general.security_level') > 0:
+        disabled.append('flow')
+
+    if not get(config_settings, 'mail'):
+        disabled.append('pms')
+
+    config.set('plugins.disabled', disabled)
+
+    config.set('general.store_plaintext_blocks',
+               get(config_settings, 'plainContrib'))
+
+    config.set('onboarding.done', True, savefile=True)
+
+
+
+def set_onboarding_finished() +
+
+

Create the onboarding completed setting file

+
+ +Expand source code + +
def set_onboarding_finished():
+    """Create the onboarding completed setting file"""
+    Path(onboarding_mark_file).touch()
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/coredb/blockmetadb/add.html b/docs/html/src/coredb/blockmetadb/add.html similarity index 79% rename from docs/html/onionr/coredb/blockmetadb/add.html rename to docs/html/src/coredb/blockmetadb/add.html index 2722000c..4f3ff62e 100644 --- a/docs/html/onionr/coredb/blockmetadb/add.html +++ b/docs/html/src/coredb/blockmetadb/add.html @@ -3,13 +3,13 @@ - -onionr.coredb.blockmetadb.add API documentation + +src.coredb.blockmetadb.add API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.blockmetadb.add

+

Module src.coredb.blockmetadb.add

Onionr - Private P2P Communication

Add an entry to the block metadata database

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -45,6 +47,7 @@
 '''
 import os, sqlite3, secrets
 from onionrutils import epoch, blockmetadata
+from etc import onionrvalues
 from .. import dbfiles
 def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
     '''
@@ -55,7 +58,7 @@ def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
 
     if blockmetadata.has_block(newHash):
         return
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     currentTime = epoch.get_epoch() + secrets.randbelow(301)
     if selfInsert or dataSaved:
@@ -75,14 +78,16 @@ def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
 

Functions

-
+
def add_to_block_DB(newHash, selfInsert=False, dataSaved=False)

Add a hash value to the block db

Should be in hex format!

-Source code + +Expand source code +
def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
     '''
         Add a hash value to the block db
@@ -92,7 +97,7 @@ def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
 
     if blockmetadata.has_block(newHash):
         return
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     currentTime = epoch.get_epoch() + secrets.randbelow(301)
     if selfInsert or dataSaved:
@@ -118,19 +123,19 @@ def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
 
 
 
diff --git a/docs/html/onionr/coredb/blockmetadb/expiredblocks.html b/docs/html/src/coredb/blockmetadb/expiredblocks.html similarity index 77% rename from docs/html/onionr/coredb/blockmetadb/expiredblocks.html rename to docs/html/src/coredb/blockmetadb/expiredblocks.html index 952cd175..bb3e1bb4 100644 --- a/docs/html/onionr/coredb/blockmetadb/expiredblocks.html +++ b/docs/html/src/coredb/blockmetadb/expiredblocks.html @@ -3,13 +3,13 @@ - -onionr.coredb.blockmetadb.expiredblocks API documentation + +src.coredb.blockmetadb.expiredblocks API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.blockmetadb.expiredblocks

+

Module src.coredb.blockmetadb.expiredblocks

Onionr - Private P2P Communication

Get a list of expired blocks still stored

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -46,9 +48,11 @@
 import sqlite3
 from onionrutils import epoch
 from .. import dbfiles
+from etc import onionrvalues
+
 def get_expired_blocks():
     '''Returns a list of expired blocks'''
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     date = int(epoch.get_epoch())
 
@@ -70,16 +74,18 @@ def get_expired_blocks():
 

Functions

-
+
def get_expired_blocks()

Returns a list of expired blocks

-Source code + +Expand source code +
def get_expired_blocks():
     '''Returns a list of expired blocks'''
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     date = int(epoch.get_epoch())
 
@@ -107,19 +113,19 @@ def get_expired_blocks():
 
 
 
diff --git a/docs/html/onionr/coredb/blockmetadb/index.html b/docs/html/src/coredb/blockmetadb/index.html similarity index 70% rename from docs/html/onionr/coredb/blockmetadb/index.html rename to docs/html/src/coredb/blockmetadb/index.html index 74cda827..8066af1e 100644 --- a/docs/html/onionr/coredb/blockmetadb/index.html +++ b/docs/html/src/coredb/blockmetadb/index.html @@ -3,13 +3,13 @@ - -onionr.coredb.blockmetadb API documentation + +src.coredb.blockmetadb API documentation - + @@ -17,19 +17,26 @@
-

Module onionr.coredb.blockmetadb

+

Module src.coredb.blockmetadb

Onionr - Private P2P Communication

This module works with information relating to blocks stored on the node

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
     This module works with information relating to blocks stored on the node
-'''
-'''
+"""
+import sqlite3
+
+from etc import onionrvalues
+from . import expiredblocks, updateblockinfo, add
+from .. import dbfiles
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,20 +49,20 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sqlite3
-from . import expiredblocks, updateblockinfo, add
-from .. import dbfiles
+"""
+
 update_block_info = updateblockinfo.update_block_info
 add_to_block_DB = add.add_to_block_DB
+
+
 def get_block_list(dateRec = None, unsaved = False):
-    '''
+    """
         Get list of our blocks
-    '''
+    """
     if dateRec == None:
         dateRec = 0
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;'
@@ -67,12 +74,13 @@ def get_block_list(dateRec = None, unsaved = False):
     conn.close()
     return rows
 
-def get_block_date(blockHash):
-    '''
-        Returns the date a block was received
-    '''
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+def get_block_date(blockHash):
+    """
+        Returns the date a block was received
+    """
+
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     execute = 'SELECT dateReceived FROM hashes WHERE hash=?;'
@@ -83,12 +91,13 @@ def get_block_date(blockHash):
     conn.close()
     return None
 
-def get_blocks_by_type(blockType, orderDate=True):
-    '''
-        Returns a list of blocks by the type
-    '''
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+def get_blocks_by_type(blockType, orderDate=True):
+    """
+        Returns a list of blocks by the type
+    """
+
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     if orderDate:
@@ -109,15 +118,15 @@ def get_blocks_by_type(blockType, orderDate=True):
 

Sub-modules

-
onionr.coredb.blockmetadb.add
+
src.coredb.blockmetadb.add

Onionr - Private P2P Communication …

-
onionr.coredb.blockmetadb.expiredblocks
+
src.coredb.blockmetadb.expiredblocks

Onionr - Private P2P Communication …

-
onionr.coredb.blockmetadb.updateblockinfo
+
src.coredb.blockmetadb.updateblockinfo

Onionr - Private P2P Communication …

@@ -128,19 +137,21 @@ def get_blocks_by_type(blockType, orderDate=True):

Functions

-
+
def get_block_date(blockHash)

Returns the date a block was received

-Source code + +Expand source code +
def get_block_date(blockHash):
-    '''
+    """
         Returns the date a block was received
-    '''
+    """
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     execute = 'SELECT dateReceived FROM hashes WHERE hash=?;'
@@ -152,21 +163,23 @@ def get_blocks_by_type(blockType, orderDate=True):
     return None
-
+
def get_block_list(dateRec=None, unsaved=False)

Get list of our blocks

-Source code + +Expand source code +
def get_block_list(dateRec = None, unsaved = False):
-    '''
+    """
         Get list of our blocks
-    '''
+    """
     if dateRec == None:
         dateRec = 0
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;'
@@ -179,19 +192,21 @@ def get_blocks_by_type(blockType, orderDate=True):
     return rows
-
+
def get_blocks_by_type(blockType, orderDate=True)

Returns a list of blocks by the type

-Source code + +Expand source code +
def get_blocks_by_type(blockType, orderDate=True):
-    '''
+    """
         Returns a list of blocks by the type
-    '''
+    """
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     if orderDate:
@@ -222,28 +237,28 @@ def get_blocks_by_type(blockType, orderDate=True):
 
 
 
diff --git a/docs/html/onionr/coredb/blockmetadb/updateblockinfo.html b/docs/html/src/coredb/blockmetadb/updateblockinfo.html similarity index 83% rename from docs/html/onionr/coredb/blockmetadb/updateblockinfo.html rename to docs/html/src/coredb/blockmetadb/updateblockinfo.html index 1833ccc9..03c39009 100644 --- a/docs/html/onionr/coredb/blockmetadb/updateblockinfo.html +++ b/docs/html/src/coredb/blockmetadb/updateblockinfo.html @@ -3,13 +3,13 @@ - -onionr.coredb.blockmetadb.updateblockinfo API documentation + +src.coredb.blockmetadb.updateblockinfo API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.blockmetadb.updateblockinfo

+

Module src.coredb.blockmetadb.updateblockinfo

Onionr - Private P2P Communication

Update block information in the metadata database by a field name

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -45,6 +47,7 @@
 '''
 import sqlite3
 from .. import dbfiles
+from etc import onionrvalues
 def update_block_info(hash, key, data):
     '''
         sets info associated with a block
@@ -64,7 +67,7 @@ def update_block_info(hash, key, data):
                   'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'):
         raise ValueError('Key must be in the allowed list')
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     args = (data, hash)
     # Unfortunately, not really possible
@@ -82,7 +85,7 @@ def update_block_info(hash, key, data):
 

Functions

-
+
def update_block_info(hash, key, data)
@@ -107,7 +110,9 @@ dateClaimed expire - expire date for a block

-Source code + +Expand source code +
def update_block_info(hash, key, data):
     '''
         sets info associated with a block
@@ -127,7 +132,7 @@ expire
                   'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'):
         raise ValueError('Key must be in the allowed list')
 
-    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     args = (data, hash)
     # Unfortunately, not really possible
@@ -151,19 +156,19 @@ expire
 
 
 
diff --git a/docs/html/onionr/coredb/dbfiles.html b/docs/html/src/coredb/dbfiles.html similarity index 79% rename from docs/html/onionr/coredb/dbfiles.html rename to docs/html/src/coredb/dbfiles.html index 8461d397..81556153 100644 --- a/docs/html/onionr/coredb/dbfiles.html +++ b/docs/html/src/coredb/dbfiles.html @@ -3,13 +3,13 @@ - -onionr.coredb.dbfiles API documentation + +src.coredb.dbfiles API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.coredb.dbfiles

+

Module src.coredb.dbfiles

-Source code + +Expand source code +
from utils import identifyhome
 import filepaths
 home = identifyhome.identify_home()
@@ -29,7 +31,6 @@ if not home.endswith('/'): home += '/'
 
 block_meta_db = '%sblock-metadata.db' % (home)
 block_data_db = '%s/block-data.db' % (filepaths.block_data_location,)
-daemon_queue_db = '%sdaemon-queue.db' % (home,)
 address_info_db = '%saddress.db' % (home,)
 user_id_info_db = '%susers.db' % (home,)
 forward_keys_db = '%sforward-keys.db' % (home,)
@@ -53,14 +54,14 @@ blacklist_db = '%sblacklist.db' % (home,)
diff --git a/docs/html/src/coredb/index.html b/docs/html/src/coredb/index.html new file mode 100644 index 00000000..057f3acb --- /dev/null +++ b/docs/html/src/coredb/index.html @@ -0,0 +1,81 @@ + + + + + + +src.coredb API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/coredb/keydb/addkeys.html b/docs/html/src/coredb/keydb/addkeys.html similarity index 84% rename from docs/html/onionr/coredb/keydb/addkeys.html rename to docs/html/src/coredb/keydb/addkeys.html index 8c5a112f..0d55863d 100644 --- a/docs/html/onionr/coredb/keydb/addkeys.html +++ b/docs/html/src/coredb/keydb/addkeys.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb.addkeys API documentation + +src.coredb.keydb.addkeys API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.keydb.addkeys

+

Module src.coredb.keydb.addkeys

Onionr - Private P2P Communication

add user keys or transport addresses

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -50,6 +52,8 @@ from . import listkeys
 from utils import gettransports
 from .. import dbfiles
 import onionrcrypto
+from etc import onionrvalues
+
 def add_peer(peerID, name=''):
     '''
         Adds a public key to the key database (misleading function name)
@@ -63,7 +67,7 @@ def add_peer(peerID, name=''):
 
     #events.event('pubkey_add', data = {'key': peerID}, onionr = core_inst.onionrInst)
 
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     hashID = ""
     c = conn.cursor()
     t = (peerID, name, 'unknown', hashID, 0)
@@ -93,7 +97,7 @@ def add_address(address):
     if stringvalidators.validate_transport(address):
         if address in gettransports.get():
             return False
-        conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+        conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         # check if address is in database
         # this is safe to do because the address is validated above, but we strip some chars here too just in case
@@ -127,13 +131,15 @@ def add_address(address):
 

Functions

-
+
def add_address(address)

Add an address to the address database (only tor currently)

-Source code + +Expand source code +
def add_address(address):
     '''
         Add an address to the address database (only tor currently)
@@ -144,7 +150,7 @@ def add_address(address):
     if stringvalidators.validate_transport(address):
         if address in gettransports.get():
             return False
-        conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+        conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         # check if address is in database
         # this is safe to do because the address is validated above, but we strip some chars here too just in case
@@ -171,13 +177,15 @@ def add_address(address):
         return False
-
+
def add_peer(peerID, name='')

Adds a public key to the key database (misleading function name)

-Source code + +Expand source code +
def add_peer(peerID, name=''):
     '''
         Adds a public key to the key database (misleading function name)
@@ -191,7 +199,7 @@ def add_address(address):
 
     #events.event('pubkey_add', data = {'key': peerID}, onionr = core_inst.onionrInst)
 
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     hashID = ""
     c = conn.cursor()
     t = (peerID, name, 'unknown', hashID, 0)
@@ -225,20 +233,20 @@ def add_address(address):
 
 
 
diff --git a/docs/html/onionr/coredb/keydb/index.html b/docs/html/src/coredb/keydb/index.html similarity index 66% rename from docs/html/onionr/coredb/keydb/index.html rename to docs/html/src/coredb/keydb/index.html index 0d94b0f2..4c5fe651 100644 --- a/docs/html/onionr/coredb/keydb/index.html +++ b/docs/html/src/coredb/keydb/index.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb API documentation + +src.coredb.keydb API documentation - + @@ -17,34 +17,36 @@
-

Module onionr.coredb.keydb

+

Module src.coredb.keydb

-Source code + +Expand source code +
from . import addkeys, listkeys, removekeys, userinfo, transportinfo

Sub-modules

-
onionr.coredb.keydb.addkeys
+
src.coredb.keydb.addkeys

Onionr - Private P2P Communication …

-
onionr.coredb.keydb.listkeys
+
src.coredb.keydb.listkeys

Onionr - Private P2P Communication …

-
onionr.coredb.keydb.removekeys
+
src.coredb.keydb.removekeys

Onionr - Private P2P Communication …

-
onionr.coredb.keydb.transportinfo
+
src.coredb.keydb.transportinfo

Onionr - Private P2P Communication …

-
onionr.coredb.keydb.userinfo
+
src.coredb.keydb.userinfo

Onionr - Private P2P Communication …

@@ -65,23 +67,23 @@
diff --git a/docs/html/onionr/coredb/keydb/listkeys.html b/docs/html/src/coredb/keydb/listkeys.html similarity index 81% rename from docs/html/onionr/coredb/keydb/listkeys.html rename to docs/html/src/coredb/keydb/listkeys.html index 2b5732ae..1c50f23b 100644 --- a/docs/html/onionr/coredb/keydb/listkeys.html +++ b/docs/html/src/coredb/keydb/listkeys.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb.listkeys API documentation + +src.coredb.keydb.listkeys API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.keydb.listkeys

+

Module src.coredb.keydb.listkeys

Onionr - Private P2P Communication

get lists for user keys or transport addresses

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -46,6 +48,7 @@
 import sqlite3
 import logger
 from onionrutils import epoch
+from etc import onionrvalues
 from .. import dbfiles
 from . import userinfo, transportinfo
 def list_peers(randomOrder=True, getPow=False, trust=0):
@@ -55,7 +58,7 @@ def list_peers(randomOrder=True, getPow=False, trust=0):
         randomOrder determines if the list should be in a random order
         trust sets the minimum trust to list
     '''
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     payload = ''
@@ -89,7 +92,7 @@ def list_adders(randomOrder=True, i2p=True, recent=0):
     '''
         Return a list of transport addresses
     '''
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     if randomOrder:
         addresses = c.execute('SELECT * FROM adders ORDER BY RANDOM();')
@@ -118,18 +121,20 @@ def list_adders(randomOrder=True, i2p=True, recent=0):
 

Functions

-
+
def list_adders(randomOrder=True, i2p=True, recent=0)

Return a list of transport addresses

-Source code + +Expand source code +
def list_adders(randomOrder=True, i2p=True, recent=0):
     '''
         Return a list of transport addresses
     '''
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
     if randomOrder:
         addresses = c.execute('SELECT * FROM adders ORDER BY RANDOM();')
@@ -151,7 +156,7 @@ def list_adders(randomOrder=True, i2p=True, recent=0):
     return addressList
-
+
def list_peers(randomOrder=True, getPow=False, trust=0)
@@ -159,7 +164,9 @@ def list_adders(randomOrder=True, i2p=True, recent=0):

randomOrder determines if the list should be in a random order trust sets the minimum trust to list

-Source code + +Expand source code +
def list_peers(randomOrder=True, getPow=False, trust=0):
     '''
         Return a list of public keys (misleading function name)
@@ -167,7 +174,7 @@ trust sets the minimum trust to list

randomOrder determines if the list should be in a random order trust sets the minimum trust to list ''' - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30) + conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() payload = '' @@ -211,20 +218,20 @@ trust sets the minimum trust to list

diff --git a/docs/html/onionr/coredb/keydb/removekeys.html b/docs/html/src/coredb/keydb/removekeys.html similarity index 67% rename from docs/html/onionr/coredb/keydb/removekeys.html rename to docs/html/src/coredb/keydb/removekeys.html index fbd1e5ab..52ca4940 100644 --- a/docs/html/onionr/coredb/keydb/removekeys.html +++ b/docs/html/src/coredb/keydb/removekeys.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb.removekeys API documentation + +src.coredb.keydb.removekeys API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.keydb.removekeys

+

Module src.coredb.keydb.removekeys

Onionr - Private P2P Communication

Remove a transport address but don't ban them

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -46,14 +48,17 @@
 import sqlite3
 from onionrplugins import onionrevents as events
 from onionrutils import stringvalidators
+from onionrutils import mnemonickeys
 from .. import dbfiles
+from etc import onionrvalues
+
 def remove_address(address):
     '''
         Remove an address from the address database
     '''
 
     if stringvalidators.validate_transport(address):
-        conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+        conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         t = (address,)
         c.execute('Delete from adders where address=?;', t)
@@ -61,6 +66,23 @@ def remove_address(address):
         conn.close()
 
         #events.event('address_remove', data = {'address': address}, onionr = core_inst.onionrInst)
+        return True
+    else:
+        return False
+
+def remove_user(pubkey: str)->bool:
+    '''
+        Remove a user from the user database
+    '''
+    pubkey = mnemonickeys.get_base32(pubkey)
+    if stringvalidators.validate_pub_key(pubkey):
+        conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
+        c = conn.cursor()
+        t = (pubkey,)
+        c.execute('Delete from peers where id=?;', t)
+        conn.commit()
+        conn.close()
+
         return True
     else:
         return False
@@ -73,20 +95,22 @@ def remove_address(address):

Functions

-
+
def remove_address(address)

Remove an address from the address database

-Source code + +Expand source code +
def remove_address(address):
     '''
         Remove an address from the address database
     '''
 
     if stringvalidators.validate_transport(address):
-        conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+        conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         t = (address,)
         c.execute('Delete from adders where address=?;', t)
@@ -99,6 +123,33 @@ def remove_address(address):
         return False
+
+def remove_user(pubkey) +
+
+

Remove a user from the user database

+
+ +Expand source code + +
def remove_user(pubkey: str)->bool:
+    '''
+        Remove a user from the user database
+    '''
+    pubkey = mnemonickeys.get_base32(pubkey)
+    if stringvalidators.validate_pub_key(pubkey):
+        conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
+        c = conn.cursor()
+        t = (pubkey,)
+        c.execute('Delete from peers where id=?;', t)
+        conn.commit()
+        conn.close()
+
+        return True
+    else:
+        return False
+
+
@@ -112,19 +163,20 @@ def remove_address(address):
diff --git a/docs/html/onionr/coredb/keydb/transportinfo.html b/docs/html/src/coredb/keydb/transportinfo.html similarity index 80% rename from docs/html/onionr/coredb/keydb/transportinfo.html rename to docs/html/src/coredb/keydb/transportinfo.html index a8c201e1..c2f1a568 100644 --- a/docs/html/onionr/coredb/keydb/transportinfo.html +++ b/docs/html/src/coredb/keydb/transportinfo.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb.transportinfo API documentation + +src.coredb.keydb.transportinfo API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.keydb.transportinfo

+

Module src.coredb.keydb.transportinfo

Onionr - Private P2P Communication

get or set transport address meta information

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -45,6 +47,8 @@
 '''
 import sqlite3
 from .. import dbfiles
+from etc import onionrvalues
+
 def get_address_info(address, info):
     '''
         Get info about an address from its database entry
@@ -61,7 +65,7 @@ def get_address_info(address, info):
         introduced  9
     '''
 
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (address,)
@@ -86,7 +90,7 @@ def set_address_info(address, key, data):
         Update an address for a key
     '''
 
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (data, address)
@@ -106,7 +110,7 @@ def set_address_info(address, key, data):
 

Functions

-
+
def get_address_info(address, info)
@@ -125,7 +129,9 @@ trust introduced 9

-Source code + +Expand source code +
def get_address_info(address, info):
     '''
         Get info about an address from its database entry
@@ -142,7 +148,7 @@ introduced
         introduced  9
     '''
 
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (address,)
@@ -163,19 +169,21 @@ introduced
     return retVal
-
+
def set_address_info(address, key, data)

Update an address for a key

-Source code + +Expand source code +
def set_address_info(address, key, data):
     '''
         Update an address for a key
     '''
 
-    conn = sqlite3.connect(dbfiles.address_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (data, address)
@@ -201,20 +209,20 @@ introduced
 
 
 
diff --git a/docs/html/onionr/coredb/keydb/userinfo.html b/docs/html/src/coredb/keydb/userinfo.html similarity index 78% rename from docs/html/onionr/coredb/keydb/userinfo.html rename to docs/html/src/coredb/keydb/userinfo.html index cb79d4b7..34ecea70 100644 --- a/docs/html/onionr/coredb/keydb/userinfo.html +++ b/docs/html/src/coredb/keydb/userinfo.html @@ -3,13 +3,13 @@ - -onionr.coredb.keydb.userinfo API documentation + +src.coredb.keydb.userinfo API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.coredb.keydb.userinfo

+

Module src.coredb.keydb.userinfo

Onionr - Private P2P Communication

get or set information about a user id

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -45,6 +47,8 @@
 '''
 import sqlite3
 from .. import dbfiles
+from etc import onionrvalues
+
 def get_user_info(peer, info):
     '''
         Get info about a peer from their database entry
@@ -56,7 +60,7 @@ def get_user_info(peer, info):
         trust int           4
         hashID text         5
     '''
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (peer,)
@@ -82,7 +86,7 @@ def set_peer_info(peer, key, data):
         Update a peer for a key
     '''
 
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (data, peer)
@@ -104,7 +108,7 @@ set_user_info = set_peer_info

Functions

-
+
def get_user_info(peer, info)
@@ -122,7 +126,9 @@ trust int hashID text 5

-Source code + +Expand source code +
def get_user_info(peer, info):
     '''
         Get info about a peer from their database entry
@@ -134,7 +140,7 @@ hashID text
         trust int           4
         hashID text         5
     '''
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (peer,)
@@ -156,19 +162,21 @@ hashID text
     return retVal
-
+
def set_peer_info(peer, key, data)

Update a peer for a key

-Source code + +Expand source code +
def set_peer_info(peer, key, data):
     '''
         Update a peer for a key
     '''
 
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (data, peer)
@@ -181,19 +189,21 @@ hashID text
     conn.close()
-
+
def set_user_info(peer, key, data)

Update a peer for a key

-Source code + +Expand source code +
def set_peer_info(peer, key, data):
     '''
         Update a peer for a key
     '''
 
-    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=30)
+    conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
     c = conn.cursor()
 
     command = (data, peer)
@@ -219,21 +229,21 @@ hashID text
 
 
 
diff --git a/docs/html/src/data2871027835/index.html b/docs/html/src/data2871027835/index.html new file mode 100644 index 00000000..2098ec17 --- /dev/null +++ b/docs/html/src/data2871027835/index.html @@ -0,0 +1,65 @@ + + + + + + +src.data2871027835 API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/chat/controlapi.html b/docs/html/src/data2871027835/plugins/chat/controlapi.html new file mode 100644 index 00000000..48ebb6fa --- /dev/null +++ b/docs/html/src/data2871027835/plugins/chat/controlapi.html @@ -0,0 +1,246 @@ + + + + + + +src.data2871027835.plugins.chat.controlapi API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.chat.controlapi

+
+
+

Onionr - Private P2P Communication

+

HTTP endpoints for controlling IMs

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    HTTP endpoints for controlling IMs
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+import json
+from flask import Response, request, redirect, Blueprint, send_from_directory
+import deadsimplekv as simplekv
+import filepaths
+flask_blueprint = Blueprint('chat_control', __name__)
+key_store = simplekv.DeadSimpleKV(filepaths.cached_storage, refresh_seconds=5)
+@flask_blueprint.route('/chatapi/ping')
+def ping():
+    return 'pong!'
+
+@flask_blueprint.route('/chatapi/send/<peer>', methods=['POST'])
+def send_message(peer):
+    """Send a message to the peer"""
+    data = request.get_json(force=True)
+    key_store.refresh()
+    existing = key_store.get('s' + peer)
+    if existing is None:
+        existing = []
+    existing.append(data)
+    key_store.put('s' + peer, existing)
+    key_store.flush()
+    return Response('success')
+
+@flask_blueprint.route('/chatapi/gets/<peer>')
+def get_sent(peer):
+    """Get messages sent to peer"""
+    sent = key_store.get('s' + peer)
+    if sent is None:
+        sent = []
+    return Response(json.dumps(sent))
+
+@flask_blueprint.route('/chatapi/addrec/<peer>', methods=['POST'])
+def add_rec(peer):
+    """Add a received message from the peer"""
+    data = request.get_json(force=True)
+    key_store.refresh()
+    existing = key_store.get('r' + peer)
+    if existing is None:
+        existing = []
+    existing.append(data)
+    key_store.put('r' + peer, existing)
+    key_store.flush()
+    return Response('success')
+
+@flask_blueprint.route('/chatapi/getrec/<peer>')
+def get_messages(peer):
+    """Get received messages for the peer"""
+    key_store.refresh()
+    existing = key_store.get('r' + peer)
+    if existing is None:
+        existing = []
+    else:
+        existing = list(existing)
+        key_store.delete('r' + peer)
+    return Response(json.dumps(existing))
+
+
+
+
+
+
+
+

Functions

+
+
+def add_rec(peer) +
+
+

Add a received message from the peer

+
+ +Expand source code + +
@flask_blueprint.route('/chatapi/addrec/<peer>', methods=['POST'])
+def add_rec(peer):
+    """Add a received message from the peer"""
+    data = request.get_json(force=True)
+    key_store.refresh()
+    existing = key_store.get('r' + peer)
+    if existing is None:
+        existing = []
+    existing.append(data)
+    key_store.put('r' + peer, existing)
+    key_store.flush()
+    return Response('success')
+
+
+
+def get_messages(peer) +
+
+

Get received messages for the peer

+
+ +Expand source code + +
@flask_blueprint.route('/chatapi/getrec/<peer>')
+def get_messages(peer):
+    """Get received messages for the peer"""
+    key_store.refresh()
+    existing = key_store.get('r' + peer)
+    if existing is None:
+        existing = []
+    else:
+        existing = list(existing)
+        key_store.delete('r' + peer)
+    return Response(json.dumps(existing))
+
+
+
+def get_sent(peer) +
+
+

Get messages sent to peer

+
+ +Expand source code + +
@flask_blueprint.route('/chatapi/gets/<peer>')
+def get_sent(peer):
+    """Get messages sent to peer"""
+    sent = key_store.get('s' + peer)
+    if sent is None:
+        sent = []
+    return Response(json.dumps(sent))
+
+
+
+def ping() +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/chatapi/ping')
+def ping():
+    return 'pong!'
+
+
+
+def send_message(peer) +
+
+

Send a message to the peer

+
+ +Expand source code + +
@flask_blueprint.route('/chatapi/send/<peer>', methods=['POST'])
+def send_message(peer):
+    """Send a message to the peer"""
+    data = request.get_json(force=True)
+    key_store.refresh()
+    existing = key_store.get('s' + peer)
+    if existing is None:
+        existing = []
+    existing.append(data)
+    key_store.put('s' + peer, existing)
+    key_store.flush()
+    return Response('success')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/etc/index.html b/docs/html/src/data2871027835/plugins/chat/index.html similarity index 65% rename from docs/html/onionr/etc/index.html rename to docs/html/src/data2871027835/plugins/chat/index.html index 1db9f74e..baf527a2 100644 --- a/docs/html/onionr/etc/index.html +++ b/docs/html/src/data2871027835/plugins/chat/index.html @@ -3,13 +3,13 @@ - -onionr.etc API documentation + +src.data2871027835.plugins.chat API documentation - + @@ -17,30 +17,26 @@
-

Module onionr.etc

+

Namespace src.data2871027835.plugins.chat

Sub-modules

-
onionr.etc.cleanup
-
-
-
-
onionr.etc.humanreadabletime
+
src.data2871027835.plugins.chat.controlapi

Onionr - Private P2P Communication …

-
onionr.etc.onionrvalues
+
src.data2871027835.plugins.chat.main

Onionr - Private P2P Communication …

-
onionr.etc.powchoice
+
src.data2871027835.plugins.chat.peerserver

Onionr - Private P2P Communication …

-
onionr.etc.waitforsetvar
+
src.data2871027835.plugins.chat.settings
@@ -61,23 +57,22 @@
diff --git a/docs/html/src/data2871027835/plugins/chat/main.html b/docs/html/src/data2871027835/plugins/chat/main.html new file mode 100644 index 00000000..f64ed87b --- /dev/null +++ b/docs/html/src/data2871027835/plugins/chat/main.html @@ -0,0 +1,122 @@ + + + + + + +src.data2871027835.plugins.chat.main API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.chat.main

+
+
+

Onionr - Private P2P Communication

+

Instant message conversations with Onionr peers

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    Instant message conversations with Onionr peers
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+
+# Imports some useful libraries
+import locale, sys, os, threading, json
+locale.setlocale(locale.LC_ALL, '')
+import onionrservices, logger, config
+from onionrservices import bootstrapservice
+from onionrutils import stringvalidators, epoch, basicrequests
+
+plugin_name = 'chat'
+PLUGIN_VERSION = '0.0.0'
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+import controlapi, peerserver
+flask_blueprint = controlapi.flask_blueprint
+direct_blueprint = peerserver.direct_blueprint
+security_whitelist = ['staticfiles.chat', 'staticfiles.chatIndex']
+
+def exit_with_error(text=''):
+    if text != '':
+        logger.error(text)
+    sys.exit(1)
+
+
+
+
+
+
+
+

Functions

+
+
+def exit_with_error(text='') +
+
+
+
+ +Expand source code + +
def exit_with_error(text=''):
+    if text != '':
+        logger.error(text)
+    sys.exit(1)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/chat/peerserver.html b/docs/html/src/data2871027835/plugins/chat/peerserver.html new file mode 100644 index 00000000..e3a625bb --- /dev/null +++ b/docs/html/src/data2871027835/plugins/chat/peerserver.html @@ -0,0 +1,200 @@ + + + + + + +src.data2871027835.plugins.chat.peerserver API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.chat.peerserver

+
+
+

Onionr - Private P2P Communication

+

HTTP endpoints for communicating with peers

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    HTTP endpoints for communicating with peers
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+import sys, os, json
+from utils import identifyhome
+from onionrutils import localcommand
+import deadsimplekv as simplekv, filepaths
+from flask import Response, request, redirect, Blueprint, abort, g
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+direct_blueprint = Blueprint('chat', __name__)
+
+key_store = simplekv.DeadSimpleKV(filepaths.cached_storage, refresh_seconds=5)
+storage_dir = identifyhome.identify_home()
+
+@direct_blueprint.before_request
+def request_setup():
+    key_store.refresh()
+    host = request.host
+    host = host.strip('.b32.i2p')
+    host = host.strip('.onion')
+    g.host = host
+    g.peer = key_store.get('dc-' + g.host)
+
+@direct_blueprint.route('/chat/ping')
+def pingdirect():
+    return 'pong!'
+
+@direct_blueprint.route('/chat/sendto', methods=['POST', 'GET'])
+def sendto():
+    """Endpoint peers send chat messages to"""
+    try:
+        msg = request.get_json(force=True)
+    except json.JSONDecodeError:
+        msg = ''
+    else:
+        msg = json.dumps(msg)
+        localcommand.local_command('/chat/addrec/%s' % (g.peer,), post=True, postData=msg)
+    return Response('success')
+
+@direct_blueprint.route('/chat/poll')
+def poll_chat():
+    """Endpoints peers get new messages from"""
+    return Response(localcommand.local_command('/chat/gets/%s' % (g.peer,)))
+
+
+
+
+
+
+
+

Functions

+
+
+def pingdirect() +
+
+
+
+ +Expand source code + +
@direct_blueprint.route('/chat/ping')
+def pingdirect():
+    return 'pong!'
+
+
+
+def poll_chat() +
+
+

Endpoints peers get new messages from

+
+ +Expand source code + +
@direct_blueprint.route('/chat/poll')
+def poll_chat():
+    """Endpoints peers get new messages from"""
+    return Response(localcommand.local_command('/chat/gets/%s' % (g.peer,)))
+
+
+
+def request_setup() +
+
+
+
+ +Expand source code + +
@direct_blueprint.before_request
+def request_setup():
+    key_store.refresh()
+    host = request.host
+    host = host.strip('.b32.i2p')
+    host = host.strip('.onion')
+    g.host = host
+    g.peer = key_store.get('dc-' + g.host)
+
+
+
+def sendto() +
+
+

Endpoint peers send chat messages to

+
+ +Expand source code + +
@direct_blueprint.route('/chat/sendto', methods=['POST', 'GET'])
+def sendto():
+    """Endpoint peers send chat messages to"""
+    try:
+        msg = request.get_json(force=True)
+    except json.JSONDecodeError:
+        msg = ''
+    else:
+        msg = json.dumps(msg)
+        localcommand.local_command('/chat/addrec/%s' % (g.peer,), post=True, postData=msg)
+    return Response('success')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/chat/settings.html b/docs/html/src/data2871027835/plugins/chat/settings.html new file mode 100644 index 00000000..510941c3 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/chat/settings.html @@ -0,0 +1,53 @@ + + + + + + +src.data2871027835.plugins.chat.settings API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.chat.settings

+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/encrypt/index.html b/docs/html/src/data2871027835/plugins/encrypt/index.html new file mode 100644 index 00000000..2acbd5db --- /dev/null +++ b/docs/html/src/data2871027835/plugins/encrypt/index.html @@ -0,0 +1,65 @@ + + + + + + +src.data2871027835.plugins.encrypt API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/encrypt/main.html b/docs/html/src/data2871027835/plugins/encrypt/main.html new file mode 100644 index 00000000..c080e38e --- /dev/null +++ b/docs/html/src/data2871027835/plugins/encrypt/main.html @@ -0,0 +1,414 @@ + + + + + + +src.data2871027835.plugins.encrypt.main API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.encrypt.main

+
+
+

Onionr - Private P2P Communication

+

This default plugin allows users to encrypt/decrypt messages without using blocks

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    This default plugin allows users to encrypt/decrypt messages without using blocks
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+
+# Imports some useful libraries
+import logger, config, threading, time, datetime, sys, json
+from onionrutils import stringvalidators, bytesconverter
+from onionrcrypto import encryption, keypair, signing, getourkeypair
+import onionrexceptions, onionrusers
+import locale
+locale.setlocale(locale.LC_ALL, '')
+plugin_name = 'encrypt'
+
+class PlainEncryption:
+    def __init__(self, api):
+        self.api = api
+        return
+    def encrypt(self):
+        # peer, data
+        plaintext = ""
+        encrypted = ""
+        # detect if signing is enabled
+        sign = True
+        try:
+            if sys.argv[3].lower() == 'false':
+                sign = False
+        except IndexError:
+            pass
+
+        try:
+            if not stringvalidators.validate_pub_key(sys.argv[2]):
+                raise onionrexceptions.InvalidPubkey
+        except (ValueError, IndexError) as e:
+            logger.error("Peer public key not specified", terminal=True)
+        except onionrexceptions.InvalidPubkey:
+            logger.error("Invalid public key", terminal=True)
+        else:
+            pubkey = sys.argv[2]
+            # Encrypt if public key is valid
+            logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+            try:
+                for line in sys.stdin:
+                    if line == '-q\n':
+                        break
+                    plaintext += line
+            except KeyboardInterrupt:
+                sys.exit(1)
+            # Build Message to encrypt
+            data = {}
+            myPub = keypair[0]
+            if sign:
+                data['sig'] = signing.ed_sign(plaintext, key=keypair[1], encodeResult=True)
+                data['sig'] = bytesconverter.bytes_to_str(data['sig'])
+                data['signer'] = myPub
+            data['data'] = plaintext
+            data = json.dumps(data)
+            plaintext = data
+            encrypted = encryption.pub_key_encrypt(plaintext, pubkey, encodedData=True)
+            encrypted = bytesconverter.bytes_to_str(encrypted)
+            logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,), terminal=True)
+
+    def decrypt(self):
+        plaintext = ""
+        data = ""
+        logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+        keypair = getourkeypair.get_keypair()
+        try:
+            for line in sys.stdin:
+                if line == '-q\n':
+                        break
+                data += line
+        except KeyboardInterrupt:
+            sys.exit(1)
+        if len(data) <= 1:
+            return
+        encrypted = data.replace('ONIONR ENCRYPTED DATA ', '').replace('END ENCRYPTED DATA', '')
+        myPub = keypair[0]
+        decrypted = encryption.pub_key_decrypt(encrypted, privkey=keypair[1], encodedData=True)
+        if decrypted == False:
+            logger.error("Decryption failed", terminal=True)
+        else:
+            data = json.loads(decrypted)
+            logger.info('Decrypted Message: \n\n%s' % data['data'], terminal=True)
+            try:
+                logger.info("Signing public key: %s" % (data['signer'],), terminal=True)
+                if not signing.ed_verify(data['data'], data['signer'], data['sig']): raise ValueError
+            except (ValueError, KeyError) as e:
+                logger.warn("WARNING: THIS MESSAGE HAS A MISSING OR INVALID SIGNATURE", terminal=True)
+            else:
+                logger.info("Message has good signature.", terminal=True)
+        return
+
+def on_decrypt_cmd(api, data=None):
+    PlainEncryption(api).decrypt()
+
+def on_encrypt_cmd(api, data=None):
+    PlainEncryption(api).encrypt()
+
+on_encrypt_cmd.onionr_help = """encrypt <user_key>\nEncrypt text data to an Onionr user key. Similar to PGP"""
+on_decrypt_cmd.onionr_help = """decrypt\nDecrypt text data with your Onionr key. Similar to PGP"""
+ONIONR_COMMANDS = ['encrypt', 'decrypt']
+
+
+
+
+
+
+
+

Functions

+
+
+def on_decrypt_cmd(api, data=None) +
+
+
+
+ +Expand source code + +
def on_decrypt_cmd(api, data=None):
+    PlainEncryption(api).decrypt()
+
+
+
+def on_encrypt_cmd(api, data=None) +
+
+
+
+ +Expand source code + +
def on_encrypt_cmd(api, data=None):
+    PlainEncryption(api).encrypt()
+
+
+
+
+
+

Classes

+
+
+class PlainEncryption +(api) +
+
+
+
+ +Expand source code + +
class PlainEncryption:
+    def __init__(self, api):
+        self.api = api
+        return
+    def encrypt(self):
+        # peer, data
+        plaintext = ""
+        encrypted = ""
+        # detect if signing is enabled
+        sign = True
+        try:
+            if sys.argv[3].lower() == 'false':
+                sign = False
+        except IndexError:
+            pass
+
+        try:
+            if not stringvalidators.validate_pub_key(sys.argv[2]):
+                raise onionrexceptions.InvalidPubkey
+        except (ValueError, IndexError) as e:
+            logger.error("Peer public key not specified", terminal=True)
+        except onionrexceptions.InvalidPubkey:
+            logger.error("Invalid public key", terminal=True)
+        else:
+            pubkey = sys.argv[2]
+            # Encrypt if public key is valid
+            logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+            try:
+                for line in sys.stdin:
+                    if line == '-q\n':
+                        break
+                    plaintext += line
+            except KeyboardInterrupt:
+                sys.exit(1)
+            # Build Message to encrypt
+            data = {}
+            myPub = keypair[0]
+            if sign:
+                data['sig'] = signing.ed_sign(plaintext, key=keypair[1], encodeResult=True)
+                data['sig'] = bytesconverter.bytes_to_str(data['sig'])
+                data['signer'] = myPub
+            data['data'] = plaintext
+            data = json.dumps(data)
+            plaintext = data
+            encrypted = encryption.pub_key_encrypt(plaintext, pubkey, encodedData=True)
+            encrypted = bytesconverter.bytes_to_str(encrypted)
+            logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,), terminal=True)
+
+    def decrypt(self):
+        plaintext = ""
+        data = ""
+        logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+        keypair = getourkeypair.get_keypair()
+        try:
+            for line in sys.stdin:
+                if line == '-q\n':
+                        break
+                data += line
+        except KeyboardInterrupt:
+            sys.exit(1)
+        if len(data) <= 1:
+            return
+        encrypted = data.replace('ONIONR ENCRYPTED DATA ', '').replace('END ENCRYPTED DATA', '')
+        myPub = keypair[0]
+        decrypted = encryption.pub_key_decrypt(encrypted, privkey=keypair[1], encodedData=True)
+        if decrypted == False:
+            logger.error("Decryption failed", terminal=True)
+        else:
+            data = json.loads(decrypted)
+            logger.info('Decrypted Message: \n\n%s' % data['data'], terminal=True)
+            try:
+                logger.info("Signing public key: %s" % (data['signer'],), terminal=True)
+                if not signing.ed_verify(data['data'], data['signer'], data['sig']): raise ValueError
+            except (ValueError, KeyError) as e:
+                logger.warn("WARNING: THIS MESSAGE HAS A MISSING OR INVALID SIGNATURE", terminal=True)
+            else:
+                logger.info("Message has good signature.", terminal=True)
+        return
+
+

Methods

+
+
+def decrypt(self) +
+
+
+
+ +Expand source code + +
def decrypt(self):
+    plaintext = ""
+    data = ""
+    logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+    keypair = getourkeypair.get_keypair()
+    try:
+        for line in sys.stdin:
+            if line == '-q\n':
+                    break
+            data += line
+    except KeyboardInterrupt:
+        sys.exit(1)
+    if len(data) <= 1:
+        return
+    encrypted = data.replace('ONIONR ENCRYPTED DATA ', '').replace('END ENCRYPTED DATA', '')
+    myPub = keypair[0]
+    decrypted = encryption.pub_key_decrypt(encrypted, privkey=keypair[1], encodedData=True)
+    if decrypted == False:
+        logger.error("Decryption failed", terminal=True)
+    else:
+        data = json.loads(decrypted)
+        logger.info('Decrypted Message: \n\n%s' % data['data'], terminal=True)
+        try:
+            logger.info("Signing public key: %s" % (data['signer'],), terminal=True)
+            if not signing.ed_verify(data['data'], data['signer'], data['sig']): raise ValueError
+        except (ValueError, KeyError) as e:
+            logger.warn("WARNING: THIS MESSAGE HAS A MISSING OR INVALID SIGNATURE", terminal=True)
+        else:
+            logger.info("Message has good signature.", terminal=True)
+    return
+
+
+
+def encrypt(self) +
+
+
+
+ +Expand source code + +
def encrypt(self):
+    # peer, data
+    plaintext = ""
+    encrypted = ""
+    # detect if signing is enabled
+    sign = True
+    try:
+        if sys.argv[3].lower() == 'false':
+            sign = False
+    except IndexError:
+        pass
+
+    try:
+        if not stringvalidators.validate_pub_key(sys.argv[2]):
+            raise onionrexceptions.InvalidPubkey
+    except (ValueError, IndexError) as e:
+        logger.error("Peer public key not specified", terminal=True)
+    except onionrexceptions.InvalidPubkey:
+        logger.error("Invalid public key", terminal=True)
+    else:
+        pubkey = sys.argv[2]
+        # Encrypt if public key is valid
+        logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
+        try:
+            for line in sys.stdin:
+                if line == '-q\n':
+                    break
+                plaintext += line
+        except KeyboardInterrupt:
+            sys.exit(1)
+        # Build Message to encrypt
+        data = {}
+        myPub = keypair[0]
+        if sign:
+            data['sig'] = signing.ed_sign(plaintext, key=keypair[1], encodeResult=True)
+            data['sig'] = bytesconverter.bytes_to_str(data['sig'])
+            data['signer'] = myPub
+        data['data'] = plaintext
+        data = json.dumps(data)
+        plaintext = data
+        encrypted = encryption.pub_key_encrypt(plaintext, pubkey, encodedData=True)
+        encrypted = bytesconverter.bytes_to_str(encrypted)
+        logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,), terminal=True)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/flow/flowapi.html b/docs/html/src/data2871027835/plugins/flow/flowapi.html new file mode 100644 index 00000000..eb6244bd --- /dev/null +++ b/docs/html/src/data2871027835/plugins/flow/flowapi.html @@ -0,0 +1,236 @@ + + + + + + +src.data2871027835.plugins.flow.flowapi API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.flow.flowapi

+
+
+

Onionr - Private P2P Communication.

+

This file primarily serves to allow specific fetching of flow board messages

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This file primarily serves to allow specific fetching of flow board messages
+"""
+import json
+import os
+
+from flask import Response, Blueprint
+from deadsimplekv import DeadSimpleKV
+
+from utils import identifyhome
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+flask_blueprint = Blueprint('flow', __name__)
+
+with open(os.path.dirname(os.path.realpath(__file__)) + '/info.json', 'r') as info_file:
+    data = info_file.read().strip()
+    version = json.loads(data, strict=False)['version']
+
+@flask_blueprint.route('/flow/getpostsbyboard/<board>')
+def get_post_by_board(board):
+    board_cache = DeadSimpleKV(
+        identifyhome.identify_home() + '/board-index.cache.json',
+        flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    if posts is None:
+        posts = ''
+    else:
+        posts = ','.join(posts)
+    return Response(posts)
+
+@flask_blueprint.route('/flow/getpostsbyboard/<board>/<offset>')
+def get_post_by_board_with_offset(board, offset):
+    offset = int(offset)
+    OFFSET_COUNT = 10
+    board_cache = DeadSimpleKV(
+        identifyhome.identify_home() + '/board-index.cache.json',
+        flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    if posts is None:
+        posts = ''
+    else:
+        posts.reverse()
+        posts = ','.join(posts[offset:offset + OFFSET_COUNT])
+    return Response(posts)
+
+@flask_blueprint.route('/flow/version')
+def get_version():
+    return Response(version)
+
+@flask_blueprint.route('/flow/removefromcache/<board>/<name>', methods=['POST'])
+def remove_from_cache(board, name):
+    board_cache = DeadSimpleKV(identifyhome.identify_home() +
+                               '/board-index.cache.json',
+                               flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    try:
+        posts.remove(name)
+    except ValueError:
+        pass
+    board_cache.put(board, posts)
+    return Response('success')
+
+
+
+
+
+
+
+

Functions

+
+
+def get_post_by_board(board) +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/flow/getpostsbyboard/<board>')
+def get_post_by_board(board):
+    board_cache = DeadSimpleKV(
+        identifyhome.identify_home() + '/board-index.cache.json',
+        flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    if posts is None:
+        posts = ''
+    else:
+        posts = ','.join(posts)
+    return Response(posts)
+
+
+
+def get_post_by_board_with_offset(board, offset) +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/flow/getpostsbyboard/<board>/<offset>')
+def get_post_by_board_with_offset(board, offset):
+    offset = int(offset)
+    OFFSET_COUNT = 10
+    board_cache = DeadSimpleKV(
+        identifyhome.identify_home() + '/board-index.cache.json',
+        flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    if posts is None:
+        posts = ''
+    else:
+        posts.reverse()
+        posts = ','.join(posts[offset:offset + OFFSET_COUNT])
+    return Response(posts)
+
+
+
+def get_version() +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/flow/version')
+def get_version():
+    return Response(version)
+
+
+
+def remove_from_cache(board, name) +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/flow/removefromcache/<board>/<name>', methods=['POST'])
+def remove_from_cache(board, name):
+    board_cache = DeadSimpleKV(identifyhome.identify_home() +
+                               '/board-index.cache.json',
+                               flush_on_exit=False)
+    board_cache.refresh()
+    posts = board_cache.get(board)
+    try:
+        posts.remove(name)
+    except ValueError:
+        pass
+    board_cache.put(board, posts)
+    return Response('success')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/apiservers/index.html b/docs/html/src/data2871027835/plugins/flow/index.html similarity index 71% rename from docs/html/onionr/apiservers/index.html rename to docs/html/src/data2871027835/plugins/flow/index.html index 43bcd455..f60145a3 100644 --- a/docs/html/onionr/apiservers/index.html +++ b/docs/html/src/data2871027835/plugins/flow/index.html @@ -3,13 +3,13 @@ - -onionr.apiservers API documentation + +src.data2871027835.plugins.flow API documentation - + @@ -17,24 +17,18 @@
-

Module onionr.apiservers

+

Namespace src.data2871027835.plugins.flow

-
-Source code -
from . import public, private
-PublicAPI = public.PublicAPI
-ClientAPI = private.PrivateAPI
-

Sub-modules

-
onionr.apiservers.private
+
src.data2871027835.plugins.flow.flowapi

Onionr - Private P2P Communication …

-
onionr.apiservers.public
+
src.data2871027835.plugins.flow.main

Onionr - Private P2P Communication …

@@ -55,20 +49,20 @@ ClientAPI = private.PrivateAPI
diff --git a/docs/html/src/data2871027835/plugins/flow/main.html b/docs/html/src/data2871027835/plugins/flow/main.html new file mode 100644 index 00000000..8c54351b --- /dev/null +++ b/docs/html/src/data2871027835/plugins/flow/main.html @@ -0,0 +1,476 @@ + + + + + + +src.data2871027835.plugins.flow.main API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.flow.main

+
+
+

Onionr - Private P2P Communication.

+

This default plugin handles "flow" messages +(global chatroom style communication)

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This default plugin handles "flow" messages
+(global chatroom style communication)
+"""
+import sys
+import os
+import deadsimplekv as simplekv
+from utils import identifyhome, reconstructhash
+from coredb import blockmetadb
+import threading
+import time
+import locale
+from onionrblocks.onionrblockapi import Block
+import logger
+import onionrblocks
+from onionrutils import escapeansi, epoch, bytesconverter
+
+locale.setlocale(locale.LC_ALL, '')
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+# import after path insert
+import flowapi  # noqa
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+flask_blueprint = flowapi.flask_blueprint
+security_whitelist = ['staticfiles.boardContent', 'staticfiles.board']
+
+plugin_name = 'flow'
+PLUGIN_VERSION = '0.0.1'
+
+
+class OnionrFlow:
+    def __init__(self):
+        self.alreadyOutputed = []
+        self.flowRunning = False
+        self.channel = ""
+        return
+
+    def start(self):
+        logger.warn(
+            "Please note: everything said here is public, " +
+            "even if a random channel name is used.", terminal=True)
+        message = ""
+        self.flowRunning = True
+        try:
+            self.channel = logger.readline(
+                "Enter a channel name or none for default:").strip()
+        except (KeyboardInterrupt, EOFError):
+            self.flowRunning = False
+        newThread = threading.Thread(target=self.showOutput, daemon=True)
+        newThread.start()
+        while self.flowRunning:
+            if self.channel == "":
+                self.channel = "global"
+            try:
+                message = logger.readline('\nInsert message into flow:').strip().replace(
+                    '\n', '\\n').replace('\r', '\\r')
+            except EOFError:
+                pass
+            except KeyboardInterrupt:
+                self.flowRunning = False
+            else:
+                if message == "q":
+                    self.flowRunning = False
+                expireTime = epoch.get_epoch() + 43200
+                if len(message) > 0:
+                    logger.info('Inserting message as block...', terminal=True)
+                    onionrblocks.insert(message, header='brd',
+                                        expire=expireTime,
+                                        meta = {
+                                        'ch': self.channel})
+
+        logger.info("Flow is exiting, goodbye", terminal=True)
+        return
+
+    def showOutput(self):
+        while type(self.channel) is type(None) and self.flowRunning:
+            time.sleep(1)
+        try:
+            while self.flowRunning:
+                for block in blockmetadb.get_blocks_by_type('brd'):
+                    if block in self.alreadyOutputed:
+                        continue
+                    block = Block(block)
+                    b_hash = bytesconverter.bytes_to_str(block.getHash())
+                    if block.getMetadata('ch') != self.channel:
+                        continue
+                    if not self.flowRunning:
+                        break
+                    logger.info('\n------------------------',
+                                prompt=False, terminal=True)
+                    content = block.getContent()
+                    # Escape new lines, remove trailing whitespace, and escape ansi sequences
+                    content = escapeansi.escape_ANSI(content.replace(
+                        '\n', '\\n').replace('\r', '\\r').strip())
+                    logger.info(block.getDate().strftime(
+                        "%m/%d %H:%M") + ' - ' + logger.colors.reset + content, prompt=False, terminal=True)
+                    self.alreadyOutputed.append(b_hash)
+                time.sleep(5)
+        except KeyboardInterrupt:
+            self.flowRunning = False
+
+
+def on_flow_cmd(api, data=None):
+    OnionrFlow().start()
+
+
+def on_softreset(api, data=None):
+    try:
+        os.remove(identifyhome.identify_home() + '/board-index.cache.json')
+        logger.info('Cleared Circles board cache')
+    except FileNotFoundError:
+        pass
+
+
+def on_processblocks(api, data=None):
+    metadata = data['block'].bmetadata  # Get the block metadata
+    if data['type'] != 'brd':
+        return
+
+    b_hash = reconstructhash.deconstruct_hash(
+        data['block'].hash)  # Get the 0-truncated block hash
+    board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home(
+    ) + '/board-index.cache.json', flush_on_exit=False)  # get the board index cache
+    board_cache.refresh()
+    # Validate the channel name is sane for caching
+    try:
+        ch = metadata['ch']
+    except KeyError:
+        ch = 'global'
+    ch_len = len(ch)
+    if ch_len == 0:
+        ch = 'global'
+    elif ch_len > 12:
+        return
+
+    existing_posts = board_cache.get(ch)
+    if existing_posts is None:
+        existing_posts = []
+    existing_posts.append(data['block'].hash)
+    board_cache.put(ch, existing_posts)
+    board_cache.flush()
+
+
+
+
+
+
+
+

Functions

+
+
+def on_flow_cmd(api, data=None) +
+
+
+
+ +Expand source code + +
def on_flow_cmd(api, data=None):
+    OnionrFlow().start()
+
+
+
+def on_processblocks(api, data=None) +
+
+
+
+ +Expand source code + +
def on_processblocks(api, data=None):
+    metadata = data['block'].bmetadata  # Get the block metadata
+    if data['type'] != 'brd':
+        return
+
+    b_hash = reconstructhash.deconstruct_hash(
+        data['block'].hash)  # Get the 0-truncated block hash
+    board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home(
+    ) + '/board-index.cache.json', flush_on_exit=False)  # get the board index cache
+    board_cache.refresh()
+    # Validate the channel name is sane for caching
+    try:
+        ch = metadata['ch']
+    except KeyError:
+        ch = 'global'
+    ch_len = len(ch)
+    if ch_len == 0:
+        ch = 'global'
+    elif ch_len > 12:
+        return
+
+    existing_posts = board_cache.get(ch)
+    if existing_posts is None:
+        existing_posts = []
+    existing_posts.append(data['block'].hash)
+    board_cache.put(ch, existing_posts)
+    board_cache.flush()
+
+
+
+def on_softreset(api, data=None) +
+
+
+
+ +Expand source code + +
def on_softreset(api, data=None):
+    try:
+        os.remove(identifyhome.identify_home() + '/board-index.cache.json')
+        logger.info('Cleared Circles board cache')
+    except FileNotFoundError:
+        pass
+
+
+
+
+
+

Classes

+
+
+class OnionrFlow +
+
+
+
+ +Expand source code + +
class OnionrFlow:
+    def __init__(self):
+        self.alreadyOutputed = []
+        self.flowRunning = False
+        self.channel = ""
+        return
+
+    def start(self):
+        logger.warn(
+            "Please note: everything said here is public, " +
+            "even if a random channel name is used.", terminal=True)
+        message = ""
+        self.flowRunning = True
+        try:
+            self.channel = logger.readline(
+                "Enter a channel name or none for default:").strip()
+        except (KeyboardInterrupt, EOFError):
+            self.flowRunning = False
+        newThread = threading.Thread(target=self.showOutput, daemon=True)
+        newThread.start()
+        while self.flowRunning:
+            if self.channel == "":
+                self.channel = "global"
+            try:
+                message = logger.readline('\nInsert message into flow:').strip().replace(
+                    '\n', '\\n').replace('\r', '\\r')
+            except EOFError:
+                pass
+            except KeyboardInterrupt:
+                self.flowRunning = False
+            else:
+                if message == "q":
+                    self.flowRunning = False
+                expireTime = epoch.get_epoch() + 43200
+                if len(message) > 0:
+                    logger.info('Inserting message as block...', terminal=True)
+                    onionrblocks.insert(message, header='brd',
+                                        expire=expireTime,
+                                        meta = {
+                                        'ch': self.channel})
+
+        logger.info("Flow is exiting, goodbye", terminal=True)
+        return
+
+    def showOutput(self):
+        while type(self.channel) is type(None) and self.flowRunning:
+            time.sleep(1)
+        try:
+            while self.flowRunning:
+                for block in blockmetadb.get_blocks_by_type('brd'):
+                    if block in self.alreadyOutputed:
+                        continue
+                    block = Block(block)
+                    b_hash = bytesconverter.bytes_to_str(block.getHash())
+                    if block.getMetadata('ch') != self.channel:
+                        continue
+                    if not self.flowRunning:
+                        break
+                    logger.info('\n------------------------',
+                                prompt=False, terminal=True)
+                    content = block.getContent()
+                    # Escape new lines, remove trailing whitespace, and escape ansi sequences
+                    content = escapeansi.escape_ANSI(content.replace(
+                        '\n', '\\n').replace('\r', '\\r').strip())
+                    logger.info(block.getDate().strftime(
+                        "%m/%d %H:%M") + ' - ' + logger.colors.reset + content, prompt=False, terminal=True)
+                    self.alreadyOutputed.append(b_hash)
+                time.sleep(5)
+        except KeyboardInterrupt:
+            self.flowRunning = False
+
+

Methods

+
+
+def showOutput(self) +
+
+
+
+ +Expand source code + +
def showOutput(self):
+    while type(self.channel) is type(None) and self.flowRunning:
+        time.sleep(1)
+    try:
+        while self.flowRunning:
+            for block in blockmetadb.get_blocks_by_type('brd'):
+                if block in self.alreadyOutputed:
+                    continue
+                block = Block(block)
+                b_hash = bytesconverter.bytes_to_str(block.getHash())
+                if block.getMetadata('ch') != self.channel:
+                    continue
+                if not self.flowRunning:
+                    break
+                logger.info('\n------------------------',
+                            prompt=False, terminal=True)
+                content = block.getContent()
+                # Escape new lines, remove trailing whitespace, and escape ansi sequences
+                content = escapeansi.escape_ANSI(content.replace(
+                    '\n', '\\n').replace('\r', '\\r').strip())
+                logger.info(block.getDate().strftime(
+                    "%m/%d %H:%M") + ' - ' + logger.colors.reset + content, prompt=False, terminal=True)
+                self.alreadyOutputed.append(b_hash)
+            time.sleep(5)
+    except KeyboardInterrupt:
+        self.flowRunning = False
+
+
+
+def start(self) +
+
+
+
+ +Expand source code + +
def start(self):
+    logger.warn(
+        "Please note: everything said here is public, " +
+        "even if a random channel name is used.", terminal=True)
+    message = ""
+    self.flowRunning = True
+    try:
+        self.channel = logger.readline(
+            "Enter a channel name or none for default:").strip()
+    except (KeyboardInterrupt, EOFError):
+        self.flowRunning = False
+    newThread = threading.Thread(target=self.showOutput, daemon=True)
+    newThread.start()
+    while self.flowRunning:
+        if self.channel == "":
+            self.channel = "global"
+        try:
+            message = logger.readline('\nInsert message into flow:').strip().replace(
+                '\n', '\\n').replace('\r', '\\r')
+        except EOFError:
+            pass
+        except KeyboardInterrupt:
+            self.flowRunning = False
+        else:
+            if message == "q":
+                self.flowRunning = False
+            expireTime = epoch.get_epoch() + 43200
+            if len(message) > 0:
+                logger.info('Inserting message as block...', terminal=True)
+                onionrblocks.insert(message, header='brd',
+                                    expire=expireTime,
+                                    meta = {
+                                    'ch': self.channel})
+
+    logger.info("Flow is exiting, goodbye", terminal=True)
+    return
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/coredb/index.html b/docs/html/src/data2871027835/plugins/index.html similarity index 59% rename from docs/html/onionr/coredb/index.html rename to docs/html/src/data2871027835/plugins/index.html index 01fadb74..7ae6a764 100644 --- a/docs/html/onionr/coredb/index.html +++ b/docs/html/src/data2871027835/plugins/index.html @@ -3,13 +3,13 @@ - -onionr.coredb API documentation + +src.data2871027835.plugins API documentation - + @@ -17,30 +17,34 @@
-

Module onionr.coredb

+

Namespace src.data2871027835.plugins

-
-Source code -
from . import keydb, blockmetadb, daemonqueue
-

Sub-modules

-
onionr.coredb.blockmetadb
-
-

Onionr - Private P2P Communication …

-
-
onionr.coredb.daemonqueue
-
-

Onionr - Private P2P Communication …

-
-
onionr.coredb.dbfiles
+
src.data2871027835.plugins.chat
-
onionr.coredb.keydb
+
src.data2871027835.plugins.encrypt
+
+
+
+
src.data2871027835.plugins.flow
+
+
+
+
src.data2871027835.plugins.metadataprocessor
+
+
+
+
src.data2871027835.plugins.pms
+
+
+
+
src.data2871027835.plugins.searchengine
@@ -61,22 +65,24 @@
diff --git a/docs/html/src/data2871027835/plugins/metadataprocessor/index.html b/docs/html/src/data2871027835/plugins/metadataprocessor/index.html new file mode 100644 index 00000000..28c7dbbc --- /dev/null +++ b/docs/html/src/data2871027835/plugins/metadataprocessor/index.html @@ -0,0 +1,65 @@ + + + + + + +src.data2871027835.plugins.metadataprocessor API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/metadataprocessor/main.html b/docs/html/src/data2871027835/plugins/metadataprocessor/main.html new file mode 100644 index 00000000..980c7581 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/metadataprocessor/main.html @@ -0,0 +1,165 @@ + + + + + + +src.data2871027835.plugins.metadataprocessor.main API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.metadataprocessor.main

+
+
+

Onionr - Private P2P Communication

+

This processes metadata for Onionr blocks

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    This processes metadata for Onionr blocks
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+
+# useful libraries
+import logger, config
+import os, sys, json, time, random, shutil, base64, getpass, datetime, re
+import onionrusers, onionrexceptions
+from onionrutils import stringvalidators
+
+plugin_name = 'metadataprocessor'
+
+# event listeners
+
+def _processForwardKey(api, myBlock):
+    '''
+        Get the forward secrecy key specified by the user for us to use
+    '''
+    peer = onionrusers.OnionrUser(myBlock.signer)
+    key = myBlock.getMetadata('newFSKey')
+
+    # We don't need to validate here probably, but it helps
+    if stringvalidators.validate_pub_key(key):
+        peer.addForwardKey(key)
+    else:
+        raise onionrexceptions.InvalidPubkey("%s is not a valid pubkey key" % (key,))
+
+def on_processblocks(api, data=None):
+    # Generally fired by utils.
+    myBlock = api.data['block']
+    blockType = api.data['type']
+    # Process specific block types
+
+    # forwardKey blocks, add a new forward secrecy key for a peer
+    if blockType == 'forwardKey':
+        if api.data['validSig'] == True:
+            _processForwardKey(api, myBlock)
+    
+def on_init(api, data = None):
+
+    pluginapi = api
+
+    return
+
+
+
+
+
+
+
+

Functions

+
+
+def on_init(api, data=None) +
+
+
+
+ +Expand source code + +
def on_init(api, data = None):
+
+    pluginapi = api
+
+    return
+
+
+
+def on_processblocks(api, data=None) +
+
+
+
+ +Expand source code + +
def on_processblocks(api, data=None):
+    # Generally fired by utils.
+    myBlock = api.data['block']
+    blockType = api.data['type']
+    # Process specific block types
+
+    # forwardKey blocks, add a new forward secrecy key for a peer
+    if blockType == 'forwardKey':
+        if api.data['validSig'] == True:
+            _processForwardKey(api, myBlock)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/pms/index.html b/docs/html/src/data2871027835/plugins/pms/index.html new file mode 100644 index 00000000..eb147a73 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/pms/index.html @@ -0,0 +1,85 @@ + + + + + + +src.data2871027835.plugins.pms API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/httpapi/onionrsitesapi/index.html b/docs/html/src/data2871027835/plugins/pms/loadinbox.html similarity index 64% rename from docs/html/onionr/httpapi/onionrsitesapi/index.html rename to docs/html/src/data2871027835/plugins/pms/loadinbox.html index 087ddae0..bb46baf1 100644 --- a/docs/html/onionr/httpapi/onionrsitesapi/index.html +++ b/docs/html/src/data2871027835/plugins/pms/loadinbox.html @@ -3,13 +3,13 @@ - -onionr.httpapi.onionrsitesapi API documentation + +src.data2871027835.plugins.pms.loadinbox API documentation - + @@ -17,17 +17,19 @@
-

Module onionr.httpapi.onionrsitesapi

+

Module src.data2871027835.plugins.pms.loadinbox

Onionr - Private P2P Communication

-

view and interact with onionr sites

+

Load the user's inbox and return it as a list

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
-    view and interact with onionr sites
+    Load the user's inbox and return it as a list
 '''
 '''
     This program is free software: you can redistribute it and/or modify
@@ -43,33 +45,23 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
-import base64
-import binascii
-from flask import Blueprint, Response, request, abort
 from onionrblocks import onionrblockapi
-import onionrexceptions
-from onionrutils import stringvalidators
+from coredb import blockmetadb
+import filepaths
+from utils import reconstructhash, identifyhome
+import deadsimplekv as simplekv
+def load_inbox():
+    inbox_list = []
+    deleted = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/mailcache.dat').get('deleted_mail')
+    if deleted is None:
+        deleted = []
 
-site_api = Blueprint('siteapi', __name__)
-
-@site_api.route('/site/<name>', endpoint='site')
-def site(name):
-    bHash = name
-    resp = 'Not Found'
-    if stringvalidators.validate_hash(bHash):
-        try:
-            resp = onionrblockapi.Block(bHash).bcontent
-        except onionrexceptions.NoDataAvailable:
-            abort(404)
-        except TypeError:
-            pass
-        try:
-            resp = base64.b64decode(resp)
-        except binascii.Error:
-            pass
-    if resp == 'Not Found' or not resp:
-        abort(404)
-    return Response(resp)
+ for blockHash in blockmetadb.get_blocks_by_type('pm'): + block = onionrblockapi.Block(blockHash) + block.decrypt() + if block.decrypted and reconstructhash.deconstruct_hash(blockHash) not in deleted: + inbox_list.append(blockHash) + return inbox_list
@@ -79,31 +71,27 @@ def site(name):

Functions

-
-def site(name) +
+def load_inbox()
-Source code -
@site_api.route('/site/<name>', endpoint='site')
-def site(name):
-    bHash = name
-    resp = 'Not Found'
-    if stringvalidators.validate_hash(bHash):
-        try:
-            resp = onionrblockapi.Block(bHash).bcontent
-        except onionrexceptions.NoDataAvailable:
-            abort(404)
-        except TypeError:
-            pass
-        try:
-            resp = base64.b64decode(resp)
-        except binascii.Error:
-            pass
-    if resp == 'Not Found' or not resp:
-        abort(404)
-    return Response(resp)
+ +Expand source code + +
def load_inbox():
+    inbox_list = []
+    deleted = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/mailcache.dat').get('deleted_mail')
+    if deleted is None:
+        deleted = []
+
+    for blockHash in blockmetadb.get_blocks_by_type('pm'):
+        block = onionrblockapi.Block(blockHash)
+        block.decrypt()
+        if block.decrypted and reconstructhash.deconstruct_hash(blockHash) not in deleted:
+            inbox_list.append(blockHash)
+    return inbox_list
@@ -119,19 +107,19 @@ def site(name):
diff --git a/docs/html/src/data2871027835/plugins/pms/mailapi.html b/docs/html/src/data2871027835/plugins/pms/mailapi.html new file mode 100644 index 00000000..72958ae6 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/pms/mailapi.html @@ -0,0 +1,216 @@ + + + + + + +src.data2871027835.plugins.pms.mailapi API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.pms.mailapi

+
+
+

Onionr - Private P2P Communication

+

HTTP endpoints for mail plugin.

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    HTTP endpoints for mail plugin.
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+import sys, os, json
+from flask import Response, request, redirect, Blueprint, abort
+from onionrusers import contactmanager
+from onionrutils import stringvalidators
+from utils import reconstructhash, identifyhome
+import filepaths
+import deadsimplekv as simplekv
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+import loadinbox, sentboxdb
+
+flask_blueprint = Blueprint('mail', __name__)
+kv = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/mailcache.dat')
+
+@flask_blueprint.route('/mail/ping')
+def mail_ping():
+    return 'pong!'
+
+@flask_blueprint.route('/mail/deletemsg/<block>', methods=['POST'])
+def mail_delete(block):
+    if not stringvalidators.validate_hash(block):
+        abort(504)
+    block = reconstructhash.deconstruct_hash(block)
+    existing = kv.get('deleted_mail')
+    if existing is None:
+        existing = []
+    if block not in existing:
+        existing.append(block)
+    kv.put('deleted_mail', existing)
+    kv.flush()
+    return 'success'
+
+@flask_blueprint.route('/mail/getinbox')
+def list_inbox():
+    return ','.join(loadinbox.load_inbox())
+
+@flask_blueprint.route('/mail/getsentbox')
+def list_sentbox():
+    kv.refresh()
+    sentbox_list = sentboxdb.SentBox().listSent()
+    list_copy = list(sentbox_list)
+    deleted = kv.get('deleted_mail')
+    if deleted is None:
+        deleted = []
+    for sent in list_copy:
+        if sent['hash'] in deleted:
+            sentbox_list.remove(sent)
+            continue
+        sent['name'] = contactmanager.ContactManager(sent['peer'], saveUser=False).get_info('name')
+    return json.dumps(sentbox_list)
+
+
+
+
+
+
+
+

Functions

+
+
+def list_inbox() +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/mail/getinbox')
+def list_inbox():
+    return ','.join(loadinbox.load_inbox())
+
+
+
+def list_sentbox() +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/mail/getsentbox')
+def list_sentbox():
+    kv.refresh()
+    sentbox_list = sentboxdb.SentBox().listSent()
+    list_copy = list(sentbox_list)
+    deleted = kv.get('deleted_mail')
+    if deleted is None:
+        deleted = []
+    for sent in list_copy:
+        if sent['hash'] in deleted:
+            sentbox_list.remove(sent)
+            continue
+        sent['name'] = contactmanager.ContactManager(sent['peer'], saveUser=False).get_info('name')
+    return json.dumps(sentbox_list)
+
+
+
+def mail_delete(block) +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/mail/deletemsg/<block>', methods=['POST'])
+def mail_delete(block):
+    if not stringvalidators.validate_hash(block):
+        abort(504)
+    block = reconstructhash.deconstruct_hash(block)
+    existing = kv.get('deleted_mail')
+    if existing is None:
+        existing = []
+    if block not in existing:
+        existing.append(block)
+    kv.put('deleted_mail', existing)
+    kv.flush()
+    return 'success'
+
+
+
+def mail_ping() +
+
+
+
+ +Expand source code + +
@flask_blueprint.route('/mail/ping')
+def mail_ping():
+    return 'pong!'
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/pms/main.html b/docs/html/src/data2871027835/plugins/pms/main.html new file mode 100644 index 00000000..0fb87cd8 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/pms/main.html @@ -0,0 +1,206 @@ + + + + + + +src.data2871027835.plugins.pms.main API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.pms.main

+
+
+

Onionr - Private P2P Communication

+

This default plugin handles private messages in an email like fashion

+
+ +Expand source code + +
'''
+    Onionr - Private P2P Communication
+
+    This default plugin handles private messages in an email like fashion
+'''
+'''
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+'''
+
+# Imports some useful libraries
+import logger, config, threading, time, datetime
+import onionrexceptions
+from onionrusers import onionrusers, contactmanager
+from utils import reconstructhash
+from onionrutils import stringvalidators, escapeansi, bytesconverter
+import notifier
+import locale, sys, os, json
+
+locale.setlocale(locale.LC_ALL, '')
+
+plugin_name = 'pms'
+PLUGIN_VERSION = '0.0.1'
+
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+import sentboxdb, mailapi, loadinbox # import after path insert
+from onblacklist import on_blacklist_add
+
+flask_blueprint = mailapi.flask_blueprint
+security_whitelist = ['staticfiles.mail', 'staticfiles.mailindex']
+
+def add_deleted(keyStore, b_hash):
+    existing = keyStore.get('deleted_mail')
+    bHash = reconstructhash.reconstruct_hash(b_hash)
+    if existing is None:
+        existing = []
+    else:
+        if bHash in existing:
+            return
+    keyStore.put('deleted_mail', existing.append(b_hash))
+
+def on_insertblock(api, data={}):
+    meta = json.loads(data['meta'])
+    if meta['type'] == 'pm':
+        sentboxTools = sentboxdb.SentBox()
+        sentboxTools.addToSent(data['hash'], data['peer'], data['content'], meta['subject'])
+
+def on_processblocks(api, data=None):
+    if data['type'] != 'pm':
+        return
+    data['block'].decrypt()
+    metadata = data['block'].bmetadata
+
+    signer = bytesconverter.bytes_to_str(data['block'].signer)
+    user = contactmanager.ContactManager(signer, saveUser=False)
+    name = user.get_info("name")
+    if name != 'anonymous' and name != None:
+        signer = name.title()
+    else:
+        signer = signer[:5]
+
+    if data['block'].decrypted:
+        notifier.notify(title="Onionr Mail - New Message", message="From: %s\n\nSubject: %s" % (signer, metadata['subject']))
+
+
+
+
+
+
+
+

Functions

+
+
+def add_deleted(keyStore, b_hash) +
+
+
+
+ +Expand source code + +
def add_deleted(keyStore, b_hash):
+    existing = keyStore.get('deleted_mail')
+    bHash = reconstructhash.reconstruct_hash(b_hash)
+    if existing is None:
+        existing = []
+    else:
+        if bHash in existing:
+            return
+    keyStore.put('deleted_mail', existing.append(b_hash))
+
+
+
+def on_insertblock(api, data={}) +
+
+
+
+ +Expand source code + +
def on_insertblock(api, data={}):
+    meta = json.loads(data['meta'])
+    if meta['type'] == 'pm':
+        sentboxTools = sentboxdb.SentBox()
+        sentboxTools.addToSent(data['hash'], data['peer'], data['content'], meta['subject'])
+
+
+
+def on_processblocks(api, data=None) +
+
+
+
+ +Expand source code + +
def on_processblocks(api, data=None):
+    if data['type'] != 'pm':
+        return
+    data['block'].decrypt()
+    metadata = data['block'].bmetadata
+
+    signer = bytesconverter.bytes_to_str(data['block'].signer)
+    user = contactmanager.ContactManager(signer, saveUser=False)
+    name = user.get_info("name")
+    if name != 'anonymous' and name != None:
+        signer = name.title()
+    else:
+        signer = signer[:5]
+
+    if data['block'].decrypted:
+        notifier.notify(title="Onionr Mail - New Message", message="From: %s\n\nSubject: %s" % (signer, metadata['subject']))
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/pms/onblacklist.html b/docs/html/src/data2871027835/plugins/pms/onblacklist.html new file mode 100644 index 00000000..f406ec84 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/pms/onblacklist.html @@ -0,0 +1,96 @@ + + + + + + +src.data2871027835.plugins.pms.onblacklist API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.pms.onblacklist

+
+
+
+ +Expand source code + +
from threading import Thread
+
+from onionrutils import localcommand
+
+
+def on_blacklist_add(api, data=None):
+    blacklisted_data = data['data']
+
+    def remove():
+        localcommand.local_command(f'/mail/deletemsg/{blacklisted_data}', post=True)
+
+    Thread(target=remove).start()
+
+
+
+
+
+
+
+

Functions

+
+
+def on_blacklist_add(api, data=None) +
+
+
+
+ +Expand source code + +
def on_blacklist_add(api, data=None):
+    blacklisted_data = data['data']
+
+    def remove():
+        localcommand.local_command(f'/mail/deletemsg/{blacklisted_data}', post=True)
+
+    Thread(target=remove).start()
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/pms/sentboxdb.html b/docs/html/src/data2871027835/plugins/pms/sentboxdb.html new file mode 100644 index 00000000..e0f772d9 --- /dev/null +++ b/docs/html/src/data2871027835/plugins/pms/sentboxdb.html @@ -0,0 +1,333 @@ + + + + + + +src.data2871027835.plugins.pms.sentboxdb API documentation + + + + + + + + + +
+
+
+

Module src.data2871027835.plugins.pms.sentboxdb

+
+
+

Onionr - Private P2P Communication

+

This file handles the sentbox for the mail plugin

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    This file handles the sentbox for the mail plugin
+"""
+import sqlite3
+import os
+from onionrutils import epoch
+from utils import identifyhome, reconstructhash
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class SentBox:
+    def __init__(self):
+        self.dbLocation = identifyhome.identify_home() + '/sentbox.db'
+        if not os.path.exists(self.dbLocation):
+            self.createDB()
+        return
+
+    def connect(self):
+        self.conn = sqlite3.connect(self.dbLocation)
+        self.cursor = self.conn.cursor()
+
+    def close(self):
+        self.conn.close()
+
+    def createDB(self):
+        conn = sqlite3.connect(self.dbLocation)
+        cursor = conn.cursor()
+        cursor.execute("""CREATE TABLE sent(
+            hash id not null,
+            peer text not null,
+            message text not null,
+            subject text not null,
+            date int not null
+            );
+        """)
+        conn.commit()
+        conn.close()
+        return
+
+    def listSent(self):
+        self.connect()
+        retData = []
+        for entry in self.cursor.execute('SELECT * FROM sent;'):
+            retData.append({'hash': entry[0], 'peer': entry[1], 'message': entry[2], 'subject': entry[3], 'date': entry[4]})
+        self.close()
+        return retData
+
+    def addToSent(self, blockID, peer, message, subject=''):
+        blockID = reconstructhash.deconstruct_hash(blockID)
+        self.connect()
+        args = (blockID, peer, message, subject, epoch.get_epoch())
+        self.cursor.execute('INSERT INTO sent VALUES(?, ?, ?, ?, ?)', args)
+        self.conn.commit()
+        self.close()
+        return
+
+    def removeSent(self, blockID):
+        blockID = reconstructhash.deconstruct_hash(blockID)
+        self.connect()
+        args = (blockID,)
+        self.cursor.execute('DELETE FROM sent where hash=?', args)
+        self.conn.commit()
+        self.close()
+        return
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class SentBox +
+
+
+
+ +Expand source code + +
class SentBox:
+    def __init__(self):
+        self.dbLocation = identifyhome.identify_home() + '/sentbox.db'
+        if not os.path.exists(self.dbLocation):
+            self.createDB()
+        return
+
+    def connect(self):
+        self.conn = sqlite3.connect(self.dbLocation)
+        self.cursor = self.conn.cursor()
+
+    def close(self):
+        self.conn.close()
+
+    def createDB(self):
+        conn = sqlite3.connect(self.dbLocation)
+        cursor = conn.cursor()
+        cursor.execute("""CREATE TABLE sent(
+            hash id not null,
+            peer text not null,
+            message text not null,
+            subject text not null,
+            date int not null
+            );
+        """)
+        conn.commit()
+        conn.close()
+        return
+
+    def listSent(self):
+        self.connect()
+        retData = []
+        for entry in self.cursor.execute('SELECT * FROM sent;'):
+            retData.append({'hash': entry[0], 'peer': entry[1], 'message': entry[2], 'subject': entry[3], 'date': entry[4]})
+        self.close()
+        return retData
+
+    def addToSent(self, blockID, peer, message, subject=''):
+        blockID = reconstructhash.deconstruct_hash(blockID)
+        self.connect()
+        args = (blockID, peer, message, subject, epoch.get_epoch())
+        self.cursor.execute('INSERT INTO sent VALUES(?, ?, ?, ?, ?)', args)
+        self.conn.commit()
+        self.close()
+        return
+
+    def removeSent(self, blockID):
+        blockID = reconstructhash.deconstruct_hash(blockID)
+        self.connect()
+        args = (blockID,)
+        self.cursor.execute('DELETE FROM sent where hash=?', args)
+        self.conn.commit()
+        self.close()
+        return
+
+

Methods

+
+
+def addToSent(self, blockID, peer, message, subject='') +
+
+
+
+ +Expand source code + +
def addToSent(self, blockID, peer, message, subject=''):
+    blockID = reconstructhash.deconstruct_hash(blockID)
+    self.connect()
+    args = (blockID, peer, message, subject, epoch.get_epoch())
+    self.cursor.execute('INSERT INTO sent VALUES(?, ?, ?, ?, ?)', args)
+    self.conn.commit()
+    self.close()
+    return
+
+
+
+def close(self) +
+
+
+
+ +Expand source code + +
def close(self):
+    self.conn.close()
+
+
+
+def connect(self) +
+
+
+
+ +Expand source code + +
def connect(self):
+    self.conn = sqlite3.connect(self.dbLocation)
+    self.cursor = self.conn.cursor()
+
+
+
+def createDB(self) +
+
+
+
+ +Expand source code + +
def createDB(self):
+    conn = sqlite3.connect(self.dbLocation)
+    cursor = conn.cursor()
+    cursor.execute("""CREATE TABLE sent(
+        hash id not null,
+        peer text not null,
+        message text not null,
+        subject text not null,
+        date int not null
+        );
+    """)
+    conn.commit()
+    conn.close()
+    return
+
+
+
+def listSent(self) +
+
+
+
+ +Expand source code + +
def listSent(self):
+    self.connect()
+    retData = []
+    for entry in self.cursor.execute('SELECT * FROM sent;'):
+        retData.append({'hash': entry[0], 'peer': entry[1], 'message': entry[2], 'subject': entry[3], 'date': entry[4]})
+    self.close()
+    return retData
+
+
+
+def removeSent(self, blockID) +
+
+
+
+ +Expand source code + +
def removeSent(self, blockID):
+    blockID = reconstructhash.deconstruct_hash(blockID)
+    self.connect()
+    args = (blockID,)
+    self.cursor.execute('DELETE FROM sent where hash=?', args)
+    self.conn.commit()
+    self.close()
+    return
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/data2871027835/plugins/searchengine/index.html b/docs/html/src/data2871027835/plugins/searchengine/index.html new file mode 100644 index 00000000..9b45e00e --- /dev/null +++ b/docs/html/src/data2871027835/plugins/searchengine/index.html @@ -0,0 +1,65 @@ + + + + + + +src.data2871027835.plugins.searchengine API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/etc/onionrvalues.html b/docs/html/src/data2871027835/plugins/searchengine/main.html similarity index 65% rename from docs/html/onionr/etc/onionrvalues.html rename to docs/html/src/data2871027835/plugins/searchengine/main.html index f925b049..3c8858bb 100644 --- a/docs/html/onionr/etc/onionrvalues.html +++ b/docs/html/src/data2871027835/plugins/searchengine/main.html @@ -3,13 +3,13 @@ - -onionr.etc.onionrvalues API documentation + +src.data2871027835.plugins.searchengine.main API documentation - + @@ -17,17 +17,19 @@
-

Module onionr.etc.onionrvalues

+

Module src.data2871027835.plugins.searchengine.main

Onionr - Private P2P Communication

-

This file defines values and requirements used by Onionr

+

Search engine plugin for Onionr, to search for

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
-    This file defines values and requirements used by Onionr
+    Search engine plugin for Onionr, to search for 
 '''
 '''
     This program is free software: you can redistribute it and/or modify
@@ -43,40 +45,9 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
-import platform
-import os
 
-import filepaths
 
-DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA===="
-PASSWORD_LENGTH = 25
-ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
-ONIONR_VERSION = '0.0.0' # for debugging and stuff
-ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
-API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
-MIN_PY_VERSION = 7
-DEVELOPMENT_MODE = True
-MAX_BLOCK_TYPE_LENGTH = 15
-MAX_BLOCK_CLOCK_SKEW = 120
-MAIN_PUBLIC_KEY_SIZE = 32
-ORIG_RUN_DIR_ENV_VAR = 'ORIG_ONIONR_RUN_DIR'
-
-# Block creation anonymization requirements
-MIN_BLOCK_UPLOAD_PEER_PERCENT = 0.1
-
-# Begin OnionrValues migrated values
-ANNOUNCE_POW = 5
-DEFAULT_EXPIRE = 2592000
-BLOCK_METADATA_LENGTHS = {'meta': 1000, 'sig': 200, 'signer': 200, 'time': 10, 'pow': 1000, 'encryptType': 4, 'expire': 14}
-
-platform = platform.system()
-if platform == 'Windows':
-    SCRIPT_NAME = 'run-windows.bat'
-else:
-    if os.path.exists(filepaths.daemon_mark_file):
-        SCRIPT_NAME = 'start-daemon.sh'
-    else:
-        SCRIPT_NAME = 'onionr.sh'
+plugin_name = 'searchengine'
@@ -96,14 +67,14 @@ else:
diff --git a/docs/html/onionr/onionrcommands/restartonionr.html b/docs/html/src/etc/cleanup/index.html similarity index 68% rename from docs/html/onionr/onionrcommands/restartonionr.html rename to docs/html/src/etc/cleanup/index.html index a500c3f2..8a10283c 100644 --- a/docs/html/onionr/onionrcommands/restartonionr.html +++ b/docs/html/src/etc/cleanup/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.restartonionr API documentation + +src.etc.cleanup API documentation - + @@ -17,17 +17,19 @@
-

Module onionr.onionrcommands.restartonionr

+

Module src.etc.cleanup

Onionr - Private P2P Communication

-

Command to restart Onionr

+

cleanup files

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
-    Command to restart Onionr
+    cleanup files
 """
 """
     This program is free software: you can redistribute it and/or modify
@@ -43,28 +45,19 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
-import time
-import os
-import subprocess
-import platform
+import os, filepaths
 
-from etc import onionrvalues
-from onionrutils import localcommand
-import logger
+def _safe_remove(path):
+    try:
+        os.remove(path)
+    except FileNotFoundError:
+        pass
 
-from . import daemonlaunch
-
-SCRIPT_NAME = os.path.dirname(os.path.realpath(__file__)) + f'/../../{onionrvalues.SCRIPT_NAME}'
-
-def restart():
-    logger.info('Restarting Onionr', terminal=True)
-    daemonlaunch.kill_daemon()
-    while localcommand.local_command('ping', maxWait=8) == 'pong!':
-        time.sleep(0.3)
-    time.sleep(4)
-    subprocess.Popen([SCRIPT_NAME, 'start'])
-
-restart.onionr_help = 'Gracefully restart Onionr'
+def delete_run_files(): + _safe_remove(filepaths.public_API_host_file) + _safe_remove(filepaths.private_API_host_file) + _safe_remove(filepaths.daemon_mark_file) + _safe_remove(filepaths.lock_file)
@@ -74,20 +67,20 @@ restart.onionr_help = 'Gracefully restart Onionr'

Functions

-
-def restart() +
+def delete_run_files()
-Source code -
def restart():
-    logger.info('Restarting Onionr', terminal=True)
-    daemonlaunch.kill_daemon()
-    while localcommand.local_command('ping', maxWait=8) == 'pong!':
-        time.sleep(0.3)
-    time.sleep(4)
-    subprocess.Popen([SCRIPT_NAME, 'start'])
+ +Expand source code + +
def delete_run_files():
+     _safe_remove(filepaths.public_API_host_file)
+     _safe_remove(filepaths.private_API_host_file)
+     _safe_remove(filepaths.daemon_mark_file)
+     _safe_remove(filepaths.lock_file)
@@ -103,19 +96,19 @@ restart.onionr_help = 'Gracefully restart Onionr'
diff --git a/docs/html/src/etc/dependencycheck.html b/docs/html/src/etc/dependencycheck.html new file mode 100644 index 00000000..66153dd6 --- /dev/null +++ b/docs/html/src/etc/dependencycheck.html @@ -0,0 +1,59 @@ + + + + + + +src.etc.dependencycheck API documentation + + + + + + + + + +
+
+
+

Module src.etc.dependencycheck

+
+
+
+ +Expand source code + +
from urllib3.contrib.socks import SOCKSProxyManager # noqa
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/etc/humanreadabletime.html b/docs/html/src/etc/humanreadabletime.html similarity index 81% rename from docs/html/onionr/etc/humanreadabletime.html rename to docs/html/src/etc/humanreadabletime.html index 6367f8b3..64224a62 100644 --- a/docs/html/onionr/etc/humanreadabletime.html +++ b/docs/html/src/etc/humanreadabletime.html @@ -3,13 +3,13 @@ - -onionr.etc.humanreadabletime API documentation + +src.etc.humanreadabletime API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.etc.humanreadabletime

+

Module src.etc.humanreadabletime

Onionr - Private P2P Communication

human_readable_time takes integer seconds and returns a human readable string

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -71,13 +73,15 @@ def human_readable_time(seconds):
 

Functions

-
+
def human_readable_time(seconds)
-Source code + +Expand source code +
def human_readable_time(seconds):
     build = ''
 
@@ -112,19 +116,19 @@ def human_readable_time(seconds):
 
 
 
diff --git a/docs/html/onionr/netcontroller/index.html b/docs/html/src/etc/index.html similarity index 63% rename from docs/html/onionr/netcontroller/index.html rename to docs/html/src/etc/index.html index 38477d89..f83f6b7b 100644 --- a/docs/html/onionr/netcontroller/index.html +++ b/docs/html/src/etc/index.html @@ -3,13 +3,13 @@ - -onionr.netcontroller API documentation + +src.etc API documentation - + @@ -17,37 +17,34 @@
-

Module onionr.netcontroller

+

Module src.etc

-
-Source code -
from . import torbinary, getopenport, netcontrol
-tor_binary = torbinary.tor_binary
-get_open_port = getopenport.get_open_port
-NetController = netcontrol.NetController
-

Sub-modules

-
onionr.netcontroller.getopenport
+
src.etc.cleanup

Onionr - Private P2P Communication …

-
onionr.netcontroller.netcontrol
-
-

Onionr - Private P2P Communication …

-
-
onionr.netcontroller.rebuildtor
+
src.etc.dependencycheck
-
onionr.netcontroller.torbinary
+
src.etc.humanreadabletime

Onionr - Private P2P Communication …

-
onionr.netcontroller.torcontroller
+
src.etc.onionrvalues
+
+

Onionr - Private P2P Communication …

+
+
src.etc.powchoice
+
+

Onionr - Private P2P Communication …

+
+
src.etc.waitforsetvar
@@ -68,23 +65,24 @@ NetController = netcontrol.NetController
diff --git a/docs/html/src/etc/onionrvalues.html b/docs/html/src/etc/onionrvalues.html new file mode 100644 index 00000000..d0b1c3f8 --- /dev/null +++ b/docs/html/src/etc/onionrvalues.html @@ -0,0 +1,171 @@ + + + + + + +src.etc.onionrvalues API documentation + + + + + + + + + +
+
+
+

Module src.etc.onionrvalues

+
+
+

Onionr - Private P2P Communication.

+

This file defines values and requirements used by Onionr

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This file defines values and requirements used by Onionr
+"""
+import platform
+import os
+
+import filepaths
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA"
+PASSWORD_LENGTH = 25
+ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
+ONIONR_VERSION = '0.1.0' # for debugging and stuff
+ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
+API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
+MIN_PY_VERSION = 7 # min version of 7 so we can take advantage of non-cyclic type hints
+DEVELOPMENT_MODE = False
+"""limit type length for a block (soft enforced, ignored if invalid but block still stored)."""
+MAX_BLOCK_TYPE_LENGTH = 15
+"""limit clock timestamp for new blocks to be skewed in the future in seconds,
+2 minutes to allow plenty of time for slow block insertion and slight clock inaccuracies"""
+MAX_BLOCK_CLOCK_SKEW = 120
+"""Onionr user IDs are ed25519 keys, which are always 32 bytes in length"""
+MAIN_PUBLIC_KEY_SIZE = 32
+ORIG_RUN_DIR_ENV_VAR = 'ORIG_ONIONR_RUN_DIR'
+
+DATABASE_LOCK_TIMEOUT = 60
+
+# Block creation anonymization requirements
+MIN_BLOCK_UPLOAD_PEER_PERCENT = 0.1
+MIN_SHARE_WAIT_DELAY_SECS = 5
+
+WSGI_SERVER_REQUEST_TIMEOUT_SECS = 120
+
+MAX_NEW_PEER_QUEUE = 1000
+
+# Begin OnionrValues migrated values
+
+"""30 days is plenty of time for someone to decide to renew a block"""
+DEFAULT_EXPIRE = 2592000
+# Metadata header section length limits, in bytes
+BLOCK_METADATA_LENGTHS = {'meta': 1000, 'sig': 200, 'signer': 200, 'time': 10, 'pow': 1000, 'encryptType': 4, 'expire': 14}
+
+# Pool Eligibility Max Age
+BLOCK_POOL_MAX_AGE = 300
+
+"""Public key that signs MOTD messages shown in the web UI"""
+MOTD_SIGN_KEY = "TRH763JURNY47QPBTTQ4LLPYCYQK6Q5YA33R6GANKZK5C5DKCIGQ"
+
+"""Public key that signs update notifications."""
+UPDATE_SIGN_KEY = "TRH763JURNY47QPBTTQ4LLPYCYQK6Q5YA33R6GANKZK5C5DKCIGQ"
+
+platform = platform.system()
+if platform == 'Windows':
+    SCRIPT_NAME = 'run-windows.bat'
+else:
+    if os.path.exists(filepaths.daemon_mark_file):
+        SCRIPT_NAME = 'start-daemon.sh'
+    else:
+        SCRIPT_NAME = 'onionr.sh'
+
+
+
+
+
+

Global variables

+
+
var BLOCK_POOL_MAX_AGE
+
+

Public key that signs MOTD messages shown in the web UI

+
+
var DEVELOPMENT_MODE
+
+

limit type length for a block (soft enforced, ignored if invalid but block still stored).

+
+
var MAX_BLOCK_CLOCK_SKEW
+
+

Onionr user IDs are ed25519 keys, which are always 32 bytes in length

+
+
var MAX_BLOCK_TYPE_LENGTH
+
+

limit clock timestamp for new blocks to be skewed in the future in seconds, +2 minutes to allow plenty of time for slow block insertion and slight clock inaccuracies

+
+
var MAX_NEW_PEER_QUEUE
+
+

30 days is plenty of time for someone to decide to renew a block

+
+
var MOTD_SIGN_KEY
+
+

Public key that signs update notifications.

+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/etc/powchoice.html b/docs/html/src/etc/powchoice.html similarity index 80% rename from docs/html/onionr/etc/powchoice.html rename to docs/html/src/etc/powchoice.html index 1803c159..c033a737 100644 --- a/docs/html/onionr/etc/powchoice.html +++ b/docs/html/src/etc/powchoice.html @@ -3,13 +3,13 @@ - -onionr.etc.powchoice API documentation + +src.etc.powchoice API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.etc.powchoice

+

Module src.etc.powchoice

Onionr - Private P2P Communication

This file does determinations for what proof of work module should be used

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -60,13 +62,15 @@ def use_subprocess(config_inst):
 

Functions

-
+
def use_subprocess(config_inst)
-Source code + +Expand source code +
def use_subprocess(config_inst):
     use = True
     if not config_inst.get('general.use_subprocess_pow_if_possible', True):
@@ -89,19 +93,19 @@ def use_subprocess(config_inst):
 
 
 
diff --git a/docs/html/onionr/etc/waitforsetvar.html b/docs/html/src/etc/waitforsetvar.html similarity index 78% rename from docs/html/onionr/etc/waitforsetvar.html rename to docs/html/src/etc/waitforsetvar.html index b45ab0e6..ed0978f8 100644 --- a/docs/html/onionr/etc/waitforsetvar.html +++ b/docs/html/src/etc/waitforsetvar.html @@ -3,13 +3,13 @@ - -onionr.etc.waitforsetvar API documentation + +src.etc.waitforsetvar API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.etc.waitforsetvar

+

Module src.etc.waitforsetvar

-Source code + +Expand source code +
from __future__ import annotations
 from typing import Union, Generic
 from gevent import sleep
@@ -39,13 +41,15 @@ def wait_for_set_var(obj, attribute, sleep_seconds: Union[int, float]=0):
 

Functions

-
+
def wait_for_set_var(obj, attribute, sleep_seconds=0)

Wait for an object to get an attribute with an optional sleep time

-Source code + +Expand source code +
def wait_for_set_var(obj, attribute, sleep_seconds: Union[int, float]=0):
     """Wait for an object to get an attribute with an optional sleep time"""
     while not hasattr(obj, attribute):
@@ -66,19 +70,19 @@ def wait_for_set_var(obj, attribute, sleep_seconds: Union[int, float]=0):
 
 
 
diff --git a/docs/html/onionr/filepaths/index.html b/docs/html/src/filepaths/index.html similarity index 78% rename from docs/html/onionr/filepaths/index.html rename to docs/html/src/filepaths/index.html index 157af2c1..271c63b4 100644 --- a/docs/html/onionr/filepaths/index.html +++ b/docs/html/src/filepaths/index.html @@ -3,13 +3,13 @@ - -onionr.filepaths API documentation + +src.filepaths API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.filepaths

+

Module src.filepaths

-Source code + +Expand source code +
from utils import identifyhome
 import os
 home = identifyhome.identify_home()
@@ -42,14 +44,20 @@ export_location = home + 'block-export/'
 upload_list = home + 'upload-list.json'
 config_file = home + 'config.json'
 daemon_mark_file = app_root + '/daemon-true.txt'
+lock_file = home + 'onionr.lock'
 
+site_cache = home + 'onionr-sites.txt'
+
+tor_hs_loc = home + 'hs/'
 tor_hs_address_file = home + 'hs/hostname'
 
 run_check_file = home + '.runcheck'
 
 data_nonce_file = home + 'block-nonces.dat'
 
-keys_file = home + 'keys.txt'
+keys_file = home + 'keys.txt' + +onboarding_mark_file = home + 'onboarding-completed'
@@ -69,14 +77,14 @@ keys_file = home + 'keys.txt'
diff --git a/docs/html/onionr/httpapi/apiutils/getblockdata.html b/docs/html/src/httpapi/apiutils/getblockdata.html similarity index 82% rename from docs/html/onionr/httpapi/apiutils/getblockdata.html rename to docs/html/src/httpapi/apiutils/getblockdata.html index 99a66a34..36df77e4 100644 --- a/docs/html/onionr/httpapi/apiutils/getblockdata.html +++ b/docs/html/src/httpapi/apiutils/getblockdata.html @@ -3,13 +3,13 @@ - -onionr.httpapi.apiutils.getblockdata API documentation + +src.httpapi.apiutils.getblockdata API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.httpapi.apiutils.getblockdata

+

Module src.httpapi.apiutils.getblockdata

-Source code + +Expand source code +
import json
 from onionrblocks import onionrblockapi
 from onionrutils import bytesconverter, stringvalidators
@@ -68,14 +70,16 @@ class GetBlockData:
 

Classes

-
+
class GetBlockData (client_api_inst=None)
-Source code + +Expand source code +
class GetBlockData:
     def __init__(self, client_api_inst=None):
         return
@@ -110,13 +114,15 @@ class GetBlockData:
 

Methods

-
+
def get_block_data(self, bHash, decrypt=False, raw=False, headerOnly=False)
-Source code + +Expand source code +
def get_block_data(self, bHash, decrypt=False, raw=False, headerOnly=False):
     if not stringvalidators.validate_hash(bHash): raise onionrexceptions.InvalidHexHash("block hash not valid hash format")
     bl = onionrblockapi.Block(bHash)
@@ -159,15 +165,15 @@ class GetBlockData:
 
diff --git a/docs/html/onionr/httpapi/apiutils/index.html b/docs/html/src/httpapi/apiutils/index.html similarity index 69% rename from docs/html/onionr/httpapi/apiutils/index.html rename to docs/html/src/httpapi/apiutils/index.html index e1a8c674..a066e4cd 100644 --- a/docs/html/onionr/httpapi/apiutils/index.html +++ b/docs/html/src/httpapi/apiutils/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.apiutils API documentation + +src.httpapi.apiutils API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.httpapi.apiutils

+

Module src.httpapi.apiutils

-Source code + +Expand source code +
from . import shutdown, setbindip, getblockdata
 
 GetBlockData = getblockdata.GetBlockData
@@ -30,15 +32,15 @@ GetBlockData = getblockdata.GetBlockData

Sub-modules

-
onionr.httpapi.apiutils.getblockdata
+
src.httpapi.apiutils.getblockdata
-
onionr.httpapi.apiutils.setbindip
+
src.httpapi.apiutils.setbindip
-
onionr.httpapi.apiutils.shutdown
+
src.httpapi.apiutils.shutdown

Onionr - Private P2P Communication …

@@ -59,21 +61,21 @@ GetBlockData = getblockdata.GetBlockData
diff --git a/docs/html/onionr/httpapi/apiutils/setbindip.html b/docs/html/src/httpapi/apiutils/setbindip.html similarity index 82% rename from docs/html/onionr/httpapi/apiutils/setbindip.html rename to docs/html/src/httpapi/apiutils/setbindip.html index 58fd35b4..748f2593 100644 --- a/docs/html/onionr/httpapi/apiutils/setbindip.html +++ b/docs/html/src/httpapi/apiutils/setbindip.html @@ -3,13 +3,13 @@ - -onionr.httpapi.apiutils.setbindip API documentation + +src.httpapi.apiutils.setbindip API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.httpapi.apiutils.setbindip

+

Module src.httpapi.apiutils.setbindip

-Source code + +Expand source code +
import gevent
 from gevent import socket, sleep
 import secrets, random
@@ -73,13 +75,15 @@ def set_bind_IP(filePath=''):
 

Functions

-
+
def set_bind_IP(filePath='')

Set a random localhost IP to a specified file (intended for private or public API localhost IPs)

-Source code + +Expand source code +
def set_bind_IP(filePath=''):
     '''Set a random localhost IP to a specified file (intended for private or public API localhost IPs)'''
     if config.get('general.random_bind_ip', True):
@@ -121,19 +125,19 @@ def set_bind_IP(filePath=''):
 
 
 
diff --git a/docs/html/onionr/httpapi/apiutils/shutdown.html b/docs/html/src/httpapi/apiutils/shutdown.html similarity index 76% rename from docs/html/onionr/httpapi/apiutils/shutdown.html rename to docs/html/src/httpapi/apiutils/shutdown.html index 8dcb7c41..10ca98d3 100644 --- a/docs/html/onionr/httpapi/apiutils/shutdown.html +++ b/docs/html/src/httpapi/apiutils/shutdown.html @@ -3,13 +3,13 @@ - -onionr.httpapi.apiutils.shutdown API documentation + +src.httpapi.apiutils.shutdown API documentation - + @@ -17,19 +17,26 @@
-

Module onionr.httpapi.apiutils.shutdown

+

Module src.httpapi.apiutils.shutdown

Onionr - Private P2P Communication

Shutdown the node either hard or cleanly

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
     Shutdown the node either hard or cleanly
-'''
-'''
+"""
+from flask import Blueprint, Response
+from flask import g
+from onionrblocks import onionrblockapi
+import onionrexceptions
+from onionrutils import stringvalidators
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,12 +49,8 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from flask import Blueprint, Response
-from onionrblocks import onionrblockapi
-import onionrexceptions
-from onionrutils import stringvalidators
-from coredb import daemonqueue
+"""
+
 shutdown_bp = Blueprint('shutdown', __name__)
 
 def shutdown(client_api_inst):
@@ -61,7 +64,7 @@ def shutdown(client_api_inst):
 @shutdown_bp.route('/shutdownclean')
 def shutdown_clean():
     # good for calling from other clients
-    daemonqueue.daemon_queue_add('shutdown')
+    g.too_many.get_by_string("OnionrCommunicatorDaemon").shutdown = True
     return Response("bye")
@@ -72,13 +75,15 @@ def shutdown_clean():

Functions

-
+
def shutdown(client_api_inst)
-Source code + +Expand source code +
def shutdown(client_api_inst):
     try:
         client_api_inst.publicAPI.httpServer.stop()
@@ -88,17 +93,19 @@ def shutdown_clean():
     return Response("bye")
-
+
def shutdown_clean()
-Source code + +Expand source code +
@shutdown_bp.route('/shutdownclean')
 def shutdown_clean():
     # good for calling from other clients
-    daemonqueue.daemon_queue_add('shutdown')
+    g.too_many.get_by_string("OnionrCommunicatorDaemon").shutdown = True
     return Response("bye")
@@ -115,20 +122,20 @@ def shutdown_clean():
diff --git a/docs/html/onionr/httpapi/configapi/index.html b/docs/html/src/httpapi/configapi/index.html similarity index 73% rename from docs/html/onionr/httpapi/configapi/index.html rename to docs/html/src/httpapi/configapi/index.html index 1f18bf38..f7a81f85 100644 --- a/docs/html/onionr/httpapi/configapi/index.html +++ b/docs/html/src/httpapi/configapi/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.configapi API documentation + +src.httpapi.configapi API documentation - + @@ -17,19 +17,21 @@
-

Module onionr.httpapi.configapi

+

Module src.httpapi.configapi

Onionr - Private P2P Communication

This file handles configuration setting and getting from the HTTP API

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
     This file handles configuration setting and getting from the HTTP API
-'''
-'''
+"""
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,7 +44,7 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
+"""
 import json
 from flask import Blueprint, request, Response, abort
 import config, onionrutils
@@ -52,17 +54,17 @@ config_BP = Blueprint('config_BP', __name__)
 
 @config_BP.route('/config/get')
 def get_all_config():
-    '''Simply return all configuration as JSON string'''
+    """Simply return all configuration as JSON string"""
     return Response(json.dumps(config.get_config(), indent=4, sort_keys=True))
 
 @config_BP.route('/config/get/<key>')
 def get_by_key(key):
-    '''Return a config setting by key'''
+    """Return a config setting by key"""
     return Response(json.dumps(config.get(key)))
 
 @config_BP.route('/config/setall', methods=['POST'])
 def set_all_config():
-    '''Overwrite existing JSON config with new JSON string'''
+    """Overwrite existing JSON config with new JSON string"""
     try:
         new_config = request.get_json(force=True)
     except json.JSONDecodeError:
@@ -74,12 +76,12 @@ def set_all_config():
 
 @config_BP.route('/config/set/<key>', methods=['POST'])
 def set_by_key(key):
-    '''Overwrite/set only 1 config key'''
-    '''
+    """Overwrite/set only 1 config key"""
+    """
     {
         'data': data
     }
-    '''
+    """
     try:
         data = json.loads(onionrutils.OnionrUtils.bytesToStr(request.data))['data']
     except (json.JSONDecodeError, KeyError):
@@ -95,42 +97,48 @@ def set_by_key(key):
 

Functions

-
+
def get_all_config()

Simply return all configuration as JSON string

-Source code + +Expand source code +
@config_BP.route('/config/get')
 def get_all_config():
-    '''Simply return all configuration as JSON string'''
+    """Simply return all configuration as JSON string"""
     return Response(json.dumps(config.get_config(), indent=4, sort_keys=True))
-
+
def get_by_key(key)

Return a config setting by key

-Source code + +Expand source code +
@config_BP.route('/config/get/<key>')
 def get_by_key(key):
-    '''Return a config setting by key'''
+    """Return a config setting by key"""
     return Response(json.dumps(config.get(key)))
-
+
def set_all_config()

Overwrite existing JSON config with new JSON string

-Source code + +Expand source code +
@config_BP.route('/config/setall', methods=['POST'])
 def set_all_config():
-    '''Overwrite existing JSON config with new JSON string'''
+    """Overwrite existing JSON config with new JSON string"""
     try:
         new_config = request.get_json(force=True)
     except json.JSONDecodeError:
@@ -141,21 +149,23 @@ def set_all_config():
         return Response('success')
-
+
def set_by_key(key)

Overwrite/set only 1 config key

-Source code + +Expand source code +
@config_BP.route('/config/set/<key>', methods=['POST'])
 def set_by_key(key):
-    '''Overwrite/set only 1 config key'''
-    '''
+    """Overwrite/set only 1 config key"""
+    """
     {
         'data': data
     }
-    '''
+    """
     try:
         data = json.loads(onionrutils.OnionrUtils.bytesToStr(request.data))['data']
     except (json.JSONDecodeError, KeyError):
@@ -177,22 +187,22 @@ def set_by_key(key):
 
 
 
diff --git a/docs/html/src/httpapi/daemoneventsapi/index.html b/docs/html/src/httpapi/daemoneventsapi/index.html new file mode 100644 index 00000000..c98a7f23 --- /dev/null +++ b/docs/html/src/httpapi/daemoneventsapi/index.html @@ -0,0 +1,188 @@ + + + + + + +src.httpapi.daemoneventsapi API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.daemoneventsapi

+
+
+

Onionr - Private P2P Communication.

+

Event driven interface to trigger events in communicator

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Event driven interface to trigger events in communicator
+"""
+from typing import Callable
+
+from flask import Blueprint, request, Response, abort
+from werkzeug.exceptions import BadRequest
+from gevent import spawn
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class DaemonEventsBP:
+    def __init__(self):
+        """Create DaemonEvents instance, intended to be a singleton.
+
+        Attributes:
+        listeners: callables that are called when a new event is added.
+            The callables name should match the event name
+        _too_many: TooManyObjects instance set by external code
+        """
+        event_BP = Blueprint('event_BP', __name__)
+        self.listeners = set([])
+        self.flask_bp = event_BP
+        event_BP = self.flask_bp
+
+        @event_BP.route('/daemon-event/<name>', methods=['POST'])
+        def daemon_event_handler(name):
+            handler: Callable
+
+            try:
+                json_data = request.get_json(force=True)
+            except BadRequest:
+                json_data = {}
+            for handler in self.listeners:
+                if handler.__name__ == name:
+                    return Response(handler(**json_data))
+            abort(404)
+
+    def register_listener(self, listener: Callable):
+        self.listeners.add(listener)
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class DaemonEventsBP +
+
+

Create DaemonEvents instance, intended to be a singleton.

+

Attributes: +listeners: callables that are called when a new event is added. +The callables name should match the event name +_too_many: TooManyObjects instance set by external code

+
+ +Expand source code + +
class DaemonEventsBP:
+    def __init__(self):
+        """Create DaemonEvents instance, intended to be a singleton.
+
+        Attributes:
+        listeners: callables that are called when a new event is added.
+            The callables name should match the event name
+        _too_many: TooManyObjects instance set by external code
+        """
+        event_BP = Blueprint('event_BP', __name__)
+        self.listeners = set([])
+        self.flask_bp = event_BP
+        event_BP = self.flask_bp
+
+        @event_BP.route('/daemon-event/<name>', methods=['POST'])
+        def daemon_event_handler(name):
+            handler: Callable
+
+            try:
+                json_data = request.get_json(force=True)
+            except BadRequest:
+                json_data = {}
+            for handler in self.listeners:
+                if handler.__name__ == name:
+                    return Response(handler(**json_data))
+            abort(404)
+
+    def register_listener(self, listener: Callable):
+        self.listeners.add(listener)
+
+

Methods

+
+
+def register_listener(self, listener) +
+
+
+
+ +Expand source code + +
def register_listener(self, listener: Callable):
+    self.listeners.add(listener)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/httpapi/directconnections/index.html b/docs/html/src/httpapi/directconnections/index.html similarity index 85% rename from docs/html/onionr/httpapi/directconnections/index.html rename to docs/html/src/httpapi/directconnections/index.html index 485049b5..38716183 100644 --- a/docs/html/onionr/httpapi/directconnections/index.html +++ b/docs/html/src/httpapi/directconnections/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.directconnections API documentation + +src.httpapi.directconnections API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.directconnections

+

Module src.httpapi.directconnections

Onionr - Private P2P Communication

Misc client API endpoints too small to need their own file and that need access to the client api inst

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -104,14 +106,16 @@ class DirectConnectionManagement:
 

Classes

-
+
class DirectConnectionManagement (client_api)
-Source code + +Expand source code +
class DirectConnectionManagement:
     def __init__(self, client_api):
         direct_conn_management_bp = Blueprint('direct_conn_management', __name__)
@@ -157,13 +161,13 @@ class DirectConnectionManagement:
 
diff --git a/docs/html/onionr/httpapi/fdsafehandler.html b/docs/html/src/httpapi/fdsafehandler.html similarity index 78% rename from docs/html/onionr/httpapi/fdsafehandler.html rename to docs/html/src/httpapi/fdsafehandler.html index 9e9a5e0a..457e5daa 100644 --- a/docs/html/onionr/httpapi/fdsafehandler.html +++ b/docs/html/src/httpapi/fdsafehandler.html @@ -3,13 +3,13 @@ - -onionr.httpapi.fdsafehandler API documentation + +src.httpapi.fdsafehandler API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.httpapi.fdsafehandler

+

Module src.httpapi.fdsafehandler

-Source code + +Expand source code +
from gevent.pywsgi import WSGIServer, WSGIHandler
 from gevent import Timeout
 class FDSafeHandler(WSGIHandler):
@@ -47,14 +49,16 @@ class FDSafeHandler(WSGIHandler):
 

Classes

-
+
class FDSafeHandler (sock, address, server, rfile=None)

Our WSGI handler. Doesn't do much non-default except timeouts

-Source code + +Expand source code +
class FDSafeHandler(WSGIHandler):
     '''Our WSGI handler. Doesn't do much non-default except timeouts'''
     def handle(self):
@@ -74,7 +78,7 @@ class FDSafeHandler(WSGIHandler):
 
 

Methods

-
+
def handle(self)
@@ -84,7 +88,9 @@ class FDSafeHandler(WSGIHandler): connection have been handled (that is, it implements keep-alive).

-Source code + +Expand source code +
def handle(self):
     self.timeout = Timeout(120, Exception)
     self.timeout.start()
@@ -110,15 +116,15 @@ keep-alive).

diff --git a/docs/html/onionr/httpapi/friendsapi/index.html b/docs/html/src/httpapi/friendsapi/index.html similarity index 77% rename from docs/html/onionr/httpapi/friendsapi/index.html rename to docs/html/src/httpapi/friendsapi/index.html index c6680f5b..e78547f8 100644 --- a/docs/html/onionr/httpapi/friendsapi/index.html +++ b/docs/html/src/httpapi/friendsapi/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.friendsapi API documentation + +src.httpapi.friendsapi API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.friendsapi

+

Module src.httpapi.friendsapi

Onionr - Private P2P Communication

This file creates http endpoints for friend management

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -46,6 +48,7 @@
 import json
 from onionrusers import contactmanager
 from flask import Blueprint, Response, request, abort, redirect
+from coredb import keydb
 
 friends = Blueprint('friends', __name__)
 
@@ -65,6 +68,8 @@ def add_friend(pubkey):
 @friends.route('/friends/remove/<pubkey>', methods=['POST'])
 def remove_friend(pubkey):
     contactmanager.ContactManager(pubkey).setTrust(0)
+    contactmanager.ContactManager(pubkey).delete_contact()
+    keydb.removekeys.remove_user(pubkey)
     return redirect(request.referrer + '#' + request.form['token'])
 
 @friends.route('/friends/setinfo/<pubkey>/<key>', methods=['POST'])
@@ -89,26 +94,30 @@ def get_info(pubkey, key):
 

Functions

-
+
def add_friend(pubkey)
-Source code + +Expand source code +
@friends.route('/friends/add/<pubkey>', methods=['POST'])
 def add_friend(pubkey):
     contactmanager.ContactManager(pubkey, saveUser=True).setTrust(1)
     return redirect(request.referrer + '#' + request.form['token'])
-
+
def get_info(pubkey, key)
-Source code + +Expand source code +
@friends.route('/friends/getinfo/<pubkey>/<key>')
 def get_info(pubkey, key):
     retData = contactmanager.ContactManager(pubkey).get_info(key)
@@ -118,13 +127,15 @@ def get_info(pubkey, key):
         return retData
-
+
def list_friends()
-Source code + +Expand source code +
@friends.route('/friends/list')
 def list_friends():
     pubkey_list = {}
@@ -134,26 +145,32 @@ def list_friends():
     return json.dumps(pubkey_list)
-
+
def remove_friend(pubkey)
-Source code + +Expand source code +
@friends.route('/friends/remove/<pubkey>', methods=['POST'])
 def remove_friend(pubkey):
     contactmanager.ContactManager(pubkey).setTrust(0)
+    contactmanager.ContactManager(pubkey).delete_contact()
+    keydb.removekeys.remove_user(pubkey)
     return redirect(request.referrer + '#' + request.form['token'])
-
+
def set_info(pubkey, key)
-Source code + +Expand source code +
@friends.route('/friends/setinfo/<pubkey>/<key>', methods=['POST'])
 def set_info(pubkey, key):
     data = request.form['data']
@@ -174,23 +191,23 @@ def set_info(pubkey, key):
 
 
 
diff --git a/docs/html/onionr/httpapi/index.html b/docs/html/src/httpapi/index.html similarity index 58% rename from docs/html/onionr/httpapi/index.html rename to docs/html/src/httpapi/index.html index 9f65fdd4..2884dccf 100644 --- a/docs/html/onionr/httpapi/index.html +++ b/docs/html/src/httpapi/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi API documentation + +src.httpapi API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi

+

Module src.httpapi

Onionr - Private P2P Communication

This file registers plugin's flask blueprints for the client http server

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
@@ -44,10 +46,15 @@
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
 import onionrplugins
+import config
 
 def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint'):
     """Iterate enabled plugins and load any http endpoints they have"""
+    config.reload()
+    disabled = config.get('plugins.disabled')
     for plugin in onionrplugins.get_enabled_plugins():
+        if plugin in disabled:
+            continue
         plugin = onionrplugins.get_plugin(plugin)
         try:
             flaskapp.register_blueprint(getattr(plugin, blueprint))
@@ -58,50 +65,62 @@ def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint')
 

Sub-modules

-
onionr.httpapi.apiutils
+
src.httpapi.apiutils
-
onionr.httpapi.configapi
+
src.httpapi.configapi

Onionr - Private P2P Communication …

-
onionr.httpapi.directconnections
+
src.httpapi.daemoneventsapi

Onionr - Private P2P Communication …

-
onionr.httpapi.fdsafehandler
+
src.httpapi.directconnections
+
+

Onionr - Private P2P Communication …

+
+
src.httpapi.fdsafehandler
-
onionr.httpapi.friendsapi
+
src.httpapi.friendsapi

Onionr - Private P2P Communication …

-
onionr.httpapi.insertblock
+
src.httpapi.insertblock

Onionr - Private P2P Communication …

-
onionr.httpapi.miscclientapi
+
src.httpapi.miscclientapi
-
onionr.httpapi.miscpublicapi
+
src.httpapi.miscpublicapi
-
onionr.httpapi.onionrsitesapi
+
src.httpapi.onionrsitesapi

Onionr - Private P2P Communication …

-
onionr.httpapi.profilesapi
+
src.httpapi.profilesapi

Onionr - Private P2P Communication …

-
onionr.httpapi.security
+
src.httpapi.security
+
src.httpapi.sse
+
+

Onionr - Private P2P Communication …

+
+
src.httpapi.themeapi
+
+

Onionr - Private P2P Communication …

+
@@ -109,16 +128,22 @@ def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint')

Functions

-
+
def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint')

Iterate enabled plugins and load any http endpoints they have

-Source code + +Expand source code +
def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint'):
     """Iterate enabled plugins and load any http endpoints they have"""
+    config.reload()
+    disabled = config.get('plugins.disabled')
     for plugin in onionrplugins.get_enabled_plugins():
+        if plugin in disabled:
+            continue
         plugin = onionrplugins.get_plugin(plugin)
         try:
             flaskapp.register_blueprint(getattr(plugin, blueprint))
@@ -139,34 +164,37 @@ def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint')
 
 
 
diff --git a/docs/html/onionr/httpapi/insertblock.html b/docs/html/src/httpapi/insertblock.html similarity index 85% rename from docs/html/onionr/httpapi/insertblock.html rename to docs/html/src/httpapi/insertblock.html index 5451b1a8..c6d48e8f 100644 --- a/docs/html/onionr/httpapi/insertblock.html +++ b/docs/html/src/httpapi/insertblock.html @@ -3,13 +3,13 @@ - -onionr.httpapi.insertblock API documentation + +src.httpapi.insertblock API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.insertblock

+

Module src.httpapi.insertblock

Onionr - Private P2P Communication

Create blocks with the client api server

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -106,13 +108,15 @@ def client_api_insert_block():
 

Functions

-
+
def client_api_insert_block()
-Source code + +Expand source code +
@ib.route('/insertblock', methods=['POST'])
 def client_api_insert_block():
     encrypt = False
@@ -174,19 +178,19 @@ def client_api_insert_block():
 
 
 
diff --git a/docs/html/onionr/httpapi/miscclientapi/endpoints.html b/docs/html/src/httpapi/miscclientapi/endpoints.html similarity index 69% rename from docs/html/onionr/httpapi/miscclientapi/endpoints.html rename to docs/html/src/httpapi/miscclientapi/endpoints.html index a419195b..3c096a08 100644 --- a/docs/html/onionr/httpapi/miscclientapi/endpoints.html +++ b/docs/html/src/httpapi/miscclientapi/endpoints.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscclientapi.endpoints API documentation + +src.httpapi.miscclientapi.endpoints API documentation - + @@ -17,19 +17,37 @@
-

Module onionr.httpapi.miscclientapi.endpoints

+

Module src.httpapi.miscclientapi.endpoints

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Misc client API endpoints too small to need their own file and that need access to the client api inst

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Misc client API endpoints too small to need their own file and that need access to the client api inst
-'''
-'''
+Misc client API endpoints too small to need their own file and that need access to the client api inst
+"""
+import os
+import subprocess
+
+from flask import Response, Blueprint, request, send_from_directory, abort
+from gevent import spawn
+from gevent import sleep
+import unpaddedbase32
+
+from httpapi import apiutils
+import onionrcrypto
+import config
+from netcontroller import NetController
+from onionrstatistics.serializeddata import SerializedData
+from onionrutils import mnemonickeys
+from onionrutils import bytesconverter
+from etc import onionrvalues
+from utils import reconstructhash
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,21 +60,13 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from flask import Response, Blueprint, request, send_from_directory, abort
-import unpaddedbase32
-
-from httpapi import apiutils
-import onionrcrypto, config
-from netcontroller import NetController
-from serializeddata import SerializedData
-from onionrutils import mnemonickeys
-from onionrutils import bytesconverter
-from utils import reconstructhash
-from onionrcommands import restartonionr
+"""
 
 pub_key = onionrcrypto.pub_key.replace('=', '')
 
+SCRIPT_NAME = os.path.dirname(os.path.realpath(__file__)) + \
+              f'/../../../{onionrvalues.SCRIPT_NAME}'
+
 class PrivateEndpoints:
     def __init__(self, client_api):
         private_endpoints_bp = Blueprint('privateendpoints', __name__)
@@ -72,27 +82,6 @@ class PrivateEndpoints:
         def get_hit_count():
             return Response(str(client_api.publicAPI.hitCount))
 
-        @private_endpoints_bp.route('/queueResponseAdd/<name>', methods=['post'])
-        def queueResponseAdd(name):
-            # Responses from the daemon. TODO: change to direct var access instead of http endpoint
-            client_api.queueResponse[name] = request.form['data']
-            return Response('success')
-        
-        @private_endpoints_bp.route('/queueResponse/<name>')
-        def queueResponse(name):
-            # Fetch a daemon queue response
-            resp = 'failure'
-            try:
-                resp = client_api.queueResponse[name]
-            except KeyError:
-                pass
-            else:
-                del client_api.queueResponse[name]
-            if resp == 'failure':
-                return resp, 404
-            else:
-                return resp
-            
         @private_endpoints_bp.route('/ping')
         def ping():
             # Used to check if client api is working
@@ -103,13 +92,17 @@ class PrivateEndpoints:
             return Response(str(client_api.publicAPI.lastRequest))
 
         @private_endpoints_bp.route('/waitforshare/<name>', methods=['post'])
-        def waitforshare(name):
-            '''Used to prevent the **public** api from sharing blocks we just created'''
-            if not name.isalnum(): raise ValueError('block hash needs to be alpha numeric')
+        def wait_for_share(name):
+            """Prevent the **public** api from sharing blocks.
+
+            Used for blocks we created usually
+            """
+            if not name.isalnum():
+                raise ValueError('block hash needs to be alpha numeric')
             name = reconstructhash.reconstruct_hash(name)
             if name in client_api.publicAPI.hideBlocks:
-                client_api.publicAPI.hideBlocks.remove(name)
-                return Response("removed")
+                spawn(_delay_wait_for_share_block_removal)
+                return Response("will be removed")
             else:
                 client_api.publicAPI.hideBlocks.append(name)
                 return Response("added")
@@ -120,22 +113,27 @@ class PrivateEndpoints:
 
         @private_endpoints_bp.route('/restartclean')
         def restart_clean():
-            restartonionr.restart()
+            subprocess.Popen([SCRIPT_NAME, 'restart'])
             return Response("bye")
-        
+
+        @private_endpoints_bp.route('/gethidden')
+        def get_hidden_blocks():
+            return Response('\n'.join(client_api.publicAPI.hideBlocks))
+
         @private_endpoints_bp.route('/getstats')
-        def getStats():
-            # returns node stats
+        def get_stats():
+            """Return serialized node statistics."""
             while True:
-                try:    
-                    return Response(client_api._too_many.get(SerializedData).get_stats())
-                except AttributeError as e:
+                try:
+                    return Response(client_api._too_many.get(
+                        SerializedData).get_stats())
+                except AttributeError:
                     pass
-        
+
         @private_endpoints_bp.route('/getuptime')
         def showUptime():
             return Response(str(client_api.getUptime()))
-        
+
         @private_endpoints_bp.route('/getActivePubkey')
         def getActivePubkey():
             return Response(pub_key)
@@ -148,14 +146,18 @@ class PrivateEndpoints:
         def getHumanReadable(name):
             name = unpaddedbase32.repad(bytesconverter.str_to_bytes(name))
             return Response(mnemonickeys.get_human_readable_ID(name))
-        
+
         @private_endpoints_bp.route('/getBase32FromHumanReadable/<words>')
         def get_base32_from_human_readable(words):
             return Response(bytesconverter.bytes_to_str(mnemonickeys.get_base32(words)))
 
         @private_endpoints_bp.route('/gettorsocks')
         def get_tor_socks():
-            return Response(str(client_api._too_many.get(NetController).socksPort))
+ return Response(str(client_api._too_many.get(NetController).socksPort)) + + @private_endpoints_bp.route('/setonboarding', methods=['POST']) + def set_onboarding(): + return Response(config.onboarding.set_config_from_onboarding(request.get_json()))
@@ -167,14 +169,16 @@ class PrivateEndpoints:

Classes

-
+
class PrivateEndpoints (client_api)
-Source code + +Expand source code +
class PrivateEndpoints:
     def __init__(self, client_api):
         private_endpoints_bp = Blueprint('privateendpoints', __name__)
@@ -190,27 +194,6 @@ class PrivateEndpoints:
         def get_hit_count():
             return Response(str(client_api.publicAPI.hitCount))
 
-        @private_endpoints_bp.route('/queueResponseAdd/<name>', methods=['post'])
-        def queueResponseAdd(name):
-            # Responses from the daemon. TODO: change to direct var access instead of http endpoint
-            client_api.queueResponse[name] = request.form['data']
-            return Response('success')
-        
-        @private_endpoints_bp.route('/queueResponse/<name>')
-        def queueResponse(name):
-            # Fetch a daemon queue response
-            resp = 'failure'
-            try:
-                resp = client_api.queueResponse[name]
-            except KeyError:
-                pass
-            else:
-                del client_api.queueResponse[name]
-            if resp == 'failure':
-                return resp, 404
-            else:
-                return resp
-            
         @private_endpoints_bp.route('/ping')
         def ping():
             # Used to check if client api is working
@@ -221,13 +204,17 @@ class PrivateEndpoints:
             return Response(str(client_api.publicAPI.lastRequest))
 
         @private_endpoints_bp.route('/waitforshare/<name>', methods=['post'])
-        def waitforshare(name):
-            '''Used to prevent the **public** api from sharing blocks we just created'''
-            if not name.isalnum(): raise ValueError('block hash needs to be alpha numeric')
+        def wait_for_share(name):
+            """Prevent the **public** api from sharing blocks.
+
+            Used for blocks we created usually
+            """
+            if not name.isalnum():
+                raise ValueError('block hash needs to be alpha numeric')
             name = reconstructhash.reconstruct_hash(name)
             if name in client_api.publicAPI.hideBlocks:
-                client_api.publicAPI.hideBlocks.remove(name)
-                return Response("removed")
+                spawn(_delay_wait_for_share_block_removal)
+                return Response("will be removed")
             else:
                 client_api.publicAPI.hideBlocks.append(name)
                 return Response("added")
@@ -238,22 +225,27 @@ class PrivateEndpoints:
 
         @private_endpoints_bp.route('/restartclean')
         def restart_clean():
-            restartonionr.restart()
+            subprocess.Popen([SCRIPT_NAME, 'restart'])
             return Response("bye")
-        
+
+        @private_endpoints_bp.route('/gethidden')
+        def get_hidden_blocks():
+            return Response('\n'.join(client_api.publicAPI.hideBlocks))
+
         @private_endpoints_bp.route('/getstats')
-        def getStats():
-            # returns node stats
+        def get_stats():
+            """Return serialized node statistics."""
             while True:
-                try:    
-                    return Response(client_api._too_many.get(SerializedData).get_stats())
-                except AttributeError as e:
+                try:
+                    return Response(client_api._too_many.get(
+                        SerializedData).get_stats())
+                except AttributeError:
                     pass
-        
+
         @private_endpoints_bp.route('/getuptime')
         def showUptime():
             return Response(str(client_api.getUptime()))
-        
+
         @private_endpoints_bp.route('/getActivePubkey')
         def getActivePubkey():
             return Response(pub_key)
@@ -266,14 +258,18 @@ class PrivateEndpoints:
         def getHumanReadable(name):
             name = unpaddedbase32.repad(bytesconverter.str_to_bytes(name))
             return Response(mnemonickeys.get_human_readable_ID(name))
-        
+
         @private_endpoints_bp.route('/getBase32FromHumanReadable/<words>')
         def get_base32_from_human_readable(words):
             return Response(bytesconverter.bytes_to_str(mnemonickeys.get_base32(words)))
 
         @private_endpoints_bp.route('/gettorsocks')
         def get_tor_socks():
-            return Response(str(client_api._too_many.get(NetController).socksPort))
+ return Response(str(client_api._too_many.get(NetController).socksPort)) + + @private_endpoints_bp.route('/setonboarding', methods=['POST']) + def set_onboarding(): + return Response(config.onboarding.set_config_from_onboarding(request.get_json()))
@@ -287,13 +283,13 @@ class PrivateEndpoints:
diff --git a/docs/html/onionr/httpapi/miscclientapi/getblocks.html b/docs/html/src/httpapi/miscclientapi/getblocks.html similarity index 77% rename from docs/html/onionr/httpapi/miscclientapi/getblocks.html rename to docs/html/src/httpapi/miscclientapi/getblocks.html index df238228..ab26d224 100644 --- a/docs/html/onionr/httpapi/miscclientapi/getblocks.html +++ b/docs/html/src/httpapi/miscclientapi/getblocks.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscclientapi.getblocks API documentation + +src.httpapi.miscclientapi.getblocks API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.miscclientapi.getblocks

+

Module src.httpapi.miscclientapi.getblocks

Onionr - Private P2P Communication

Create blocks with the client api server

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -98,13 +100,15 @@ def getBlockHeader(name):
 

Functions

-
+
def getBlockBodyData(name)
-Source code + +Expand source code +
@client_get_blocks.route('/getblockbody/<name>')
 def getBlockBodyData(name):
     resp = ''
@@ -118,26 +122,30 @@ def getBlockBodyData(name):
     return Response(resp)
-
+
def getBlockHeader(name)
-Source code + +Expand source code +
@client_get_blocks.route('/getblockheader/<name>')
 def getBlockHeader(name):
     resp = client_get_block.get_block_data(name, decrypt=True, headerOnly=True)
     return Response(resp)
-
+
def getData(name)
-Source code + +Expand source code +
@client_get_blocks.route('/getblockdata/<name>')
 def getData(name):
     resp = ""
@@ -154,13 +162,15 @@ def getData(name):
     return Response(resp)
-
+
def get_blocks_by_type_endpoint(name)
-Source code + +Expand source code +
@client_get_blocks.route('/getblocksbytype/<name>')
 def get_blocks_by_type_endpoint(name):
     blocks = blockmetadb.get_blocks_by_type(name)
@@ -180,22 +190,22 @@ def get_blocks_by_type_endpoint(name):
 
 
 
diff --git a/docs/html/src/httpapi/miscclientapi/index.html b/docs/html/src/httpapi/miscclientapi/index.html new file mode 100644 index 00000000..955a22ed --- /dev/null +++ b/docs/html/src/httpapi/miscclientapi/index.html @@ -0,0 +1,86 @@ + + + + + + +src.httpapi.miscclientapi API documentation + + + + + + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/miscclientapi/motd/index.html b/docs/html/src/httpapi/miscclientapi/motd/index.html new file mode 100644 index 00000000..9bd08195 --- /dev/null +++ b/docs/html/src/httpapi/miscclientapi/motd/index.html @@ -0,0 +1,117 @@ + + + + + + +src.httpapi.miscclientapi.motd API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.miscclientapi.motd

+
+
+
+ +Expand source code + +
from flask import Blueprint
+from flask import Response
+import unpaddedbase32
+
+from coredb import blockmetadb
+import onionrblocks
+from etc import onionrvalues
+import config
+from onionrutils import bytesconverter
+
+bp = Blueprint('motd', __name__)
+
+signer = config.get("motd.motd_key", onionrvalues.MOTD_SIGN_KEY)
+
+@bp.route('/getmotd')
+def get_motd()->Response:
+    motds = blockmetadb.get_blocks_by_type("motd")
+    newest_time = 0
+    message = "No MOTD currently present."
+    for x in motds:
+        bl = onionrblocks.onionrblockapi.Block(x)
+        if not bl.verifySig() or bl.signer != bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))): continue
+        if not bl.isSigner(signer): continue
+        if bl.claimedTime > newest_time:
+            newest_time = bl.claimedTime
+            message = bl.bcontent
+    return Response(message, headers={"Content-Type": "text/plain"})
+
+
+
+
+
+
+
+

Functions

+
+
+def get_motd() +
+
+
+
+ +Expand source code + +
@bp.route('/getmotd')
+def get_motd()->Response:
+    motds = blockmetadb.get_blocks_by_type("motd")
+    newest_time = 0
+    message = "No MOTD currently present."
+    for x in motds:
+        bl = onionrblocks.onionrblockapi.Block(x)
+        if not bl.verifySig() or bl.signer != bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))): continue
+        if not bl.isSigner(signer): continue
+        if bl.claimedTime > newest_time:
+            newest_time = bl.claimedTime
+            message = bl.bcontent
+    return Response(message, headers={"Content-Type": "text/plain"})
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/httpapi/miscclientapi/staticfiles.html b/docs/html/src/httpapi/miscclientapi/staticfiles.html similarity index 67% rename from docs/html/onionr/httpapi/miscclientapi/staticfiles.html rename to docs/html/src/httpapi/miscclientapi/staticfiles.html index 1aac0e75..50f9c086 100644 --- a/docs/html/onionr/httpapi/miscclientapi/staticfiles.html +++ b/docs/html/src/httpapi/miscclientapi/staticfiles.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscclientapi.staticfiles API documentation + +src.httpapi.miscclientapi.staticfiles API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.miscclientapi.staticfiles

+

Module src.httpapi.miscclientapi.staticfiles

Onionr - Private P2P Communication

Register static file routes

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -56,6 +58,14 @@ static_files_bp = Blueprint('staticfiles', __name__)
 
 root = os.path.dirname(os.path.realpath(__file__)) + '/../../../static-data/www/' # should be set to onionr install directory from onionr startup
 
+@static_files_bp.route('/onboarding/', endpoint='onboardingIndex')
+def onboard():
+    return send_from_directory(f'{root}onboarding/', "index.html")
+
+@static_files_bp.route('/onboarding/<path:path>', endpoint='onboarding')
+def onboard_files(path):
+    return send_from_directory(f'{root}onboarding/', path)
+
 @static_files_bp.route('/chat/', endpoint='chatIndex')
 def chat_index():
     return send_from_directory(root + 'chat/', "index.html")
@@ -117,122 +127,170 @@ def homedata(path):
 

Functions

-
+
def boardContent(path)
-Source code + +Expand source code +
@static_files_bp.route('/board/<path:path>', endpoint='boardContent')
 def boardContent(path):
     return send_from_directory(root + 'board/', path)
-
+
def chat_index()
-Source code + +Expand source code +
@static_files_bp.route('/chat/', endpoint='chatIndex')
 def chat_index():
     return send_from_directory(root + 'chat/', "index.html")
-
+
def hello()
-Source code + +Expand source code +
@static_files_bp.route('/', endpoint='onionrhome')
 def hello():
     # ui home
     return send_from_directory(root + 'private/', 'index.html')
-
+
def homedata(path)
-Source code + +Expand source code +
@static_files_bp.route('/private/<path:path>', endpoint='homedata')
 def homedata(path):
     return send_from_directory(root + 'private/', path)
-
+
def loadBoard()
-Source code + +Expand source code +
@static_files_bp.route('/board/', endpoint='board')
 def loadBoard():
     return send_from_directory(root + 'board/', "index.html")
-
+
def loadContacts()
-Source code + +Expand source code +
@static_files_bp.route('/profiles/', endpoint='profilesindex')
 def loadContacts():
     return send_from_directory(root + 'profiles/', 'index.html')
-
+
def loadMail(path)
-Source code + +Expand source code +
@static_files_bp.route('/mail/<path:path>', endpoint='mail')
 def loadMail(path):
     return send_from_directory(root + 'mail/', path)
-
+
def loadMailIndex()
-Source code + +Expand source code +
@static_files_bp.route('/mail/', endpoint='mailindex')
 def loadMailIndex():
     return send_from_directory(root + 'mail/', 'index.html')
-
+
def load_chat(path)
-Source code + +Expand source code +
@static_files_bp.route('/chat/<path:path>', endpoint='chat')
 def load_chat(path):
     return send_from_directory(root + 'chat/', path)
-
+
+def onboard() +
+
+
+
+ +Expand source code + +
@static_files_bp.route('/onboarding/', endpoint='onboardingIndex')
+def onboard():
+    return send_from_directory(f'{root}onboarding/', "index.html")
+
+
+
+def onboard_files(path) +
+
+
+
+ +Expand source code + +
@static_files_bp.route('/onboarding/<path:path>', endpoint='onboarding')
+def onboard_files(path):
+    return send_from_directory(f'{root}onboarding/', path)
+
+
+
def sharedContent(path)
-Source code + +Expand source code +
@static_files_bp.route('/shared/<path:path>', endpoint='sharedContent')
 def sharedContent(path):
     return send_from_directory(root + 'shared/', path)
@@ -251,28 +309,30 @@ def sharedContent(path):
diff --git a/docs/html/onionr/httpapi/miscpublicapi/announce.html b/docs/html/src/httpapi/miscpublicapi/announce.html similarity index 56% rename from docs/html/onionr/httpapi/miscpublicapi/announce.html rename to docs/html/src/httpapi/miscpublicapi/announce.html index 00d3760c..50d3fc23 100644 --- a/docs/html/onionr/httpapi/miscpublicapi/announce.html +++ b/docs/html/src/httpapi/miscpublicapi/announce.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscpublicapi.announce API documentation + +src.httpapi.miscpublicapi.announce API documentation - + @@ -17,19 +17,28 @@
-

Module onionr.httpapi.miscpublicapi.announce

+

Module src.httpapi.miscpublicapi.announce

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Handle announcements to the public API server

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Handle announcements to the public API server
-'''
-'''
+Handle announcements to the public API server
+"""
+from flask import Response, g
+import deadsimplekv
+
+import logger
+from etc import onionrvalues
+from onionrutils import stringvalidators, bytesconverter
+import filepaths
+from communicator import OnionrCommunicatorDaemon
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,60 +51,39 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import base64
-from flask import Response, g
-import deadsimplekv
-import logger
-from etc import onionrvalues
-from onionrutils import stringvalidators, bytesconverter
-from utils import gettransports
-import onionrcrypto as crypto, filepaths
-from communicator import OnionrCommunicatorDaemon
+"""
+
+
 def handle_announce(request):
-    '''
-    accept announcement posts, validating POW
+    """accept announcement posts, validating POW
     clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request
-    '''
+    """
     resp = 'failure'
-    powHash = ''
-    randomData = ''
     newNode = ''
 
     try:
         newNode = request.form['node'].encode()
     except KeyError:
         logger.warn('No node specified for upload')
-        pass
     else:
-        try:
-            randomData = request.form['random']
-            randomData = base64.b64decode(randomData)
-        except KeyError:
-            logger.warn('No random data specified for upload')
+        newNode = bytesconverter.bytes_to_str(newNode)
+        announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
+        announce_queue_list = announce_queue.get('new_peers')
+        if announce_queue_list is None:
+            announce_queue_list = []
         else:
-            nodes = newNode + bytesconverter.str_to_bytes(gettransports.get()[0])
-            nodes = crypto.hashers.blake2b_hash(nodes)
-            powHash = crypto.hashers.blake2b_hash(randomData + nodes)
-            try:
-                powHash = powHash.decode()
-            except AttributeError:
-                pass
-            if powHash.startswith('0' * onionrvalues.ANNOUNCE_POW):
-                newNode = bytesconverter.bytes_to_str(newNode)
-                announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
-                announce_queue_list = announce_queue.get('new_peers')
-                if announce_queue_list is None:
-                    announce_queue_list = []
+            if len(announce_queue_list) >= onionrvalues.MAX_NEW_PEER_QUEUE:
+                newNode = ''
+
+        if stringvalidators.validate_transport(newNode) and \
+                newNode not in announce_queue_list:
+            g.shared_state.get(
+                OnionrCommunicatorDaemon).newPeers.append(newNode)
+            announce_queue.put('new_peers',
+                               announce_queue_list.append(newNode))
+            announce_queue.flush()
+            resp = 'Success'
 
-                if stringvalidators.validate_transport(newNode) and not newNode in announce_queue_list:
-                    #clientAPI.onionrInst.communicatorInst.newPeers.append(newNode)
-                    g.shared_state.get(OnionrCommunicatorDaemon).newPeers.append(newNode)
-                    announce_queue.put('new_peers', announce_queue_list.append(newNode))
-                    announce_queue.flush()
-                    resp = 'Success'
-            else:
-                logger.warn(newNode.decode() + ' failed to meet POW: ' + powHash)
     resp = Response(resp)
     if resp == 'failure':
         return resp, 406
@@ -109,58 +97,46 @@ def handle_announce(request):
 

Functions

-
+
def handle_announce(request)

accept announcement posts, validating POW clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request

-Source code + +Expand source code +
def handle_announce(request):
-    '''
-    accept announcement posts, validating POW
+    """accept announcement posts, validating POW
     clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request
-    '''
+    """
     resp = 'failure'
-    powHash = ''
-    randomData = ''
     newNode = ''
 
     try:
         newNode = request.form['node'].encode()
     except KeyError:
         logger.warn('No node specified for upload')
-        pass
     else:
-        try:
-            randomData = request.form['random']
-            randomData = base64.b64decode(randomData)
-        except KeyError:
-            logger.warn('No random data specified for upload')
+        newNode = bytesconverter.bytes_to_str(newNode)
+        announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
+        announce_queue_list = announce_queue.get('new_peers')
+        if announce_queue_list is None:
+            announce_queue_list = []
         else:
-            nodes = newNode + bytesconverter.str_to_bytes(gettransports.get()[0])
-            nodes = crypto.hashers.blake2b_hash(nodes)
-            powHash = crypto.hashers.blake2b_hash(randomData + nodes)
-            try:
-                powHash = powHash.decode()
-            except AttributeError:
-                pass
-            if powHash.startswith('0' * onionrvalues.ANNOUNCE_POW):
-                newNode = bytesconverter.bytes_to_str(newNode)
-                announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
-                announce_queue_list = announce_queue.get('new_peers')
-                if announce_queue_list is None:
-                    announce_queue_list = []
+            if len(announce_queue_list) >= onionrvalues.MAX_NEW_PEER_QUEUE:
+                newNode = ''
+
+        if stringvalidators.validate_transport(newNode) and \
+                newNode not in announce_queue_list:
+            g.shared_state.get(
+                OnionrCommunicatorDaemon).newPeers.append(newNode)
+            announce_queue.put('new_peers',
+                               announce_queue_list.append(newNode))
+            announce_queue.flush()
+            resp = 'Success'
 
-                if stringvalidators.validate_transport(newNode) and not newNode in announce_queue_list:
-                    #clientAPI.onionrInst.communicatorInst.newPeers.append(newNode)
-                    g.shared_state.get(OnionrCommunicatorDaemon).newPeers.append(newNode)
-                    announce_queue.put('new_peers', announce_queue_list.append(newNode))
-                    announce_queue.flush()
-                    resp = 'Success'
-            else:
-                logger.warn(newNode.decode() + ' failed to meet POW: ' + powHash)
     resp = Response(resp)
     if resp == 'failure':
         return resp, 406
@@ -180,19 +156,19 @@ clientAPI should be an instance of the clientAPI server running, request is a in
 
 
 
diff --git a/docs/html/onionr/httpapi/miscpublicapi/endpoints.html b/docs/html/src/httpapi/miscpublicapi/endpoints.html similarity index 87% rename from docs/html/onionr/httpapi/miscpublicapi/endpoints.html rename to docs/html/src/httpapi/miscpublicapi/endpoints.html index ca5b9fe9..d40f9415 100644 --- a/docs/html/onionr/httpapi/miscpublicapi/endpoints.html +++ b/docs/html/src/httpapi/miscpublicapi/endpoints.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscpublicapi.endpoints API documentation + +src.httpapi.miscpublicapi.endpoints API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.miscpublicapi.endpoints

+

Module src.httpapi.miscpublicapi.endpoints

Onionr - Private P2P Communication

Misc public API endpoints too small to need their own file and that need access to the public api inst

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -116,14 +118,16 @@ class PublicEndpoints:
 

Classes

-
+
class PublicEndpoints (public_api)
-Source code + +Expand source code +
class PublicEndpoints:
     def __init__(self, public_api):
 
@@ -195,13 +199,13 @@ class PublicEndpoints:
 
diff --git a/docs/html/onionr/httpapi/miscpublicapi/getblocks.html b/docs/html/src/httpapi/miscpublicapi/getblocks.html similarity index 82% rename from docs/html/onionr/httpapi/miscpublicapi/getblocks.html rename to docs/html/src/httpapi/miscpublicapi/getblocks.html index 8553ba25..e4e542cc 100644 --- a/docs/html/onionr/httpapi/miscpublicapi/getblocks.html +++ b/docs/html/src/httpapi/miscpublicapi/getblocks.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscpublicapi.getblocks API documentation + +src.httpapi.miscpublicapi.getblocks API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.miscpublicapi.getblocks

+

Module src.httpapi.miscpublicapi.getblocks

Onionr - Private P2P Communication

Public endpoints to get block data and lists

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -91,13 +93,15 @@ def get_block_data(publicAPI, data):
 

Functions

-
+
def get_block_data(publicAPI, data)

data is the block hash in hex

-Source code + +Expand source code +
def get_block_data(publicAPI, data):
     '''data is the block hash in hex'''
     resp = ''
@@ -119,13 +123,15 @@ def get_block_data(publicAPI, data):
     return Response(resp, mimetype='application/octet-stream')
-
+
def get_public_block_list(publicAPI, request)
-Source code + +Expand source code +
def get_public_block_list(publicAPI, request):
     # Provide a list of our blocks, with a date offset
     dateAdjust = request.args.get('date')
@@ -154,20 +160,20 @@ def get_block_data(publicAPI, data):
 
 
 
diff --git a/docs/html/onionr/httpapi/miscpublicapi/index.html b/docs/html/src/httpapi/miscpublicapi/index.html similarity index 69% rename from docs/html/onionr/httpapi/miscpublicapi/index.html rename to docs/html/src/httpapi/miscpublicapi/index.html index ddd946ba..8c230c1e 100644 --- a/docs/html/onionr/httpapi/miscpublicapi/index.html +++ b/docs/html/src/httpapi/miscpublicapi/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscpublicapi API documentation + +src.httpapi.miscpublicapi API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.httpapi.miscpublicapi

+

Module src.httpapi.miscpublicapi

-Source code + +Expand source code +
from . import announce, upload, getblocks, endpoints
 
 announce = announce.handle_announce # endpoint handler for accepting peer announcements
@@ -33,19 +35,19 @@ public_get_block_data = getblocks.get_block_data # endpoint handler for respondi
 

Sub-modules

-
onionr.httpapi.miscpublicapi.announce
+
src.httpapi.miscpublicapi.announce

Onionr - Private P2P Communication …

-
onionr.httpapi.miscpublicapi.endpoints
+
src.httpapi.miscpublicapi.endpoints

Onionr - Private P2P Communication …

-
onionr.httpapi.miscpublicapi.getblocks
+
src.httpapi.miscpublicapi.getblocks

Onionr - Private P2P Communication …

-
onionr.httpapi.miscpublicapi.upload
+
src.httpapi.miscpublicapi.upload

Onionr - Private P2P Communication …

@@ -66,22 +68,22 @@ public_get_block_data = getblocks.get_block_data # endpoint handler for respondi
diff --git a/docs/html/onionr/httpapi/miscpublicapi/upload.html b/docs/html/src/httpapi/miscpublicapi/upload.html similarity index 71% rename from docs/html/onionr/httpapi/miscpublicapi/upload.html rename to docs/html/src/httpapi/miscpublicapi/upload.html index ac2cf0ce..4a9b9e7c 100644 --- a/docs/html/onionr/httpapi/miscpublicapi/upload.html +++ b/docs/html/src/httpapi/miscpublicapi/upload.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscpublicapi.upload API documentation + +src.httpapi.miscpublicapi.upload API documentation - + @@ -17,18 +17,32 @@
-

Module onionr.httpapi.miscpublicapi.upload

+

Module src.httpapi.miscpublicapi.upload

Onionr - Private P2P Communication

Accept block uploads to the public API server

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
     Accept block uploads to the public API server
 '''
+from gevent import spawn
+from gevent import threading
+
+import sys
+from flask import Response
+from flask import abort
+
+from onionrutils import localcommand
+from onionrblocks import blockimporter
+import onionrexceptions
+import logger
+
 '''
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,18 +57,24 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
-import sys
-from flask import Response, abort
 
-from onionrblocks import blockimporter
-import onionrexceptions, logger
 
 def accept_upload(request):
+    """Accept uploaded blocks to our public Onionr protocol API server"""
     resp = 'failure'
     data = request.get_data()
+    b_hash = ''
     if sys.getsizeof(data) < 100000000:
         try:
-            if blockimporter.importBlockFromData(data):
+            b_hash = blockimporter.import_block_from_data(data)
+            if b_hash:
+                spawn(
+                    localcommand.local_command,
+                    f'/daemon-event/upload_event',
+                    post=True,
+                    is_json=True,
+                    postData={'block': b_hash}
+                    ).get(timeout=10)
                 resp = 'success'
             else:
                 resp = 'failure'
@@ -82,19 +102,31 @@ def accept_upload(request):
 

Functions

-
+
def accept_upload(request)
-
+

Accept uploaded blocks to our public Onionr protocol API server

-Source code + +Expand source code +
def accept_upload(request):
+    """Accept uploaded blocks to our public Onionr protocol API server"""
     resp = 'failure'
     data = request.get_data()
+    b_hash = ''
     if sys.getsizeof(data) < 100000000:
         try:
-            if blockimporter.importBlockFromData(data):
+            b_hash = blockimporter.import_block_from_data(data)
+            if b_hash:
+                spawn(
+                    localcommand.local_command,
+                    f'/daemon-event/upload_event',
+                    post=True,
+                    is_json=True,
+                    postData={'block': b_hash}
+                    ).get(timeout=10)
                 resp = 'success'
             else:
                 resp = 'failure'
@@ -128,19 +160,19 @@ def accept_upload(request):
 
 
 
diff --git a/docs/html/src/httpapi/onionrsitesapi/findsite.html b/docs/html/src/httpapi/onionrsitesapi/findsite.html new file mode 100644 index 00000000..83d3d79a --- /dev/null +++ b/docs/html/src/httpapi/onionrsitesapi/findsite.html @@ -0,0 +1,146 @@ + + + + + + +src.httpapi.onionrsitesapi.findsite API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.onionrsitesapi.findsite

+
+
+

Onionr - Private P2P Communication

+

view and interact with onionr sites

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    view and interact with onionr sites
+"""
+
+from typing import Union
+
+import onionrexceptions
+from onionrutils import mnemonickeys
+from onionrutils import stringvalidators
+from coredb import blockmetadb
+from onionrblocks.onionrblockapi import Block
+from onionrtypes import BlockHash
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def find_site(user_id: str) -> Union[BlockHash, None]:
+    """Returns block hash str for latest block for a site by a given user id"""
+    # If mnemonic delim in key, convert to base32 version
+    if mnemonickeys.DELIMITER in user_id:
+        user_id = mnemonickeys.get_base32(user_id)
+
+    if not stringvalidators.validate_pub_key(user_id):
+        raise onionrexceptions.InvalidPubkey
+
+    found_site = None
+    sites = blockmetadb.get_blocks_by_type('zsite')
+
+    # Find site by searching all site blocks. eww O(N) ☹️, TODO: event based
+    for site in sites:
+        site = Block(site)
+        if site.isSigner(user_id) and site.verifySig():
+            found_site = site.hash
+    return found_site
+
+
+
+
+
+
+
+

Functions

+
+
+def find_site(user_id) +
+
+

Returns block hash str for latest block for a site by a given user id

+
+ +Expand source code + +
def find_site(user_id: str) -> Union[BlockHash, None]:
+    """Returns block hash str for latest block for a site by a given user id"""
+    # If mnemonic delim in key, convert to base32 version
+    if mnemonickeys.DELIMITER in user_id:
+        user_id = mnemonickeys.get_base32(user_id)
+
+    if not stringvalidators.validate_pub_key(user_id):
+        raise onionrexceptions.InvalidPubkey
+
+    found_site = None
+    sites = blockmetadb.get_blocks_by_type('zsite')
+
+    # Find site by searching all site blocks. eww O(N) ☹️, TODO: event based
+    for site in sites:
+        site = Block(site)
+        if site.isSigner(user_id) and site.verifySig():
+            found_site = site.hash
+    return found_site
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/onionrsitesapi/index.html b/docs/html/src/httpapi/onionrsitesapi/index.html new file mode 100644 index 00000000..2a410cab --- /dev/null +++ b/docs/html/src/httpapi/onionrsitesapi/index.html @@ -0,0 +1,261 @@ + + + + + + +src.httpapi.onionrsitesapi API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.onionrsitesapi

+
+
+

Onionr - Private P2P Communication

+

view and interact with onionr sites

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    view and interact with onionr sites
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+import base64
+import binascii
+import mimetypes
+
+import unpaddedbase32
+
+from flask import Blueprint, Response, request, abort
+
+from onionrblocks import onionrblockapi
+import onionrexceptions
+from onionrutils import stringvalidators
+from utils import safezip
+from onionrutils import mnemonickeys
+from . import sitefiles
+
+site_api = Blueprint('siteapi', __name__)
+
+@site_api.route('/site/<name>/', endpoint='site')
+def site(name: str)->Response:
+    """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
+    resp: str = 'Not Found'
+    mime_type = 'text/html'
+
+    # If necessary convert the name to base32 from mnemonic
+    if mnemonickeys.DELIMITER in name:
+        name = mnemonickeys.get_base32(name)
+
+    # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
+    if stringvalidators.validate_pub_key(name):
+        name = unpaddedbase32.repad(name)
+        resp = sitefiles.get_file(name, 'index.html')
+
+    elif stringvalidators.validate_hash(name):
+        try:
+            resp = onionrblockapi.Block(name).bcontent
+        except onionrexceptions.NoDataAvailable:
+            abort(404)
+        except TypeError:
+            pass
+        try:
+            resp = base64.b64decode(resp)
+        except binascii.Error:
+            pass
+    if resp == 'Not Found' or not resp:
+        abort(404)
+    return Response(resp)
+
+@site_api.route('/site/<name>/<path:file>', endpoint='siteFile')
+def site_file(name: str, file: str)->Response:
+    """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
+    resp: str = 'Not Found'
+    mime_type = mimetypes.MimeTypes().guess_type(file)[0]
+
+    # If necessary convert the name to base32 from mnemonic
+    if mnemonickeys.DELIMITER in name:
+        name = mnemonickeys.get_base32(name)
+
+    # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
+    if stringvalidators.validate_pub_key(name):
+        name = unpaddedbase32.repad(name)
+        resp = sitefiles.get_file(name, file)
+
+    elif stringvalidators.validate_hash(name):
+        try:
+            resp = onionrblockapi.Block(name).bcontent
+        except onionrexceptions.NoDataAvailable:
+            abort(404)
+        except TypeError:
+            pass
+        try:
+            resp = base64.b64decode(resp)
+        except binascii.Error:
+            pass
+    if resp == 'Not Found' or not resp:
+        abort(404)
+    return Response(resp, mimetype=mime_type)
+
+
+
+

Sub-modules

+
+
src.httpapi.onionrsitesapi.findsite
+
+

Onionr - Private P2P Communication …

+
+
src.httpapi.onionrsitesapi.sitefiles
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+

Functions

+
+
+def site(name) +
+
+

Accept a site 'name', if pubkey then show multi-page site, if hash show single page site

+
+ +Expand source code + +
@site_api.route('/site/<name>/', endpoint='site')
+def site(name: str)->Response:
+    """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
+    resp: str = 'Not Found'
+    mime_type = 'text/html'
+
+    # If necessary convert the name to base32 from mnemonic
+    if mnemonickeys.DELIMITER in name:
+        name = mnemonickeys.get_base32(name)
+
+    # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
+    if stringvalidators.validate_pub_key(name):
+        name = unpaddedbase32.repad(name)
+        resp = sitefiles.get_file(name, 'index.html')
+
+    elif stringvalidators.validate_hash(name):
+        try:
+            resp = onionrblockapi.Block(name).bcontent
+        except onionrexceptions.NoDataAvailable:
+            abort(404)
+        except TypeError:
+            pass
+        try:
+            resp = base64.b64decode(resp)
+        except binascii.Error:
+            pass
+    if resp == 'Not Found' or not resp:
+        abort(404)
+    return Response(resp)
+
+
+
+def site_file(name, file) +
+
+

Accept a site 'name', if pubkey then show multi-page site, if hash show single page site

+
+ +Expand source code + +
@site_api.route('/site/<name>/<path:file>', endpoint='siteFile')
+def site_file(name: str, file: str)->Response:
+    """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
+    resp: str = 'Not Found'
+    mime_type = mimetypes.MimeTypes().guess_type(file)[0]
+
+    # If necessary convert the name to base32 from mnemonic
+    if mnemonickeys.DELIMITER in name:
+        name = mnemonickeys.get_base32(name)
+
+    # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
+    if stringvalidators.validate_pub_key(name):
+        name = unpaddedbase32.repad(name)
+        resp = sitefiles.get_file(name, file)
+
+    elif stringvalidators.validate_hash(name):
+        try:
+            resp = onionrblockapi.Block(name).bcontent
+        except onionrexceptions.NoDataAvailable:
+            abort(404)
+        except TypeError:
+            pass
+        try:
+            resp = base64.b64decode(resp)
+        except binascii.Error:
+            pass
+    if resp == 'Not Found' or not resp:
+        abort(404)
+    return Response(resp, mimetype=mime_type)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/onionrsitesapi/sitefiles.html b/docs/html/src/httpapi/onionrsitesapi/sitefiles.html new file mode 100644 index 00000000..7946b644 --- /dev/null +++ b/docs/html/src/httpapi/onionrsitesapi/sitefiles.html @@ -0,0 +1,210 @@ + + + + + + +src.httpapi.onionrsitesapi.sitefiles API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.onionrsitesapi.sitefiles

+
+
+

Onionr - Private P2P Communication

+

Read onionr site files

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    Read onionr site files
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+from typing import Union, Tuple
+import tarfile
+import io
+import os
+
+import unpaddedbase32
+
+from coredb import blockmetadb
+from onionrblocks import onionrblockapi
+from onionrblocks import insert
+
+# Import types. Just for type hiting
+from onionrtypes import UserID, DeterministicKeyPassphrase, BlockHash
+
+from onionrcrypto import generate_deterministic
+
+def find_site_gzip(user_id: str)->tarfile.TarFile:
+    """Return verified site tar object"""
+    sites = blockmetadb.get_blocks_by_type('osite')
+    user_site = None
+    user_id = unpaddedbase32.repad(user_id)
+    for site in sites:
+        block = onionrblockapi.Block(site)
+        if block.isSigner(user_id):
+            user_site = block
+    if not user_site is None:
+        return tarfile.open(fileobj=io.BytesIO(user_site.bcontent), mode='r')
+    return None
+
+def get_file(user_id, file)->Union[bytes, None]:
+    """Get a site file content"""
+    ret_data = ""
+    site = find_site_gzip(user_id)
+    if site is None: return None
+    for t_file in site.getmembers():
+        if t_file.name.replace('./', '') == file:
+            return site.extractfile(t_file)
+    return None
+
+def create_site(admin_pass: DeterministicKeyPassphrase, directory:str='.')->Tuple[UserID, BlockHash]:
+    public_key, private_key = generate_deterministic(admin_pass)
+
+    raw_tar = io.BytesIO()
+
+    tar = tarfile.open(mode='x:gz', fileobj=raw_tar)
+    tar.add(directory)
+    tar.close()
+
+    raw_tar.seek(0)
+
+    block_hash = insert(raw_tar.read(), header='osite', signing_key=private_key, sign=True)
+
+    return (public_key, block_hash)
+
+
+
+
+
+
+
+

Functions

+
+
+def create_site(admin_pass, directory='.') +
+
+
+
+ +Expand source code + +
def create_site(admin_pass: DeterministicKeyPassphrase, directory:str='.')->Tuple[UserID, BlockHash]:
+    public_key, private_key = generate_deterministic(admin_pass)
+
+    raw_tar = io.BytesIO()
+
+    tar = tarfile.open(mode='x:gz', fileobj=raw_tar)
+    tar.add(directory)
+    tar.close()
+
+    raw_tar.seek(0)
+
+    block_hash = insert(raw_tar.read(), header='osite', signing_key=private_key, sign=True)
+
+    return (public_key, block_hash)
+
+
+
+def find_site_gzip(user_id) +
+
+

Return verified site tar object

+
+ +Expand source code + +
def find_site_gzip(user_id: str)->tarfile.TarFile:
+    """Return verified site tar object"""
+    sites = blockmetadb.get_blocks_by_type('osite')
+    user_site = None
+    user_id = unpaddedbase32.repad(user_id)
+    for site in sites:
+        block = onionrblockapi.Block(site)
+        if block.isSigner(user_id):
+            user_site = block
+    if not user_site is None:
+        return tarfile.open(fileobj=io.BytesIO(user_site.bcontent), mode='r')
+    return None
+
+
+
+def get_file(user_id, file) +
+
+

Get a site file content

+
+ +Expand source code + +
def get_file(user_id, file)->Union[bytes, None]:
+    """Get a site file content"""
+    ret_data = ""
+    site = find_site_gzip(user_id)
+    if site is None: return None
+    for t_file in site.getmembers():
+        if t_file.name.replace('./', '') == file:
+            return site.extractfile(t_file)
+    return None
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/httpapi/profilesapi/index.html b/docs/html/src/httpapi/profilesapi/index.html similarity index 77% rename from docs/html/onionr/httpapi/profilesapi/index.html rename to docs/html/src/httpapi/profilesapi/index.html index 8b5bb4a1..c83b6291 100644 --- a/docs/html/onionr/httpapi/profilesapi/index.html +++ b/docs/html/src/httpapi/profilesapi/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.profilesapi API documentation + +src.httpapi.profilesapi API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.profilesapi

+

Module src.httpapi.profilesapi

Onionr - Private P2P Communication

This file creates http endpoints for user profile pages

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -56,7 +58,7 @@ def get_profile_page(pubkey):
 

Sub-modules

-
onionr.httpapi.profilesapi.profiles
+
src.httpapi.profilesapi.profiles
@@ -67,13 +69,15 @@ def get_profile_page(pubkey):

Functions

-
+
def get_profile_page(pubkey)
-Source code + +Expand source code +
@profile_BP.route('/profile/get/<pubkey>', endpoint='profiles')
 def get_profile_page(pubkey):
     return Response(pubkey)
@@ -92,24 +96,24 @@ def get_profile_page(pubkey):
diff --git a/docs/html/onionr/httpapi/profilesapi/profiles.html b/docs/html/src/httpapi/profilesapi/profiles.html similarity index 74% rename from docs/html/onionr/httpapi/profilesapi/profiles.html rename to docs/html/src/httpapi/profilesapi/profiles.html index 02e05882..baa8daf2 100644 --- a/docs/html/onionr/httpapi/profilesapi/profiles.html +++ b/docs/html/src/httpapi/profilesapi/profiles.html @@ -3,13 +3,13 @@ - -onionr.httpapi.profilesapi.profiles API documentation + +src.httpapi.profilesapi.profiles API documentation - + @@ -17,11 +17,13 @@
diff --git a/docs/html/onionr/httpapi/security/client.html b/docs/html/src/httpapi/security/client.html similarity index 80% rename from docs/html/onionr/httpapi/security/client.html rename to docs/html/src/httpapi/security/client.html index eb72078b..c100f6cd 100644 --- a/docs/html/onionr/httpapi/security/client.html +++ b/docs/html/src/httpapi/security/client.html @@ -3,13 +3,13 @@ - -onionr.httpapi.security.client API documentation + +src.httpapi.security.client API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.security.client

+

Module src.httpapi.security.client

Onionr - Private P2P Communication

Process incoming requests to the client api server to validate they are legitimate

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -49,8 +51,9 @@ from onionrservices import httpheaders
 from . import pluginwhitelist
 
 # Be extremely mindful of this. These are endpoints available without a password
-whitelist_endpoints = ['www', 'staticfiles.homedata', 'staticfiles.sharedContent', 
-'staticfiles.friends', 'staticfiles.friendsindex', 'siteapi.site', 'staticfiles.onionrhome']
+whitelist_endpoints = ['www', 'staticfiles.homedata', 'staticfiles.sharedContent',
+'staticfiles.friends', 'staticfiles.friendsindex', 'siteapi.site', 'siteapi.siteFile', 'staticfiles.onionrhome',
+'themes.getTheme', 'staticfiles.onboarding', 'staticfiles.onboardingIndex']
 
 class ClientAPISecurity:
     def __init__(self, client_api):
@@ -74,6 +77,8 @@ class ClientAPISecurity:
 
             if request.endpoint in whitelist_endpoints:
                 return
+            if request.path.startswith('/site/'): return
+
             try:
                 if not hmac.compare_digest(request.headers['token'], client_api.clientToken):
                     if not hmac.compare_digest(request.form['token'], client_api.clientToken):
@@ -86,8 +91,8 @@ class ClientAPISecurity:
         def after_req(resp):
             # Security headers
             resp = httpheaders.set_default_onionr_http_headers(resp)
-            if request.endpoint == 'siteapi.site':
-                resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
+            if request.endpoint in ('siteapi.site', 'siteapi.siteFile'):
+                resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src 'self' data: 'unsafe-inline'; img-src 'self' data:; media-src 'self' data:"
             else:
                 resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; media-src 'none'; frame-src 'none'; font-src 'self'; connect-src 'self'"
             return resp
@@ -102,14 +107,16 @@ class ClientAPISecurity:

Classes

-
+
class ClientAPISecurity (client_api)
-Source code + +Expand source code +
class ClientAPISecurity:
     def __init__(self, client_api):
         client_api_security_bp = Blueprint('clientapisecurity', __name__)
@@ -132,6 +139,8 @@ class ClientAPISecurity:
 
             if request.endpoint in whitelist_endpoints:
                 return
+            if request.path.startswith('/site/'): return
+
             try:
                 if not hmac.compare_digest(request.headers['token'], client_api.clientToken):
                     if not hmac.compare_digest(request.form['token'], client_api.clientToken):
@@ -144,8 +153,8 @@ class ClientAPISecurity:
         def after_req(resp):
             # Security headers
             resp = httpheaders.set_default_onionr_http_headers(resp)
-            if request.endpoint == 'siteapi.site':
-                resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
+            if request.endpoint in ('siteapi.site', 'siteapi.siteFile'):
+                resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src 'self' data: 'unsafe-inline'; img-src 'self' data:; media-src 'self' data:"
             else:
                 resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; media-src 'none'; frame-src 'none'; font-src 'self'; connect-src 'self'"
             return resp
@@ -162,13 +171,13 @@ class ClientAPISecurity:
diff --git a/docs/html/onionr/httpapi/security/index.html b/docs/html/src/httpapi/security/index.html similarity index 70% rename from docs/html/onionr/httpapi/security/index.html rename to docs/html/src/httpapi/security/index.html index b9ab048f..0b4a36e0 100644 --- a/docs/html/onionr/httpapi/security/index.html +++ b/docs/html/src/httpapi/security/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.security API documentation + +src.httpapi.security API documentation - + @@ -17,26 +17,28 @@
-

Module onionr.httpapi.security

+

Module src.httpapi.security

-Source code + +Expand source code +
from . import client, public

Sub-modules

-
onionr.httpapi.security.client
+
src.httpapi.security.client

Onionr - Private P2P Communication …

-
onionr.httpapi.security.pluginwhitelist
+
src.httpapi.security.pluginwhitelist

Onionr - Private P2P Communication …

-
onionr.httpapi.security.public
+
src.httpapi.security.public

Onionr - Private P2P Communication …

@@ -57,21 +59,21 @@
diff --git a/docs/html/onionr/httpapi/security/pluginwhitelist.html b/docs/html/src/httpapi/security/pluginwhitelist.html similarity index 80% rename from docs/html/onionr/httpapi/security/pluginwhitelist.html rename to docs/html/src/httpapi/security/pluginwhitelist.html index 4afd34fd..8b2a4f73 100644 --- a/docs/html/onionr/httpapi/security/pluginwhitelist.html +++ b/docs/html/src/httpapi/security/pluginwhitelist.html @@ -3,13 +3,13 @@ - -onionr.httpapi.security.pluginwhitelist API documentation + +src.httpapi.security.pluginwhitelist API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.security.pluginwhitelist

+

Module src.httpapi.security.pluginwhitelist

Onionr - Private P2P Communication

Load web UI client endpoints into the whitelist from plugins

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
@@ -65,14 +67,16 @@ def load_plugin_security_whitelist_endpoints(whitelist: list):
 

Functions

-
+
def load_plugin_security_whitelist_endpoints(whitelist)

Accept a list reference of whitelist endpoints from security/client.py and append plugin's specified endpoints to them by attribute

-Source code + +Expand source code +
def load_plugin_security_whitelist_endpoints(whitelist: list):
     """Accept a list reference of whitelist endpoints from security/client.py and
     append plugin's specified endpoints to them by attribute"""
@@ -100,19 +104,19 @@ append plugin's specified endpoints to them by attribute

diff --git a/docs/html/onionr/httpapi/security/public.html b/docs/html/src/httpapi/security/public.html similarity index 86% rename from docs/html/onionr/httpapi/security/public.html rename to docs/html/src/httpapi/security/public.html index d3d13860..a568397d 100644 --- a/docs/html/onionr/httpapi/security/public.html +++ b/docs/html/src/httpapi/security/public.html @@ -3,13 +3,13 @@ - -onionr.httpapi.security.public API documentation + +src.httpapi.security.public API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.httpapi.security.public

+

Module src.httpapi.security.public

Onionr - Private P2P Communication

Process incoming requests to the public api server for certain attacks

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -95,14 +97,16 @@ class PublicAPISecurity:
 

Classes

-
+
class PublicAPISecurity (public_api)
-Source code + +Expand source code +
class PublicAPISecurity:
     def __init__(self, public_api):
         public_api_security_bp = Blueprint('publicapisecurity', __name__)
@@ -153,13 +157,13 @@ class PublicAPISecurity:
 
diff --git a/docs/html/src/httpapi/sse/index.html b/docs/html/src/httpapi/sse/index.html new file mode 100644 index 00000000..a65ded29 --- /dev/null +++ b/docs/html/src/httpapi/sse/index.html @@ -0,0 +1,95 @@ + + + + + + +src.httpapi.sse API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.sse

+
+
+

Onionr - Private P2P Communication.

+

server sent event modules, incl a wrapper and endpoints for client + public api

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+server sent event modules, incl a wrapper and endpoints for client + public api
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+
+

Sub-modules

+
+
src.httpapi.sse.private
+
+

Onionr - Private P2P Communication …

+
+
src.httpapi.sse.wrapper
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/sse/private/index.html b/docs/html/src/httpapi/sse/private/index.html new file mode 100644 index 00000000..269b5828 --- /dev/null +++ b/docs/html/src/httpapi/sse/private/index.html @@ -0,0 +1,153 @@ + + + + + + +src.httpapi.sse.private API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.sse.private

+
+
+

Onionr - Private P2P Communication.

+

SSE API for node client access

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+SSE API for node client access
+"""
+from flask import g, Blueprint
+from gevent import sleep
+import gevent
+
+from onionrstatistics.transports.tor import TorStats
+from .. import wrapper
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+private_sse_blueprint = Blueprint('privatesse', __name__)
+SSEWrapper = wrapper.SSEWrapper()
+
+gevent.hub.Hub.NOT_ERROR = (gevent.GreenletExit, SystemExit, Exception)
+
+@private_sse_blueprint.route('/hello')
+def stream_hello():
+    def print_hello():
+        while True:
+            yield "hello\n\n"
+            sleep(1)
+    return SSEWrapper.handle_sse_request(print_hello)
+
+
+@private_sse_blueprint.route('/torcircuits')
+def stream_tor_circuits():
+    tor_stats = g.too_many.get(TorStats)
+    def circuit_stat_stream():
+        while True:
+            yield "data: " + tor_stats.get_json() + "\n\n"
+            sleep(10)
+    return SSEWrapper.handle_sse_request(circuit_stat_stream)
+
+
+
+
+
+
+
+

Functions

+
+
+def stream_hello() +
+
+
+
+ +Expand source code + +
@private_sse_blueprint.route('/hello')
+def stream_hello():
+    def print_hello():
+        while True:
+            yield "hello\n\n"
+            sleep(1)
+    return SSEWrapper.handle_sse_request(print_hello)
+
+
+
+def stream_tor_circuits() +
+
+
+
+ +Expand source code + +
@private_sse_blueprint.route('/torcircuits')
+def stream_tor_circuits():
+    tor_stats = g.too_many.get(TorStats)
+    def circuit_stat_stream():
+        while True:
+            yield "data: " + tor_stats.get_json() + "\n\n"
+            sleep(10)
+    return SSEWrapper.handle_sse_request(circuit_stat_stream)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/sse/wrapper.html b/docs/html/src/httpapi/sse/wrapper.html new file mode 100644 index 00000000..84c01195 --- /dev/null +++ b/docs/html/src/httpapi/sse/wrapper.html @@ -0,0 +1,148 @@ + + + + + + +src.httpapi.sse.wrapper API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.sse.wrapper

+
+
+

Onionr - Private P2P Communication.

+

wrapper for server sent event endpoints

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+wrapper for server sent event endpoints
+"""
+from typing import Callable
+
+from flask import Response
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+class SSEWrapper:
+    def __init__(self):
+        self.active_count: int = 0
+
+    def handle_sse_request(self, handler: Callable):
+        self.active_count += 1
+        resp = Response(handler())
+        resp.content_type = "text/event-stream"
+        self.active_count -= 1
+        return resp
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class SSEWrapper +
+
+
+
+ +Expand source code + +
class SSEWrapper:
+    def __init__(self):
+        self.active_count: int = 0
+
+    def handle_sse_request(self, handler: Callable):
+        self.active_count += 1
+        resp = Response(handler())
+        resp.content_type = "text/event-stream"
+        self.active_count -= 1
+        return resp
+
+

Methods

+
+
+def handle_sse_request(self, handler) +
+
+
+
+ +Expand source code + +
def handle_sse_request(self, handler: Callable):
+    self.active_count += 1
+    resp = Response(handler())
+    resp.content_type = "text/event-stream"
+    self.active_count -= 1
+    return resp
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/httpapi/themeapi/index.html b/docs/html/src/httpapi/themeapi/index.html new file mode 100644 index 00000000..2a40e2f6 --- /dev/null +++ b/docs/html/src/httpapi/themeapi/index.html @@ -0,0 +1,135 @@ + + + + + + +src.httpapi.themeapi API documentation + + + + + + + + + +
+
+
+

Module src.httpapi.themeapi

+
+
+

Onionr - Private P2P Communication

+

API to get current CSS theme for the client web UI

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    API to get current CSS theme for the client web UI
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+from flask import Blueprint, Response
+
+import config
+from utils import readstatic
+
+theme_blueprint = Blueprint('themes', __name__)
+
+LIGHT_THEME_FILES = ['bulma-light.min.css', 'styles-light.css']
+DARK_THEME_FILES = ['bulma-dark.min.css', 'styles-dark.css']
+
+def _load_from_files(file_list: list)->str:
+    """Loads multiple static dir files and returns them in combined string format (non-binary)"""
+    combo_data = ''
+    for f in file_list:
+        combo_data += readstatic.read_static('www/shared/main/themes/' + f)
+    return combo_data
+
+@theme_blueprint.route('/gettheme', endpoint='getTheme')
+def get_theme_file()->Response:
+    """Returns the css theme data"""
+    css: str
+    theme = config.get('ui.theme', 'dark').lower()
+    if theme == 'dark':
+        css = _load_from_files(DARK_THEME_FILES)
+    elif theme == 'light':
+        css = _load_from_files(LIGHT_THEME_FILES)
+    return Response(css, mimetype='text/css')
+
+
+
+
+
+
+
+

Functions

+
+
+def get_theme_file() +
+
+

Returns the css theme data

+
+ +Expand source code + +
@theme_blueprint.route('/gettheme', endpoint='getTheme')
+def get_theme_file()->Response:
+    """Returns the css theme data"""
+    css: str
+    theme = config.get('ui.theme', 'dark').lower()
+    if theme == 'dark':
+        css = _load_from_files(DARK_THEME_FILES)
+    elif theme == 'light':
+        css = _load_from_files(LIGHT_THEME_FILES)
+    return Response(css, mimetype='text/css')
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/index.html b/docs/html/src/index.html new file mode 100644 index 00000000..9886b4db --- /dev/null +++ b/docs/html/src/index.html @@ -0,0 +1,339 @@ + + + + + + +src API documentation + + + + + + + + + +
+
+
+

Module src

+
+
+

Onionr - Private P2P Communication

+

This file initializes Onionr when ran to be a daemon or with commands

+

Run with 'help' for usage.

+
+ +Expand source code + +
#!/usr/bin/env python3
+"""
+    Onionr - Private P2P Communication
+
+    This file initializes Onionr when ran to be a daemon or with commands
+
+    Run with 'help' for usage.
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+# Set the user's locale for encoding reasons
+import locale # noqa
+locale.setlocale(locale.LC_ALL, '')
+
+ran_as_script = False
+if __name__ == "__main__": ran_as_script = True
+
+# Import standard libraries
+import sys # noqa
+
+try:
+    from etc import dependencycheck # noqa
+except ModuleNotFoundError as e:
+    print('Onionr needs ' + str(e) + ' installed')
+
+# Onionr imports
+
+# For different Onionr related constants such as versions
+from etc import onionrvalues # noqa
+
+import onionrexceptions # noqa
+import onionrsetup as setup # noqa
+
+min_ver = onionrvalues.MIN_PY_VERSION
+
+# Ensure we have at least the minimum python version
+if sys.version_info[0] == 2 or sys.version_info[1] < min_ver:
+    sys.stderr.write('Error, Onionr requires Python 3.' + str(min_ver) + '\n')
+    sys.exit(1)
+
+# Create Onionr data directories, must be done before most imports
+from utils import createdirs
+createdirs.create_dirs()
+
+import bigbrother # noqa
+from onionrcommands import parser # noqa
+from onionrplugins import onionrevents as events # noqa
+from onionrblocks.deleteplaintext import delete_plaintext_no_blacklist  # noqa
+
+setup.setup_config()
+
+import config # noqa
+from utils import identifyhome
+
+if config.get('advanced.security_auditing', True):
+    try:
+        bigbrother.enable_ministries()
+    except onionrexceptions.PythonVersion:
+        pass
+
+if not config.get('general.store_plaintext_blocks', True):
+    delete_plaintext_no_blacklist()
+
+setup.setup_default_plugins()
+
+
+def onionr_main():
+    """Onionr entrypoint, start command processor"""
+    parser.register()
+
+
+if ran_as_script:
+    onionr_main()
+
+    # Wipe Onionr data directory if security level calls for it
+    config.reload()
+
+    # Cleanup standard out/err because Python refuses to do it itsself
+    try:
+        sys.stderr.close()
+    except (IOError, BrokenPipeError):
+        pass
+    try:
+        sys.stdout.close()
+    except (IOError, BrokenPipeError):
+        pass
+
+
+
+

Sub-modules

+
+
src.apiservers
+
+

Flask WSGI apps for the public and private API servers …

+
+
src.bigbrother
+
+

Onionr - Private P2P Communication …

+
+
src.communicator
+
+

Onionr - Private P2P Communication …

+
+
src.communicatorutils
+
+
+
+
src.config
+
+

Onionr - Private P2P Communication …

+
+
src.coredb
+
+
+
+
src.data2871027835
+
+
+
+
src.etc
+
+
+
+
src.filepaths
+
+
+
+
src.httpapi
+
+

Onionr - Private P2P Communication …

+
+
src.keymanager
+
+

Onionr - Private P2P Communication …

+
+
src.logger
+
+

Onionr - Private P2P Communication …

+
+
src.netcontroller
+
+
+
+
src.notifier
+
+

Onionr - Private P2P Communication …

+
+
src.onionrblocks
+
+
+
+
src.onionrcommands
+
+
+
+
src.onionrcrypto
+
+

Onionr - Private P2P Communication …

+
+
src.onionrexceptions
+
+

Onionr - Private P2P Communication …

+
+
src.onionrpeers
+
+
+
+
src.onionrplugins
+
+

Onionr - Private P2P Communication …

+
+
src.onionrproofs
+
+

Onionr - Private P2P Communication …

+
+
src.onionrservices
+
+

Onionr - Private P2P Communication …

+
+
src.onionrsetup
+
+
+
+
src.onionrstatistics
+
+
+
+
src.onionrstorage
+
+

Onionr - Private P2P Communication …

+
+
src.onionrtypes
+
+
+
+
src.onionrusers
+
+
+
+
src.onionrutils
+
+
+
+
src.runtests
+
+

Onionr - Private P2P Communication …

+
+
src.utils
+
+
+
+
src.vanityonionr
+
+

Onionr Vanity address generator …

+
+
+
+
+
+
+

Functions

+
+
+def onionr_main() +
+
+

Onionr entrypoint, start command processor

+
+ +Expand source code + +
def onionr_main():
+    """Onionr entrypoint, start command processor"""
+    parser.register()
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/keymanager.html b/docs/html/src/keymanager.html similarity index 84% rename from docs/html/onionr/keymanager.html rename to docs/html/src/keymanager.html index 38368779..1818253a 100644 --- a/docs/html/onionr/keymanager.html +++ b/docs/html/src/keymanager.html @@ -3,13 +3,13 @@ - -onionr.keymanager API documentation + +src.keymanager API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.keymanager

+

Module src.keymanager

Onionr - Private P2P Communication

Load, save, and delete the user's public key pairs (does not handle peer keys)

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -113,13 +115,15 @@ class KeyManager:
 

Classes

-
+
class KeyManager
-Source code + +Expand source code +
class KeyManager:
     def __init__(self):
         self.keyFile = filepaths.keys_file
@@ -177,13 +181,15 @@ class KeyManager:
 

Methods

-
+
def addKey(self, pubKey=None, privKey=None)

Add a new key pair, either specified or none to generate a new pair automatically

-Source code + +Expand source code +
def addKey(self, pubKey=None, privKey=None):
     '''Add a new key pair, either specified or none to generate a new pair automatically'''
     if type(pubKey) is type(None) and type(privKey) is type(None):
@@ -201,13 +207,15 @@ class KeyManager:
     return (pubKey, privKey)
-
+
def getPrivkey(self, pubKey)
-Source code + +Expand source code +
def getPrivkey(self, pubKey):
     privKey = None
     with open(self.keyFile, "r") as keyFile:
@@ -218,13 +226,15 @@ class KeyManager:
     return privKey
-
+
def getPubkeyList(self)

Return a list of the user's keys

-Source code + +Expand source code +
def getPubkeyList(self):
     '''Return a list of the user's keys'''
     keyList = []
@@ -239,13 +249,15 @@ class KeyManager:
     return keyList
-
+
def removeKey(self, pubKey)

Remove a key pair by pubkey

-Source code + +Expand source code +
def removeKey(self, pubKey):
     '''Remove a key pair by pubkey'''
     keyList = self.getPubkeyList()
@@ -273,18 +285,18 @@ class KeyManager:
 
diff --git a/docs/html/onionr/logger/colors.html b/docs/html/src/logger/colors.html similarity index 50% rename from docs/html/onionr/logger/colors.html rename to docs/html/src/logger/colors.html index 04cdf064..2b8bfa46 100644 --- a/docs/html/onionr/logger/colors.html +++ b/docs/html/src/logger/colors.html @@ -3,13 +3,13 @@ - -onionr.logger.colors API documentation + +src.logger.colors API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.colors

+

Module src.logger.colors

Onionr - Private P2P Communication

class to access ANSI control codes

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -95,14 +97,15 @@ class Colors:
 

Classes

-
+
class Colors -(*args, **kwargs)

This class allows you to set the color if ANSI codes are supported

-Source code + +Expand source code +
class Colors:
     '''
         This class allows you to set the color if ANSI codes are supported
@@ -146,56 +149,157 @@ class Colors:
 

Class variables

-
var bg
+
var bg
+
+ +Expand source code + +
class bg:
+    black='\033[40m'
+    red='\033[41m'
+    green='\033[42m'
+    orange='\033[43m'
+    blue='\033[44m'
+    purple='\033[45m'
+    cyan='\033[46m'
+    lightgrey='\033[47m'
+
-
var bold
+
var bold
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var disable
+
var disable
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var fg
+
var fg
+
+ +Expand source code + +
class fg:
+    black='\033[30m'
+    red='\033[31m'
+    green='\033[32m'
+    orange='\033[33m'
+    blue='\033[34m'
+    purple='\033[35m'
+    cyan='\033[36m'
+    lightgrey='\033[37m'
+    darkgrey='\033[90m'
+    lightred='\033[91m'
+    lightgreen='\033[92m'
+    yellow='\033[93m'
+    lightblue='\033[94m'
+    pink='\033[95m'
+    lightcyan='\033[96m'
+
-
var invisible
+
var invisible
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var italics
+
var italics
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var reset
+
var reset
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var reverse
+
var reverse
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var strikethrough
+
var strikethrough
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

-
var underline
+
var underline
-
+

str(object='') -> str +str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or +errors is specified, then the object must expose a data buffer +that will be decoded using the given encoding and error handler. +Otherwise, returns the result of object.str() (if defined) +or repr(object). +encoding defaults to sys.getdefaultencoding(). +errors defaults to 'strict'.

Static methods

-
+
def filter(data)
-Source code + +Expand source code +
@staticmethod
 def filter(data):
     return re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]').sub('', str(data))
@@ -214,25 +318,25 @@ def filter(data):
diff --git a/docs/html/onionr/logger/confirm.html b/docs/html/src/logger/confirm.html similarity index 84% rename from docs/html/onionr/logger/confirm.html rename to docs/html/src/logger/confirm.html index 97122144..34dc41de 100644 --- a/docs/html/onionr/logger/confirm.html +++ b/docs/html/src/logger/confirm.html @@ -3,13 +3,13 @@ - -onionr.logger.confirm API documentation + +src.logger.confirm API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.confirm

+

Module src.logger.confirm

Onionr - Private P2P Communication

confirm y/n cli prompt

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -87,7 +89,7 @@ def confirm(default = 'y', message = 'Are you sure %s? '):
 

Functions

-
+
def confirm(default='y', message='Are you sure %s? ')
@@ -95,7 +97,9 @@ def confirm(default = 'y', message = 'Are you sure %s? '): message: The confirmation message, use %s for (y/n) default: which to prefer– y or n

-Source code + +Expand source code +
def confirm(default = 'y', message = 'Are you sure %s? '):
     '''
         Displays an "Are you sure" message, returns True for Y and False for N
@@ -143,19 +147,19 @@ default: which to prefer– y or n

diff --git a/docs/html/onionr/logger/index.html b/docs/html/src/logger/index.html similarity index 77% rename from docs/html/onionr/logger/index.html rename to docs/html/src/logger/index.html index 740cb01e..b56c7b7a 100644 --- a/docs/html/onionr/logger/index.html +++ b/docs/html/src/logger/index.html @@ -3,13 +3,13 @@ - -onionr.logger API documentation + +src.logger API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger

+

Module src.logger

Onionr - Private P2P Communication

This file handles all operations involving logging

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -100,27 +102,27 @@ def parse_error():
 

Sub-modules

-
onionr.logger.colors
+
src.logger.colors

Onionr - Private P2P Communication …

-
onionr.logger.confirm
+
src.logger.confirm

Onionr - Private P2P Communication …

-
onionr.logger.log
+
src.logger.log

Onionr - Private P2P Communication …

-
onionr.logger.raw
+
src.logger.raw

Onionr - Private P2P Communication …

-
onionr.logger.readline
+
src.logger.readline

Onionr - Private P2P Communication …

-
onionr.logger.settings
+
src.logger.settings

Onionr - Private P2P Communication …

@@ -131,13 +133,15 @@ def parse_error():

Functions

-
+
def debug(data, error=None, timestamp=True, prompt=True, terminal=False, level=1)
-Source code + +Expand source code +
def debug(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_DEBUG):
     if settings.get_level() <= level:
         log('/', data, timestamp = timestamp, prompt = prompt, terminal = terminal)
@@ -145,13 +149,15 @@ def parse_error():
         debug('Error: ' + str(error) + parse_error())
-
+
def error(data, error=None, timestamp=True, prompt=True, terminal=False, level=4)
-Source code + +Expand source code +
def error(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_ERROR):
     if settings.get_level() <= level:
         log('-', data, colors.fg.red, timestamp = timestamp, fd = sys.stderr, prompt = prompt, terminal = terminal)
@@ -159,13 +165,15 @@ def parse_error():
         debug('Error: ' + str(error) + parse_error())
-
+
def fatal(data, error=None, timestamp=True, prompt=True, terminal=False, level=5)
-Source code + +Expand source code +
def fatal(data: str, error = None, timestamp=True, prompt = True, terminal = False, level = settings.LEVEL_FATAL):
     if not error is None:
         debug('Error: ' + str(error) + parse_error(), terminal = terminal)
@@ -173,25 +181,29 @@ def parse_error():
         log('#', data, colors.bg.red + colors.fg.green + colors.bold, timestamp = timestamp, fd = sys.stderr, prompt = prompt, terminal = terminal)
-
+
def info(data, timestamp=False, prompt=True, terminal=False, level=2)
-Source code + +Expand source code +
def info(data: str, timestamp = False, prompt = True, terminal = False, level = settings.LEVEL_INFO):
     if settings.get_level() <= level:
         log('+', data, colors.fg.green, timestamp = timestamp, prompt = prompt, terminal = terminal)
-
+
def parse_error()
-Source code + +Expand source code +
def parse_error():
     details = traceback.extract_tb(sys.exc_info()[2])
     output = ''
@@ -202,13 +214,15 @@ def parse_error():
     return output
-
+
def warn(data, error=None, timestamp=True, prompt=True, terminal=False, level=3)
-Source code + +Expand source code +
def warn(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_WARN):
     if not error is None:
         debug('Error: ' + str(error) + parse_error())
@@ -229,34 +243,34 @@ def parse_error():
 
 
 
diff --git a/docs/html/onionr/logger/log.html b/docs/html/src/logger/log.html similarity index 82% rename from docs/html/onionr/logger/log.html rename to docs/html/src/logger/log.html index 47741757..283c08a3 100644 --- a/docs/html/onionr/logger/log.html +++ b/docs/html/src/logger/log.html @@ -3,13 +3,13 @@ - -onionr.logger.log API documentation + +src.logger.log API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.log

+

Module src.logger.log

Onionr - Private P2P Communication

god log function

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -71,8 +73,8 @@ def log(prefix, data, color = '', timestamp=True, fd = sys.stdout, promp
 

Functions

-
-def log(prefix, data, color='', timestamp=True, fd=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, prompt=True, terminal=False) +
+def log(prefix, data, color='', timestamp=True, fd=sys.stdout, prompt=True, terminal=False)

Logs the data @@ -82,7 +84,9 @@ data color : The color to output before the data

-Source code + +Expand source code +
def log(prefix, data, color = '', timestamp=True, fd = sys.stdout, prompt = True, terminal = False):
     '''
         Logs the data
@@ -114,19 +118,19 @@ color
 
 
 
diff --git a/docs/html/onionr/logger/raw.html b/docs/html/src/logger/raw.html similarity index 82% rename from docs/html/onionr/logger/raw.html rename to docs/html/src/logger/raw.html index afab8177..f2036dce 100644 --- a/docs/html/onionr/logger/raw.html +++ b/docs/html/src/logger/raw.html @@ -3,13 +3,13 @@ - -onionr.logger.raw API documentation + +src.logger.raw API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.raw

+

Module src.logger.raw

Onionr - Private P2P Communication

Output raw data to file or terminal

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -79,13 +81,15 @@ def raw(data, fd = sys.stdout, terminal = False):
 

Functions

-
-def raw(data, fd=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, terminal=False) +
+def raw(data, fd=sys.stdout, terminal=False)

Outputs raw data to console without formatting

-Source code + +Expand source code +
def raw(data, fd = sys.stdout, terminal = False):
     '''
         Outputs raw data to console without formatting
@@ -125,19 +129,19 @@ def raw(data, fd = sys.stdout, terminal = False):
 
 
 
diff --git a/docs/html/onionr/logger/readline.html b/docs/html/src/logger/readline.html similarity index 81% rename from docs/html/onionr/logger/readline.html rename to docs/html/src/logger/readline.html index 282fa247..1c3f3f98 100644 --- a/docs/html/onionr/logger/readline.html +++ b/docs/html/src/logger/readline.html @@ -3,13 +3,13 @@ - -onionr.logger.readline API documentation + +src.logger.readline API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.readline

+

Module src.logger.readline

Onionr - Private P2P Communication

get a line of input from stdin

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -70,14 +72,16 @@ def readline(message = ''):
 

Functions

-
+
def readline(message='')

Takes in input from the console, not stored in logs message: The message to display before taking input

-Source code + +Expand source code +
def readline(message = ''):
     '''
         Takes in input from the console, not stored in logs
@@ -108,19 +112,19 @@ message: The message to display before taking input

diff --git a/docs/html/onionr/logger/settings.html b/docs/html/src/logger/settings.html similarity index 77% rename from docs/html/onionr/logger/settings.html rename to docs/html/src/logger/settings.html index 7c70f340..312caa3a 100644 --- a/docs/html/onionr/logger/settings.html +++ b/docs/html/src/logger/settings.html @@ -3,13 +3,13 @@ - -onionr.logger.settings API documentation + +src.logger.settings API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.logger.settings

+

Module src.logger.settings

Onionr - Private P2P Communication

logger settings

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -120,13 +122,15 @@ def get_file():
 

Functions

-
+
def get_file()

Get the file to output to

-Source code + +Expand source code +
def get_file():
     '''
         Get the file to output to
@@ -135,13 +139,15 @@ def get_file():
     return _outputfile
-
+
def get_level()

Get the lowest log level currently being outputted

-Source code + +Expand source code +
def get_level()->int:
     '''
         Get the lowest log level currently being outputted
@@ -150,13 +156,15 @@ def get_file():
     return _level
-
+
def get_settings()

Get settings from the logger

-Source code + +Expand source code +
def get_settings():
     '''
         Get settings from the logger
@@ -165,13 +173,15 @@ def get_file():
     return _type
-
+
def set_file(outputfile)

Set the file to output to, if enabled

-Source code + +Expand source code +
def set_file(outputfile):
     '''
         Set the file to output to, if enabled
@@ -181,13 +191,15 @@ def get_file():
     _outputfile = outputfile
-
+
def set_level(level)

Set the lowest log level to output

-Source code + +Expand source code +
def set_level(level):
     '''
         Set the lowest log level to output
@@ -197,13 +209,15 @@ def get_file():
     _level = level
-
+
def set_settings(type)

Set the settings for the logger using bitwise operators

-Source code + +Expand source code +
def set_settings(type):
     '''
         Set the settings for the logger using bitwise operators
@@ -226,24 +240,24 @@ def get_file():
 
 
 
diff --git a/docs/html/onionr/netcontroller/getopenport.html b/docs/html/src/netcontroller/getopenport.html similarity index 80% rename from docs/html/onionr/netcontroller/getopenport.html rename to docs/html/src/netcontroller/getopenport.html index 112bd039..5408a249 100644 --- a/docs/html/onionr/netcontroller/getopenport.html +++ b/docs/html/src/netcontroller/getopenport.html @@ -3,13 +3,13 @@ - -onionr.netcontroller.getopenport API documentation + +src.netcontroller.getopenport API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.netcontroller.getopenport

+

Module src.netcontroller.getopenport

Onionr - Private P2P Communication

get an open port

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -62,13 +64,15 @@ def get_open_port():
 

Functions

-
+
def get_open_port()
-Source code + +Expand source code +
def get_open_port():
     # taken from (but modified) https://stackoverflow.com/a/2838309 by https://stackoverflow.com/users/133374/albert ccy-by-sa-3 https://creativecommons.org/licenses/by-sa/3.0/
     # changes from source: import moved to top of file, bind specifically to localhost
@@ -93,19 +97,19 @@ def get_open_port():
 
 
 
diff --git a/docs/html/onionr/httpapi/miscclientapi/index.html b/docs/html/src/netcontroller/index.html similarity index 67% rename from docs/html/onionr/httpapi/miscclientapi/index.html rename to docs/html/src/netcontroller/index.html index 60f471f5..fdb14ad7 100644 --- a/docs/html/onionr/httpapi/miscclientapi/index.html +++ b/docs/html/src/netcontroller/index.html @@ -3,13 +3,13 @@ - -onionr.httpapi.miscclientapi API documentation + +src.netcontroller API documentation - + @@ -17,26 +17,32 @@
-

Module onionr.httpapi.miscclientapi

+

Module src.netcontroller

-Source code -
from . import getblocks, staticfiles, endpoints
+ +Expand source code + +
from . import getopenport, torcontrol
+from . import torcontrol
+tor_binary = torcontrol.torbinary.tor_binary
+get_open_port = getopenport.get_open_port
+NetController = torcontrol.NetController

Sub-modules

-
onionr.httpapi.miscclientapi.endpoints
+
src.netcontroller.getopenport

Onionr - Private P2P Communication …

-
onionr.httpapi.miscclientapi.getblocks
+
src.netcontroller.torcontrol

Onionr - Private P2P Communication …

-
onionr.httpapi.miscclientapi.staticfiles
+
src.netcontroller.watchdog

Onionr - Private P2P Communication …

@@ -57,21 +63,21 @@
diff --git a/docs/html/src/netcontroller/torcontrol/addbridges.html b/docs/html/src/netcontroller/torcontrol/addbridges.html new file mode 100644 index 00000000..da4670db --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/addbridges.html @@ -0,0 +1,126 @@ + + + + + + +src.netcontroller.torcontrol.addbridges API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.addbridges

+
+
+

Onionr - Private P2P Communication

+

Add bridge info to torrc configuration string

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    Add bridge info to torrc configuration string
+"""
+import config
+import logger
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def add_bridges(torrc: str) -> str:
+    """Configure tor to use a bridge using Onionr config keys"""
+    if config.get('tor.use_bridge', False) is True:
+        bridge = config.get('tor.bridge_ip', None)
+        if bridge is not None:
+            # allow blank fingerprint purposefully
+            fingerprint = config.get('tor.bridge_fingerprint', '')
+            torrc += '\nUseBridges 1\nBridge %s %s\n' % (bridge, fingerprint)
+        else:
+            logger.warn('bridge was enabled but not specified in config')
+
+    return torrc
+
+
+
+
+
+
+
+

Functions

+
+
+def add_bridges(torrc) +
+
+

Configure tor to use a bridge using Onionr config keys

+
+ +Expand source code + +
def add_bridges(torrc: str) -> str:
+    """Configure tor to use a bridge using Onionr config keys"""
+    if config.get('tor.use_bridge', False) is True:
+        bridge = config.get('tor.bridge_ip', None)
+        if bridge is not None:
+            # allow blank fingerprint purposefully
+            fingerprint = config.get('tor.bridge_fingerprint', '')
+            torrc += '\nUseBridges 1\nBridge %s %s\n' % (bridge, fingerprint)
+        else:
+            logger.warn('bridge was enabled but not specified in config')
+
+    return torrc
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/netcontroller/torcontrol/customtorrc.html b/docs/html/src/netcontroller/torcontrol/customtorrc.html new file mode 100644 index 00000000..3ac1297b --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/customtorrc.html @@ -0,0 +1,157 @@ + + + + + + +src.netcontroller.torcontrol.customtorrc API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.customtorrc

+
+
+

Onionr - Private P2P Communication

+

Load or set custom torrc

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    Load or set custom torrc
+"""
+from utils import identifyhome
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+CUSTOM_TORRC_FILE = identifyhome.identify_home() + '/torrc-custom'
+
+
+def set_custom_torrc(torrc_data: str):
+    """write torrc_data to custom torrc file stored in home dir.
+    if set it will be used in addition to onionr's generated settings
+    """
+    torrc_comment = f'\n# BEGIN CUSTOM TORRC FROM {CUSTOM_TORRC_FILE}\n'
+    torrc_data = torrc_comment + torrc_data
+    with open(CUSTOM_TORRC_FILE, 'w') as torrc:
+        torrc.write(torrc_data)
+
+
+def get_custom_torrc() -> str:
+    """read torrc_data from custom torrc file stored in home dir.
+    if set it will be used in addition to onionr's generated settings
+    """
+    torrc = ''
+    try:
+        with open(CUSTOM_TORRC_FILE, 'r') as torrc:
+            torrc = torrc.read()
+    except FileNotFoundError:
+        pass
+    return '\n' + torrc
+
+
+
+
+
+
+
+

Functions

+
+
+def get_custom_torrc() +
+
+

read torrc_data from custom torrc file stored in home dir. +if set it will be used in addition to onionr's generated settings

+
+ +Expand source code + +
def get_custom_torrc() -> str:
+    """read torrc_data from custom torrc file stored in home dir.
+    if set it will be used in addition to onionr's generated settings
+    """
+    torrc = ''
+    try:
+        with open(CUSTOM_TORRC_FILE, 'r') as torrc:
+            torrc = torrc.read()
+    except FileNotFoundError:
+        pass
+    return '\n' + torrc
+
+
+
+def set_custom_torrc(torrc_data) +
+
+

write torrc_data to custom torrc file stored in home dir. +if set it will be used in addition to onionr's generated settings

+
+ +Expand source code + +
def set_custom_torrc(torrc_data: str):
+    """write torrc_data to custom torrc file stored in home dir.
+    if set it will be used in addition to onionr's generated settings
+    """
+    torrc_comment = f'\n# BEGIN CUSTOM TORRC FROM {CUSTOM_TORRC_FILE}\n'
+    torrc_data = torrc_comment + torrc_data
+    with open(CUSTOM_TORRC_FILE, 'w') as torrc:
+        torrc.write(torrc_data)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/netcontroller/torcontrol/gentorrc.html b/docs/html/src/netcontroller/torcontrol/gentorrc.html new file mode 100644 index 00000000..babda79e --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/gentorrc.html @@ -0,0 +1,207 @@ + + + + + + +src.netcontroller.torcontrol.gentorrc API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.gentorrc

+
+
+
+ +Expand source code + +
import base64
+import os
+import subprocess
+
+from .. import getopenport
+from . import customtorrc
+from . import addbridges
+from . import torbinary
+from utils import identifyhome
+import config
+
+add_bridges = addbridges.add_bridges
+
+
+def generate_torrc(net_controller, api_server_ip):
+    """
+        Generate a torrc file for our tor instance
+    """
+    socks_port = net_controller.socksPort
+    hs_ver = '# v2 onions'
+    hs_port = net_controller.hsPort
+    home_dir = identifyhome.identify_home()
+    tor_config_location = home_dir + '/torrc'
+
+    if config.get('tor.v3onions'):
+        hs_ver = 'HiddenServiceVersion 3'
+
+    """
+    Set the Tor control password.
+    Meant to make it harder to manipulate our Tor instance
+    """
+    plaintext = base64.b64encode(os.urandom(50)).decode()
+    config.set('tor.controlpassword', plaintext, savefile=True)
+    config.set('tor.socksport', socks_port, savefile=True)
+
+    controlPort = getopenport.get_open_port()
+
+    config.set('tor.controlPort', controlPort, savefile=True)
+
+    hashedPassword = subprocess.Popen([torbinary.tor_binary(),
+                                      '--hash-password',
+                                       plaintext],
+                                      stdout=subprocess.PIPE,
+                                      stderr=subprocess.PIPE)
+    for line in iter(hashedPassword.stdout.readline, b''):
+        password = line.decode()
+        if 'warn' not in password:
+            break
+
+    torrc_data = """SocksPort """ + str(socks_port) + """ OnionTrafficOnly
+DataDirectory """ + home_dir + """tordata/
+CookieAuthentication 1
+KeepalivePeriod 40
+CircuitsAvailableTimeout 86400
+ControlPort """ + str(controlPort) + """
+HashedControlPassword """ + str(password) + """
+    """
+    if config.get('general.security_level', 1) == 0:
+        torrc_data += """\nHiddenServiceDir """ + home_dir + """hs/
+\n""" + hs_ver + """\n
+HiddenServiceNumIntroductionPoints 6
+HiddenServiceMaxStreams 100
+HiddenServiceMaxStreamsCloseCircuit 1
+HiddenServicePort 80 """ + api_server_ip + """:""" + str(hs_port)
+
+    torrc_data = add_bridges(torrc_data)
+
+    torrc_data += customtorrc.get_custom_torrc()
+
+    torrc = open(tor_config_location, 'w')
+    torrc.write(torrc_data)
+    torrc.close()
+
+
+
+
+
+
+
+

Functions

+
+
+def generate_torrc(net_controller, api_server_ip) +
+
+

Generate a torrc file for our tor instance

+
+ +Expand source code + +
def generate_torrc(net_controller, api_server_ip):
+    """
+        Generate a torrc file for our tor instance
+    """
+    socks_port = net_controller.socksPort
+    hs_ver = '# v2 onions'
+    hs_port = net_controller.hsPort
+    home_dir = identifyhome.identify_home()
+    tor_config_location = home_dir + '/torrc'
+
+    if config.get('tor.v3onions'):
+        hs_ver = 'HiddenServiceVersion 3'
+
+    """
+    Set the Tor control password.
+    Meant to make it harder to manipulate our Tor instance
+    """
+    plaintext = base64.b64encode(os.urandom(50)).decode()
+    config.set('tor.controlpassword', plaintext, savefile=True)
+    config.set('tor.socksport', socks_port, savefile=True)
+
+    controlPort = getopenport.get_open_port()
+
+    config.set('tor.controlPort', controlPort, savefile=True)
+
+    hashedPassword = subprocess.Popen([torbinary.tor_binary(),
+                                      '--hash-password',
+                                       plaintext],
+                                      stdout=subprocess.PIPE,
+                                      stderr=subprocess.PIPE)
+    for line in iter(hashedPassword.stdout.readline, b''):
+        password = line.decode()
+        if 'warn' not in password:
+            break
+
+    torrc_data = """SocksPort """ + str(socks_port) + """ OnionTrafficOnly
+DataDirectory """ + home_dir + """tordata/
+CookieAuthentication 1
+KeepalivePeriod 40
+CircuitsAvailableTimeout 86400
+ControlPort """ + str(controlPort) + """
+HashedControlPassword """ + str(password) + """
+    """
+    if config.get('general.security_level', 1) == 0:
+        torrc_data += """\nHiddenServiceDir """ + home_dir + """hs/
+\n""" + hs_ver + """\n
+HiddenServiceNumIntroductionPoints 6
+HiddenServiceMaxStreams 100
+HiddenServiceMaxStreamsCloseCircuit 1
+HiddenServicePort 80 """ + api_server_ip + """:""" + str(hs_port)
+
+    torrc_data = add_bridges(torrc_data)
+
+    torrc_data += customtorrc.get_custom_torrc()
+
+    torrc = open(tor_config_location, 'w')
+    torrc.write(torrc_data)
+    torrc.close()
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/netcontroller/netcontrol.html b/docs/html/src/netcontroller/torcontrol/index.html similarity index 54% rename from docs/html/onionr/netcontroller/netcontrol.html rename to docs/html/src/netcontroller/torcontrol/index.html index 6b1e9523..c94d03e2 100644 --- a/docs/html/onionr/netcontroller/netcontrol.html +++ b/docs/html/src/netcontroller/torcontrol/index.html @@ -3,13 +3,13 @@ - -onionr.netcontroller.netcontrol API documentation + +src.netcontroller.torcontrol API documentation - + @@ -17,19 +17,39 @@
-

Module onionr.netcontroller.netcontrol

+

Module src.netcontroller.torcontrol

Onionr - Private P2P Communication

-

Netcontroller library, used to control/work with Tor/I2P and send requests through them

+

Netcontroller library, used to control/work with Tor and send requests through them

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
-    Netcontroller library, used to control/work with Tor/I2P and send requests through them
-'''
-'''
+    Netcontroller library, used to control/work with Tor and send requests through them
+"""
+import os
+import base64
+import subprocess
+import signal
+import time
+import multiprocessing
+import platform  # For windows sigkill workaround
+
+from onionrtypes import BooleanSuccessState
+import logger
+import filepaths
+from .. import getopenport
+from .. import watchdog
+from . import customtorrc
+from . import gentorrc
+from . import addbridges
+from . import torbinary
+from utils import identifyhome
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,106 +62,35 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os, sys, base64, subprocess, signal, time
-import platform # For windows sigkill workaround
-import config, logger
-from . import getopenport
-from utils import identifyhome
-config.reload()
+"""
+
 TOR_KILL_WAIT = 3
+addbridges = addbridges.add_bridges
 
-def add_bridges(torrc: str)->str:
-    """Configure tor to use a bridge using Onionr config keys"""
-    if config.get('tor.use_bridge', False) == True:
-        bridge = config.get('tor.bridge_ip', None)
-        if not bridge is None:
-            fingerprint = config.get('tor.bridge_fingerprint', '') # allow blank fingerprint purposefully
-            torrc += '\nUseBridges 1\nBridge %s %s\n' % (bridge, fingerprint)
-        else:
-            logger.warn('bridge was enabled but not specified in config')
-
-    return torrc
 
 class NetController:
-    '''
-        This class handles hidden service setup on Tor and I2P
-    '''
+    """
+        This class handles hidden service setup on Tor
+    """
 
     def __init__(self, hsPort, apiServerIP='127.0.0.1'):
         # set data dir
         self.dataDir = identifyhome.identify_home()
-
+        self.socksPort = getopenport.get_open_port()
         self.torConfigLocation = self.dataDir + 'torrc'
         self.readyState = False
-        self.socksPort = getopenport.get_open_port()
         self.hsPort = hsPort
         self._torInstnace = ''
         self.myID = ''
         self.apiServerIP = apiServerIP
+        self.torBinary = torbinary.tor_binary()
 
-        if os.path.exists('./tor'):
-            self.torBinary = './tor'
-        elif os.path.exists('/usr/bin/tor'):
-            self.torBinary = '/usr/bin/tor'
-        else:
-            self.torBinary = 'tor'
-
-    def generateTorrc(self):
-        '''
-            Generate a torrc file for our tor instance
-        '''
-        hsVer = '# v2 onions'
-        if config.get('tor.v3onions'):
-            hsVer = 'HiddenServiceVersion 3'
-
-        if os.path.exists(self.torConfigLocation):
-            os.remove(self.torConfigLocation)
-
-        # Set the Tor control password. Meant to make it harder to manipulate our Tor instance
-        plaintext = base64.b64encode(os.urandom(50)).decode()
-        config.set('tor.controlpassword', plaintext, savefile=True)
-        config.set('tor.socksport', self.socksPort, savefile=True)
-
-        controlPort = getopenport.get_open_port()
-
-        config.set('tor.controlPort', controlPort, savefile=True)
-
-        hashedPassword = subprocess.Popen([self.torBinary, '--hash-password', plaintext], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        for line in iter(hashedPassword.stdout.readline, b''):
-            password = line.decode()
-            if 'warn' not in password:
-                break
-
-        torrcData = '''SocksPort ''' + str(self.socksPort) + ''' OnionTrafficOnly
-DataDirectory ''' + self.dataDir + '''tordata/
-CookieAuthentication 1
-KeepalivePeriod 40
-CircuitsAvailableTimeout 86400
-ControlPort ''' + str(controlPort) + '''
-HashedControlPassword ''' + str(password) + '''
-        '''
-        if config.get('general.security_level', 1) == 0:
-            torrcData += '''\nHiddenServiceDir ''' + self.dataDir + '''hs/
-\n''' + hsVer + '''\n
-HiddenServiceNumIntroductionPoints 6
-HiddenServiceMaxStreams 100
-HiddenServiceMaxStreamsCloseCircuit 1
-HiddenServicePort 80 ''' + self.apiServerIP + ''':''' + str(self.hsPort)
-
-        torrcData = add_bridges(torrcData)
-
-        torrc = open(self.torConfigLocation, 'w')
-        torrc.write(torrcData)
-        torrc.close()
-        return
-
-    def startTor(self, gen_torrc=True):
-        '''
+    def startTor(self, gen_torrc=True) -> BooleanSuccessState:
+        """
             Start Tor with onion service on port 80 & socks proxy on random port
-        '''
+        """
         if gen_torrc:
-            self.generateTorrc()
+            gentorrc.generate_torrc(self, self.apiServerIP)
 
         if os.path.exists('./tor'):
             self.torBinary = './tor'
@@ -154,15 +103,16 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
             tor = subprocess.Popen([self.torBinary, '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         except FileNotFoundError:
             logger.fatal("Tor was not found in your path or the Onionr directory. Please install Tor and try again.", terminal=True)
-            sys.exit(1)
+            return False
         else:
             # Test Tor Version
-            torVersion = subprocess.Popen([self.torBinary, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            torVersion = subprocess.Popen([self.torBinary, '--version'],
+                                          stdout=subprocess.PIPE,
+                                          stderr=subprocess.PIPE)
             for line in iter(torVersion.stdout.readline, b''):
                 if 'Tor 0.2.' in line.decode():
                     logger.fatal('Tor 0.3+ required', terminal=True)
-                    sys.exit(1)
-                    break
+                    return False
             torVersion.kill()
 
         # wait for tor to get to 100% bootstrap
@@ -173,6 +123,13 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
                     break
                 elif 'opening socks listener' in line.decode().lower():
                     logger.debug(line.decode().replace('\n', ''))
+                else:
+                    if 'err' in line.decode():
+                        logger.error(line.decode().replace('\n', ''))
+                    elif 'warn' in line.decode():
+                        logger.warn(line.decode().replace('\n', ''))
+                    else:
+                        logger.debug(line.decode().replace('\n', ''))
             else:
                 logger.fatal('Failed to start Tor. Maybe a stray instance of Tor used by Onionr is still running? This can also be a result of file permissions being too open', terminal=True)
                 return False
@@ -191,16 +148,17 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
         except FileNotFoundError:
             self.myID = ""
 
-        torPidFile = open(self.dataDir + 'torPid.txt', 'w')
-        torPidFile.write(str(tor.pid))
-        torPidFile.close()
+        with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file:
+            tor_pid_file.write(str(tor.pid))
 
+        multiprocessing.Process(target=watchdog.watchdog,
+                                args=[os.getpid(), tor.pid]).start()
         return True
 
     def killTor(self):
-        '''
+        """
             Properly kill tor based on pid saved to file
-        '''
+        """
 
         try:
             pid = open(self.dataDir + 'torPid.txt', 'r')
@@ -211,7 +169,7 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
 
         try:
             int(pidN)
-        except:
+        except ValueError:
             return
 
         try:
@@ -225,141 +183,99 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
             pass
         except FileNotFoundError:
             pass
-        
+
         try:
             time.sleep(TOR_KILL_WAIT)
         except KeyboardInterrupt:
             pass
 
         if 'windows' == platform.system().lower():
-            os.system('taskkill /PID %s /F' % (pidN,))
+            os.system(f'taskkill /PID {pidN} /F')
             time.sleep(0.5)
             return
         try:
             os.kill(int(pidN), signal.SIGKILL)
-        except (ProcessLookupError, PermissionError) as e:
+        except (ProcessLookupError, PermissionError):
+            pass
+        try:
+            os.remove(self.dataDir + 'tordata/lock')
+        except FileNotFoundError:
             pass
-
-
-
-
-

Functions

+

Sub-modules

-
-def add_bridges(torrc) -
+
src.netcontroller.torcontrol.addbridges
-

Configure tor to use a bridge using Onionr config keys

-
-Source code -
def add_bridges(torrc: str)->str:
-    """Configure tor to use a bridge using Onionr config keys"""
-    if config.get('tor.use_bridge', False) == True:
-        bridge = config.get('tor.bridge_ip', None)
-        if not bridge is None:
-            fingerprint = config.get('tor.bridge_fingerprint', '') # allow blank fingerprint purposefully
-            torrc += '\nUseBridges 1\nBridge %s %s\n' % (bridge, fingerprint)
-        else:
-            logger.warn('bridge was enabled but not specified in config')
-
-    return torrc
-
+

Onionr - Private P2P Communication …

+
+
src.netcontroller.torcontrol.customtorrc
+
+

Onionr - Private P2P Communication …

+
+
src.netcontroller.torcontrol.gentorrc
+
+
+
+
src.netcontroller.torcontrol.onionservicecreator
+
+

Onionr - Private P2P Communication …

+
+
src.netcontroller.torcontrol.rebuildtor
+
+

Onionr - P2P Anonymous Storage Network …

+
+
src.netcontroller.torcontrol.torbinary
+
+

Onionr - Private P2P Communication …

+
+
src.netcontroller.torcontrol.torcontroller
+
+
+
+
+
+

Classes

-
+
class NetController (hsPort, apiServerIP='127.0.0.1')
-

This class handles hidden service setup on Tor and I2P

+

This class handles hidden service setup on Tor

-Source code + +Expand source code +
class NetController:
-    '''
-        This class handles hidden service setup on Tor and I2P
-    '''
+    """
+        This class handles hidden service setup on Tor
+    """
 
     def __init__(self, hsPort, apiServerIP='127.0.0.1'):
         # set data dir
         self.dataDir = identifyhome.identify_home()
-
+        self.socksPort = getopenport.get_open_port()
         self.torConfigLocation = self.dataDir + 'torrc'
         self.readyState = False
-        self.socksPort = getopenport.get_open_port()
         self.hsPort = hsPort
         self._torInstnace = ''
         self.myID = ''
         self.apiServerIP = apiServerIP
+        self.torBinary = torbinary.tor_binary()
 
-        if os.path.exists('./tor'):
-            self.torBinary = './tor'
-        elif os.path.exists('/usr/bin/tor'):
-            self.torBinary = '/usr/bin/tor'
-        else:
-            self.torBinary = 'tor'
-
-    def generateTorrc(self):
-        '''
-            Generate a torrc file for our tor instance
-        '''
-        hsVer = '# v2 onions'
-        if config.get('tor.v3onions'):
-            hsVer = 'HiddenServiceVersion 3'
-
-        if os.path.exists(self.torConfigLocation):
-            os.remove(self.torConfigLocation)
-
-        # Set the Tor control password. Meant to make it harder to manipulate our Tor instance
-        plaintext = base64.b64encode(os.urandom(50)).decode()
-        config.set('tor.controlpassword', plaintext, savefile=True)
-        config.set('tor.socksport', self.socksPort, savefile=True)
-
-        controlPort = getopenport.get_open_port()
-
-        config.set('tor.controlPort', controlPort, savefile=True)
-
-        hashedPassword = subprocess.Popen([self.torBinary, '--hash-password', plaintext], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        for line in iter(hashedPassword.stdout.readline, b''):
-            password = line.decode()
-            if 'warn' not in password:
-                break
-
-        torrcData = '''SocksPort ''' + str(self.socksPort) + ''' OnionTrafficOnly
-DataDirectory ''' + self.dataDir + '''tordata/
-CookieAuthentication 1
-KeepalivePeriod 40
-CircuitsAvailableTimeout 86400
-ControlPort ''' + str(controlPort) + '''
-HashedControlPassword ''' + str(password) + '''
-        '''
-        if config.get('general.security_level', 1) == 0:
-            torrcData += '''\nHiddenServiceDir ''' + self.dataDir + '''hs/
-\n''' + hsVer + '''\n
-HiddenServiceNumIntroductionPoints 6
-HiddenServiceMaxStreams 100
-HiddenServiceMaxStreamsCloseCircuit 1
-HiddenServicePort 80 ''' + self.apiServerIP + ''':''' + str(self.hsPort)
-
-        torrcData = add_bridges(torrcData)
-
-        torrc = open(self.torConfigLocation, 'w')
-        torrc.write(torrcData)
-        torrc.close()
-        return
-
-    def startTor(self, gen_torrc=True):
-        '''
+    def startTor(self, gen_torrc=True) -> BooleanSuccessState:
+        """
             Start Tor with onion service on port 80 & socks proxy on random port
-        '''
+        """
         if gen_torrc:
-            self.generateTorrc()
+            gentorrc.generate_torrc(self, self.apiServerIP)
 
         if os.path.exists('./tor'):
             self.torBinary = './tor'
@@ -372,15 +288,16 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
             tor = subprocess.Popen([self.torBinary, '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         except FileNotFoundError:
             logger.fatal("Tor was not found in your path or the Onionr directory. Please install Tor and try again.", terminal=True)
-            sys.exit(1)
+            return False
         else:
             # Test Tor Version
-            torVersion = subprocess.Popen([self.torBinary, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            torVersion = subprocess.Popen([self.torBinary, '--version'],
+                                          stdout=subprocess.PIPE,
+                                          stderr=subprocess.PIPE)
             for line in iter(torVersion.stdout.readline, b''):
                 if 'Tor 0.2.' in line.decode():
                     logger.fatal('Tor 0.3+ required', terminal=True)
-                    sys.exit(1)
-                    break
+                    return False
             torVersion.kill()
 
         # wait for tor to get to 100% bootstrap
@@ -391,6 +308,13 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
                     break
                 elif 'opening socks listener' in line.decode().lower():
                     logger.debug(line.decode().replace('\n', ''))
+                else:
+                    if 'err' in line.decode():
+                        logger.error(line.decode().replace('\n', ''))
+                    elif 'warn' in line.decode():
+                        logger.warn(line.decode().replace('\n', ''))
+                    else:
+                        logger.debug(line.decode().replace('\n', ''))
             else:
                 logger.fatal('Failed to start Tor. Maybe a stray instance of Tor used by Onionr is still running? This can also be a result of file permissions being too open', terminal=True)
                 return False
@@ -409,16 +333,17 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
         except FileNotFoundError:
             self.myID = ""
 
-        torPidFile = open(self.dataDir + 'torPid.txt', 'w')
-        torPidFile.write(str(tor.pid))
-        torPidFile.close()
+        with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file:
+            tor_pid_file.write(str(tor.pid))
 
+        multiprocessing.Process(target=watchdog.watchdog,
+                                args=[os.getpid(), tor.pid]).start()
         return True
 
     def killTor(self):
-        '''
+        """
             Properly kill tor based on pid saved to file
-        '''
+        """
 
         try:
             pid = open(self.dataDir + 'torPid.txt', 'r')
@@ -429,7 +354,7 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
 
         try:
             int(pidN)
-        except:
+        except ValueError:
             return
 
         try:
@@ -443,91 +368,40 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
             pass
         except FileNotFoundError:
             pass
-        
+
         try:
             time.sleep(TOR_KILL_WAIT)
         except KeyboardInterrupt:
             pass
 
         if 'windows' == platform.system().lower():
-            os.system('taskkill /PID %s /F' % (pidN,))
+            os.system(f'taskkill /PID {pidN} /F')
             time.sleep(0.5)
             return
         try:
             os.kill(int(pidN), signal.SIGKILL)
-        except (ProcessLookupError, PermissionError) as e:
+        except (ProcessLookupError, PermissionError):
+            pass
+        try:
+            os.remove(self.dataDir + 'tordata/lock')
+        except FileNotFoundError:
             pass

Methods

-
-def generateTorrc(self) -
-
-

Generate a torrc file for our tor instance

-
-Source code -
    def generateTorrc(self):
-        '''
-            Generate a torrc file for our tor instance
-        '''
-        hsVer = '# v2 onions'
-        if config.get('tor.v3onions'):
-            hsVer = 'HiddenServiceVersion 3'
-
-        if os.path.exists(self.torConfigLocation):
-            os.remove(self.torConfigLocation)
-
-        # Set the Tor control password. Meant to make it harder to manipulate our Tor instance
-        plaintext = base64.b64encode(os.urandom(50)).decode()
-        config.set('tor.controlpassword', plaintext, savefile=True)
-        config.set('tor.socksport', self.socksPort, savefile=True)
-
-        controlPort = getopenport.get_open_port()
-
-        config.set('tor.controlPort', controlPort, savefile=True)
-
-        hashedPassword = subprocess.Popen([self.torBinary, '--hash-password', plaintext], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        for line in iter(hashedPassword.stdout.readline, b''):
-            password = line.decode()
-            if 'warn' not in password:
-                break
-
-        torrcData = '''SocksPort ''' + str(self.socksPort) + ''' OnionTrafficOnly
-DataDirectory ''' + self.dataDir + '''tordata/
-CookieAuthentication 1
-KeepalivePeriod 40
-CircuitsAvailableTimeout 86400
-ControlPort ''' + str(controlPort) + '''
-HashedControlPassword ''' + str(password) + '''
-        '''
-        if config.get('general.security_level', 1) == 0:
-            torrcData += '''\nHiddenServiceDir ''' + self.dataDir + '''hs/
-\n''' + hsVer + '''\n
-HiddenServiceNumIntroductionPoints 6
-HiddenServiceMaxStreams 100
-HiddenServiceMaxStreamsCloseCircuit 1
-HiddenServicePort 80 ''' + self.apiServerIP + ''':''' + str(self.hsPort)
-
-        torrcData = add_bridges(torrcData)
-
-        torrc = open(self.torConfigLocation, 'w')
-        torrc.write(torrcData)
-        torrc.close()
-        return
-
-
-
+
def killTor(self)

Properly kill tor based on pid saved to file

-Source code + +Expand source code +
def killTor(self):
-    '''
+    """
         Properly kill tor based on pid saved to file
-    '''
+    """
 
     try:
         pid = open(self.dataDir + 'torPid.txt', 'r')
@@ -538,7 +412,7 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
 
     try:
         int(pidN)
-    except:
+    except ValueError:
         return
 
     try:
@@ -552,35 +426,41 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
         pass
     except FileNotFoundError:
         pass
-    
+
     try:
         time.sleep(TOR_KILL_WAIT)
     except KeyboardInterrupt:
         pass
 
     if 'windows' == platform.system().lower():
-        os.system('taskkill /PID %s /F' % (pidN,))
+        os.system(f'taskkill /PID {pidN} /F')
         time.sleep(0.5)
         return
     try:
         os.kill(int(pidN), signal.SIGKILL)
-    except (ProcessLookupError, PermissionError) as e:
+    except (ProcessLookupError, PermissionError):
+        pass
+    try:
+        os.remove(self.dataDir + 'tordata/lock')
+    except FileNotFoundError:
         pass
-
+
def startTor(self, gen_torrc=True)

Start Tor with onion service on port 80 & socks proxy on random port

-Source code -
def startTor(self, gen_torrc=True):
-    '''
+
+Expand source code
+
+
def startTor(self, gen_torrc=True) -> BooleanSuccessState:
+    """
         Start Tor with onion service on port 80 & socks proxy on random port
-    '''
+    """
     if gen_torrc:
-        self.generateTorrc()
+        gentorrc.generate_torrc(self, self.apiServerIP)
 
     if os.path.exists('./tor'):
         self.torBinary = './tor'
@@ -593,15 +473,16 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
         tor = subprocess.Popen([self.torBinary, '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     except FileNotFoundError:
         logger.fatal("Tor was not found in your path or the Onionr directory. Please install Tor and try again.", terminal=True)
-        sys.exit(1)
+        return False
     else:
         # Test Tor Version
-        torVersion = subprocess.Popen([self.torBinary, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        torVersion = subprocess.Popen([self.torBinary, '--version'],
+                                      stdout=subprocess.PIPE,
+                                      stderr=subprocess.PIPE)
         for line in iter(torVersion.stdout.readline, b''):
             if 'Tor 0.2.' in line.decode():
                 logger.fatal('Tor 0.3+ required', terminal=True)
-                sys.exit(1)
-                break
+                return False
         torVersion.kill()
 
     # wait for tor to get to 100% bootstrap
@@ -612,6 +493,13 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
                 break
             elif 'opening socks listener' in line.decode().lower():
                 logger.debug(line.decode().replace('\n', ''))
+            else:
+                if 'err' in line.decode():
+                    logger.error(line.decode().replace('\n', ''))
+                elif 'warn' in line.decode():
+                    logger.warn(line.decode().replace('\n', ''))
+                else:
+                    logger.debug(line.decode().replace('\n', ''))
         else:
             logger.fatal('Failed to start Tor. Maybe a stray instance of Tor used by Onionr is still running? This can also be a result of file permissions being too open', terminal=True)
             return False
@@ -630,10 +518,11 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
     except FileNotFoundError:
         self.myID = ""
 
-    torPidFile = open(self.dataDir + 'torPid.txt', 'w')
-    torPidFile.write(str(tor.pid))
-    torPidFile.close()
+    with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file:
+        tor_pid_file.write(str(tor.pid))
 
+    multiprocessing.Process(target=watchdog.watchdog,
+                            args=[os.getpid(), tor.pid]).start()
     return True
@@ -650,22 +539,27 @@ HiddenServicePort 80 ''' + self.apiServerIP + ''':'&
diff --git a/docs/html/src/netcontroller/torcontrol/onionservicecreator.html b/docs/html/src/netcontroller/torcontrol/onionservicecreator.html new file mode 100644 index 00000000..0b4f001c --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/onionservicecreator.html @@ -0,0 +1,118 @@ + + + + + + +src.netcontroller.torcontrol.onionservicecreator API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.onionservicecreator

+
+
+

Onionr - Private P2P Communication.

+

Create an ephemeral onion service

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Create an ephemeral onion service
+"""
+from .torcontroller import get_controller
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def create_onion_service(port=80):
+    controller = get_controller()
+    hs = controller.create_ephemeral_hidden_service(
+        {80: port},
+        key_type = 'NEW',
+        key_content = 'ED25519-V3',
+        await_publication=True,
+        detached=True)
+    return (hs.service_id, hs.private_key)
+
+
+
+
+
+
+
+

Functions

+
+
+def create_onion_service(port=80) +
+
+
+
+ +Expand source code + +
def create_onion_service(port=80):
+    controller = get_controller()
+    hs = controller.create_ephemeral_hidden_service(
+        {80: port},
+        key_type = 'NEW',
+        key_content = 'ED25519-V3',
+        await_publication=True,
+        detached=True)
+    return (hs.service_id, hs.private_key)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/netcontroller/torcontrol/rebuildtor.html b/docs/html/src/netcontroller/torcontrol/rebuildtor.html new file mode 100644 index 00000000..6c365b93 --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/rebuildtor.html @@ -0,0 +1,122 @@ + + + + + + +src.netcontroller.torcontrol.rebuildtor API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.rebuildtor

+
+
+

Onionr - P2P Anonymous Storage Network.

+

Send Tor restart command

+
+ +Expand source code + +
"""Onionr - P2P Anonymous Storage Network.
+
+Send Tor restart command
+"""
+import time
+
+from gevent import spawn
+
+from onionrutils import localcommand
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def rebuild():
+    """Send Tor restart command"""
+    spawn(
+        localcommand.local_command,
+        f'/daemon-event/restart_tor',
+        post=True,
+        is_json=True,
+        postData={}
+    ).get(10)
+
+
+
+
+
+
+
+

Functions

+
+
+def rebuild() +
+
+

Send Tor restart command

+
+ +Expand source code + +
def rebuild():
+    """Send Tor restart command"""
+    spawn(
+        localcommand.local_command,
+        f'/daemon-event/restart_tor',
+        post=True,
+        is_json=True,
+        postData={}
+    ).get(10)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/netcontroller/torbinary.html b/docs/html/src/netcontroller/torcontrol/torbinary.html similarity index 75% rename from docs/html/onionr/netcontroller/torbinary.html rename to docs/html/src/netcontroller/torcontrol/torbinary.html index 3edd6368..34727020 100644 --- a/docs/html/onionr/netcontroller/torbinary.html +++ b/docs/html/src/netcontroller/torcontrol/torbinary.html @@ -3,13 +3,13 @@ - -onionr.netcontroller.torbinary API documentation + +src.netcontroller.torcontrol.torbinary API documentation - + @@ -17,19 +17,23 @@
-

Module onionr.netcontroller.torbinary

+

Module src.netcontroller.torcontrol.torbinary

Onionr - Private P2P Communication

get the tor binary path

-Source code -
'''
+
+Expand source code
+
+
"""
     Onionr - Private P2P Communication
 
     get the tor binary path
-'''
-'''
+"""
+import os
+from shutil import which
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,12 +46,11 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os
-from shutil import which
+"""
+
 
 def tor_binary():
-    '''Return tor binary path or none if not exists'''
+    """Return tor binary path or none if not exists"""
     tor_path = './tor'
     if not os.path.exists(tor_path):
         tor_path = which('tor')
@@ -61,15 +64,17 @@ def tor_binary():
 

Functions

-
+
def tor_binary()

Return tor binary path or none if not exists

-Source code + +Expand source code +
def tor_binary():
-    '''Return tor binary path or none if not exists'''
+    """Return tor binary path or none if not exists"""
     tor_path = './tor'
     if not os.path.exists(tor_path):
         tor_path = which('tor')
@@ -89,19 +94,19 @@ def tor_binary():
 
 
 
diff --git a/docs/html/src/netcontroller/torcontrol/torcontroller.html b/docs/html/src/netcontroller/torcontrol/torcontroller.html new file mode 100644 index 00000000..5b90be2c --- /dev/null +++ b/docs/html/src/netcontroller/torcontrol/torcontroller.html @@ -0,0 +1,103 @@ + + + + + + +src.netcontroller.torcontrol.torcontroller API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.torcontrol.torcontroller

+
+
+
+ +Expand source code + +
from stem.control import Controller
+
+import config
+config.reload()
+
+
+def get_controller() -> Controller:
+    """Create and return a Tor controller connection."""
+    port = config.get('tor.controlPort', 0)
+    password = config.get('tor.controlpassword', '')
+    if config.get('tor.use_existing_tor', False):
+        port = config.get('tor.existing_control_port', 0)
+        password = config.get('tor.existing_control_password', '')
+    c = Controller.from_port(port=port)
+    c.authenticate(password)
+    return c
+
+
+
+
+
+
+
+

Functions

+
+
+def get_controller() +
+
+

Create and return a Tor controller connection.

+
+ +Expand source code + +
def get_controller() -> Controller:
+    """Create and return a Tor controller connection."""
+    port = config.get('tor.controlPort', 0)
+    password = config.get('tor.controlpassword', '')
+    if config.get('tor.use_existing_tor', False):
+        port = config.get('tor.existing_control_port', 0)
+        password = config.get('tor.existing_control_password', '')
+    c = Controller.from_port(port=port)
+    c.authenticate(password)
+    return c
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/netcontroller/watchdog.html b/docs/html/src/netcontroller/watchdog.html new file mode 100644 index 00000000..3e11082c --- /dev/null +++ b/docs/html/src/netcontroller/watchdog.html @@ -0,0 +1,140 @@ + + + + + + +src.netcontroller.watchdog API documentation + + + + + + + + + +
+
+
+

Module src.netcontroller.watchdog

+
+
+

Onionr - Private P2P Communication

+

Watch 1 process, then terminate second safely

+
+ +Expand source code + +
"""
+    Onionr - Private P2P Communication
+
+    Watch 1 process, then terminate second safely
+"""
+
+import time
+import os
+
+import psutil
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def watchdog(parent_proc, child_proc):
+    """watch for proc1 to die, then kill proc2"""
+
+    try:
+        if os.forkpty() != 0:
+            return
+    except AttributeError:
+        pass
+
+    parent_proc = psutil.Process(parent_proc)
+    child_proc = psutil.Process(child_proc)
+
+    while parent_proc.is_running():
+        time.sleep(10)
+
+    if child_proc.is_running():
+        child_proc.terminate()
+
+
+
+
+
+
+
+

Functions

+
+
+def watchdog(parent_proc, child_proc) +
+
+

watch for proc1 to die, then kill proc2

+
+ +Expand source code + +
def watchdog(parent_proc, child_proc):
+    """watch for proc1 to die, then kill proc2"""
+
+    try:
+        if os.forkpty() != 0:
+            return
+    except AttributeError:
+        pass
+
+    parent_proc = psutil.Process(parent_proc)
+    child_proc = psutil.Process(child_proc)
+
+    while parent_proc.is_running():
+        time.sleep(10)
+
+    if child_proc.is_running():
+        child_proc.terminate()
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/notifier/index.html b/docs/html/src/notifier/index.html similarity index 73% rename from docs/html/onionr/notifier/index.html rename to docs/html/src/notifier/index.html index 12c6b1fe..a49aa9f7 100644 --- a/docs/html/onionr/notifier/index.html +++ b/docs/html/src/notifier/index.html @@ -3,13 +3,13 @@ - -onionr.notifier API documentation + +src.notifier API documentation - + @@ -17,19 +17,29 @@
-

Module onionr.notifier

+

Module src.notifier

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Desktop notification wrapper

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Desktop notification wrapper
-'''
-'''
+Desktop notification wrapper
+"""
+try:
+    import simplenotifications as simplenotify
+except ImportError:
+    notifications_enabled = False
+else:
+    notifications_enabled = True
+
+import config
+
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,17 +52,16 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-try:
-    import simplenotifications as simplenotify
-except ImportError:
+"""
+
+if not config.get('general.show_notifications', True):
     notifications_enabled = False
-else:
-    notifications_enabled = True
+
 
 def notify(title: str = "Onionr", message: str = ""):
-    """cross platform method to show a notification"""
-    if not notifications_enabled: return
+    """Cross platform method to show a notification."""
+    if not notifications_enabled:
+        return
     simplenotify.notify(title, message)
@@ -63,16 +72,19 @@ def notify(title: str = "Onionr", message: str = ""):

Functions

-
+
def notify(title='Onionr', message='')
-

cross platform method to show a notification

+

Cross platform method to show a notification.

-Source code + +Expand source code +
def notify(title: str = "Onionr", message: str = ""):
-    """cross platform method to show a notification"""
-    if not notifications_enabled: return
+    """Cross platform method to show a notification."""
+    if not notifications_enabled:
+        return
     simplenotify.notify(title, message)
@@ -89,19 +101,19 @@ def notify(title: str = "Onionr", message: str = ""):
diff --git a/docs/html/onionr/onionrblocks/blockimporter.html b/docs/html/src/onionrblocks/blockimporter.html similarity index 61% rename from docs/html/onionr/onionrblocks/blockimporter.html rename to docs/html/src/onionrblocks/blockimporter.html index de72f9bd..fe9d55b6 100644 --- a/docs/html/onionr/onionrblocks/blockimporter.html +++ b/docs/html/src/onionrblocks/blockimporter.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks.blockimporter API documentation + +src.onionrblocks.blockimporter API documentation - + @@ -17,18 +17,32 @@
-

Module onionr.onionrblocks.blockimporter

+

Module src.onionrblocks.blockimporter

Onionr - Private P2P Communication

Import block data and save it

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
     Import block data and save it
 '''
+from onionrexceptions import BlacklistedBlock
+from onionrexceptions import DiskAllocationReached
+from onionrexceptions import InvalidProof
+from onionrexceptions import InvalidMetadata
+import logger
+from onionrutils import validatemetadata
+from onionrutils import blockmetadata
+from coredb import blockmetadb
+import onionrstorage
+import onionrcrypto as crypto
+from . import onionrblacklist
+
 '''
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,42 +57,47 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
-import onionrexceptions, logger
-from onionrutils import validatemetadata, blockmetadata
-from coredb import blockmetadb
-from . import onionrblacklist
-import onionrstorage
-import onionrcrypto as crypto
-def importBlockFromData(content):
+
+
+def import_block_from_data(content):
     blacklist = onionrblacklist.OnionrBlackList()
-    retData = False
+    ret_data = False
 
     try:
         content = content.encode()
     except AttributeError:
         pass
 
-    dataHash = crypto.hashers.sha3_hash(content)
+    data_hash = crypto.hashers.sha3_hash(content)
 
-    if blacklist.inBlacklist(dataHash):
-        raise onionrexceptions.BlacklistedBlock('%s is a blacklisted block' % (dataHash,))
+    if blacklist.inBlacklist(data_hash):
+        raise BlacklistedBlock(f'%s is a blacklisted block {data_hash}')
 
-    metas = blockmetadata.get_block_metadata_from_data(content) # returns tuple(metadata, meta), meta is also in metadata
+    # returns tuple(metadata, meta), meta is also in metadata
+    metas = blockmetadata.get_block_metadata_from_data(content)
     metadata = metas[0]
-    if validatemetadata.validate_metadata(metadata, metas[2]): # check if metadata is valid
-        if crypto.cryptoutils.verify_POW(content): # check if POW is enough/correct
-            logger.info('Block passed proof, saving.', terminal=True)
+
+    # check if metadata is valid
+    if validatemetadata.validate_metadata(metadata, metas[2]):
+        # check if POW is enough/correct
+        if crypto.cryptoutils.verify_POW(content):
+            logger.info(f'Imported block passed proof, saving: {data_hash}.',
+                        terminal=True)
             try:
                 blockHash = onionrstorage.set_data(content)
-            except onionrexceptions.DiskAllocationReached:
+            except DiskAllocationReached:
                 logger.warn('Failed to save block due to full disk allocation')
+                raise
             else:
                 blockmetadb.add_to_block_DB(blockHash, dataSaved=True)
-                blockmetadata.process_block_metadata(blockHash) # caches block metadata values to block database
-                retData = True
+                # caches block metadata values to block database
+                blockmetadata.process_block_metadata(blockHash)
+                ret_data = blockHash
         else:
-            raise onionrexceptions.InvalidProof
-    return retData
+ raise InvalidProof + else: + raise InvalidMetadata + return ret_data
@@ -88,43 +107,54 @@ def importBlockFromData(content):

Functions

-
-def importBlockFromData(content) +
+def import_block_from_data(content)
-Source code -
def importBlockFromData(content):
+
+Expand source code
+
+
def import_block_from_data(content):
     blacklist = onionrblacklist.OnionrBlackList()
-    retData = False
+    ret_data = False
 
     try:
         content = content.encode()
     except AttributeError:
         pass
 
-    dataHash = crypto.hashers.sha3_hash(content)
+    data_hash = crypto.hashers.sha3_hash(content)
 
-    if blacklist.inBlacklist(dataHash):
-        raise onionrexceptions.BlacklistedBlock('%s is a blacklisted block' % (dataHash,))
+    if blacklist.inBlacklist(data_hash):
+        raise BlacklistedBlock(f'%s is a blacklisted block {data_hash}')
 
-    metas = blockmetadata.get_block_metadata_from_data(content) # returns tuple(metadata, meta), meta is also in metadata
+    # returns tuple(metadata, meta), meta is also in metadata
+    metas = blockmetadata.get_block_metadata_from_data(content)
     metadata = metas[0]
-    if validatemetadata.validate_metadata(metadata, metas[2]): # check if metadata is valid
-        if crypto.cryptoutils.verify_POW(content): # check if POW is enough/correct
-            logger.info('Block passed proof, saving.', terminal=True)
+
+    # check if metadata is valid
+    if validatemetadata.validate_metadata(metadata, metas[2]):
+        # check if POW is enough/correct
+        if crypto.cryptoutils.verify_POW(content):
+            logger.info(f'Imported block passed proof, saving: {data_hash}.',
+                        terminal=True)
             try:
                 blockHash = onionrstorage.set_data(content)
-            except onionrexceptions.DiskAllocationReached:
+            except DiskAllocationReached:
                 logger.warn('Failed to save block due to full disk allocation')
+                raise
             else:
                 blockmetadb.add_to_block_DB(blockHash, dataSaved=True)
-                blockmetadata.process_block_metadata(blockHash) # caches block metadata values to block database
-                retData = True
+                # caches block metadata values to block database
+                blockmetadata.process_block_metadata(blockHash)
+                ret_data = blockHash
         else:
-            raise onionrexceptions.InvalidProof
-    return retData
+ raise InvalidProof + else: + raise InvalidMetadata + return ret_data
@@ -140,19 +170,19 @@ def importBlockFromData(content):
diff --git a/docs/html/src/onionrblocks/deleteplaintext.html b/docs/html/src/onionrblocks/deleteplaintext.html new file mode 100644 index 00000000..a1f24811 --- /dev/null +++ b/docs/html/src/onionrblocks/deleteplaintext.html @@ -0,0 +1,123 @@ + + + + + + +src.onionrblocks.deleteplaintext API documentation + + + + + + + + + +
+
+
+

Module src.onionrblocks.deleteplaintext

+
+
+

Onionr - P2P Anonymous Storage Network.

+

Delete but do not blacklist plaintext blocks

+
+ +Expand source code + +
"""Onionr - P2P Anonymous Storage Network.
+
+Delete but do not blacklist plaintext blocks
+"""
+from coredb import blockmetadb
+from onionrstorage.removeblock import remove_block
+import onionrstorage
+from .onionrblockapi import Block
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def delete_plaintext_no_blacklist():
+    """Delete, but do not blacklist, plaintext blocks."""
+
+    block_list = blockmetadb.get_block_list()
+
+    for block in block_list:
+        block = Block(hash=block)
+        if not block.isEncrypted:
+            remove_block(block.hash)
+            onionrstorage.deleteBlock(block.hash)
+
+
+
+
+
+
+
+

Functions

+
+
+def delete_plaintext_no_blacklist() +
+
+

Delete, but do not blacklist, plaintext blocks.

+
+ +Expand source code + +
def delete_plaintext_no_blacklist():
+    """Delete, but do not blacklist, plaintext blocks."""
+
+    block_list = blockmetadb.get_block_list()
+
+    for block in block_list:
+        block = Block(hash=block)
+        if not block.isEncrypted:
+            remove_block(block.hash)
+            onionrstorage.deleteBlock(block.hash)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrblocks/index.html b/docs/html/src/onionrblocks/index.html similarity index 62% rename from docs/html/onionr/onionrblocks/index.html rename to docs/html/src/onionrblocks/index.html index 418786e8..25d3d392 100644 --- a/docs/html/onionr/onionrblocks/index.html +++ b/docs/html/src/onionrblocks/index.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks API documentation + +src.onionrblocks API documentation - + @@ -17,36 +17,44 @@
-

Module onionr.onionrblocks

+

Module src.onionrblocks

-Source code + +Expand source code +
from . import insert
+from .insert import time_insert
 
-insert = insert.insert_block
+insert = insert.insert_block +time_insert = time_insert

Sub-modules

-
onionr.onionrblocks.blockimporter
+
src.onionrblocks.blockimporter

Onionr - Private P2P Communication …

-
onionr.onionrblocks.insert
-
-
-
-
onionr.onionrblocks.onionrblacklist
-
-

Onionr - Private P2P Communication …

-
-
onionr.onionrblocks.onionrblockapi
+
src.onionrblocks.deleteplaintext

Onionr - P2P Anonymous Storage Network …

-
onionr.onionrblocks.storagecounter
+
src.onionrblocks.insert
+
+
+
+
src.onionrblocks.onionrblacklist
+
+

Onionr - Private P2P Communication …

+
+
src.onionrblocks.onionrblockapi
+
+

Onionr - P2P Anonymous Storage Network …

+
+
src.onionrblocks.storagecounter

Onionr - Private P2P Communication …

@@ -67,23 +75,24 @@ insert = insert.insert_block
diff --git a/docs/html/src/onionrblocks/insert/index.html b/docs/html/src/onionrblocks/insert/index.html new file mode 100644 index 00000000..b4e56e5a --- /dev/null +++ b/docs/html/src/onionrblocks/insert/index.html @@ -0,0 +1,79 @@ + + + + + + +src.onionrblocks.insert API documentation + + + + + + + + + +
+
+
+

Module src.onionrblocks.insert

+
+
+
+ +Expand source code + +
from . import main, timeinsert
+
+insert_block = main.insert_block
+time_insert = timeinsert.time_insert
+
+
+
+

Sub-modules

+
+
src.onionrblocks.insert.main
+
+

Onionr - Private P2P Communication …

+
+
src.onionrblocks.insert.timeinsert
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrblocks/insert.html b/docs/html/src/onionrblocks/insert/main.html similarity index 71% rename from docs/html/onionr/onionrblocks/insert.html rename to docs/html/src/onionrblocks/insert/main.html index f6a7588e..b6f619a3 100644 --- a/docs/html/onionr/onionrblocks/insert.html +++ b/docs/html/src/onionrblocks/insert/main.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks.insert API documentation - + +src.onionrblocks.insert.main API documentation + - + @@ -17,16 +17,42 @@
-

Module onionr.onionrblocks.insert

+

Module src.onionrblocks.insert.main

+

Onionr - Private P2P Communication

+

Create and insert Onionr blocks

-Source code -
from typing import Union
+
+Expand source code
+
+
"""
+    Onionr - Private P2P Communication
+
+    Create and insert Onionr blocks
+"""
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+from typing import Union
 import json
+
+from gevent import spawn
+
 from onionrutils import bytesconverter, epoch
 import filepaths, onionrstorage
-from . import storagecounter
+from .. import storagecounter
 from onionrplugins import onionrevents as events
 from etc import powchoice, onionrvalues
 import config, onionrcrypto as crypto, onionrexceptions
@@ -36,20 +62,57 @@ import coredb
 import onionrproofs
 from onionrproofs import subprocesspow
 import logger
-def insert_block(data: Union[str, bytes], header: str ='txt', 
-                sign: bool =False, encryptType:str ='', symKey:str ='',
-                asymPeer:str ='', meta:dict = {},
-                expire:Union[int, None] =None, disableForward:bool =False)->Union[str,bool]:
+from onionrtypes import UserIDSecretKey
+
+
+def _check_upload_queue():
+    """Returns the current upload queue len
+    raises OverflowError if max, false if api not running
+    """
+    max_upload_queue: int = 5000
+    queue = localcommand.local_command('/gethidden', maxWait=10)
+    up_queue = False
+
+    try:
+        up_queue = len(queue.splitlines())
+    except AttributeError:
+        pass
+    else:
+        if up_queue >= max_upload_queue:
+            raise OverflowError
+    return up_queue
+
+
+def insert_block(data: Union[str, bytes], header: str = 'txt',
+                 sign: bool = False, encryptType: str = '', symKey: str = '',
+                 asymPeer: str = '', meta: dict = {},
+                 expire: Union[int, None] = None, disableForward: bool = False,
+                 signing_key: UserIDSecretKey = '') -> Union[str, bool]:
     """
         Inserts a block into the network
         encryptType must be specified to encrypt a block
     """
-    use_subprocess = powchoice.use_subprocess(config)
+    our_private_key = crypto.priv_key
+    our_pub_key = crypto.pub_key
+
+    is_offline = True
+
     storage_counter = storagecounter.StorageCounter()
+
     allocationReachedMessage = 'Cannot insert block, disk allocation reached.'
     if storage_counter.is_full():
         logger.error(allocationReachedMessage)
         raise onionrexceptions.DiskAllocationReached
+
+    if not _check_upload_queue() is False: is_offline = False
+
+    if signing_key != '':
+        # if it was specified to use an alternative private key
+        our_private_key = signing_key
+        our_pub_key = bytesconverter.bytes_to_str(crypto.cryptoutils.get_pub_key_from_priv(our_private_key))
+
+    use_subprocess = powchoice.use_subprocess(config)
+
     retData = False
 
     if type(data) is None:
@@ -68,9 +131,6 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
     with open(filepaths.data_nonce_file, 'a') as nonceFile:
         nonceFile.write(dataNonce + '\n')
 
-    if type(data) is bytes:
-        data = data.decode()
-    data = str(data)
     plaintext = data
     plaintextMeta = {}
     plaintextPeer = asymPeer
@@ -79,6 +139,7 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
     signature = ''
     signer = ''
     metadata = {}
+
     # metadata is full block metadata, meta is internal, user specified metadata
 
     # only use header if not set in provided meta
@@ -88,6 +149,7 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
     if encryptType in ('asym', 'sym'):
         metadata['encryptType'] = encryptType
     else:
+        if not config.get('general.store_plaintext_blocks', True): raise onionrexceptions.InvalidMetadata("Plaintext blocks are disabled, yet a plaintext block was being inserted")
         if not encryptType in ('', None):
             raise onionrexceptions.InvalidMetadata('encryptType must be asym or sym, or blank')
 
@@ -98,7 +160,7 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
 
     if encryptType == 'asym':
         meta['rply'] = createTime # Duplicate the time in encrypted messages to prevent replays
-        if not disableForward and sign and asymPeer != crypto.pub_key:
+        if not disableForward and sign and asymPeer != our_pub_key:
             try:
                 forwardEncrypted = onionrusers.OnionrUser(asymPeer).forwardEncrypt(data)
                 data = forwardEncrypted[0]
@@ -113,8 +175,8 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
     jsonMeta = json.dumps(meta)
     plaintextMeta = jsonMeta
     if sign:
-        signature = crypto.signing.ed_sign(jsonMeta.encode() + data, key=crypto.priv_key, encodeResult=True)
-        signer = crypto.pub_key
+        signature = crypto.signing.ed_sign(jsonMeta.encode() + data, key=our_private_key, encodeResult=True)
+        signer = our_pub_key
 
     if len(jsonMeta) > 1000:
         raise onionrexceptions.InvalidMetadata('meta in json encoded form must not exceed 1000 bytes')
@@ -140,7 +202,7 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
 
     # compile metadata
     metadata['meta'] = jsonMeta
-    if len(signature) > 0: # I don't like not pattern
+    if len(signature) > 0:  # I don't like not pattern
         metadata['sig'] = signature
         metadata['signer'] = signer
     metadata['time'] = createTime
@@ -163,19 +225,21 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
             retData = False
         else:
             # Tell the api server through localCommand to wait for the daemon to upload this block to make statistical analysis more difficult
-            if localcommand.local_command('/ping', maxWait=10) == 'pong!':
-                if config.get('general.security_level', 1) == 0:
-                    localcommand.local_command('/waitforshare/' + retData, post=True, maxWait=5)
-                coredb.daemonqueue.daemon_queue_add('uploadBlock', retData)
-            else:
-                pass
+            spawn(
+                localcommand.local_command,
+                f'/daemon-event/upload_event',
+                post=True,
+                is_json=True,
+                postData={'block': retData}
+                ).get(timeout=5)
             coredb.blockmetadb.add.add_to_block_DB(retData, selfInsert=True, dataSaved=True)
 
             if expire is None:
-                coredb.blockmetadb.update_block_info(retData, 'expire', createTime + onionrvalues.DEFAULT_EXPIRE)
+                coredb.blockmetadb.update_block_info(retData, 'expire',
+                                                     createTime + onionrvalues.DEFAULT_EXPIRE)
             else:
                 coredb.blockmetadb.update_block_info(retData, 'expire', expire)
-            
+
             blockmetadata.process_block_metadata(retData)
 
     if retData != False:
@@ -183,7 +247,14 @@ def insert_block(data: Union[str, bytes], header: str ='txt',
             events.event('insertdeniable', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': bytesconverter.bytes_to_str(asymPeer)}, threaded = True)
         else:
             events.event('insertblock', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': bytesconverter.bytes_to_str(asymPeer)}, threaded = True)
-    coredb.daemonqueue.daemon_queue_add('remove_from_insert_list', data=dataNonce)
+
+    spawn(
+        localcommand.local_command,
+        '/daemon-event/remove_from_insert_queue_wrapper',
+        post=True,
+        postData={'block_hash': retData},
+        is_json=True
+        ).get(timeout=5)
     return retData
@@ -194,28 +265,46 @@ def insert_block(data: Union[str, bytes], header: str ='txt',

Functions

-
-def insert_block(data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta={}, expire=None, disableForward=False) +
+def insert_block(data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta={}, expire=None, disableForward=False, signing_key='')

Inserts a block into the network encryptType must be specified to encrypt a block

-Source code -
def insert_block(data: Union[str, bytes], header: str ='txt', 
-                sign: bool =False, encryptType:str ='', symKey:str ='',
-                asymPeer:str ='', meta:dict = {},
-                expire:Union[int, None] =None, disableForward:bool =False)->Union[str,bool]:
+
+Expand source code
+
+
def insert_block(data: Union[str, bytes], header: str = 'txt',
+                 sign: bool = False, encryptType: str = '', symKey: str = '',
+                 asymPeer: str = '', meta: dict = {},
+                 expire: Union[int, None] = None, disableForward: bool = False,
+                 signing_key: UserIDSecretKey = '') -> Union[str, bool]:
     """
         Inserts a block into the network
         encryptType must be specified to encrypt a block
     """
-    use_subprocess = powchoice.use_subprocess(config)
+    our_private_key = crypto.priv_key
+    our_pub_key = crypto.pub_key
+
+    is_offline = True
+
     storage_counter = storagecounter.StorageCounter()
+
     allocationReachedMessage = 'Cannot insert block, disk allocation reached.'
     if storage_counter.is_full():
         logger.error(allocationReachedMessage)
         raise onionrexceptions.DiskAllocationReached
+
+    if not _check_upload_queue() is False: is_offline = False
+
+    if signing_key != '':
+        # if it was specified to use an alternative private key
+        our_private_key = signing_key
+        our_pub_key = bytesconverter.bytes_to_str(crypto.cryptoutils.get_pub_key_from_priv(our_private_key))
+
+    use_subprocess = powchoice.use_subprocess(config)
+
     retData = False
 
     if type(data) is None:
@@ -234,9 +323,6 @@ encryptType must be specified to encrypt a block

with open(filepaths.data_nonce_file, 'a') as nonceFile: nonceFile.write(dataNonce + '\n') - if type(data) is bytes: - data = data.decode() - data = str(data) plaintext = data plaintextMeta = {} plaintextPeer = asymPeer @@ -245,6 +331,7 @@ encryptType must be specified to encrypt a block

signature = '' signer = '' metadata = {} + # metadata is full block metadata, meta is internal, user specified metadata # only use header if not set in provided meta @@ -254,6 +341,7 @@ encryptType must be specified to encrypt a block

if encryptType in ('asym', 'sym'): metadata['encryptType'] = encryptType else: + if not config.get('general.store_plaintext_blocks', True): raise onionrexceptions.InvalidMetadata("Plaintext blocks are disabled, yet a plaintext block was being inserted") if not encryptType in ('', None): raise onionrexceptions.InvalidMetadata('encryptType must be asym or sym, or blank') @@ -264,7 +352,7 @@ encryptType must be specified to encrypt a block

if encryptType == 'asym': meta['rply'] = createTime # Duplicate the time in encrypted messages to prevent replays - if not disableForward and sign and asymPeer != crypto.pub_key: + if not disableForward and sign and asymPeer != our_pub_key: try: forwardEncrypted = onionrusers.OnionrUser(asymPeer).forwardEncrypt(data) data = forwardEncrypted[0] @@ -279,8 +367,8 @@ encryptType must be specified to encrypt a block

jsonMeta = json.dumps(meta) plaintextMeta = jsonMeta if sign: - signature = crypto.signing.ed_sign(jsonMeta.encode() + data, key=crypto.priv_key, encodeResult=True) - signer = crypto.pub_key + signature = crypto.signing.ed_sign(jsonMeta.encode() + data, key=our_private_key, encodeResult=True) + signer = our_pub_key if len(jsonMeta) > 1000: raise onionrexceptions.InvalidMetadata('meta in json encoded form must not exceed 1000 bytes') @@ -306,7 +394,7 @@ encryptType must be specified to encrypt a block

# compile metadata metadata['meta'] = jsonMeta - if len(signature) > 0: # I don't like not pattern + if len(signature) > 0: # I don't like not pattern metadata['sig'] = signature metadata['signer'] = signer metadata['time'] = createTime @@ -329,19 +417,21 @@ encryptType must be specified to encrypt a block

retData = False else: # Tell the api server through localCommand to wait for the daemon to upload this block to make statistical analysis more difficult - if localcommand.local_command('/ping', maxWait=10) == 'pong!': - if config.get('general.security_level', 1) == 0: - localcommand.local_command('/waitforshare/' + retData, post=True, maxWait=5) - coredb.daemonqueue.daemon_queue_add('uploadBlock', retData) - else: - pass + spawn( + localcommand.local_command, + f'/daemon-event/upload_event', + post=True, + is_json=True, + postData={'block': retData} + ).get(timeout=5) coredb.blockmetadb.add.add_to_block_DB(retData, selfInsert=True, dataSaved=True) if expire is None: - coredb.blockmetadb.update_block_info(retData, 'expire', createTime + onionrvalues.DEFAULT_EXPIRE) + coredb.blockmetadb.update_block_info(retData, 'expire', + createTime + onionrvalues.DEFAULT_EXPIRE) else: coredb.blockmetadb.update_block_info(retData, 'expire', expire) - + blockmetadata.process_block_metadata(retData) if retData != False: @@ -349,7 +439,14 @@ encryptType must be specified to encrypt a block

events.event('insertdeniable', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': bytesconverter.bytes_to_str(asymPeer)}, threaded = True) else: events.event('insertblock', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': bytesconverter.bytes_to_str(asymPeer)}, threaded = True) - coredb.daemonqueue.daemon_queue_add('remove_from_insert_list', data=dataNonce) + + spawn( + localcommand.local_command, + '/daemon-event/remove_from_insert_queue_wrapper', + post=True, + postData={'block_hash': retData}, + is_json=True + ).get(timeout=5) return retData
@@ -366,19 +463,19 @@ encryptType must be specified to encrypt a block

diff --git a/docs/html/src/onionrblocks/insert/timeinsert.html b/docs/html/src/onionrblocks/insert/timeinsert.html new file mode 100644 index 00000000..23f51167 --- /dev/null +++ b/docs/html/src/onionrblocks/insert/timeinsert.html @@ -0,0 +1,163 @@ + + + + + + +src.onionrblocks.insert.timeinsert API documentation + + + + + + + + + +
+
+
+

Module src.onionrblocks.insert.timeinsert

+
+
+

Onionr - Private P2P Communication.

+

Wrapper to insert blocks with variable delay

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Wrapper to insert blocks with variable delay
+"""
+from . import main
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def time_insert(*args, **kwargs):
+    """Block insert wrapper to allow for insertions independent of mixmate.
+
+    Takes exact args as insert_block, with additional keyword:
+    delay=n; where n=seconds to tell initial nodes to delay share for.
+
+    defaults to 0 or previously set value in current block meta
+    """
+    try:
+        kwargs['meta']
+    except KeyError:
+        kwargs['meta'] = {}
+
+    try:
+        delay = int(kwargs['meta']['dly'])
+    except KeyError:
+        delay = 0
+    try:
+        delay = kwargs['delay']
+        del kwargs['delay']
+    except KeyError:
+        delay = 0
+
+    # Ensure delay >=0
+    if delay < 0:
+        raise ValueError('delay cannot be less than 0')
+
+    kwargs['meta']['dly'] = delay
+
+    return main.insert_block(*args, **kwargs)
+
+
+
+
+
+
+
+

Functions

+
+
+def time_insert(*args, **kwargs) +
+
+

Block insert wrapper to allow for insertions independent of mixmate.

+

Takes exact args as insert_block, with additional keyword: +delay=n; where n=seconds to tell initial nodes to delay share for.

+

defaults to 0 or previously set value in current block meta

+
+ +Expand source code + +
def time_insert(*args, **kwargs):
+    """Block insert wrapper to allow for insertions independent of mixmate.
+
+    Takes exact args as insert_block, with additional keyword:
+    delay=n; where n=seconds to tell initial nodes to delay share for.
+
+    defaults to 0 or previously set value in current block meta
+    """
+    try:
+        kwargs['meta']
+    except KeyError:
+        kwargs['meta'] = {}
+
+    try:
+        delay = int(kwargs['meta']['dly'])
+    except KeyError:
+        delay = 0
+    try:
+        delay = kwargs['delay']
+        del kwargs['delay']
+    except KeyError:
+        delay = 0
+
+    # Ensure delay >=0
+    if delay < 0:
+        raise ValueError('delay cannot be less than 0')
+
+    kwargs['meta']['dly'] = delay
+
+    return main.insert_block(*args, **kwargs)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrblocks/onionrblacklist.html b/docs/html/src/onionrblocks/onionrblacklist.html similarity index 74% rename from docs/html/onionr/onionrblocks/onionrblacklist.html rename to docs/html/src/onionrblocks/onionrblacklist.html index f4a5331b..33d7a5bc 100644 --- a/docs/html/onionr/onionrblocks/onionrblacklist.html +++ b/docs/html/src/onionrblocks/onionrblacklist.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks.onionrblacklist API documentation + +src.onionrblocks.onionrblacklist API documentation - + @@ -17,19 +17,27 @@
-

Module onionr.onionrblocks.onionrblacklist

+

Module src.onionrblocks.onionrblacklist

-

Onionr - Private P2P Communication

-

This file handles maintenence of a blacklist database, for blocks and peers

+

Onionr - Private P2P Communication.

+

Handle maintenance of a blacklist database, for blocks and peers

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file handles maintenence of a blacklist database, for blocks and peers
-'''
-'''
+Handle maintenance of a blacklist database, for blocks and peers
+"""
+import sqlite3
+import os
+
+from onionrplugins.onionrevents import event
+import onionrcrypto
+from onionrutils import epoch, bytesconverter
+from coredb import dbfiles
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,11 +50,8 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sqlite3, os
-import logger, onionrcrypto
-from onionrutils import epoch, bytesconverter
-from coredb import dbfiles
+"""
+
 
 class OnionrBlackList:
     def __init__(self):
@@ -83,7 +88,7 @@ class OnionrBlackList:
         return
 
     def deleteExpired(self, dataType=0):
-        '''Delete expired entries'''
+        """Delete expired entries"""
         deleteList = []
         curTime = epoch.get_epoch()
 
@@ -104,7 +109,7 @@ class OnionrBlackList:
         return
 
     def clearDB(self):
-        self._dbExecute('''DELETE FROM blacklist;''')
+        self._dbExecute("""DELETE FROM blacklist;""")
 
     def getList(self):
         data = self._dbExecute('SELECT * FROM blacklist')
@@ -114,14 +119,17 @@ class OnionrBlackList:
         return myList
 
     def addToDB(self, data, dataType=0, expire=0):
-        '''Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
+        """Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
         0=block
         1=peer
         2=pubkey
-        '''
+        """
 
         # we hash the data so we can remove data entirely from our node's disk
         hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
+
+        event('blacklist_add', data={'data': data, 'hash': hashed})
+
         if len(hashed) > 64:
             raise Exception("Hashed data is too large")
 
@@ -154,13 +162,15 @@ class OnionrBlackList:
 

Classes

-
+
class OnionrBlackList
-Source code + +Expand source code +
class OnionrBlackList:
     def __init__(self):
         self.blacklistDB = dbfiles.blacklist_db
@@ -196,7 +206,7 @@ class OnionrBlackList:
         return
 
     def deleteExpired(self, dataType=0):
-        '''Delete expired entries'''
+        """Delete expired entries"""
         deleteList = []
         curTime = epoch.get_epoch()
 
@@ -217,7 +227,7 @@ class OnionrBlackList:
         return
 
     def clearDB(self):
-        self._dbExecute('''DELETE FROM blacklist;''')
+        self._dbExecute("""DELETE FROM blacklist;""")
 
     def getList(self):
         data = self._dbExecute('SELECT * FROM blacklist')
@@ -227,14 +237,17 @@ class OnionrBlackList:
         return myList
 
     def addToDB(self, data, dataType=0, expire=0):
-        '''Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
+        """Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
         0=block
         1=peer
         2=pubkey
-        '''
+        """
 
         # we hash the data so we can remove data entirely from our node's disk
         hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
+
+        event('blacklist_add', data={'data': data, 'hash': hashed})
+
         if len(hashed) > 64:
             raise Exception("Hashed data is too large")
 
@@ -259,7 +272,7 @@ class OnionrBlackList:
 

Methods

-
+
def addToDB(self, data, dataType=0, expire=0)
@@ -268,16 +281,21 @@ class OnionrBlackList: 1=peer 2=pubkey

-Source code + +Expand source code +
def addToDB(self, data, dataType=0, expire=0):
-    '''Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
+    """Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
     0=block
     1=peer
     2=pubkey
-    '''
+    """
 
     # we hash the data so we can remove data entirely from our node's disk
     hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
+
+    event('blacklist_add', data={'data': data, 'hash': hashed})
+
     if len(hashed) > 64:
         raise Exception("Hashed data is too large")
 
@@ -301,38 +319,44 @@ class OnionrBlackList:
         pass
-
+
def clearDB(self)
-Source code + +Expand source code +
def clearDB(self):
-    self._dbExecute('''DELETE FROM blacklist;''')
+ self._dbExecute("""DELETE FROM blacklist;""")
-
+
def deleteBeforeDate(self, date)
-Source code + +Expand source code +
def deleteBeforeDate(self, date):
     # TODO, delete blacklist entries before date
     return
-
+
def deleteExpired(self, dataType=0)

Delete expired entries

-Source code + +Expand source code +
def deleteExpired(self, dataType=0):
-    '''Delete expired entries'''
+    """Delete expired entries"""
     deleteList = []
     curTime = epoch.get_epoch()
 
@@ -350,24 +374,28 @@ class OnionrBlackList:
         self._dbExecute("DELETE FROM blacklist WHERE hash = ?", (thing,))
-
+
def generateDB(self)
-Source code + +Expand source code +
def generateDB(self):
     return
-
+
def getList(self)
-Source code + +Expand source code +
def getList(self):
     data = self._dbExecute('SELECT * FROM blacklist')
     myList = []
@@ -376,13 +404,15 @@ class OnionrBlackList:
     return myList
-
+
def inBlacklist(self, data)
-Source code + +Expand source code +
def inBlacklist(self, data):
     hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
     retData = False
@@ -412,21 +442,21 @@ class OnionrBlackList:
 
diff --git a/docs/html/onionr/onionrblocks/onionrblockapi.html b/docs/html/src/onionrblocks/onionrblockapi.html similarity index 78% rename from docs/html/onionr/onionrblocks/onionrblockapi.html rename to docs/html/src/onionrblocks/onionrblockapi.html index f34439b5..26dca2b5 100644 --- a/docs/html/onionr/onionrblocks/onionrblockapi.html +++ b/docs/html/src/onionrblocks/onionrblockapi.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks.onionrblockapi API documentation + +src.onionrblocks.onionrblockapi API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.onionrblocks.onionrblockapi

+

Module src.onionrblocks.onionrblockapi

Onionr - P2P Anonymous Storage Network

This file contains the OnionrBlocks class which is a class for working with Onionr blocks

-Source code + +Expand source code +
'''
     Onionr - P2P Anonymous Storage Network
 
@@ -43,12 +45,14 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 '''
+import unpaddedbase32
 import binascii
 import logger, config, onionrexceptions, nacl.exceptions
 import json, os, sys, datetime, base64, onionrstorage
 from onionrusers import onionrusers
 from onionrutils import stringvalidators, epoch
 from coredb import blockmetadb
+from onionrutils import bytesconverter
 from onionrstorage import removeblock
 import onionrblocks
 from onionrcrypto import encryption, cryptoutils as cryptoutils, signing
@@ -119,7 +123,7 @@ class Block:
                 # Check for replay attacks
                 try:
                     if epoch.get_epoch() - blockmetadb.get_block_date(self.hash) > 60:
-                        if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack 
+                        if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack
                 except (AssertionError, KeyError, TypeError, onionrexceptions.ReplayAttack) as e:
                     if not self.bypassReplayCheck:
                         # Zero out variables to prevent reading of replays
@@ -153,7 +157,9 @@ class Block:
         '''
             Verify if a block's signature is signed by its claimed signer
         '''
-        if self.signer is None or signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
+        if self.signer is None:
+            return False
+        if signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
             self.validSig = True
         else:
             self.validSig = False
@@ -201,7 +207,7 @@ class Block:
             self.signer = self.getHeader('signer', None)
             self.signature = self.getHeader('sig', None)
             # signed data is jsonMeta + block content (no linebreak)
-            self.signedData = (None if not self.isSigned() else self.getHeader('meta') + self.getContent())
+            self.signedData = (None if not self.isSigned() else self.getHeader('meta').encode() + self.getContent())
             self.date = blockmetadb.get_block_date(self.getHash())
             self.claimedTime = self.getHeader('time', None)
 
@@ -209,7 +215,7 @@ class Block:
                 self.date = datetime.datetime.fromtimestamp(self.getDate())
 
             self.valid = True
-            
+
             if self.autoDecrypt:
                 self.decrypt()
 
@@ -354,7 +360,7 @@ class Block:
             - (str): the contents of the block
         '''
 
-        return str(self.bcontent)
+        return self.bcontent
 
     def getDate(self):
         '''
@@ -427,7 +433,7 @@ class Block:
             Outputs:
             - (bool): whether or not the signer of the block is the signer inputted
         '''
-
+        signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
         try:
             if (not self.isSigned()) or (not stringvalidators.validate_pub_key(signer)):
                 return False
@@ -484,61 +490,6 @@ class Block:
         return self
 
     # static functions
-
-    def getBlocks(type = None, signer = None, signed = None, reverse = False, limit = None):
-        '''
-            Returns a list of Block objects based on supplied filters
-
-            Inputs:
-            - type (str): filters by block type
-            - signer (str/list): filters by signer (one in the list has to be a signer)
-            - signed (bool): filters out by whether or not the block is signed
-            - reverse (bool): reverses the list if True
-
-            Outputs:
-            - (list): a list of Block objects that match the input
-        '''
-
-        try:
-
-            relevant_blocks = list()
-            blocks = (blockmetadb.get_block_list() if type is None else blockmetadb.get_blocks_by_type(type))
-
-            for block in blocks:
-                if Block.exists(block):
-                    block = Block(block)
-
-                    relevant = True
-
-                    if (not signed is None) and (block.isSigned() != bool(signed)):
-                        relevant = False
-                    if not signer is None:
-                        if isinstance(signer, (str,)):
-                            signer = [signer]
-                        if isinstance(signer, (bytes,)):
-                            signer = [signer.decode()]
-
-                        isSigner = False
-                        for key in signer:
-                            if block.isSigner(key):
-                                isSigner = True
-                                break
-
-                        if not isSigner:
-                            relevant = False
-
-                    if relevant and (limit is None or len(relevant_Blocks) <= int(limit)):
-                        relevant_blocks.append(block)
-
-            if bool(reverse):
-                relevant_blocks.reverse()
-
-            return relevant_blocks
-        except Exception as e:
-            logger.debug('Failed to get blocks.', error = e)
-
-        return list()
-
     def exists(bHash):
         '''
             Checks if a block is saved to file or not
@@ -558,7 +509,7 @@ class Block:
 
         if isinstance(bHash, Block):
             bHash = bHash.getHash()
-        
+
         ret = isinstance(onionrstorage.getData(bHash), type(None))
 
         return not ret
@@ -573,14 +524,16 @@ class Block:

Classes

-
+
class Block (hash=None, type=None, content=None, expire=None, decrypt=False, bypassReplayCheck=False)
-Source code + +Expand source code +
class Block:
     blockCacheOrder = list() # NEVER write your own code that writes to this!
     blockCache = dict() # should never be accessed directly, look at Block.getCache()
@@ -648,7 +601,7 @@ class Block:
                 # Check for replay attacks
                 try:
                     if epoch.get_epoch() - blockmetadb.get_block_date(self.hash) > 60:
-                        if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack 
+                        if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack
                 except (AssertionError, KeyError, TypeError, onionrexceptions.ReplayAttack) as e:
                     if not self.bypassReplayCheck:
                         # Zero out variables to prevent reading of replays
@@ -682,7 +635,9 @@ class Block:
         '''
             Verify if a block's signature is signed by its claimed signer
         '''
-        if self.signer is None or signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
+        if self.signer is None:
+            return False
+        if signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
             self.validSig = True
         else:
             self.validSig = False
@@ -730,7 +685,7 @@ class Block:
             self.signer = self.getHeader('signer', None)
             self.signature = self.getHeader('sig', None)
             # signed data is jsonMeta + block content (no linebreak)
-            self.signedData = (None if not self.isSigned() else self.getHeader('meta') + self.getContent())
+            self.signedData = (None if not self.isSigned() else self.getHeader('meta').encode() + self.getContent())
             self.date = blockmetadb.get_block_date(self.getHash())
             self.claimedTime = self.getHeader('time', None)
 
@@ -738,7 +693,7 @@ class Block:
                 self.date = datetime.datetime.fromtimestamp(self.getDate())
 
             self.valid = True
-            
+
             if self.autoDecrypt:
                 self.decrypt()
 
@@ -883,7 +838,7 @@ class Block:
             - (str): the contents of the block
         '''
 
-        return str(self.bcontent)
+        return self.bcontent
 
     def getDate(self):
         '''
@@ -956,7 +911,7 @@ class Block:
             Outputs:
             - (bool): whether or not the signer of the block is the signer inputted
         '''
-
+        signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
         try:
             if (not self.isSigned()) or (not stringvalidators.validate_pub_key(signer)):
                 return False
@@ -1013,61 +968,6 @@ class Block:
         return self
 
     # static functions
-
-    def getBlocks(type = None, signer = None, signed = None, reverse = False, limit = None):
-        '''
-            Returns a list of Block objects based on supplied filters
-
-            Inputs:
-            - type (str): filters by block type
-            - signer (str/list): filters by signer (one in the list has to be a signer)
-            - signed (bool): filters out by whether or not the block is signed
-            - reverse (bool): reverses the list if True
-
-            Outputs:
-            - (list): a list of Block objects that match the input
-        '''
-
-        try:
-
-            relevant_blocks = list()
-            blocks = (blockmetadb.get_block_list() if type is None else blockmetadb.get_blocks_by_type(type))
-
-            for block in blocks:
-                if Block.exists(block):
-                    block = Block(block)
-
-                    relevant = True
-
-                    if (not signed is None) and (block.isSigned() != bool(signed)):
-                        relevant = False
-                    if not signer is None:
-                        if isinstance(signer, (str,)):
-                            signer = [signer]
-                        if isinstance(signer, (bytes,)):
-                            signer = [signer.decode()]
-
-                        isSigner = False
-                        for key in signer:
-                            if block.isSigner(key):
-                                isSigner = True
-                                break
-
-                        if not isSigner:
-                            relevant = False
-
-                    if relevant and (limit is None or len(relevant_Blocks) <= int(limit)):
-                        relevant_blocks.append(block)
-
-            if bool(reverse):
-                relevant_blocks.reverse()
-
-            return relevant_blocks
-        except Exception as e:
-            logger.debug('Failed to get blocks.', error = e)
-
-        return list()
-
     def exists(bHash):
         '''
             Checks if a block is saved to file or not
@@ -1087,31 +987,45 @@ class Block:
 
         if isinstance(bHash, Block):
             bHash = bHash.getHash()
-        
+
         ret = isinstance(onionrstorage.getData(bHash), type(None))
 
         return not ret

Class variables

-
var blockCache
+
var blockCache
-
+

dict() -> new empty dictionary +dict(mapping) -> new dictionary initialized from a mapping object's +(key, value) pairs +dict(iterable) -> new dictionary initialized as if via: +d = {} +for k, v in iterable: +d[k] = v +dict(**kwargs) -> new dictionary initialized with the name=value pairs +in the keyword argument list. +For example: +dict(one=1, two=2)

-
var blockCacheOrder
+
var blockCacheOrder
-
+

Built-in mutable sequence.

+

If no argument is given, the constructor creates a new empty list. +The argument must be an iterable if specified.

Methods

-
+
def decrypt(self, encodedData=True)

Decrypt a block, loading decrypted data into their vars

-Source code + +Expand source code +
def decrypt(self, encodedData = True):
     '''
         Decrypt a block, loading decrypted data into their vars
@@ -1146,7 +1060,7 @@ class Block:
             # Check for replay attacks
             try:
                 if epoch.get_epoch() - blockmetadb.get_block_date(self.hash) > 60:
-                    if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack 
+                    if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack
             except (AssertionError, KeyError, TypeError, onionrexceptions.ReplayAttack) as e:
                 if not self.bypassReplayCheck:
                     # Zero out variables to prevent reading of replays
@@ -1177,7 +1091,7 @@ class Block:
     return retData
-
+
def delete(self)
@@ -1185,7 +1099,9 @@ class Block:

Outputs: - (bool): whether or not the operation was successful

-Source code + +Expand source code +
def delete(self):
     '''
         Deletes the block's file and records, if they exist
@@ -1206,7 +1122,7 @@ class Block:
     return False
-
+
def exists(bHash)
@@ -1218,7 +1134,9 @@ class Block:

Outputs: - (bool): whether or not the block file exists

-Source code + +Expand source code +
def exists(bHash):
     '''
         Checks if a block is saved to file or not
@@ -1238,13 +1156,13 @@ class Block:
 
     if isinstance(bHash, Block):
         bHash = bHash.getHash()
-    
+
     ret = isinstance(onionrstorage.getData(bHash), type(None))
 
     return not ret
-
+
def getBlockFile(self)
@@ -1252,7 +1170,9 @@ class Block:

Outputs: - (str): the location of the block file, or None

-Source code + +Expand source code +
def getBlockFile(self):
     '''
         Returns the location of the block file if it is saved
@@ -1264,76 +1184,7 @@ class Block:
     return self.blockFile
-
-def getBlocks(type=None, signer=None, signed=None, reverse=False, limit=None) -
-
-

Returns a list of Block objects based on supplied filters

-

Inputs: -- type (str): filters by block type -- signer (str/list): filters by signer (one in the list has to be a signer) -- signed (bool): filters out by whether or not the block is signed -- reverse (bool): reverses the list if True

-

Outputs: -- (list): a list of Block objects that match the input

-
-Source code -
def getBlocks(type = None, signer = None, signed = None, reverse = False, limit = None):
-    '''
-        Returns a list of Block objects based on supplied filters
-
-        Inputs:
-        - type (str): filters by block type
-        - signer (str/list): filters by signer (one in the list has to be a signer)
-        - signed (bool): filters out by whether or not the block is signed
-        - reverse (bool): reverses the list if True
-
-        Outputs:
-        - (list): a list of Block objects that match the input
-    '''
-
-    try:
-
-        relevant_blocks = list()
-        blocks = (blockmetadb.get_block_list() if type is None else blockmetadb.get_blocks_by_type(type))
-
-        for block in blocks:
-            if Block.exists(block):
-                block = Block(block)
-
-                relevant = True
-
-                if (not signed is None) and (block.isSigned() != bool(signed)):
-                    relevant = False
-                if not signer is None:
-                    if isinstance(signer, (str,)):
-                        signer = [signer]
-                    if isinstance(signer, (bytes,)):
-                        signer = [signer.decode()]
-
-                    isSigner = False
-                    for key in signer:
-                        if block.isSigner(key):
-                            isSigner = True
-                            break
-
-                    if not isSigner:
-                        relevant = False
-
-                if relevant and (limit is None or len(relevant_Blocks) <= int(limit)):
-                    relevant_blocks.append(block)
-
-        if bool(reverse):
-            relevant_blocks.reverse()
-
-        return relevant_blocks
-    except Exception as e:
-        logger.debug('Failed to get blocks.', error = e)
-
-    return list()
-
-
-
+
def getContent(self)
@@ -1341,7 +1192,9 @@ class Block:

Outputs: - (str): the contents of the block

-Source code + +Expand source code +
def getContent(self):
     '''
         Returns the contents of the block
@@ -1350,10 +1203,10 @@ class Block:
         - (str): the contents of the block
     '''
 
-    return str(self.bcontent)
+ return self.bcontent
-
+
def getDate(self)
@@ -1361,7 +1214,9 @@ class Block:

Outputs: - (datetime): the date that the block was received

-Source code + +Expand source code +
def getDate(self):
     '''
         Returns the date that the block was received, if loaded from file
@@ -1373,7 +1228,7 @@ class Block:
     return self.date
-
+
def getExpire(self)
@@ -1381,7 +1236,9 @@ class Block:

Outputs: - (int): the expire time for a block, or None

-Source code + +Expand source code +
def getExpire(self):
     '''
         Returns the expire time for a block
@@ -1392,7 +1249,7 @@ class Block:
     return self.expire
-
+
def getHash(self)
@@ -1400,7 +1257,9 @@ class Block:

Outputs: - (str): the hash of the block, or None

-Source code + +Expand source code +
def getHash(self):
     '''
         Returns the hash of the block if saved to file
@@ -1412,7 +1271,7 @@ class Block:
     return self.hash
-
+
def getHeader(self, key=None, default=None)
@@ -1422,7 +1281,9 @@ class Block:

Outputs: - (dict/str): either the whole header as a dict, or one value

-Source code + +Expand source code +
def getHeader(self, key = None, default = None):
     '''
         Returns the header information
@@ -1441,7 +1302,7 @@ class Block:
     return self.bheader
-
+
def getMetadata(self, key=None, default=None)
@@ -1451,7 +1312,9 @@ class Block:

Outputs: - (dict/str): either the whole metadata as a dict, or one value

-Source code + +Expand source code +
def getMetadata(self, key = None, default = None):
     '''
         Returns the metadata information
@@ -1470,7 +1333,7 @@ class Block:
     return self.bmetadata
-
+
def getRaw(self)
@@ -1478,7 +1341,9 @@ class Block:

Outputs: - (bytes): the raw contents of the block, or None

-Source code + +Expand source code +
def getRaw(self):
     '''
         Returns the raw contents of the block, if saved to file
@@ -1490,7 +1355,7 @@ class Block:
     return self.raw
-
+
def getSignature(self)
@@ -1498,7 +1363,9 @@ class Block:

Outputs: - (str): the signature, or None

-Source code + +Expand source code +
def getSignature(self):
     '''
         Returns the base64-encoded signature
@@ -1510,7 +1377,7 @@ class Block:
     return self.signature
-
+
def getSignedData(self)
@@ -1518,7 +1385,9 @@ class Block:

Outputs: - (str): the data that was signed, or None

-Source code + +Expand source code +
def getSignedData(self):
     '''
         Returns the data that was signed
@@ -1530,7 +1399,7 @@ class Block:
     return self.signedData
-
+
def getType(self)
@@ -1538,7 +1407,9 @@ class Block:

Outputs: - (str): the type of the block

-Source code + +Expand source code +
def getType(self):
     '''
         Returns the type of the block
@@ -1549,7 +1420,7 @@ class Block:
     return self.btype
-
+
def isSigned(self)
@@ -1557,7 +1428,9 @@ class Block:

Outputs: - (bool): whether or not the block is signed

-Source code + +Expand source code +
def isSigned(self):
     '''
         Checks if the block was signed
@@ -1569,7 +1442,7 @@ class Block:
     return self.signed
-
+
def isSigner(self, signer, encodedData=True)
@@ -1580,7 +1453,9 @@ class Block:

Outputs: - (bool): whether or not the signer of the block is the signer inputted

-Source code + +Expand source code +
def isSigner(self, signer, encodedData = True):
     '''
         Checks if the block was signed by the signer inputted
@@ -1592,7 +1467,7 @@ class Block:
         Outputs:
         - (bool): whether or not the signer of the block is the signer inputted
     '''
-
+    signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
     try:
         if (not self.isSigned()) or (not stringvalidators.validate_pub_key(signer)):
             return False
@@ -1602,7 +1477,7 @@ class Block:
         return False
-
+
def isValid(self)
@@ -1610,7 +1485,9 @@ class Block:

Outputs: - (bool): whether or not the block is valid

-Source code + +Expand source code +
def isValid(self):
     '''
         Checks if the block is valid
@@ -1622,7 +1499,7 @@ class Block:
     return self.valid
-
+
def save(self, sign=False, recreate=True)
@@ -1633,7 +1510,9 @@ class Block:

Outputs: - (bool): whether or not the operation was successful

-Source code + +Expand source code +
def save(self, sign = False, recreate = True):
     '''
         Saves a block to file and imports it into Onionr
@@ -1662,7 +1541,7 @@ class Block:
     return False
-
+
def setContent(self, bcontent)
@@ -1672,7 +1551,9 @@ class Block:

Outputs: - (Block): the Block instance

-Source code + +Expand source code +
def setContent(self, bcontent):
     '''
         Sets the contents of the block
@@ -1688,7 +1569,7 @@ class Block:
     return self
-
+
def setMetadata(self, key, val)
@@ -1700,7 +1581,9 @@ class Block:

Outputs: - (Block): the Block instance

-Source code + +Expand source code +
def setMetadata(self, key, val):
     '''
         Sets a custom metadata value
@@ -1719,7 +1602,7 @@ class Block:
     return self
-
+
def setType(self, btype)
@@ -1729,7 +1612,9 @@ class Block:

Outputs: - (Block): the Block instance

-Source code + +Expand source code +
def setType(self, btype):
     '''
         Sets the type of the block
@@ -1745,7 +1630,7 @@ class Block:
     return self
-
+
def update(self, data=None, file=None)
@@ -1760,7 +1645,9 @@ class Block:

Outputs: - (bool): indicates whether or not the operation was successful

-Source code + +Expand source code +
def update(self, data = None, file = None):
     '''
         Loads data from a block in to the current object.
@@ -1803,7 +1690,7 @@ class Block:
         self.signer = self.getHeader('signer', None)
         self.signature = self.getHeader('sig', None)
         # signed data is jsonMeta + block content (no linebreak)
-        self.signedData = (None if not self.isSigned() else self.getHeader('meta') + self.getContent())
+        self.signedData = (None if not self.isSigned() else self.getHeader('meta').encode() + self.getContent())
         self.date = blockmetadb.get_block_date(self.getHash())
         self.claimedTime = self.getHeader('time', None)
 
@@ -1811,7 +1698,7 @@ class Block:
             self.date = datetime.datetime.fromtimestamp(self.getDate())
 
         self.valid = True
-        
+
         if self.autoDecrypt:
             self.decrypt()
 
@@ -1829,18 +1716,22 @@ class Block:
     return False
-
+
def verifySig(self)

Verify if a block's signature is signed by its claimed signer

-Source code + +Expand source code +
def verifySig(self):
     '''
         Verify if a block's signature is signed by its claimed signer
     '''
-    if self.signer is None or signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
+    if self.signer is None:
+        return False
+    if signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
         self.validSig = True
     else:
         self.validSig = False
@@ -1860,40 +1751,39 @@ class Block:
 
diff --git a/docs/html/onionr/onionrblocks/storagecounter.html b/docs/html/src/onionrblocks/storagecounter.html similarity index 80% rename from docs/html/onionr/onionrblocks/storagecounter.html rename to docs/html/src/onionrblocks/storagecounter.html index a54d9e3c..ad3a4d79 100644 --- a/docs/html/onionr/onionrblocks/storagecounter.html +++ b/docs/html/src/onionrblocks/storagecounter.html @@ -3,13 +3,13 @@ - -onionr.onionrblocks.storagecounter API documentation + +src.onionrblocks.storagecounter API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.onionrblocks.storagecounter

+

Module src.onionrblocks.storagecounter

Onionr - Private P2P Communication

Keeps track of how much disk space we're using

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
@@ -104,13 +106,15 @@ class StorageCounter:
 

Classes

-
+
class StorageCounter
-Source code + +Expand source code +
class StorageCounter:
     def __init__(self):
         self.data_file = filepaths.usage_file
@@ -162,13 +166,15 @@ class StorageCounter:
 

Methods

-
+
def add_bytes(self, amount)

Record that we are now using more disk space, unless doing so would exceed configured max

-Source code + +Expand source code +
def add_bytes(self, amount)->int:
     """Record that we are now using more disk space, unless doing so would exceed configured max"""
     new_amount = amount + self.get_amount()
@@ -180,13 +186,15 @@ class StorageCounter:
     return ret_data
-
+
def get_amount(self)

Return how much disk space we're using (according to record)

-Source code + +Expand source code +
def get_amount(self)->int:
     """Return how much disk space we're using (according to record)"""
     ret_data = 0
@@ -200,26 +208,30 @@ class StorageCounter:
     return ret_data
-
+
def get_percent(self)

Return percent (decimal/float) of disk space we're using

-Source code + +Expand source code +
def get_percent(self)->int:
     """Return percent (decimal/float) of disk space we're using"""
     amount = self.get_amount()
     return round(amount / config.get('allocations.disk', 2000000000), 2)
-
+
def is_full(self)

Returns if the allocated disk space is full (this is Onionr config, not true FS capacity)

-Source code + +Expand source code +
def is_full(self)->bool:
     """Returns if the allocated disk space is full (this is Onionr config, not true FS capacity)"""
     ret_data = False
@@ -228,13 +240,15 @@ class StorageCounter:
     return ret_data
-
+
def remove_bytes(self, amount)

Record that we are now using less disk space

-Source code + +Expand source code +
def remove_bytes(self, amount)->int:
     """Record that we are now using less disk space"""
     new_amount = self.get_amount() - amount
@@ -255,19 +269,19 @@ class StorageCounter:
 
diff --git a/docs/html/onionr/onionrcommands/banblocks.html b/docs/html/src/onionrcommands/banblocks.html similarity index 69% rename from docs/html/onionr/onionrcommands/banblocks.html rename to docs/html/src/onionrcommands/banblocks.html index 00407312..591daae8 100644 --- a/docs/html/onionr/onionrcommands/banblocks.html +++ b/docs/html/src/onionrcommands/banblocks.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.banblocks API documentation + +src.onionrcommands.banblocks API documentation - + @@ -17,19 +17,27 @@
-

Module onionr.onionrcommands.banblocks

+

Module src.onionrcommands.banblocks

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This file contains the command for banning blocks from the node

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file contains the command for banning blocks from the node
-'''
-'''
+This file contains the command for banning blocks from the node
+"""
+import sys
+import logger
+from onionrutils import stringvalidators
+from onionrstorage import removeblock
+from onionrstorage import deleteBlock
+from onionrblocks import onionrblacklist
+from utils import reconstructhash
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,26 +50,28 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sys
-import logger
-from onionrutils import stringvalidators
-from onionrstorage import removeblock
-from onionrblocks import onionrblacklist
+"""
+
 
 def ban_block():
+    """Delete a block, permanently blacklisting it."""
     blacklist = onionrblacklist.OnionrBlackList()
     try:
         ban = sys.argv[2]
     except IndexError:
-        ban = logger.readline('Enter a block hash:')
+        # Get the hash if its not provided as a CLI argument
+        ban = logger.readline('Enter a block hash:').strip()
+    # Make sure the hash has no truncated zeroes
+    ban = reconstructhash.reconstruct_hash(ban)
     if stringvalidators.validate_hash(ban):
         if not blacklist.inBlacklist(ban):
             try:
                 blacklist.addToDB(ban)
                 removeblock.remove_block(ban)
-            except Exception as error:
-                logger.error('Could not blacklist block', error=error, terminal=True)
+                deleteBlock(ban)
+            except Exception as error:  # pylint: disable=W0703
+                logger.error('Could not blacklist block',
+                             error=error, terminal=True)
             else:
                 logger.info('Block blacklisted', terminal=True)
         else:
@@ -69,7 +79,9 @@ def ban_block():
     else:
         logger.error('Invalid block hash', terminal=True)
 
-ban_block.onionr_help = "<block hash>: deletes and blacklists a block"
+ +ban_block.onionr_help = "<block hash>: " # type: ignore +ban_block.onionr_help += "deletes and blacklists a block" # type: ignore
@@ -79,26 +91,34 @@ ban_block.onionr_help = "<block hash>: deletes and blacklists a block&

Functions

-
+
def ban_block()
-
+

Delete a block, permanently blacklisting it.

-Source code + +Expand source code +
def ban_block():
+    """Delete a block, permanently blacklisting it."""
     blacklist = onionrblacklist.OnionrBlackList()
     try:
         ban = sys.argv[2]
     except IndexError:
-        ban = logger.readline('Enter a block hash:')
+        # Get the hash if its not provided as a CLI argument
+        ban = logger.readline('Enter a block hash:').strip()
+    # Make sure the hash has no truncated zeroes
+    ban = reconstructhash.reconstruct_hash(ban)
     if stringvalidators.validate_hash(ban):
         if not blacklist.inBlacklist(ban):
             try:
                 blacklist.addToDB(ban)
                 removeblock.remove_block(ban)
-            except Exception as error:
-                logger.error('Could not blacklist block', error=error, terminal=True)
+                deleteBlock(ban)
+            except Exception as error:  # pylint: disable=W0703
+                logger.error('Could not blacklist block',
+                             error=error, terminal=True)
             else:
                 logger.info('Block blacklisted', terminal=True)
         else:
@@ -120,19 +140,19 @@ ban_block.onionr_help = "<block hash>: deletes and blacklists a block&
 
 
 
diff --git a/docs/html/src/onionrcommands/daemonlaunch/getapihost.html b/docs/html/src/onionrcommands/daemonlaunch/getapihost.html new file mode 100644 index 00000000..86389e89 --- /dev/null +++ b/docs/html/src/onionrcommands/daemonlaunch/getapihost.html @@ -0,0 +1,133 @@ + + + + + + +src.onionrcommands.daemonlaunch.getapihost API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.daemonlaunch.getapihost

+
+
+

Onionr - Private P2P Communication.

+

Wait for the api host to be available in the public api host file. +returns string of ip for the local public host interface

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Wait for the api host to be available in the public api host file.
+returns string of ip for the local public host interface
+"""
+from time import sleep
+
+from filepaths import public_API_host_file
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def get_api_host_until_available() -> str:
+    """Wait for the api host to be available in the public api host file.
+
+    returns string of ip for the local public host interface
+    """
+    api_host = ''
+    while api_host == '':
+        try:
+            with open(public_API_host_file, 'r') as file:
+                api_host = file.read()
+        except FileNotFoundError:
+            pass
+        sleep(0.5)
+    return api_host
+
+
+
+
+
+
+
+

Functions

+
+
+def get_api_host_until_available() +
+
+

Wait for the api host to be available in the public api host file.

+

returns string of ip for the local public host interface

+
+ +Expand source code + +
def get_api_host_until_available() -> str:
+    """Wait for the api host to be available in the public api host file.
+
+    returns string of ip for the local public host interface
+    """
+    api_host = ''
+    while api_host == '':
+        try:
+            with open(public_API_host_file, 'r') as file:
+                api_host = file.read()
+        except FileNotFoundError:
+            pass
+        sleep(0.5)
+    return api_host
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/onionrcommands/daemonlaunch/index.html b/docs/html/src/onionrcommands/daemonlaunch/index.html new file mode 100644 index 00000000..5ed0a172 --- /dev/null +++ b/docs/html/src/onionrcommands/daemonlaunch/index.html @@ -0,0 +1,511 @@ + + + + + + +src.onionrcommands.daemonlaunch API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.daemonlaunch

+
+
+

Onionr - Private P2P Communication.

+

launch the api servers and communicator

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+launch the api servers and communicator
+"""
+import os
+import sys
+import platform
+import sqlite3
+from threading import Thread
+
+from gevent import time
+from gevent import spawn
+from stem.connection import IncorrectPassword
+import toomanyobjs
+import filenuke
+
+import config
+import onionrstatistics
+from onionrstatistics import serializeddata
+import apiservers
+import logger
+import communicator
+from onionrplugins import onionrevents as events
+from netcontroller import NetController
+from netcontroller import get_open_port
+from onionrutils import localcommand
+from utils import identifyhome
+import filepaths
+from etc import onionrvalues, cleanup
+from onionrcrypto import getourkeypair
+from utils import hastor, logoheader
+import runtests
+from httpapi import daemoneventsapi
+from .. import version
+from .getapihost import get_api_host_until_available
+from utils.bettersleep import better_sleep
+from netcontroller.torcontrol.onionservicecreator import create_onion_service
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def _proper_shutdown():
+    localcommand.local_command('shutdown')
+    sys.exit(1)
+
+
+def daemon():
+    """Start the Onionr communication daemon."""
+    offline_mode = config.get('general.offline_mode', False)
+
+    if not hastor.has_tor():
+        offline_mode = True
+        logger.error("Tor is not present in system path or Onionr directory",
+                     terminal=True)
+
+    # remove runcheck if it exists
+    if os.path.isfile(filepaths.run_check_file):
+        logger.debug('Runcheck file found on daemon start, deleting.')
+        os.remove(filepaths.run_check_file)
+
+    # Create shared objects
+
+    shared_state = toomanyobjs.TooMany()
+
+    shared_state.get(daemoneventsapi.DaemonEventsBP)
+
+    Thread(target=shared_state.get(apiservers.ClientAPI).start,
+           daemon=True, name='client HTTP API').start()
+    if not offline_mode:
+        Thread(target=shared_state.get(apiservers.PublicAPI).start,
+               daemon=True, name='public HTTP API').start()
+
+    # Init run time tester
+    # (ensures Onionr is running right, for testing purposes)
+
+    shared_state.get(runtests.OnionrRunTestManager)
+    shared_state.get(serializeddata.SerializedData)
+
+    shared_state.share_object()  # share the parent object to the threads
+
+    apiHost = ''
+    if not offline_mode:
+        apiHost = get_api_host_until_available()
+
+    logger.raw('', terminal=True)
+    # print nice header thing :)
+    if config.get('general.display_header', True):
+        logoheader.header()
+    version.version(verbosity=5, function=logger.info)
+    logger.debug('Python version %s' % platform.python_version())
+
+    if onionrvalues.DEVELOPMENT_MODE:
+        logger.warn('Development mode enabled', timestamp=False, terminal=True)
+
+    net = NetController(config.get('client.public.port', 59497),
+                        apiServerIP=apiHost)
+    shared_state.add(net)
+
+    shared_state.get(onionrstatistics.tor.TorStats)
+
+    security_level = config.get('general.security_level', 1)
+    use_existing_tor = config.get('tor.use_existing_tor', False)
+
+    if not offline_mode:
+
+        if use_existing_tor:
+            try:
+                os.mkdir(filepaths.tor_hs_loc)
+            except FileExistsError:
+                pass
+            net.socksPort = config.get('tor.existing_socks_port')
+            try:
+                net.myID = create_onion_service(
+                    port=net.apiServerIP + ':' + str(net.hsPort))[0]
+            except IncorrectPassword:
+                logger.error('Invalid Tor control password', terminal=True)
+                localcommand.local_command('shutdown')
+                cleanup.delete_run_files()
+                sys.exit(1)
+
+            if not net.myID.endswith('.onion'):
+                net.myID += '.onion'
+            with open(filepaths.tor_hs_address_file, 'w') as tor_file:
+                tor_file.write(net.myID)
+        else:
+            logger.info('Tor is starting...', terminal=True)
+            if not net.startTor():
+                localcommand.local_command('shutdown')
+                cleanup.delete_run_files()
+                sys.exit(1)
+        if len(net.myID) > 0 and security_level == 0:
+            logger.debug('Started .onion service: %s' %
+                         (logger.colors.underline + net.myID))
+        else:
+            logger.debug('.onion service disabled')
+
+    logger.info('Using public key: %s' %
+                (logger.colors.underline +
+                 getourkeypair.get_keypair()[0][:52]))
+
+    better_sleep(1)
+
+    events.event('init', threaded=False)
+    events.event('daemon_start')
+    communicator.startCommunicator(shared_state)
+
+    if not offline_mode and not use_existing_tor:
+        net.killTor()
+    else:
+        try:
+            os.remove(filepaths.tor_hs_address_file)
+        except FileNotFoundError:
+            pass
+
+    better_sleep(5)
+
+    cleanup.delete_run_files()
+    if config.get('general.security_level', 1) >= 2:
+        filenuke.nuke.clean_tree(identifyhome.identify_home())
+
+
+def _ignore_sigint(sig, frame):  # pylint: disable=W0612,W0613
+    """Space intentionally left blank."""
+    return
+
+
+def kill_daemon():
+    """Shutdown the Onionr daemon (communicator)."""
+    logger.warn('Stopping the running daemon...', timestamp=False,
+                terminal=True)
+
+    # On platforms where we can, fork out to prevent locking
+    try:
+        pid = os.fork()
+        if pid != 0:
+            return
+    except (AttributeError, OSError):
+        pass
+
+    events.event('daemon_stop')
+    net = NetController(config.get('client.port', 59496))
+    try:
+        spawn(
+            localcommand.local_command,
+            '/shutdownclean'
+            ).get(timeout=5)
+    except sqlite3.OperationalError:
+        pass
+
+    net.killTor()
+
+
+kill_daemon.onionr_help = "Gracefully stops the "  # type: ignore
+kill_daemon.onionr_help += "Onionr API servers"  # type: ignore
+
+
+def start(override: bool = False):
+    """If no lock file, make one and start onionr.
+
+    Error exit if there is and its not overridden
+    """
+    if os.path.exists(filepaths.lock_file) and not override:
+        logger.fatal('Cannot start. Daemon is already running,'
+                     + ' or it did not exit cleanly.\n'
+                     + ' (if you are sure that there is not a daemon running,'
+                     + ' delete onionr.lock & try again).', terminal=True)
+    else:
+        if not onionrvalues.DEVELOPMENT_MODE:
+            lock_file = open(filepaths.lock_file, 'w')
+            lock_file.write('delete at your own risk')
+            lock_file.close()
+
+        # Start Onionr daemon
+        daemon()
+
+        try:
+            os.remove(filepaths.lock_file)
+        except FileNotFoundError:
+            pass
+
+
+start.onionr_help = "Start Onionr node "  # type: ignore
+start.onionr_help += "(public and clients API servers)"  # type: ignore
+
+
+
+

Sub-modules

+
+
src.onionrcommands.daemonlaunch.getapihost
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+

Functions

+
+
+def daemon() +
+
+

Start the Onionr communication daemon.

+
+ +Expand source code + +
def daemon():
+    """Start the Onionr communication daemon."""
+    offline_mode = config.get('general.offline_mode', False)
+
+    if not hastor.has_tor():
+        offline_mode = True
+        logger.error("Tor is not present in system path or Onionr directory",
+                     terminal=True)
+
+    # remove runcheck if it exists
+    if os.path.isfile(filepaths.run_check_file):
+        logger.debug('Runcheck file found on daemon start, deleting.')
+        os.remove(filepaths.run_check_file)
+
+    # Create shared objects
+
+    shared_state = toomanyobjs.TooMany()
+
+    shared_state.get(daemoneventsapi.DaemonEventsBP)
+
+    Thread(target=shared_state.get(apiservers.ClientAPI).start,
+           daemon=True, name='client HTTP API').start()
+    if not offline_mode:
+        Thread(target=shared_state.get(apiservers.PublicAPI).start,
+               daemon=True, name='public HTTP API').start()
+
+    # Init run time tester
+    # (ensures Onionr is running right, for testing purposes)
+
+    shared_state.get(runtests.OnionrRunTestManager)
+    shared_state.get(serializeddata.SerializedData)
+
+    shared_state.share_object()  # share the parent object to the threads
+
+    apiHost = ''
+    if not offline_mode:
+        apiHost = get_api_host_until_available()
+
+    logger.raw('', terminal=True)
+    # print nice header thing :)
+    if config.get('general.display_header', True):
+        logoheader.header()
+    version.version(verbosity=5, function=logger.info)
+    logger.debug('Python version %s' % platform.python_version())
+
+    if onionrvalues.DEVELOPMENT_MODE:
+        logger.warn('Development mode enabled', timestamp=False, terminal=True)
+
+    net = NetController(config.get('client.public.port', 59497),
+                        apiServerIP=apiHost)
+    shared_state.add(net)
+
+    shared_state.get(onionrstatistics.tor.TorStats)
+
+    security_level = config.get('general.security_level', 1)
+    use_existing_tor = config.get('tor.use_existing_tor', False)
+
+    if not offline_mode:
+
+        if use_existing_tor:
+            try:
+                os.mkdir(filepaths.tor_hs_loc)
+            except FileExistsError:
+                pass
+            net.socksPort = config.get('tor.existing_socks_port')
+            try:
+                net.myID = create_onion_service(
+                    port=net.apiServerIP + ':' + str(net.hsPort))[0]
+            except IncorrectPassword:
+                logger.error('Invalid Tor control password', terminal=True)
+                localcommand.local_command('shutdown')
+                cleanup.delete_run_files()
+                sys.exit(1)
+
+            if not net.myID.endswith('.onion'):
+                net.myID += '.onion'
+            with open(filepaths.tor_hs_address_file, 'w') as tor_file:
+                tor_file.write(net.myID)
+        else:
+            logger.info('Tor is starting...', terminal=True)
+            if not net.startTor():
+                localcommand.local_command('shutdown')
+                cleanup.delete_run_files()
+                sys.exit(1)
+        if len(net.myID) > 0 and security_level == 0:
+            logger.debug('Started .onion service: %s' %
+                         (logger.colors.underline + net.myID))
+        else:
+            logger.debug('.onion service disabled')
+
+    logger.info('Using public key: %s' %
+                (logger.colors.underline +
+                 getourkeypair.get_keypair()[0][:52]))
+
+    better_sleep(1)
+
+    events.event('init', threaded=False)
+    events.event('daemon_start')
+    communicator.startCommunicator(shared_state)
+
+    if not offline_mode and not use_existing_tor:
+        net.killTor()
+    else:
+        try:
+            os.remove(filepaths.tor_hs_address_file)
+        except FileNotFoundError:
+            pass
+
+    better_sleep(5)
+
+    cleanup.delete_run_files()
+    if config.get('general.security_level', 1) >= 2:
+        filenuke.nuke.clean_tree(identifyhome.identify_home())
+
+
+
+def kill_daemon() +
+
+

Shutdown the Onionr daemon (communicator).

+
+ +Expand source code + +
def kill_daemon():
+    """Shutdown the Onionr daemon (communicator)."""
+    logger.warn('Stopping the running daemon...', timestamp=False,
+                terminal=True)
+
+    # On platforms where we can, fork out to prevent locking
+    try:
+        pid = os.fork()
+        if pid != 0:
+            return
+    except (AttributeError, OSError):
+        pass
+
+    events.event('daemon_stop')
+    net = NetController(config.get('client.port', 59496))
+    try:
+        spawn(
+            localcommand.local_command,
+            '/shutdownclean'
+            ).get(timeout=5)
+    except sqlite3.OperationalError:
+        pass
+
+    net.killTor()
+
+
+
+def start(override=False) +
+
+

If no lock file, make one and start onionr.

+

Error exit if there is and its not overridden

+
+ +Expand source code + +
def start(override: bool = False):
+    """If no lock file, make one and start onionr.
+
+    Error exit if there is and its not overridden
+    """
+    if os.path.exists(filepaths.lock_file) and not override:
+        logger.fatal('Cannot start. Daemon is already running,'
+                     + ' or it did not exit cleanly.\n'
+                     + ' (if you are sure that there is not a daemon running,'
+                     + ' delete onionr.lock & try again).', terminal=True)
+    else:
+        if not onionrvalues.DEVELOPMENT_MODE:
+            lock_file = open(filepaths.lock_file, 'w')
+            lock_file.write('delete at your own risk')
+            lock_file.close()
+
+        # Start Onionr daemon
+        daemon()
+
+        try:
+            os.remove(filepaths.lock_file)
+        except FileNotFoundError:
+            pass
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/exportblocks.html b/docs/html/src/onionrcommands/exportblocks.html similarity index 64% rename from docs/html/onionr/onionrcommands/exportblocks.html rename to docs/html/src/onionrcommands/exportblocks.html index 942c9c70..695fcfe7 100644 --- a/docs/html/onionr/onionrcommands/exportblocks.html +++ b/docs/html/src/onionrcommands/exportblocks.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.exportblocks API documentation + +src.onionrcommands.exportblocks API documentation - + @@ -17,19 +17,27 @@
-

Module onionr.onionrcommands.exportblocks

+

Module src.onionrcommands.exportblocks

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This file handles the command for exporting blocks to disk

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file handles the command for exporting blocks to disk
-'''
-'''
+This file handles the command for exporting blocks to disk
+"""
+import sys
+
+import logger
+import onionrstorage
+from utils import createdirs
+from onionrutils import stringvalidators
+import filepaths
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,31 +50,34 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sys, os
-import logger, onionrstorage
-from utils import createdirs
-from onionrutils import stringvalidators
-import filepaths
-def doExport(bHash):
+"""
+
+
+def _do_export(b_hash):
     createdirs.create_dirs()
-    data = onionrstorage.getData(bHash)
-    with open('%s/%s.dat' % (filepaths.export_location, bHash), 'wb') as exportFile:
-        exportFile.write(data)
+    data = onionrstorage.getData(b_hash)
+    with open('%s/%s.dat' % (filepaths.export_location,
+                             b_hash), 'wb') as export:
+        export.write(data)
         logger.info('Block exported as file', terminal=True)
 
+
 def export_block():
-    exportDir = filepaths.export_location
+    """Export block based on hash from stdin or argv."""
     try:
-        if not stringvalidators.validate_hash(sys.argv[2]): raise ValueError
+        if not stringvalidators.validate_hash(sys.argv[2]):
+            raise ValueError
     except (IndexError, ValueError):
         logger.error('No valid block hash specified.', terminal=True)
         sys.exit(1)
     else:
-        bHash = sys.argv[2]
-        doExport(bHash)
+        b_hash = sys.argv[2]
+        _do_export(b_hash)
 
-export_block.onionr_help = "<block hash>: Export an Onionr block to a file. Export directory is in the Onionr data directory under block-export/"
+ +export_block.onionr_help = "<block hash>: Export block to " # type: ignore +export_block.onionr_help += "a file. Export directory is in " # type: ignore +export_block.onionr_help += "Onionr home under block-export" # type: ignore
@@ -76,38 +87,26 @@ export_block.onionr_help = "<block hash>: Export an Onionr block to a

Functions

-
-def doExport(bHash) -
-
-
-
-Source code -
def doExport(bHash):
-    createdirs.create_dirs()
-    data = onionrstorage.getData(bHash)
-    with open('%s/%s.dat' % (filepaths.export_location, bHash), 'wb') as exportFile:
-        exportFile.write(data)
-        logger.info('Block exported as file', terminal=True)
-
-
-
+
def export_block()
-
+

Export block based on hash from stdin or argv.

-Source code + +Expand source code +
def export_block():
-    exportDir = filepaths.export_location
+    """Export block based on hash from stdin or argv."""
     try:
-        if not stringvalidators.validate_hash(sys.argv[2]): raise ValueError
+        if not stringvalidators.validate_hash(sys.argv[2]):
+            raise ValueError
     except (IndexError, ValueError):
         logger.error('No valid block hash specified.', terminal=True)
         sys.exit(1)
     else:
-        bHash = sys.argv[2]
-        doExport(bHash)
+ b_hash = sys.argv[2] + _do_export(b_hash)
@@ -123,20 +122,19 @@ export_block.onionr_help = "<block hash>: Export an Onionr block to a
diff --git a/docs/html/onionr/onionrcommands/filecommands.html b/docs/html/src/onionrcommands/filecommands.html similarity index 54% rename from docs/html/onionr/onionrcommands/filecommands.html rename to docs/html/src/onionrcommands/filecommands.html index 7c9c0a80..55035d1d 100644 --- a/docs/html/onionr/onionrcommands/filecommands.html +++ b/docs/html/src/onionrcommands/filecommands.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.filecommands API documentation + +src.onionrcommands.filecommands API documentation - + @@ -17,18 +17,29 @@
-

Module onionr.onionrcommands.filecommands

+

Module src.onionrcommands.filecommands

-

Onionr - Private P2P Communication

-

This file handles the commands for adding and getting files from the Onionr network

+

Onionr - Private P2P Communication.

+

This file handles the commands for adding +and getting files from the Onionr network

-Source code -
"""
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This file handles the commands for adding and getting files from the Onionr network
+This file handles the commands for adding
+and getting files from the Onionr network
 """
+import sys
+import os
+import logger
+from onionrblocks.onionrblockapi import Block
+import onionrexceptions
+from onionrutils import stringvalidators
+from etc import onionrvalues
+from onionrblocks import insert
 """
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -44,62 +55,67 @@
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
 
-import base64, sys, os
-import logger
-from onionrblocks.onionrblockapi import Block
-import onionrexceptions
-from onionrutils import stringvalidators
-from etc import onionrvalues
-from onionrblocks import insert
 _ORIG_DIR = onionrvalues.ORIG_RUN_DIR_ENV_VAR
 
-def _get_dir(path: str)->str: 
-    if not os.getenv(_ORIG_DIR) is None: return os.getenv(_ORIG_DIR) + '/' + path
-    else: return path
+
+def _get_dir(path: str) -> str:
+    if not os.getenv(_ORIG_DIR) is None:
+        return os.getenv(_ORIG_DIR) + '/' + path  # type: ignore
+    else:
+        return path
+
 
 def add_html(singleBlock=True, blockType='html'):
-    add_file(singleBlock, blockType)
+    """Create one-off web page from HTML file, no ext resources."""
+    add_file(blockType=blockType)
 
-add_html.onionr_help = "Adds an HTML file into Onionr. Does not currently include dependant resources"
 
-def add_file(singleBlock=False, blockType='bin'):
-    """
-        Adds a file to the onionr network
-    """
+add_html.onionr_help = "Adds an HTML file into Onionr. Does "   # type: ignore
+add_html.onionr_help += "not include dependant resources"  # type: ignore
 
+
+def add_file(blockType='bin'):
+    """Add a file to the onionr network."""
     if len(sys.argv) >= 3:
         filename = sys.argv[2]
-        contents = None
-        if not os.path.exists(_get_dir(filename)):
-            logger.error('That file does not exist. Improper path (specify full path)?', terminal=True)
-            return
-        logger.info('Adding file... this might take a long time.', terminal=True)
-        try:
-            with open(_get_dir(filename), 'rb') as singleFile:
-                blockhash = insert(base64.b64encode(singleFile.read()), header=blockType)
-            if len(blockhash) > 0:
-                logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True)
-        except Exception as e:
-            logger.error('Failed to save file in block ' + str(e), timestamp = False, terminal=True)
-    else:
-        logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True)
 
-add_file.onionr_help = "<file path> Add a file into the Onionr network"
+        if not os.path.exists(_get_dir(filename)):
+            logger.error(
+                'That file does not exist. Improper path (specify full path)?',
+                terminal=True)
+            return
+        logger.info('Adding file, this might take a long time.',
+                    terminal=True)
+        try:
+            with open(_get_dir(filename), 'rb') as single_file:
+                blockhash = insert(single_file.read(), header=blockType)
+            if len(blockhash) > 0:
+                logger.info('File %s saved in block %s' %
+                            (filename, blockhash), terminal=True)
+        except Exception as err:  # pylint: disable=W0703
+            logger.error('Failed to save file in block ' +
+                         str(err), timestamp=False, terminal=True)
+    else:
+        logger.error('%s add-file <filename>' %
+                     sys.argv[0], timestamp=False, terminal=True)
+
+
+add_file.onionr_help = "<file path> Add a file into "  # type: ignore
+add_file.onionr_help += "the Onionr network"  # type: ignore
+
 
 def get_file():
-    """
-        Get a file from onionr blocks
-    """
+    """Get a file from onionr blocks."""
     try:
-        fileName = _get_dir(sys.argv[2])
+        file_name = _get_dir(sys.argv[2])
         bHash = sys.argv[3]
     except IndexError:
-        logger.error("Syntax %s %s" % (sys.argv[0], '/path/to/filename <blockhash>'), terminal=True)
+        logger.error("Syntax %s %s" % (
+            sys.argv[0], '/path/to/filename <blockhash>'), terminal=True)
     else:
-        logger.info(fileName, terminal=True)
+        logger.info(file_name, terminal=True)
 
-        contents = None
-        if os.path.exists(fileName):
+        if os.path.exists(file_name):
             logger.error("File already exists", terminal=True)
             return
         if not stringvalidators.validate_hash(bHash):
@@ -107,12 +123,16 @@ def get_file():
             return
 
         try:
-            with open(fileName, 'wb') as myFile:
-                myFile.write(base64.b64decode(Block(bHash).bcontent))
+            with open(file_name, 'wb') as my_file:
+                my_file.write(Block(bHash).bcontent)
         except onionrexceptions.NoDataAvailable:
-            logger.error('That block is not available. Trying again later may work.', terminal=True)
+            logger.error(
+                'That block is not available. Trying again later may work.',
+                terminal=True)
 
-get_file.onionr_help = "<file path> <block hash>: Download a file from the onionr network."
+ +get_file.onionr_help = "<file path> <block hash>: Download " # type: ignore +get_file.onionr_help += "a file from the onionr network." # type: ignore
@@ -122,68 +142,76 @@ get_file.onionr_help = "<file path> <block hash>: Download a fil

Functions

-
-def add_file(singleBlock=False, blockType='bin') +
+def add_file(blockType='bin')
-

Adds a file to the onionr network

+

Add a file to the onionr network.

-Source code -
def add_file(singleBlock=False, blockType='bin'):
-    """
-        Adds a file to the onionr network
-    """
-
+
+Expand source code
+
+
def add_file(blockType='bin'):
+    """Add a file to the onionr network."""
     if len(sys.argv) >= 3:
         filename = sys.argv[2]
-        contents = None
+
         if not os.path.exists(_get_dir(filename)):
-            logger.error('That file does not exist. Improper path (specify full path)?', terminal=True)
+            logger.error(
+                'That file does not exist. Improper path (specify full path)?',
+                terminal=True)
             return
-        logger.info('Adding file... this might take a long time.', terminal=True)
+        logger.info('Adding file, this might take a long time.',
+                    terminal=True)
         try:
-            with open(_get_dir(filename), 'rb') as singleFile:
-                blockhash = insert(base64.b64encode(singleFile.read()), header=blockType)
+            with open(_get_dir(filename), 'rb') as single_file:
+                blockhash = insert(single_file.read(), header=blockType)
             if len(blockhash) > 0:
-                logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True)
-        except Exception as e:
-            logger.error('Failed to save file in block ' + str(e), timestamp = False, terminal=True)
+                logger.info('File %s saved in block %s' %
+                            (filename, blockhash), terminal=True)
+        except Exception as err:  # pylint: disable=W0703
+            logger.error('Failed to save file in block ' +
+                         str(err), timestamp=False, terminal=True)
     else:
-        logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True)
+ logger.error('%s add-file <filename>' % + sys.argv[0], timestamp=False, terminal=True)
-
+
def add_html(singleBlock=True, blockType='html')
-
+

Create one-off web page from HTML file, no ext resources.

-Source code + +Expand source code +
def add_html(singleBlock=True, blockType='html'):
-    add_file(singleBlock, blockType)
+ """Create one-off web page from HTML file, no ext resources.""" + add_file(blockType=blockType)
-
+
def get_file()
-

Get a file from onionr blocks

+

Get a file from onionr blocks.

-Source code + +Expand source code +
def get_file():
-    """
-        Get a file from onionr blocks
-    """
+    """Get a file from onionr blocks."""
     try:
-        fileName = _get_dir(sys.argv[2])
+        file_name = _get_dir(sys.argv[2])
         bHash = sys.argv[3]
     except IndexError:
-        logger.error("Syntax %s %s" % (sys.argv[0], '/path/to/filename <blockhash>'), terminal=True)
+        logger.error("Syntax %s %s" % (
+            sys.argv[0], '/path/to/filename <blockhash>'), terminal=True)
     else:
-        logger.info(fileName, terminal=True)
+        logger.info(file_name, terminal=True)
 
-        contents = None
-        if os.path.exists(fileName):
+        if os.path.exists(file_name):
             logger.error("File already exists", terminal=True)
             return
         if not stringvalidators.validate_hash(bHash):
@@ -191,10 +219,12 @@ get_file.onionr_help = "<file path> <block hash>: Download a fil
             return
 
         try:
-            with open(fileName, 'wb') as myFile:
-                myFile.write(base64.b64decode(Block(bHash).bcontent))
+            with open(file_name, 'wb') as my_file:
+                my_file.write(Block(bHash).bcontent)
         except onionrexceptions.NoDataAvailable:
-            logger.error('That block is not available. Trying again later may work.', terminal=True)
+ logger.error( + 'That block is not available. Trying again later may work.', + terminal=True)
@@ -210,21 +240,21 @@ get_file.onionr_help = "<file path> <block hash>: Download a fil
diff --git a/docs/html/src/onionrcommands/index.html b/docs/html/src/onionrcommands/index.html new file mode 100644 index 00000000..def3bc2e --- /dev/null +++ b/docs/html/src/onionrcommands/index.html @@ -0,0 +1,150 @@ + + + + + + +src.onionrcommands API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands

+
+
+
+
+

Sub-modules

+
+
src.onionrcommands.banblocks
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.daemonlaunch
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.exportblocks
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.filecommands
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.keyadders
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.motdcreator
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.onionrstatistics
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.openwebinterface
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.parser
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.pubkeymanager
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.resetplugins
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.resettor
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.restartonionr
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.runtimetestcmd
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.sitecreator
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.softreset
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.togglebootstrap
+
+

Onionr - Private P2P Communication …

+
+
src.onionrcommands.version
+
+

Onionr - Private P2P Communication …

+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/keyadders.html b/docs/html/src/onionrcommands/keyadders.html similarity index 73% rename from docs/html/onionr/onionrcommands/keyadders.html rename to docs/html/src/onionrcommands/keyadders.html index dbb26ee1..55eddaac 100644 --- a/docs/html/onionr/onionrcommands/keyadders.html +++ b/docs/html/src/onionrcommands/keyadders.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.keyadders API documentation + +src.onionrcommands.keyadders API documentation - + @@ -17,19 +17,23 @@
-

Module onionr.onionrcommands.keyadders

+

Module src.onionrcommands.keyadders

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

add keys (transport and pubkey)

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    add keys (transport and pubkey)
-'''
-'''
+add keys (transport and pubkey)
+"""
+import sys
+import logger
+from coredb import keydb
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,25 +46,26 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sys
-import logger
-from coredb import keydb
+"""
+
 
 def add_address():
+    """Command to add a peer address from either an arg or stdin."""
     try:
         newAddress = sys.argv[2]
         newAddress = newAddress.replace('http:', '').replace('/', '')
     except IndexError:
         pass
     else:
-        logger.info("Adding address: " + logger.colors.underline + newAddress, terminal=True)
+        logger.info("Adding address: " + logger.colors.underline + newAddress,
+                    terminal=True)
         if keydb.addkeys.add_address(newAddress):
             logger.info("Successfully added address.", terminal=True)
         else:
             logger.warn("Unable to add address.", terminal=True)
 
-add_address.onionr_help = "Adds a node transport address to the local node list"
+ +add_address.onionr_help = "Adds a node transport address" # type: ignore
@@ -70,21 +75,25 @@ add_address.onionr_help = "Adds a node transport address to the local node l

Functions

-
+
def add_address()
-
+

Command to add a peer address from either an arg or stdin.

-Source code + +Expand source code +
def add_address():
+    """Command to add a peer address from either an arg or stdin."""
     try:
         newAddress = sys.argv[2]
         newAddress = newAddress.replace('http:', '').replace('/', '')
     except IndexError:
         pass
     else:
-        logger.info("Adding address: " + logger.colors.underline + newAddress, terminal=True)
+        logger.info("Adding address: " + logger.colors.underline + newAddress,
+                    terminal=True)
         if keydb.addkeys.add_address(newAddress):
             logger.info("Successfully added address.", terminal=True)
         else:
@@ -104,19 +113,19 @@ add_address.onionr_help = "Adds a node transport address to the local node l
 
 
 
diff --git a/docs/html/src/onionrcommands/motdcreator.html b/docs/html/src/onionrcommands/motdcreator.html new file mode 100644 index 00000000..e47427a9 --- /dev/null +++ b/docs/html/src/onionrcommands/motdcreator.html @@ -0,0 +1,127 @@ + + + + + + +src.onionrcommands.motdcreator API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.motdcreator

+
+
+

Onionr - Private P2P Communication.

+

Command to make new network-wide MOTD message. Only network admin can do this +The key is set in onionrvalues

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Command to make new network-wide MOTD message. Only network admin can do this
+The key is set in onionrvalues
+"""
+import onionrblocks
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def motd_creator():
+    """Create a new MOTD message for the Onionr network."""
+    motd = ''
+    new = ''
+    print('Enter a new MOTD, quit on a new line:')
+    while new != 'quit':
+        new = input()  # nosec B323
+        if new != 'quit':
+            motd += new
+    bl = onionrblocks.insert(motd, header='motd', sign=True)
+    print(f"inserted in {bl}")
+
+
+motd_creator.onionr_help = "Create a new MOTD for the network"  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def motd_creator() +
+
+

Create a new MOTD message for the Onionr network.

+
+ +Expand source code + +
def motd_creator():
+    """Create a new MOTD message for the Onionr network."""
+    motd = ''
+    new = ''
+    print('Enter a new MOTD, quit on a new line:')
+    while new != 'quit':
+        new = input()  # nosec B323
+        if new != 'quit':
+            motd += new
+    bl = onionrblocks.insert(motd, header='motd', sign=True)
+    print(f"inserted in {bl}")
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/onionrcommands/onionrstatistics.html b/docs/html/src/onionrcommands/onionrstatistics.html new file mode 100644 index 00000000..121c5573 --- /dev/null +++ b/docs/html/src/onionrcommands/onionrstatistics.html @@ -0,0 +1,367 @@ + + + + + + +src.onionrcommands.onionrstatistics API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.onionrstatistics

+
+
+

Onionr - Private P2P Communication.

+

This module defines commands to show stats/details about the local node

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+This module defines commands to show stats/details about the local node
+"""
+import os
+import logger
+from onionrblocks import onionrblockapi
+from onionrblocks import onionrblacklist
+from onionrutils import checkcommunicator, mnemonickeys
+from utils import sizeutils, gethostname, getconsolewidth, identifyhome
+from coredb import blockmetadb, keydb
+import onionrcrypto
+import config
+from etc import onionrvalues
+
+check_communicator = checkcommunicator.is_communicator_running
+
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def show_stats():
+    """Print/log statistic info about our Onionr install."""
+    try:
+        # define stats messages here
+        totalBlocks = len(blockmetadb.get_block_list())
+        home = identifyhome.identify_home()
+        totalBanned = len(onionrblacklist.OnionrBlackList().getList())
+
+        messages = {
+            # info about local client
+            'Onionr Daemon Status':
+            ((logger.colors.fg.green + 'Online')
+             if check_communicator(timeout=9)
+             else logger.colors.fg.red + 'Offline'),
+
+            # file and folder size stats
+            'div1': True,  # this creates a solid line across the screen, a div
+            'Total Block Size':
+            sizeutils.human_size(sizeutils.size(home + 'blocks/')),
+            'Total Plugin Size':
+            sizeutils.human_size(sizeutils.size(home + 'plugins/')),
+            'Log File Size':
+            sizeutils.human_size(sizeutils.size(home + 'output.log')),
+
+            # count stats
+            'div2': True,
+            'Known Peers (nodes)':
+            str(max(len(keydb.listkeys.list_adders()) - 1, 0)),
+            'Enabled Plugins':
+            str(len(config.get('plugins.enabled', list()))) + ' / ' +
+            str(len(os.listdir(home + 'plugins/'))),
+            'Stored Blocks': str(totalBlocks),
+            'Deleted Blocks': str(totalBanned)
+        }
+
+        # color configuration
+        colors = {
+            'title': logger.colors.bold,
+            'key': logger.colors.fg.lightgreen,
+            'val': logger.colors.fg.green,
+            'border': logger.colors.fg.lightblue,
+
+            'reset': logger.colors.reset
+        }
+
+        # pre-processing
+        maxlength = 0
+        width = getconsolewidth.get_console_width()
+        for key, val in messages.items():
+            if not (type(val) is bool and val is True):
+                maxlength = max(len(key), maxlength)
+        prewidth = maxlength + len(' | ')
+        groupsize = width - prewidth - len('[+] ')
+
+        # generate stats table
+        logger.info(colors['title'] + 'Onionr v%s Statistics' %
+                    onionrvalues.ONIONR_VERSION + colors['reset'],
+                    terminal=True)
+        logger.info(colors['border'] + '-' * (maxlength + 1) +
+                    '+' + colors['reset'], terminal=True)
+        for key, val in messages.items():
+            if not (type(val) is bool and val is True):
+                val = [str(val)[i:i + groupsize]
+                       for i in range(0, len(str(val)), groupsize)]
+
+                logger.info(colors['key'] + str(key).rjust(maxlength) +
+                            colors['reset'] + colors['border'] +
+                            ' | ' + colors['reset'] + colors['val'] +
+                            str(val.pop(0)) + colors['reset'], terminal=True)
+
+                for value in val:
+                    logger.info(' ' * maxlength + colors['border'] + ' | ' +
+                                colors['reset'] + colors['val'] + str(
+                        value) + colors['reset'], terminal=True)
+            else:
+                logger.info(colors['border'] + '-' * (maxlength +
+                                                      1) + '+' +
+                            colors['reset'], terminal=True)
+        logger.info(colors['border'] + '-' * (maxlength + 1) +
+                    '+' + colors['reset'], terminal=True)
+    except Exception as e:  # pylint: disable=W0703
+        logger.error('Failed to generate statistics table. ' +
+                     str(e), error=e, timestamp=False, terminal=True)
+
+
+def show_details():
+    """Print out details.
+
+    node transport address(es)
+    active user ID
+        active user ID in mnemonic form
+    """
+    details = {
+        'Node Address': gethostname.get_hostname(),
+        'Public Key': onionrcrypto.pub_key.replace('=', ''),
+        'Human-readable Public Key': mnemonickeys.get_human_readable_ID()
+    }
+
+    for detail in details:
+        logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen,
+                                        detail, logger.colors.fg.green,
+                                        details[detail]), terminal=True)
+
+
+show_details.onionr_help = "Shows relevant information "  # type: ignore
+show_details.onionr_help += "for your Onionr install: node "  # type: ignore
+show_details.onionr_help += "address, and active public key."  # type: ignore
+
+show_stats.onionr_help = "Shows statistics for your Onionr "  # type: ignore
+show_stats.onionr_help += "node. Slow if Onionr is not running"  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def check_communicator(timeout=5, interval=0.1) +
+
+
+
+ +Expand source code + +
def is_communicator_running(timeout = 5, interval = 0.1):
+    try:
+        runcheck_file = filepaths.run_check_file
+
+        if not os.path.isfile(runcheck_file):
+            open(runcheck_file, 'w+').close()
+
+        starttime = time.time()
+
+        while True:
+            time.sleep(interval)
+
+            if not os.path.isfile(runcheck_file):
+                return True
+            elif time.time() - starttime >= timeout:
+                return False
+    except:
+        return False
+
+
+
+def show_details() +
+
+

Print out details.

+

node transport address(es) +active user ID +active user ID in mnemonic form

+
+ +Expand source code + +
def show_details():
+    """Print out details.
+
+    node transport address(es)
+    active user ID
+        active user ID in mnemonic form
+    """
+    details = {
+        'Node Address': gethostname.get_hostname(),
+        'Public Key': onionrcrypto.pub_key.replace('=', ''),
+        'Human-readable Public Key': mnemonickeys.get_human_readable_ID()
+    }
+
+    for detail in details:
+        logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen,
+                                        detail, logger.colors.fg.green,
+                                        details[detail]), terminal=True)
+
+
+
+def show_stats() +
+
+

Print/log statistic info about our Onionr install.

+
+ +Expand source code + +
def show_stats():
+    """Print/log statistic info about our Onionr install."""
+    try:
+        # define stats messages here
+        totalBlocks = len(blockmetadb.get_block_list())
+        home = identifyhome.identify_home()
+        totalBanned = len(onionrblacklist.OnionrBlackList().getList())
+
+        messages = {
+            # info about local client
+            'Onionr Daemon Status':
+            ((logger.colors.fg.green + 'Online')
+             if check_communicator(timeout=9)
+             else logger.colors.fg.red + 'Offline'),
+
+            # file and folder size stats
+            'div1': True,  # this creates a solid line across the screen, a div
+            'Total Block Size':
+            sizeutils.human_size(sizeutils.size(home + 'blocks/')),
+            'Total Plugin Size':
+            sizeutils.human_size(sizeutils.size(home + 'plugins/')),
+            'Log File Size':
+            sizeutils.human_size(sizeutils.size(home + 'output.log')),
+
+            # count stats
+            'div2': True,
+            'Known Peers (nodes)':
+            str(max(len(keydb.listkeys.list_adders()) - 1, 0)),
+            'Enabled Plugins':
+            str(len(config.get('plugins.enabled', list()))) + ' / ' +
+            str(len(os.listdir(home + 'plugins/'))),
+            'Stored Blocks': str(totalBlocks),
+            'Deleted Blocks': str(totalBanned)
+        }
+
+        # color configuration
+        colors = {
+            'title': logger.colors.bold,
+            'key': logger.colors.fg.lightgreen,
+            'val': logger.colors.fg.green,
+            'border': logger.colors.fg.lightblue,
+
+            'reset': logger.colors.reset
+        }
+
+        # pre-processing
+        maxlength = 0
+        width = getconsolewidth.get_console_width()
+        for key, val in messages.items():
+            if not (type(val) is bool and val is True):
+                maxlength = max(len(key), maxlength)
+        prewidth = maxlength + len(' | ')
+        groupsize = width - prewidth - len('[+] ')
+
+        # generate stats table
+        logger.info(colors['title'] + 'Onionr v%s Statistics' %
+                    onionrvalues.ONIONR_VERSION + colors['reset'],
+                    terminal=True)
+        logger.info(colors['border'] + '-' * (maxlength + 1) +
+                    '+' + colors['reset'], terminal=True)
+        for key, val in messages.items():
+            if not (type(val) is bool and val is True):
+                val = [str(val)[i:i + groupsize]
+                       for i in range(0, len(str(val)), groupsize)]
+
+                logger.info(colors['key'] + str(key).rjust(maxlength) +
+                            colors['reset'] + colors['border'] +
+                            ' | ' + colors['reset'] + colors['val'] +
+                            str(val.pop(0)) + colors['reset'], terminal=True)
+
+                for value in val:
+                    logger.info(' ' * maxlength + colors['border'] + ' | ' +
+                                colors['reset'] + colors['val'] + str(
+                        value) + colors['reset'], terminal=True)
+            else:
+                logger.info(colors['border'] + '-' * (maxlength +
+                                                      1) + '+' +
+                            colors['reset'], terminal=True)
+        logger.info(colors['border'] + '-' * (maxlength + 1) +
+                    '+' + colors['reset'], terminal=True)
+    except Exception as e:  # pylint: disable=W0703
+        logger.error('Failed to generate statistics table. ' +
+                     str(e), error=e, timestamp=False, terminal=True)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/onionrcommands/openwebinterface.html b/docs/html/src/onionrcommands/openwebinterface.html new file mode 100644 index 00000000..5a533c70 --- /dev/null +++ b/docs/html/src/onionrcommands/openwebinterface.html @@ -0,0 +1,179 @@ + + + + + + +src.onionrcommands.openwebinterface API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.openwebinterface

+
+
+

Onionr - Private P2P Communication.

+

Open the web interface properly into a web browser

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Open the web interface properly into a web browser
+"""
+import webbrowser
+import logger
+from onionrutils import getclientapiserver
+import config
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def get_url() -> str:
+    """Build UI URL string and return it."""
+    try:
+        url = getclientapiserver.get_client_API_server()
+    except FileNotFoundError:
+        url = ""
+        logger.error(
+            'Onionr seems to not be running (could not get api host)',
+            terminal=True)
+    else:
+        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
+        logger.info('Onionr web interface URL: ' + url, terminal=True)
+    return url
+
+
+get_url.onionr_help = "Shows the Onionr "  # type: ignore
+get_url.onionr_help += "web interface URL with API key"  # type: ignore
+
+
+def open_home():
+    """Command to open web interface URL in default browser."""
+    try:
+        url = getclientapiserver.get_client_API_server()
+    except FileNotFoundError:
+        logger.error(
+            'Onionr seems to not be running (could not get api host)',
+            terminal=True)
+    else:
+        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
+        logger.info(
+            'If Onionr does not open automatically, use this URL: ' + url,
+            terminal=True)
+        webbrowser.open_new_tab(url)
+
+
+open_home.onionr_help = "Opens the Onionr UI in the default "  # type: ignore
+open_home.onionr_help += "browser. Node must be running."  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def get_url() +
+
+

Build UI URL string and return it.

+
+ +Expand source code + +
def get_url() -> str:
+    """Build UI URL string and return it."""
+    try:
+        url = getclientapiserver.get_client_API_server()
+    except FileNotFoundError:
+        url = ""
+        logger.error(
+            'Onionr seems to not be running (could not get api host)',
+            terminal=True)
+    else:
+        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
+        logger.info('Onionr web interface URL: ' + url, terminal=True)
+    return url
+
+
+
+def open_home() +
+
+

Command to open web interface URL in default browser.

+
+ +Expand source code + +
def open_home():
+    """Command to open web interface URL in default browser."""
+    try:
+        url = getclientapiserver.get_client_API_server()
+    except FileNotFoundError:
+        logger.error(
+            'Onionr seems to not be running (could not get api host)',
+            terminal=True)
+    else:
+        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
+        logger.info(
+            'If Onionr does not open automatically, use this URL: ' + url,
+            terminal=True)
+        webbrowser.open_new_tab(url)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/parser/arguments.html b/docs/html/src/onionrcommands/parser/arguments.html similarity index 56% rename from docs/html/onionr/onionrcommands/parser/arguments.html rename to docs/html/src/onionrcommands/parser/arguments.html index 9c13282f..31f3824a 100644 --- a/docs/html/onionr/onionrcommands/parser/arguments.html +++ b/docs/html/src/onionrcommands/parser/arguments.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.parser.arguments API documentation + +src.onionrcommands.parser.arguments API documentation - + @@ -17,19 +17,39 @@
-

Module onionr.onionrcommands.parser.arguments

+

Module src.onionrcommands.parser.arguments

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Sets CLI arguments for Onionr

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Sets CLI arguments for Onionr
-'''
-'''
+Sets CLI arguments for Onionr
+"""
+from typing import Callable
+
+from .. import onionrstatistics, version, daemonlaunch, keyadders
+from .. import openwebinterface
+from .. import banblocks  # Command to blacklist a block by its hash
+from .. import filecommands  # commands to share files with onionr
+from .. import exportblocks  # commands to export blocks
+from .. import pubkeymanager  # commands to add or change id
+from .. import resettor  # cmds to reset the tor data folder/transport keypair
+from .. import resetplugins  # command to reinstall default plugins
+from .. import softreset  # command to delete onionr blocks
+from .. import restartonionr  # command to restart Onionr
+from .. import runtimetestcmd  # cmd to execute the runtime integration tests
+from .. import motdcreator  # cmd to generate new Onionr MOTDs
+from .. import sitecreator  # cmd to create multi-page sites
+from .. import togglebootstrap   # cmd to toggle bootstrap file usage
+
+import onionrexceptions
+from onionrutils import importnewblocks  # func to import new blocks
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,25 +62,18 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-from typing import Callable
-from .. import onionrstatistics, version, daemonlaunch, keyadders, openwebinterface
-from .. import banblocks # Command to blacklist a block by its hash
-from .. import filecommands # commands to share files with onionr
-from .. import exportblocks # commands to export blocks
-from .. import pubkeymanager # commands to add or change id
-from .. import resettor # commands to reset the tor data directory or transport keypair
-from .. import resetplugins # command to reinstall default plugins
-from .. import softreset # command to delete onionr blocks
-from .. import restartonionr # command to restart Onionr
-import onionrexceptions
-from onionrutils import importnewblocks # func to import new blocks
-from onionrplugins import onionrevents as events
+"""
 
-def get_arguments()->dict:
-    """This is a function because we need to be able to dynamically modify them with plugins"""
+
+def get_arguments() -> dict:
+    """Return command argument dict, minus plugin cmds.
+
+    This is a function because we need to be able to
+    dynamically modify them with plugins
+    """
     args = {
-        ('blacklist', 'blacklist-block', 'remove-block', 'removeblock', 'banblock', 'ban-block'): banblocks.ban_block,
+        ('blacklist', 'blacklist-block', 'remove-block',
+         'removeblock', 'banblock', 'ban-block'): banblocks.ban_block,
         ('details', 'info'): onionrstatistics.show_details,
         ('stats', 'statistics'): onionrstatistics.show_stats,
         ('version',): version.version,
@@ -68,39 +81,55 @@ def get_arguments()->dict:
         ('stop', 'kill'): daemonlaunch.kill_daemon,
         ('restart',): restartonionr.restart,
         ('add-address', 'addaddress', 'addadder'): keyadders.add_address,
-        ('openhome', 'gui', 'openweb', 'open-home', 'open-web'): openwebinterface.open_home,
-        ('add-site', 'addsite', 'addhtml', 'add-html'): filecommands.add_html,
+        ('openhome', 'gui', 'openweb',
+         'open-home', 'open-web'): openwebinterface.open_home,
+        ('get-url', 'url', 'get-web'): openwebinterface.get_url,
+        ('addhtml', 'add-html'): filecommands.add_html,
+        ('addsite', 'add-site',
+         'update-site', 'updatesite'): sitecreator.create_multipage_site,
         ('addfile', 'add-file'): filecommands.add_file,
         ('get-file', 'getfile'): filecommands.get_file,
         ('export-block', 'exportblock'): exportblocks.export_block,
-        ('importblocks', 'import-blocks', 'import-block'): importnewblocks.import_new_blocks,
+        ('importblocks',
+         'import-blocks', 'import-block'): importnewblocks.import_new_blocks,
         ('addid', 'add-id'): pubkeymanager.add_ID,
         ('changeid', 'change-id'): pubkeymanager.change_ID,
         ('add-vanity', 'addvanity'): pubkeymanager.add_vanity,
         ('resettor', 'reset-tor'): resettor.reset_tor,
         ('resetplugins', 'reset-plugins'): resetplugins.reset,
         ('reset-tor-node-transport',): resettor.reset_tor_key_pair,
-        ('soft-reset', 'softreset'): softreset.soft_reset
+        ('soft-reset', 'softreset'): softreset.soft_reset,
+        ('toggle-bootstrap', 'togglebootstrap'):
+        togglebootstrap.toggle_bootstrap_config,
+        ('runtime-test', 'runtimetest'): runtimetestcmd.do_runtime_test,
+        ('makemotd', 'make-motd'): motdcreator.motd_creator
 
     }
     return args
 
+
 def get_help(arg: str) -> str:
-    """Returns the help info string from a given command"""
+    """Return the help info string from a given command."""
     arguments = get_arguments()
     # Iterate the command alias tuples
     for argument in arguments:
         # Return the help message if its found in a command alias tuple
-        if arg in argument: return arguments[argument].onionr_help
+        if arg in argument:
+            return arguments[argument].onionr_help
     raise KeyError
 
+
 def get_func(argument: str) -> Callable:
-    """Returns the function for a given command argument"""
+    """Return the function for a given command argument."""
     argument = argument.lower()
     args = get_arguments()
 
-    for arg in args.keys(): # Iterate command alias sets
-        if argument in arg: # If our argument is in the current alias set, return the command function
+    for arg in args.keys():  # Iterate command alias sets
+        """
+        If our argument is in the current alias set,
+        return the command function
+        """
+        if argument in arg:
             return args[arg]
     raise onionrexceptions.NotFound
@@ -112,17 +141,26 @@ def get_func(argument: str) -> Callable:

Functions

-
+
def get_arguments()
-

This is a function because we need to be able to dynamically modify them with plugins

+

Return command argument dict, minus plugin cmds.

+

This is a function because we need to be able to +dynamically modify them with plugins

-Source code -
def get_arguments()->dict:
-    """This is a function because we need to be able to dynamically modify them with plugins"""
+
+Expand source code
+
+
def get_arguments() -> dict:
+    """Return command argument dict, minus plugin cmds.
+
+    This is a function because we need to be able to
+    dynamically modify them with plugins
+    """
     args = {
-        ('blacklist', 'blacklist-block', 'remove-block', 'removeblock', 'banblock', 'ban-block'): banblocks.ban_block,
+        ('blacklist', 'blacklist-block', 'remove-block',
+         'removeblock', 'banblock', 'ban-block'): banblocks.ban_block,
         ('details', 'info'): onionrstatistics.show_details,
         ('stats', 'statistics'): onionrstatistics.show_stats,
         ('version',): version.version,
@@ -130,56 +168,74 @@ def get_func(argument: str) -> Callable:
         ('stop', 'kill'): daemonlaunch.kill_daemon,
         ('restart',): restartonionr.restart,
         ('add-address', 'addaddress', 'addadder'): keyadders.add_address,
-        ('openhome', 'gui', 'openweb', 'open-home', 'open-web'): openwebinterface.open_home,
-        ('add-site', 'addsite', 'addhtml', 'add-html'): filecommands.add_html,
+        ('openhome', 'gui', 'openweb',
+         'open-home', 'open-web'): openwebinterface.open_home,
+        ('get-url', 'url', 'get-web'): openwebinterface.get_url,
+        ('addhtml', 'add-html'): filecommands.add_html,
+        ('addsite', 'add-site',
+         'update-site', 'updatesite'): sitecreator.create_multipage_site,
         ('addfile', 'add-file'): filecommands.add_file,
         ('get-file', 'getfile'): filecommands.get_file,
         ('export-block', 'exportblock'): exportblocks.export_block,
-        ('importblocks', 'import-blocks', 'import-block'): importnewblocks.import_new_blocks,
+        ('importblocks',
+         'import-blocks', 'import-block'): importnewblocks.import_new_blocks,
         ('addid', 'add-id'): pubkeymanager.add_ID,
         ('changeid', 'change-id'): pubkeymanager.change_ID,
         ('add-vanity', 'addvanity'): pubkeymanager.add_vanity,
         ('resettor', 'reset-tor'): resettor.reset_tor,
         ('resetplugins', 'reset-plugins'): resetplugins.reset,
         ('reset-tor-node-transport',): resettor.reset_tor_key_pair,
-        ('soft-reset', 'softreset'): softreset.soft_reset
+        ('soft-reset', 'softreset'): softreset.soft_reset,
+        ('toggle-bootstrap', 'togglebootstrap'):
+        togglebootstrap.toggle_bootstrap_config,
+        ('runtime-test', 'runtimetest'): runtimetestcmd.do_runtime_test,
+        ('makemotd', 'make-motd'): motdcreator.motd_creator
 
     }
     return args
-
+
def get_func(argument)
-

Returns the function for a given command argument

+

Return the function for a given command argument.

-Source code + +Expand source code +
def get_func(argument: str) -> Callable:
-    """Returns the function for a given command argument"""
+    """Return the function for a given command argument."""
     argument = argument.lower()
     args = get_arguments()
 
-    for arg in args.keys(): # Iterate command alias sets
-        if argument in arg: # If our argument is in the current alias set, return the command function
+    for arg in args.keys():  # Iterate command alias sets
+        """
+        If our argument is in the current alias set,
+        return the command function
+        """
+        if argument in arg:
             return args[arg]
     raise onionrexceptions.NotFound
-
+
def get_help(arg)
-

Returns the help info string from a given command

+

Return the help info string from a given command.

-Source code + +Expand source code +
def get_help(arg: str) -> str:
-    """Returns the help info string from a given command"""
+    """Return the help info string from a given command."""
     arguments = get_arguments()
     # Iterate the command alias tuples
     for argument in arguments:
         # Return the help message if its found in a command alias tuple
-        if arg in argument: return arguments[argument].onionr_help
+        if arg in argument:
+            return arguments[argument].onionr_help
     raise KeyError
@@ -196,21 +252,21 @@ def get_func(argument: str) -> Callable:
diff --git a/docs/html/onionr/onionrcommands/parser/index.html b/docs/html/src/onionrcommands/parser/index.html similarity index 58% rename from docs/html/onionr/onionrcommands/parser/index.html rename to docs/html/src/onionrcommands/parser/index.html index 698ef6bf..3f805a9b 100644 --- a/docs/html/onionr/onionrcommands/parser/index.html +++ b/docs/html/src/onionrcommands/parser/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.parser API documentation + +src.onionrcommands.parser API documentation - + @@ -17,19 +17,28 @@
-

Module onionr.onionrcommands.parser

+

Module src.onionrcommands.parser

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This module loads in the Onionr arguments and their help messages

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This module loads in the Onionr arguments and their help messages
-'''
-'''
+This module loads in the Onionr arguments and their help messages
+"""
+import sys
+import os
+
+import logger
+import onionrexceptions
+import onionrplugins
+from onionrplugins import onionrpluginapi
+from . import arguments, recommend
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,17 +51,16 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import sys
-from etc import onionrvalues
-import logger, onionrexceptions
-import onionrplugins
-from onionrplugins import onionrpluginapi
-from . import arguments, recommend
+"""
 
-plugin_command = lambda cmd: 'on_%s_cmd' % (cmd,)
 
-def register_plugin_commands(cmd)->bool:
+def plugin_command(cmd):
+    """Build a plugin command function name."""
+    return f'on_{cmd}_cmd'
+
+
+def register_plugin_commands(cmd) -> bool:
+    """Find a plugin command hook and execute it for a given cmd."""
     plugin_cmd = plugin_command(cmd)
     for pl in onionrplugins.get_enabled_plugins():
         pl = onionrplugins.get_plugin(pl)
@@ -61,10 +69,16 @@ def register_plugin_commands(cmd)->bool:
             return True
     return False
 
+
+def _show_term(msg: str):
+    logger.info(msg, terminal=True)
+
+
 def register():
-    """Registers commands and handles help command processing"""
-    def get_help_message(cmd: str, default: str = 'No help available for this command'):
-        """Return help message for a given command, supports plugin commands"""
+    """Register commands and handles help command processing."""
+    def get_help_message(cmd: str,
+                         default: str = 'No help available for this command'):
+        """Print help message for a given command, supports plugin commands."""
         pl_cmd = plugin_command(cmd)
         for pl in onionrplugins.get_enabled_plugins():
             pl = onionrplugins.get_plugin(pl)
@@ -73,14 +87,14 @@ def register():
                     return getattr(pl, pl_cmd).onionr_help
                 except AttributeError:
                     pass
-        
+
         for i in arguments.get_arguments():
-            for alias in i:
+            for _ in i:
                 try:
                     return arguments.get_help(cmd)
                 except AttributeError:
                     pass
-        return default # Return the help string
+        return default  # Return the help string
 
     PROGRAM_NAME = "onionr"
 
@@ -92,52 +106,67 @@ def register():
         return
 
     is_help_cmd = False
-    if cmd.replace('--', '').lower() == 'help': is_help_cmd = True
+    if cmd.replace('--', '').lower() == 'help':
+        is_help_cmd = True
 
     try:
-        arguments.get_func(cmd)()
+        try:
+            if cmd not in ('start', 'details', 'show-details'):
+                os.chdir(os.environ['ORIG_ONIONR_RUN_DIR'])
+        except KeyError:
+            pass
+        try:
+            arguments.get_func(cmd)()
+        except KeyboardInterrupt:
+            pass
     except onionrexceptions.NotFound:
         if not register_plugin_commands(cmd) and not is_help_cmd:
             recommend.recommend()
             sys.exit(3)
-    
+
     if is_help_cmd:
         try:
             sys.argv[2]
         except IndexError:
             for i in arguments.get_arguments():
-                logger.info('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i), get_help_message(i[0])), terminal=True)
+                _show_term('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i),
+                                            get_help_message(i[0])))
             for pl in onionrplugins.get_enabled_plugins():
                 pl = onionrplugins.get_plugin(pl)
                 if hasattr(pl, 'ONIONR_COMMANDS'):
                     print('')
                     try:
-                        logger.info('%s commands:' % (pl.plugin_name,), terminal=True)
+                        _show_term('%s commands:' % (pl.plugin_name,))
                     except AttributeError:
-                        logger.info('%s commands:' % (pl.__name__,), terminal=True)
+                        _show_term('%s commands:' % (pl.__name__,))
                     for plugin_cmd in pl.ONIONR_COMMANDS:
-                        logger.info('%s %s: %s' % (PROGRAM_NAME, plugin_cmd, get_help_message(plugin_cmd)), terminal=True)
+                        _show_term('%s %s: %s' %
+                                   (PROGRAM_NAME,
+                                    plugin_cmd,
+                                    get_help_message(plugin_cmd)),)
                     print('')
         else:
             try:
-                logger.info('%s %s: %s' % (PROGRAM_NAME, sys.argv[2], get_help_message(sys.argv[2])), terminal=True)
+                _show_term('%s %s: %s' % (PROGRAM_NAME,
+                                          sys.argv[2],
+                                          get_help_message(sys.argv[2])))
             except KeyError:
-                logger.error('%s: command does not exist.' % [sys.argv[2]], terminal=True)
+                logger.error('%s: command does not exist.' % [sys.argv[2]],
+                             terminal=True)
                 sys.exit(3)
-        return
-    
+ return

Sub-modules

-
onionr.onionrcommands.parser.arguments
+
src.onionrcommands.parser.arguments

Onionr - Private P2P Communication …

-
onionr.onionrcommands.parser.recommend
+
src.onionrcommands.parser.recommend
-
+

Onionr - Private P2P Communication …

@@ -146,27 +175,34 @@ def register():

Functions

-
+
def plugin_command(cmd)
-
+

Build a plugin command function name.

-Source code -
plugin_command = lambda cmd: 'on_%s_cmd' % (cmd,)
+ +Expand source code + +
def plugin_command(cmd):
+    """Build a plugin command function name."""
+    return f'on_{cmd}_cmd'
-
+
def register()
-

Registers commands and handles help command processing

+

Register commands and handles help command processing.

-Source code + +Expand source code +
def register():
-    """Registers commands and handles help command processing"""
-    def get_help_message(cmd: str, default: str = 'No help available for this command'):
-        """Return help message for a given command, supports plugin commands"""
+    """Register commands and handles help command processing."""
+    def get_help_message(cmd: str,
+                         default: str = 'No help available for this command'):
+        """Print help message for a given command, supports plugin commands."""
         pl_cmd = plugin_command(cmd)
         for pl in onionrplugins.get_enabled_plugins():
             pl = onionrplugins.get_plugin(pl)
@@ -175,14 +211,14 @@ def register():
                     return getattr(pl, pl_cmd).onionr_help
                 except AttributeError:
                     pass
-        
+
         for i in arguments.get_arguments():
-            for alias in i:
+            for _ in i:
                 try:
                     return arguments.get_help(cmd)
                 except AttributeError:
                     pass
-        return default # Return the help string
+        return default  # Return the help string
 
     PROGRAM_NAME = "onionr"
 
@@ -194,49 +230,68 @@ def register():
         return
 
     is_help_cmd = False
-    if cmd.replace('--', '').lower() == 'help': is_help_cmd = True
+    if cmd.replace('--', '').lower() == 'help':
+        is_help_cmd = True
 
     try:
-        arguments.get_func(cmd)()
+        try:
+            if cmd not in ('start', 'details', 'show-details'):
+                os.chdir(os.environ['ORIG_ONIONR_RUN_DIR'])
+        except KeyError:
+            pass
+        try:
+            arguments.get_func(cmd)()
+        except KeyboardInterrupt:
+            pass
     except onionrexceptions.NotFound:
         if not register_plugin_commands(cmd) and not is_help_cmd:
             recommend.recommend()
             sys.exit(3)
-    
+
     if is_help_cmd:
         try:
             sys.argv[2]
         except IndexError:
             for i in arguments.get_arguments():
-                logger.info('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i), get_help_message(i[0])), terminal=True)
+                _show_term('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i),
+                                            get_help_message(i[0])))
             for pl in onionrplugins.get_enabled_plugins():
                 pl = onionrplugins.get_plugin(pl)
                 if hasattr(pl, 'ONIONR_COMMANDS'):
                     print('')
                     try:
-                        logger.info('%s commands:' % (pl.plugin_name,), terminal=True)
+                        _show_term('%s commands:' % (pl.plugin_name,))
                     except AttributeError:
-                        logger.info('%s commands:' % (pl.__name__,), terminal=True)
+                        _show_term('%s commands:' % (pl.__name__,))
                     for plugin_cmd in pl.ONIONR_COMMANDS:
-                        logger.info('%s %s: %s' % (PROGRAM_NAME, plugin_cmd, get_help_message(plugin_cmd)), terminal=True)
+                        _show_term('%s %s: %s' %
+                                   (PROGRAM_NAME,
+                                    plugin_cmd,
+                                    get_help_message(plugin_cmd)),)
                     print('')
         else:
             try:
-                logger.info('%s %s: %s' % (PROGRAM_NAME, sys.argv[2], get_help_message(sys.argv[2])), terminal=True)
+                _show_term('%s %s: %s' % (PROGRAM_NAME,
+                                          sys.argv[2],
+                                          get_help_message(sys.argv[2])))
             except KeyError:
-                logger.error('%s: command does not exist.' % [sys.argv[2]], terminal=True)
+                logger.error('%s: command does not exist.' % [sys.argv[2]],
+                             terminal=True)
                 sys.exit(3)
         return
-
+
def register_plugin_commands(cmd)
-
+

Find a plugin command hook and execute it for a given cmd.

-Source code -
def register_plugin_commands(cmd)->bool:
+
+Expand source code
+
+
def register_plugin_commands(cmd) -> bool:
+    """Find a plugin command hook and execute it for a given cmd."""
     plugin_cmd = plugin_command(cmd)
     for pl in onionrplugins.get_enabled_plugins():
         pl = onionrplugins.get_plugin(pl)
@@ -259,27 +314,27 @@ def register():
 
 
 
diff --git a/docs/html/src/onionrcommands/parser/recommend.html b/docs/html/src/onionrcommands/parser/recommend.html new file mode 100644 index 00000000..033129c9 --- /dev/null +++ b/docs/html/src/onionrcommands/parser/recommend.html @@ -0,0 +1,131 @@ + + + + + + +src.onionrcommands.parser.recommend API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.parser.recommend

+
+
+

Onionr - Private P2P Communication.

+

Try to provide recommendations for invalid Onionr commands

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Try to provide recommendations for invalid Onionr commands
+"""
+import sys
+from difflib import SequenceMatcher
+import logger
+from . import arguments
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def recommend(print_default: bool = True):
+    """Print out a recommendation for argv cmd if one is available."""
+    tried = sys.argv[1]
+    args = arguments.get_arguments()
+    print_message = 'Command not found:'
+    for key in args.keys():
+        for word in key:
+            if SequenceMatcher(None, tried, word).ratio() >= 0.75:
+                logger.warn(f'{print_message} "{tried}", '
+                            + f'did you mean "{word}"?',
+                            terminal=True)
+                return
+    if print_default:
+        logger.error('%s "%s"' % (print_message, tried), terminal=True)
+
+
+
+
+
+
+
+

Functions

+
+
+def recommend(print_default=True) +
+
+

Print out a recommendation for argv cmd if one is available.

+
+ +Expand source code + +
def recommend(print_default: bool = True):
+    """Print out a recommendation for argv cmd if one is available."""
+    tried = sys.argv[1]
+    args = arguments.get_arguments()
+    print_message = 'Command not found:'
+    for key in args.keys():
+        for word in key:
+            if SequenceMatcher(None, tried, word).ratio() >= 0.75:
+                logger.warn(f'{print_message} "{tried}", '
+                            + f'did you mean "{word}"?',
+                            terminal=True)
+                return
+    if print_default:
+        logger.error('%s "%s"' % (print_message, tried), terminal=True)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/pubkeymanager.html b/docs/html/src/onionrcommands/pubkeymanager.html similarity index 59% rename from docs/html/onionr/onionrcommands/pubkeymanager.html rename to docs/html/src/onionrcommands/pubkeymanager.html index 06d36632..c5b1c75f 100644 --- a/docs/html/onionr/onionrcommands/pubkeymanager.html +++ b/docs/html/src/onionrcommands/pubkeymanager.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.pubkeymanager API documentation + +src.onionrcommands.pubkeymanager API documentation - + @@ -17,19 +17,34 @@
-

Module onionr.onionrcommands.pubkeymanager

+

Module src.onionrcommands.pubkeymanager

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

This module defines user ID-related CLI commands

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    This module defines user ID-related CLI commands
-'''
-'''
+This module defines user ID-related CLI commands
+"""
+import sys
+import getpass
+
+import unpaddedbase32
+import niceware
+
+import vanityonionr
+import logger
+import onionrexceptions
+from onionrutils import stringvalidators, bytesconverter
+import config
+import keymanager
+import onionrcrypto
+from etc import onionrvalues
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,60 +57,72 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
+"""
 
-import sys, getpass
-
-import unpaddedbase32
-import vanityonionr
-import mnemonic
-
-import logger, onionrexceptions
-from onionrutils import stringvalidators, bytesconverter
-from onionrusers import onionrusers, contactmanager
-import config
-from coredb import keydb
-import keymanager, onionrcrypto
-from etc import onionrvalues
 
 DETERMINISTIC_REQUIREMENT = onionrvalues.PASSWORD_LENGTH
+
+
 def add_ID():
+    """Command to create a new user ID key pair."""
     key_manager = keymanager.KeyManager()
     try:
-        sys.argv[2]
-        if not sys.argv[2].lower() == 'true': raise ValueError
-    except (IndexError, ValueError) as e:
+        sys.argv[2]  # pylint: disable=W0104
+        if not sys.argv[2].lower() == 'true':
+            raise ValueError
+    except (IndexError, ValueError):
         newID = key_manager.addKey()[0]
     else:
-        logger.warn('Deterministic keys require random and long passphrases.', terminal=True)
-        logger.warn('If a good passphrase is not used, your key can be easily stolen.', terminal=True)
-        logger.warn('You should use a series of hard to guess words, see this for reference: https://www.xkcd.com/936/', terminal=True)
+        logger.warn(
+            'Deterministic keys require random and long passphrases.',
+            terminal=True)
+        logger.warn(
+            'If a good passphrase is not used, your key can be easily stolen.',
+            terminal=True)
+        logger.warn(
+            'You should use a series of hard to guess words, ' +
+            'see this for reference: https://www.xkcd.com/936/',
+            terminal=True)
         try:
-            pass1 = getpass.getpass(prompt='Enter at least %s characters: ' % (DETERMINISTIC_REQUIREMENT,))
+            pass1 = getpass.getpass(
+                prompt='Enter at least %s characters: ' %
+                (DETERMINISTIC_REQUIREMENT,))
             pass2 = getpass.getpass(prompt='Confirm entry: ')
         except KeyboardInterrupt:
             sys.exit(42)
         if onionrcrypto.cryptoutils.safe_compare(pass1, pass2):
             try:
-                logger.info('Generating deterministic key. This can take a while.', terminal=True)
+                logger.info(
+                    'Generating deterministic key. This can take a while.',
+                    terminal=True)
                 newID, privKey = onionrcrypto.generate_deterministic(pass1)
             except onionrexceptions.PasswordStrengthError:
-                logger.error('Passphrase must use at least %s characters.' % (DETERMINISTIC_REQUIREMENT,), terminal=True)
+                logger.error('Passphrase must use at least %s characters.' % (
+                    DETERMINISTIC_REQUIREMENT,), terminal=True)
                 sys.exit(1)
         else:
             logger.error('Passwords do not match.', terminal=True)
             sys.exit(1)
         try:
-            key_manager.addKey(pubKey=newID, 
-            privKey=privKey)
+            key_manager.addKey(pubKey=newID,
+                               privKey=privKey)
         except ValueError:
-            logger.error('That ID is already available, you can change to it with the change-id command.', terminal=True)
+            logger.error(
+                'That ID is already available, you can change to it ' +
+                'with the change-id command.', terminal=True)
             return
-    logger.info('Added ID: %s' % (bytesconverter.bytes_to_str(newID),), terminal=True)
+    logger.info('Added ID: %s' %
+                (bytesconverter.bytes_to_str(newID),), terminal=True)
+
+
+add_ID.onionr_help = "If the first argument is true, "  # type: ignore
+add_ID.onionr_help += "Onionr will show a deterministic "  # type: ignore
+add_ID.onionr_help += "generation prompt. Otherwise it will "  # type: ignore
+add_ID.onionr_help += "generate & save a new random key pair."  # type: ignore
 
-add_ID.onionr_help = "If the first argument is true, Onionr will show a deterministic generation prompt. Otherwise it will generate & save a new random key pair."
 
 def change_ID():
+    """Command to change active ID from argv or stdin."""
     key_manager = keymanager.KeyManager()
     try:
         key = sys.argv[2]
@@ -115,15 +142,24 @@ def change_ID():
         else:
             logger.warn('Invalid key %s' % (key,), terminal=True)
 
-change_ID.onionr_help = "<pubkey>: Switches Onionr to use a different user ID key. You should immediately restart Onionr if it is running."
+
+change_ID.onionr_help = "<pubkey>: Switches Onionr to "  # type: ignore
+change_ID.onionr_help += "use a different user ID key. "  # type: ignore
+change_ID.onionr_help += "You should immediately restart "  # type: ignore
+change_ID.onionr_help += "Onionr if it is running."  # type: ignore
+
 
 def add_vanity():
+    """Command to generate menmonic vanity key pair."""
     key_manager = keymanager.KeyManager()
-    tell = lambda tell: logger.info(tell, terminal=True)
+
+    def tell(tell):
+        return logger.info(tell, terminal=True)
+
     words = ''
-    m = mnemonic.Mnemonic('english')
     length = len(sys.argv) - 2
-    if length == 0: return
+    if length == 0:
+        return
     for i in range(2, len(sys.argv)):
         words += ' '
         words += sys.argv[i]
@@ -135,15 +171,22 @@ def add_vanity():
         try:
             vanity = vanityonionr.find_multiprocess(words)
         except ValueError:
-            logger.warn('Vanity words must be valid english bip39', terminal=True)
+            logger.warn('Vanity words must be valid english bip39',
+                        terminal=True)
         else:
             b32_pub = unpaddedbase32.b32encode(vanity[0])
-            tell('Found vanity address:\n' + m.to_mnemonic(vanity[0]))
+            tell('Found vanity address:\n' +
+                 niceware.bytes_to_passphrase(vanity[0]))
             tell('Base32 Public key: %s' % (b32_pub.decode(),))
             key_manager.addKey(b32_pub, unpaddedbase32.b32encode(vanity[1]))
     except KeyboardInterrupt:
         pass
-add_vanity.onionr_help = "<space separated bip32 words> - Generates and stores an Onionr vanity address (see https://github.com/trezor/python-mnemonic/blob/master/mnemonic/wordlist/english.txt)"
+ + +add_vanity.onionr_help = "<space separated words> - " # type: ignore +add_vanity.onionr_help += "Generates and stores an " # type: ignore +add_vanity.onionr_help += "Onionr vanity address " # type: ignore +add_vanity.onionr_help += "(see is.gd/YklHGe)" # type: ignore
@@ -153,62 +196,87 @@ add_vanity.onionr_help = "<space separated bip32 words> - Generates an

Functions

-
+
def add_ID()
-
+

Command to create a new user ID key pair.

-Source code + +Expand source code +
def add_ID():
+    """Command to create a new user ID key pair."""
     key_manager = keymanager.KeyManager()
     try:
-        sys.argv[2]
-        if not sys.argv[2].lower() == 'true': raise ValueError
-    except (IndexError, ValueError) as e:
+        sys.argv[2]  # pylint: disable=W0104
+        if not sys.argv[2].lower() == 'true':
+            raise ValueError
+    except (IndexError, ValueError):
         newID = key_manager.addKey()[0]
     else:
-        logger.warn('Deterministic keys require random and long passphrases.', terminal=True)
-        logger.warn('If a good passphrase is not used, your key can be easily stolen.', terminal=True)
-        logger.warn('You should use a series of hard to guess words, see this for reference: https://www.xkcd.com/936/', terminal=True)
+        logger.warn(
+            'Deterministic keys require random and long passphrases.',
+            terminal=True)
+        logger.warn(
+            'If a good passphrase is not used, your key can be easily stolen.',
+            terminal=True)
+        logger.warn(
+            'You should use a series of hard to guess words, ' +
+            'see this for reference: https://www.xkcd.com/936/',
+            terminal=True)
         try:
-            pass1 = getpass.getpass(prompt='Enter at least %s characters: ' % (DETERMINISTIC_REQUIREMENT,))
+            pass1 = getpass.getpass(
+                prompt='Enter at least %s characters: ' %
+                (DETERMINISTIC_REQUIREMENT,))
             pass2 = getpass.getpass(prompt='Confirm entry: ')
         except KeyboardInterrupt:
             sys.exit(42)
         if onionrcrypto.cryptoutils.safe_compare(pass1, pass2):
             try:
-                logger.info('Generating deterministic key. This can take a while.', terminal=True)
+                logger.info(
+                    'Generating deterministic key. This can take a while.',
+                    terminal=True)
                 newID, privKey = onionrcrypto.generate_deterministic(pass1)
             except onionrexceptions.PasswordStrengthError:
-                logger.error('Passphrase must use at least %s characters.' % (DETERMINISTIC_REQUIREMENT,), terminal=True)
+                logger.error('Passphrase must use at least %s characters.' % (
+                    DETERMINISTIC_REQUIREMENT,), terminal=True)
                 sys.exit(1)
         else:
             logger.error('Passwords do not match.', terminal=True)
             sys.exit(1)
         try:
-            key_manager.addKey(pubKey=newID, 
-            privKey=privKey)
+            key_manager.addKey(pubKey=newID,
+                               privKey=privKey)
         except ValueError:
-            logger.error('That ID is already available, you can change to it with the change-id command.', terminal=True)
+            logger.error(
+                'That ID is already available, you can change to it ' +
+                'with the change-id command.', terminal=True)
             return
-    logger.info('Added ID: %s' % (bytesconverter.bytes_to_str(newID),), terminal=True)
+ logger.info('Added ID: %s' % + (bytesconverter.bytes_to_str(newID),), terminal=True)
-
+
def add_vanity()
-
+

Command to generate menmonic vanity key pair.

-Source code + +Expand source code +
def add_vanity():
+    """Command to generate menmonic vanity key pair."""
     key_manager = keymanager.KeyManager()
-    tell = lambda tell: logger.info(tell, terminal=True)
+
+    def tell(tell):
+        return logger.info(tell, terminal=True)
+
     words = ''
-    m = mnemonic.Mnemonic('english')
     length = len(sys.argv) - 2
-    if length == 0: return
+    if length == 0:
+        return
     for i in range(2, len(sys.argv)):
         words += ' '
         words += sys.argv[i]
@@ -220,24 +288,29 @@ add_vanity.onionr_help = "<space separated bip32 words> - Generates an
         try:
             vanity = vanityonionr.find_multiprocess(words)
         except ValueError:
-            logger.warn('Vanity words must be valid english bip39', terminal=True)
+            logger.warn('Vanity words must be valid english bip39',
+                        terminal=True)
         else:
             b32_pub = unpaddedbase32.b32encode(vanity[0])
-            tell('Found vanity address:\n' + m.to_mnemonic(vanity[0]))
+            tell('Found vanity address:\n' +
+                 niceware.bytes_to_passphrase(vanity[0]))
             tell('Base32 Public key: %s' % (b32_pub.decode(),))
             key_manager.addKey(b32_pub, unpaddedbase32.b32encode(vanity[1]))
     except KeyboardInterrupt:
         pass
-
+
def change_ID()
-
+

Command to change active ID from argv or stdin.

-Source code + +Expand source code +
def change_ID():
+    """Command to change active ID from argv or stdin."""
     key_manager = keymanager.KeyManager()
     try:
         key = sys.argv[2]
@@ -271,21 +344,21 @@ add_vanity.onionr_help = "<space separated bip32 words> - Generates an
 
 
 
diff --git a/docs/html/onionr/onionrcommands/resetplugins.html b/docs/html/src/onionrcommands/resetplugins.html similarity index 69% rename from docs/html/onionr/onionrcommands/resetplugins.html rename to docs/html/src/onionrcommands/resetplugins.html index 1b3f102b..2b3204dc 100644 --- a/docs/html/onionr/onionrcommands/resetplugins.html +++ b/docs/html/src/onionrcommands/resetplugins.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.resetplugins API documentation + +src.onionrcommands.resetplugins API documentation - + @@ -17,19 +17,25 @@
-

Module onionr.onionrcommands.resetplugins

+

Module src.onionrcommands.resetplugins

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Reset default plugins from source

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Reset default plugins from source
-'''
-'''
+Reset default plugins from source
+"""
+import os
+import shutil
+
+from utils import identifyhome
+import logger
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,25 +48,24 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os
-import shutil
+"""
 
-from utils import identifyhome
-from onionrsetup import setup_default_plugins
-import logger
 
 def reset():
-    """Reinstalls Onionr default plugins"""
+    """Reinstalls Onionr default plugins."""
     home = identifyhome.identify_home()
     plugin_dir = home + '/plugins/'
-    if not os.path.exists(home): return
-    if os.path.exists(plugin_dir): shutil.rmtree(plugin_dir)
-    
-    setup_default_plugins()
+    if not os.path.exists(home):
+        return
+    if os.path.exists(plugin_dir):
+        shutil.rmtree(plugin_dir)
+
     logger.info('Default plugins have been reset.', terminal=True)
 
-reset.onionr_help = "reinstalls default Onionr plugins (e.g. mail). Should be done after git pulls or plugin modification."
+ +reset.onionr_help = "reinstalls default Onionr plugins" # type: ignore +reset.onionr_help += "(e.g. mail). Should be done after " # type: ignore +reset.onionr_help += "git pulls or plugin modification." # type: ignore
@@ -70,21 +75,24 @@ reset.onionr_help = "reinstalls default Onionr plugins (e.g. mail). Should b

Functions

-
+
def reset()
-

Reinstalls Onionr default plugins

+

Reinstalls Onionr default plugins.

-Source code + +Expand source code +
def reset():
-    """Reinstalls Onionr default plugins"""
+    """Reinstalls Onionr default plugins."""
     home = identifyhome.identify_home()
     plugin_dir = home + '/plugins/'
-    if not os.path.exists(home): return
-    if os.path.exists(plugin_dir): shutil.rmtree(plugin_dir)
-    
-    setup_default_plugins()
+    if not os.path.exists(home):
+        return
+    if os.path.exists(plugin_dir):
+        shutil.rmtree(plugin_dir)
+
     logger.info('Default plugins have been reset.', terminal=True)
@@ -101,19 +109,19 @@ reset.onionr_help = "reinstalls default Onionr plugins (e.g. mail). Should b
diff --git a/docs/html/onionr/onionrcommands/resettor.html b/docs/html/src/onionrcommands/resettor.html similarity index 63% rename from docs/html/onionr/onionrcommands/resettor.html rename to docs/html/src/onionrcommands/resettor.html index 408a3e5b..dbfe6ac3 100644 --- a/docs/html/onionr/onionrcommands/resettor.html +++ b/docs/html/src/onionrcommands/resettor.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.resettor API documentation + +src.onionrcommands.resettor API documentation - + @@ -17,19 +17,25 @@
-

Module onionr.onionrcommands.resettor

+

Module src.onionrcommands.resettor

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Command to delete the Tor data directory if its safe to do so

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Command to delete the Tor data directory if its safe to do so
-'''
-'''
+Command to delete the Tor data directory if its safe to do so
+"""
+import os
+import shutil
+import logger
+from onionrutils import localcommand
+from utils import identifyhome
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,30 +48,45 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import os, shutil
-import logger
-from onionrutils import localcommand
-from utils import identifyhome
+"""
+
 
 def __delete(directory):
     tor_dir = '%s/%s/' % (identifyhome.identify_home(), directory)
     if os.path.exists(tor_dir):
         if localcommand.local_command('/ping') == 'pong!':
-            logger.warn('Cannot delete Tor data while Onionr is running', terminal=True)
+            logger.warn(
+                'Cannot delete Tor data while Onionr is running',
+                terminal=True)
         else:
             shutil.rmtree(tor_dir)
             logger.info('Tor reset', terminal=True)
 
+
 def reset_tor():
+    """Delete tor data directory."""
     __delete('tordata')
 
-reset_tor.onionr_help = "Deletes Onionr's Tor data directory. Only do this as a last resort if you have serious Tor issues."
+
+reset_tor.onionr_help = "Deletes Onionr's Tor data directory. "  # type: ignore
+reset_tor.onionr_help += "Only do this as a last resort if "  # type: ignore
+reset_tor.onionr_help += "you have serious Tor issues."  # type: ignore
+
 
 def reset_tor_key_pair():
+    """Delete Tor HS key pair for our node."""
     __delete('hs')
 
-reset_tor_key_pair.onionr_help = "Delete's your Tor node address permanently. Note that through fingerprinting attackers may be able to know that your any new generated node address belongs to the same node as the deleted one."
+ +reset_tor_key_pair.onionr_help = "Delete's your Tor " # type: ignore +reset_tor_key_pair.onionr_help += "node address permanently. " # type: ignore +reset_tor_key_pair.onionr_help += "Note that through " # type: ignore +reset_tor_key_pair.onionr_help += "fingerprinting attackers " # type: ignore +reset_tor_key_pair.onionr_help += "may be able to know that " # type: ignore +reset_tor_key_pair.onionr_help += "your new generated node " # type: ignore +reset_tor_key_pair.onionr_help += "address belongs to " # type: ignore +reset_tor_key_pair.onionr_help += "the same node " # type: ignore +reset_tor_key_pair.onionr_help += "as the deleted one." # type: ignore
@@ -75,25 +96,31 @@ reset_tor_key_pair.onionr_help = "Delete's your Tor node address permane

Functions

-
+
def reset_tor()
-
+

Delete tor data directory.

-Source code + +Expand source code +
def reset_tor():
+    """Delete tor data directory."""
     __delete('tordata')
-
+
def reset_tor_key_pair()
-
+

Delete Tor HS key pair for our node.

-Source code + +Expand source code +
def reset_tor_key_pair():
+    """Delete Tor HS key pair for our node."""
     __delete('hs')
@@ -110,20 +137,20 @@ reset_tor_key_pair.onionr_help = "Delete's your Tor node address permane
diff --git a/docs/html/src/onionrcommands/restartonionr.html b/docs/html/src/onionrcommands/restartonionr.html new file mode 100644 index 00000000..d3ea73f6 --- /dev/null +++ b/docs/html/src/onionrcommands/restartonionr.html @@ -0,0 +1,164 @@ + + + + + + +src.onionrcommands.restartonionr API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.restartonionr

+
+
+

Onionr - Private P2P Communication.

+

Command to restart Onionr

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Command to restart Onionr
+"""
+import time
+import os
+import subprocess  # nosec
+import platform
+
+from etc import onionrvalues
+from etc import cleanup
+from onionrutils import localcommand
+import logger
+import filepaths
+
+from . import daemonlaunch
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+SCRIPT_NAME = os.path.dirname(os.path.realpath(
+    __file__)) + f'/../../{onionrvalues.SCRIPT_NAME}'
+
+
+def restart():
+    """Tell the Onionr daemon to restart."""
+    logger.info('Restarting Onionr', terminal=True)
+
+    # On platforms where we can, fork out to prevent locking
+    try:
+        pid = os.fork()
+        if pid != 0:
+            return
+    except (AttributeError, OSError):
+        if platform.platform() != 'Windows':
+            logger.warn('Could not fork on restart')
+
+    daemonlaunch.kill_daemon()
+    while localcommand.local_command('ping', maxWait=8) == 'pong!':
+        time.sleep(0.3)
+    time.sleep(15)
+    while (os.path.exists(filepaths.private_API_host_file) or
+           (os.path.exists(filepaths.daemon_mark_file))):
+        time.sleep(1)
+
+    cleanup.delete_run_files()
+    subprocess.Popen([SCRIPT_NAME, 'start'])
+
+
+restart.onionr_help = 'Gracefully restart Onionr'  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def restart() +
+
+

Tell the Onionr daemon to restart.

+
+ +Expand source code + +
def restart():
+    """Tell the Onionr daemon to restart."""
+    logger.info('Restarting Onionr', terminal=True)
+
+    # On platforms where we can, fork out to prevent locking
+    try:
+        pid = os.fork()
+        if pid != 0:
+            return
+    except (AttributeError, OSError):
+        if platform.platform() != 'Windows':
+            logger.warn('Could not fork on restart')
+
+    daemonlaunch.kill_daemon()
+    while localcommand.local_command('ping', maxWait=8) == 'pong!':
+        time.sleep(0.3)
+    time.sleep(15)
+    while (os.path.exists(filepaths.private_API_host_file) or
+           (os.path.exists(filepaths.daemon_mark_file))):
+        time.sleep(1)
+
+    cleanup.delete_run_files()
+    subprocess.Popen([SCRIPT_NAME, 'start'])
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/onionrcommands/runtimetestcmd.html b/docs/html/src/onionrcommands/runtimetestcmd.html new file mode 100644 index 00000000..64c34e41 --- /dev/null +++ b/docs/html/src/onionrcommands/runtimetestcmd.html @@ -0,0 +1,126 @@ + + + + + + +src.onionrcommands.runtimetestcmd API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.runtimetestcmd

+
+
+

Onionr - Private P2P Communication.

+

Command to tell daemon to do run time tests

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Command to tell daemon to do run time tests
+"""
+from gevent import spawn
+
+from onionrutils import localcommand
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def do_runtime_test():
+    """Send runtime test daemon queue command."""
+    spawn(
+        localcommand.local_command,
+        f'daemon-event/test_runtime',
+        post=True,
+        is_json=True,
+        postData={},
+        maxWait=300
+    ).get(300)
+
+
+do_runtime_test.onionr_help = "If Onionr is running, "  # type: ignore
+do_runtime_test.onionr_help += "run runtime tests (check logs)"  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def do_runtime_test() +
+
+

Send runtime test daemon queue command.

+
+ +Expand source code + +
def do_runtime_test():
+    """Send runtime test daemon queue command."""
+    spawn(
+        localcommand.local_command,
+        f'daemon-event/test_runtime',
+        post=True,
+        is_json=True,
+        postData={},
+        maxWait=300
+    ).get(300)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/src/onionrcommands/sitecreator.html b/docs/html/src/onionrcommands/sitecreator.html new file mode 100644 index 00000000..af3c79d8 --- /dev/null +++ b/docs/html/src/onionrcommands/sitecreator.html @@ -0,0 +1,187 @@ + + + + + + +src.onionrcommands.sitecreator API documentation + + + + + + + + + +
+
+
+

Module src.onionrcommands.sitecreator

+
+
+

Onionr - Private P2P Communication.

+

Command to create Onionr mutli-page sites

+
+ +Expand source code + +
"""Onionr - Private P2P Communication.
+
+Command to create Onionr mutli-page sites
+"""
+import sys
+import getpass
+
+from httpapi import onionrsitesapi
+import logger
+from etc import onionrvalues
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def create_multipage_site():
+    """Command to create mutlipage sites with specified dir and password."""
+    error_encountered = False
+    try:
+        directory = sys.argv[2]
+    except IndexError:
+        directory = '.'
+    try:
+        passphrase = sys.argv[3]
+    except IndexError:
+        logger.warn('''It is critical that this passphrase is long.
+If you want to update your site later you must remember the passphrase.''',
+                    terminal=True)
+
+        passphrase = getpass.getpass(
+            'Please enter a site passphrase of at least ' +
+            str(onionrvalues.PASSWORD_LENGTH) + ' characters.')
+
+        confirm = getpass.getpass('Confirm passphrase:')
+        if passphrase != confirm:
+            logger.error('Passphrases do not match', terminal=True)
+            error_encountered = True
+
+    if len(passphrase) < onionrvalues.PASSWORD_LENGTH:
+        error_encountered = True
+        logger.error(
+            f'Passphrase must be at least {onionrvalues.PASSWORD_LENGTH}' +
+            'characters.', terminal=True)
+
+    if error_encountered:
+        sys.exit(1)
+
+    results = onionrsitesapi.sitefiles.create_site(
+        passphrase, directory=directory)
+    results = (results[0].replace('=', ''), results[1])
+    logger.info(f'Site address {results[0]}', terminal=True)
+    logger.info(f'Block for this version {results[1]}', terminal=True)
+
+
+create_multipage_site.onionr_help = "[directory path "  # type: ignore
+create_multipage_site.onionr_help += "(default relative)] "  # type: ignore
+create_multipage_site.onionr_help += "- packages a whole "  # type: ignore
+create_multipage_site.onionr_help += "directory and makes "  # type: ignore
+create_multipage_site.onionr_help += "it available as "  # type: ignore
+create_multipage_site.onionr_help += "an Onionr site."  # type: ignore
+
+
+
+
+
+
+
+

Functions

+
+
+def create_multipage_site() +
+
+

Command to create mutlipage sites with specified dir and password.

+
+ +Expand source code + +
def create_multipage_site():
+    """Command to create mutlipage sites with specified dir and password."""
+    error_encountered = False
+    try:
+        directory = sys.argv[2]
+    except IndexError:
+        directory = '.'
+    try:
+        passphrase = sys.argv[3]
+    except IndexError:
+        logger.warn('''It is critical that this passphrase is long.
+If you want to update your site later you must remember the passphrase.''',
+                    terminal=True)
+
+        passphrase = getpass.getpass(
+            'Please enter a site passphrase of at least ' +
+            str(onionrvalues.PASSWORD_LENGTH) + ' characters.')
+
+        confirm = getpass.getpass('Confirm passphrase:')
+        if passphrase != confirm:
+            logger.error('Passphrases do not match', terminal=True)
+            error_encountered = True
+
+    if len(passphrase) < onionrvalues.PASSWORD_LENGTH:
+        error_encountered = True
+        logger.error(
+            f'Passphrase must be at least {onionrvalues.PASSWORD_LENGTH}' +
+            'characters.', terminal=True)
+
+    if error_encountered:
+        sys.exit(1)
+
+    results = onionrsitesapi.sitefiles.create_site(
+        passphrase, directory=directory)
+    results = (results[0].replace('=', ''), results[1])
+    logger.info(f'Site address {results[0]}', terminal=True)
+    logger.info(f'Block for this version {results[1]}', terminal=True)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/softreset.html b/docs/html/src/onionrcommands/softreset.html similarity index 71% rename from docs/html/onionr/onionrcommands/softreset.html rename to docs/html/src/onionrcommands/softreset.html index df2034a8..777139c1 100644 --- a/docs/html/onionr/onionrcommands/softreset.html +++ b/docs/html/src/onionrcommands/softreset.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.softreset API documentation + +src.onionrcommands.softreset API documentation - + @@ -17,18 +17,27 @@
-

Module onionr.onionrcommands.softreset

+

Module src.onionrcommands.softreset

-

Onionr - Private P2P Communication

+

Onionr - Private P2P Communication.

Command to soft-reset Onionr (deletes blocks)

-Source code -
"""
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Command to soft-reset Onionr (deletes blocks)
+Command to soft-reset Onionr (deletes blocks)
 """
+import os
+import shutil
+
+from onionrutils import localcommand
+from coredb import dbfiles
+import filepaths
+from onionrplugins import onionrevents
+import logger
 """
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,14 +52,7 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
-import os
-import shutil
 
-from onionrutils import localcommand
-from coredb import dbfiles
-import filepaths
-from onionrplugins import onionrevents
-import logger
 
 def _ignore_not_found_delete(path):
     try:
@@ -58,18 +60,30 @@ def _ignore_not_found_delete(path):
     except FileNotFoundError:
         pass
 
+
 def soft_reset():
+    """Command to soft reset Onionr home data.
+
+    Onionr must not be running
+    """
     if localcommand.local_command('/ping') == 'pong!':
-        logger.warn('Cannot soft reset while Onionr is running', terminal=True)
+        logger.warn('Cannot soft reset while Onionr is running',
+                    terminal=True)
         return
     path = filepaths.block_data_location
     shutil.rmtree(path)
     _ignore_not_found_delete(dbfiles.block_meta_db)
     _ignore_not_found_delete(filepaths.upload_list)
+    _ignore_not_found_delete(filepaths.usage_file)
     onionrevents.event('softreset')
     logger.info("Soft reset Onionr", terminal=True)
 
-soft_reset.onionr_help = "Deletes Onionr blocks and their associated metadata, except for any exported block files. Does NOT delete data on other nodes in the network."
+ +soft_reset.onionr_help = "Deletes Onionr blocks and their " # type: ignore +soft_reset.onionr_help += "associated metadata, except for " # type: ignore +soft_reset.onionr_help += "any exported block files. Does NOT " # type: ignore +soft_reset.onionr_help += "delete data on " # type: ignore +soft_reset.onionr_help += "other nodes in the network." # type: ignore
@@ -79,21 +93,30 @@ soft_reset.onionr_help = "Deletes Onionr blocks and their associated metadat

Functions

-
+
def soft_reset()
-
+

Command to soft reset Onionr home data.

+

Onionr must not be running

-Source code + +Expand source code +
def soft_reset():
+    """Command to soft reset Onionr home data.
+
+    Onionr must not be running
+    """
     if localcommand.local_command('/ping') == 'pong!':
-        logger.warn('Cannot soft reset while Onionr is running', terminal=True)
+        logger.warn('Cannot soft reset while Onionr is running',
+                    terminal=True)
         return
     path = filepaths.block_data_location
     shutil.rmtree(path)
     _ignore_not_found_delete(dbfiles.block_meta_db)
     _ignore_not_found_delete(filepaths.upload_list)
+    _ignore_not_found_delete(filepaths.usage_file)
     onionrevents.event('softreset')
     logger.info("Soft reset Onionr", terminal=True)
@@ -111,19 +134,19 @@ soft_reset.onionr_help = "Deletes Onionr blocks and their associated metadat
diff --git a/docs/html/onionr/onionrcommands/openwebinterface.html b/docs/html/src/onionrcommands/togglebootstrap.html similarity index 63% rename from docs/html/onionr/onionrcommands/openwebinterface.html rename to docs/html/src/onionrcommands/togglebootstrap.html index 8acb8712..ccdc5f44 100644 --- a/docs/html/onionr/onionrcommands/openwebinterface.html +++ b/docs/html/src/onionrcommands/togglebootstrap.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.openwebinterface API documentation + +src.onionrcommands.togglebootstrap API documentation - + @@ -17,19 +17,24 @@
-

Module onionr.onionrcommands.openwebinterface

+

Module src.onionrcommands.togglebootstrap

-

Onionr - Private P2P Communication

-

Open the web interface properly into a web browser

+

Onionr - Private P2P Communication.

+

Toggle the bootstrap configuration

-Source code -
'''
-    Onionr - Private P2P Communication
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
 
-    Open the web interface properly into a web browser
-'''
-'''
+Toggle the bootstrap configuration
+"""
+import sys
+
+import config
+import logger
+"""
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -42,22 +47,17 @@
 
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-'''
-import webbrowser
-import logger
-from onionrutils import getclientapiserver
-import config
-def open_home():
-    try:
-        url = getclientapiserver.get_client_API_server()
-    except FileNotFoundError:
-        logger.error('Onionr seems to not be running (could not get api host)', terminal=True)
-    else:
-        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
-        logger.info('If Onionr does not open automatically, use this URL: ' + url, terminal=True)
-        webbrowser.open_new_tab(url)
+"""
 
-open_home.onionr_help = "Opens the Onionr web UI in the default browser. Node must be running."
+ +def toggle_bootstrap_config(): + """Toggles the bootstrap configuration.""" + print("test") + if config.get('general.use_bootstrap_list') is None: + logger.error('No general.bootstrap_list setting found') + sys.exit(3) + flipped: bool = not config.get('general.use_bootstrap_list') + config.set('general.use_bootstrap_list', flipped, savefile=True)
@@ -67,22 +67,23 @@ open_home.onionr_help = "Opens the Onionr web UI in the default browser. Nod

Functions

-
-def open_home() +
+def toggle_bootstrap_config()
-
+

Toggles the bootstrap configuration.

-Source code -
def open_home():
-    try:
-        url = getclientapiserver.get_client_API_server()
-    except FileNotFoundError:
-        logger.error('Onionr seems to not be running (could not get api host)', terminal=True)
-    else:
-        url = 'http://%s/#%s' % (url, config.get('client.webpassword'))
-        logger.info('If Onionr does not open automatically, use this URL: ' + url, terminal=True)
-        webbrowser.open_new_tab(url)
+ +Expand source code + +
def toggle_bootstrap_config():
+    """Toggles the bootstrap configuration."""
+    print("test")
+    if config.get('general.use_bootstrap_list') is None:
+        logger.error('No general.bootstrap_list setting found')
+        sys.exit(3)
+    flipped: bool = not config.get('general.use_bootstrap_list')
+    config.set('general.use_bootstrap_list', flipped, savefile=True)
@@ -98,19 +99,19 @@ open_home.onionr_help = "Opens the Onionr web UI in the default browser. Nod
diff --git a/docs/html/onionr/onionrcommands/version.html b/docs/html/src/onionrcommands/version.html similarity index 57% rename from docs/html/onionr/onionrcommands/version.html rename to docs/html/src/onionrcommands/version.html index 5bd9d6c1..083b333c 100644 --- a/docs/html/onionr/onionrcommands/version.html +++ b/docs/html/src/onionrcommands/version.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.version API documentation - + +src.onionrcommands.version API documentation + - + @@ -17,21 +17,45 @@
-

Module onionr.onionrcommands.version

+

Module src.onionrcommands.version

+

Onionr - Private P2P Communication.

+

Command to show version info

-Source code -
import platform
+
+Expand source code
+
+
"""Onionr - Private P2P Communication.
+
+Command to show version info
+"""
+import platform
 from utils import identifyhome
 from etc import onionrvalues
 import logger
-def version(verbosity = 5, function = logger.info):
-    '''
-        Displays the Onionr version
-    '''
+"""
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
 
-    function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION, platform.machine(), onionrvalues.API_VERSION), terminal=True)
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+
+def version(verbosity=5, function=logger.info):
+    """Display the Onionr version."""
+    function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION,
+                                            platform.machine(),
+                                            onionrvalues.API_VERSION),
+             terminal=True)
     if verbosity >= 1:
         function(onionrvalues.ONIONR_TAGLINE, terminal=True)
     if verbosity >= 2:
@@ -39,10 +63,16 @@ def version(verbosity = 5, function = logger.info):
         release = platform.release()
         python_imp = platform.python_implementation()
         python_version = platform.python_version()
-        function(f'{python_imp} {python_version} on {pf} {release}', terminal=True)
-        function('Onionr data dir: %s' % identifyhome.identify_home(), terminal=True)
+        function(
+            f'{python_imp} {python_version} on {pf} {release}',
+            terminal=True)
+        function('Onionr data dir: %s' %
+                 identifyhome.identify_home(), terminal=True)
 
-version.onionr_help = 'Shows environment details including Onionr version & data directory, OS and Python version'
+ +version.onionr_help = 'Shows environment details including ' # type: ignore +version.onionr_help += 'Onionr version & data directory, ' # type: ignore +version.onionr_help += 'OS and Python version' # type: ignore
@@ -52,19 +82,21 @@ version.onionr_help = 'Shows environment details including Onionr version &a

Functions

-
-def version(verbosity=5, function=) +
+def version(verbosity=5, function=<function info>)
-

Displays the Onionr version

+

Display the Onionr version.

-Source code -
def version(verbosity = 5, function = logger.info):
-    '''
-        Displays the Onionr version
-    '''
-
-    function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION, platform.machine(), onionrvalues.API_VERSION), terminal=True)
+
+Expand source code
+
+
def version(verbosity=5, function=logger.info):
+    """Display the Onionr version."""
+    function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION,
+                                            platform.machine(),
+                                            onionrvalues.API_VERSION),
+             terminal=True)
     if verbosity >= 1:
         function(onionrvalues.ONIONR_TAGLINE, terminal=True)
     if verbosity >= 2:
@@ -72,8 +104,11 @@ version.onionr_help = 'Shows environment details including Onionr version &a
         release = platform.release()
         python_imp = platform.python_implementation()
         python_version = platform.python_version()
-        function(f'{python_imp} {python_version} on {pf} {release}', terminal=True)
-        function('Onionr data dir: %s' % identifyhome.identify_home(), terminal=True)
+ function( + f'{python_imp} {python_version} on {pf} {release}', + terminal=True) + function('Onionr data dir: %s' % + identifyhome.identify_home(), terminal=True)
@@ -89,19 +124,19 @@ version.onionr_help = 'Shows environment details including Onionr version &a
diff --git a/docs/html/src/onionrcrypto/cryptoutils/getpubfrompriv.html b/docs/html/src/onionrcrypto/cryptoutils/getpubfrompriv.html new file mode 100644 index 00000000..8fe9b8ff --- /dev/null +++ b/docs/html/src/onionrcrypto/cryptoutils/getpubfrompriv.html @@ -0,0 +1,85 @@ + + + + + + +src.onionrcrypto.cryptoutils.getpubfrompriv API documentation + + + + + + + + + +
+
+
+

Module src.onionrcrypto.cryptoutils.getpubfrompriv

+
+
+
+ +Expand source code + +
from nacl import signing, encoding
+
+from onionrtypes import UserID, UserIDSecretKey
+
+def get_pub_key_from_priv(priv_key: UserIDSecretKey, raw_encoding:bool=False)->UserID:
+    return signing.SigningKey(priv_key, encoder=encoding.Base32Encoder).verify_key.encode(encoding.Base32Encoder)
+
+
+
+
+
+
+
+

Functions

+
+
+def get_pub_key_from_priv(priv_key, raw_encoding=False) +
+
+
+
+ +Expand source code + +
def get_pub_key_from_priv(priv_key: UserIDSecretKey, raw_encoding:bool=False)->UserID:
+    return signing.SigningKey(priv_key, encoder=encoding.Base32Encoder).verify_key.encode(encoding.Base32Encoder)
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcrypto/cryptoutils/index.html b/docs/html/src/onionrcrypto/cryptoutils/index.html similarity index 61% rename from docs/html/onionr/onionrcrypto/cryptoutils/index.html rename to docs/html/src/onionrcrypto/cryptoutils/index.html index 8c2d47c2..eb5953a9 100644 --- a/docs/html/onionr/onionrcrypto/cryptoutils/index.html +++ b/docs/html/src/onionrcrypto/cryptoutils/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.cryptoutils API documentation + +src.onionrcrypto.cryptoutils API documentation - + @@ -17,35 +17,43 @@
-

Module onionr.onionrcrypto.cryptoutils

+

Module src.onionrcrypto.cryptoutils

-Source code + +Expand source code +
from . import safecompare, replayvalidation, randomshuffle, verifypow
+from . import getpubfrompriv
 
 replay_validator = replayvalidation.replay_timestamp_validation
 random_shuffle = randomshuffle.random_shuffle
 safe_compare = safecompare.safe_compare
-verify_POW = verifypow.verify_POW
+verify_POW = verifypow.verify_POW +get_pub_key_from_priv = getpubfrompriv.get_pub_key_from_priv

Sub-modules

-
onionr.onionrcrypto.cryptoutils.randomshuffle
+
src.onionrcrypto.cryptoutils.getpubfrompriv
-
onionr.onionrcrypto.cryptoutils.replayvalidation
+
src.onionrcrypto.cryptoutils.randomshuffle
-
onionr.onionrcrypto.cryptoutils.safecompare
+
src.onionrcrypto.cryptoutils.replayvalidation
-
onionr.onionrcrypto.cryptoutils.verifypow
+
src.onionrcrypto.cryptoutils.safecompare
+
+
+
+
src.onionrcrypto.cryptoutils.verifypow
@@ -66,22 +74,23 @@ verify_POW = verifypow.verify_POW
diff --git a/docs/html/onionr/onionrcrypto/cryptoutils/randomshuffle.html b/docs/html/src/onionrcrypto/cryptoutils/randomshuffle.html similarity index 76% rename from docs/html/onionr/onionrcrypto/cryptoutils/randomshuffle.html rename to docs/html/src/onionrcrypto/cryptoutils/randomshuffle.html index ffef2e48..88fd0caa 100644 --- a/docs/html/onionr/onionrcrypto/cryptoutils/randomshuffle.html +++ b/docs/html/src/onionrcrypto/cryptoutils/randomshuffle.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.cryptoutils.randomshuffle API documentation + +src.onionrcrypto.cryptoutils.randomshuffle API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.cryptoutils.randomshuffle

+

Module src.onionrcrypto.cryptoutils.randomshuffle

-Source code + +Expand source code +
import secrets
 def random_shuffle(theList):
     myList = list(theList)
@@ -44,13 +46,15 @@ def random_shuffle(theList):
 

Functions

-
+
def random_shuffle(theList)
-Source code + +Expand source code +
def random_shuffle(theList):
     myList = list(theList)
     shuffledList = []
@@ -78,19 +82,19 @@ def random_shuffle(theList):
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/cryptoutils/replayvalidation.html b/docs/html/src/onionrcrypto/cryptoutils/replayvalidation.html similarity index 71% rename from docs/html/onionr/onionrcrypto/cryptoutils/replayvalidation.html rename to docs/html/src/onionrcrypto/cryptoutils/replayvalidation.html index 3db25e74..b18275bd 100644 --- a/docs/html/onionr/onionrcrypto/cryptoutils/replayvalidation.html +++ b/docs/html/src/onionrcrypto/cryptoutils/replayvalidation.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.cryptoutils.replayvalidation API documentation + +src.onionrcrypto.cryptoutils.replayvalidation API documentation - + @@ -17,17 +17,16 @@
-

Module onionr.onionrcrypto.cryptoutils.replayvalidation

+

Module src.onionrcrypto.cryptoutils.replayvalidation

-Source code + +Expand source code +
from onionrutils import epoch
 def replay_timestamp_validation(timestamp):
-    if epoch.get_epoch() - int(timestamp) > 2419200:
-        return False
-    else:
-        return True
+ return epoch.get_epoch() - int(timestamp) <= 2419200
@@ -37,18 +36,17 @@ def replay_timestamp_validation(timestamp):

Functions

-
+
def replay_timestamp_validation(timestamp)
-Source code + +Expand source code +
def replay_timestamp_validation(timestamp):
-    if epoch.get_epoch() - int(timestamp) > 2419200:
-        return False
-    else:
-        return True
+ return epoch.get_epoch() - int(timestamp) <= 2419200
@@ -64,19 +62,19 @@ def replay_timestamp_validation(timestamp):
diff --git a/docs/html/onionr/onionrcrypto/cryptoutils/safecompare.html b/docs/html/src/onionrcrypto/cryptoutils/safecompare.html similarity index 75% rename from docs/html/onionr/onionrcrypto/cryptoutils/safecompare.html rename to docs/html/src/onionrcrypto/cryptoutils/safecompare.html index 0354dc8a..855470e4 100644 --- a/docs/html/onionr/onionrcrypto/cryptoutils/safecompare.html +++ b/docs/html/src/onionrcrypto/cryptoutils/safecompare.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.cryptoutils.safecompare API documentation + +src.onionrcrypto.cryptoutils.safecompare API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.cryptoutils.safecompare

+

Module src.onionrcrypto.cryptoutils.safecompare

-Source code + +Expand source code +
import hmac
 def safe_compare(one, two):
     # Do encode here to avoid spawning core
@@ -43,13 +45,15 @@ def safe_compare(one, two):
 

Functions

-
+
def safe_compare(one, two)
-Source code + +Expand source code +
def safe_compare(one, two):
     # Do encode here to avoid spawning core
     try:
@@ -76,19 +80,19 @@ def safe_compare(one, two):
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/cryptoutils/verifypow.html b/docs/html/src/onionrcrypto/cryptoutils/verifypow.html similarity index 81% rename from docs/html/onionr/onionrcrypto/cryptoutils/verifypow.html rename to docs/html/src/onionrcrypto/cryptoutils/verifypow.html index 87378160..6991c38a 100644 --- a/docs/html/onionr/onionrcrypto/cryptoutils/verifypow.html +++ b/docs/html/src/onionrcrypto/cryptoutils/verifypow.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.cryptoutils.verifypow API documentation + +src.onionrcrypto.cryptoutils.verifypow API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.cryptoutils.verifypow

+

Module src.onionrcrypto.cryptoutils.verifypow

-Source code + +Expand source code +
from .. import hashers
 import config, onionrproofs, logger
 import onionrexceptions
@@ -68,13 +70,15 @@ def verify_POW(blockContent):
 

Functions

-
+
def verify_POW(blockContent)

Verifies the proof of work associated with a block

-Source code + +Expand source code +
def verify_POW(blockContent):
     '''
         Verifies the proof of work associated with a block
@@ -124,19 +128,19 @@ def verify_POW(blockContent):
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/encryption/index.html b/docs/html/src/onionrcrypto/encryption/index.html similarity index 82% rename from docs/html/onionr/onionrcrypto/encryption/index.html rename to docs/html/src/onionrcrypto/encryption/index.html index addaccc4..63673c0f 100644 --- a/docs/html/onionr/onionrcrypto/encryption/index.html +++ b/docs/html/src/onionrcrypto/encryption/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.encryption API documentation + +src.onionrcrypto.encryption API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.encryption

+

Module src.onionrcrypto.encryption

-Source code + +Expand source code +
import nacl.encoding, nacl.public, nacl.signing
 from .. import getourkeypair
 import unpaddedbase32
@@ -78,13 +80,15 @@ def pub_key_decrypt(data, pubkey='', privkey='', encodedData=Fal
 

Functions

-
+
def pub_key_decrypt(data, pubkey='', privkey='', encodedData=False)

pubkey decrypt (Curve25519, taken from Ed25519 pubkey)

-Source code + +Expand source code +
def pub_key_decrypt(data, pubkey='', privkey='', encodedData=False):
     '''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
     if pubkey != '':
@@ -107,13 +111,15 @@ def pub_key_decrypt(data, pubkey='', privkey='', encodedData=Fal
     return decrypted
-
+
def pub_key_encrypt(data, pubkey, encodedData=False)

Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)

-Source code + +Expand source code +
def pub_key_encrypt(data, pubkey, encodedData=False):
     '''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
     pubkey = unpaddedbase32.repad(bytesconverter.str_to_bytes(pubkey))
@@ -147,20 +153,20 @@ def pub_key_decrypt(data, pubkey='', privkey='', encodedData=Fal
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/generate.html b/docs/html/src/onionrcrypto/generate.html similarity index 81% rename from docs/html/onionr/onionrcrypto/generate.html rename to docs/html/src/onionrcrypto/generate.html index ed8a76e2..7dc79263 100644 --- a/docs/html/onionr/onionrcrypto/generate.html +++ b/docs/html/src/onionrcrypto/generate.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.generate API documentation + +src.onionrcrypto.generate API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.generate

+

Module src.onionrcrypto.generate

-Source code + +Expand source code +
import nacl.signing, nacl.encoding, nacl.pwhash
 import onionrexceptions
 from onionrutils import bytesconverter
@@ -58,13 +60,15 @@ def generate_deterministic(passphrase, bypassCheck=False):
 

Functions

-
+
def generate_deterministic(passphrase, bypassCheck=False)

Generate a Ed25519 public key pair from a password

-Source code + +Expand source code +
def generate_deterministic(passphrase, bypassCheck=False):
     '''Generate a Ed25519 public key pair from a password'''
     passStrength = onionrvalues.PASSWORD_LENGTH
@@ -84,13 +88,15 @@ def generate_deterministic(passphrase, bypassCheck=False):
     return (key.verify_key.encode(nacl.encoding.Base32Encoder).decode(), key.encode(nacl.encoding.Base32Encoder).decode())
-
+
def generate_pub_key()

Generate a Ed25519 public key pair, return tuple of base32encoded pubkey, privkey

-Source code + +Expand source code +
def generate_pub_key():
     '''Generate a Ed25519 public key pair, return tuple of base32encoded pubkey, privkey'''
     private_key = nacl.signing.SigningKey.generate()
@@ -111,20 +117,20 @@ def generate_deterministic(passphrase, bypassCheck=False):
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/getourkeypair.html b/docs/html/src/onionrcrypto/getourkeypair.html similarity index 80% rename from docs/html/onionr/onionrcrypto/getourkeypair.html rename to docs/html/src/onionrcrypto/getourkeypair.html index 407950e9..3a148764 100644 --- a/docs/html/onionr/onionrcrypto/getourkeypair.html +++ b/docs/html/src/onionrcrypto/getourkeypair.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.getourkeypair API documentation + +src.onionrcrypto.getourkeypair API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.onionrcrypto.getourkeypair

+

Module src.onionrcrypto.getourkeypair

Onionr - Private P2P Communication

returns our current active keypair

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
@@ -69,13 +71,15 @@ def get_keypair():
 

Functions

-
+
def get_keypair()
-Source code + +Expand source code +
def get_keypair():
     key_m = keymanager.KeyManager()
     if os.path.exists(filepaths.keys_file):
@@ -105,19 +109,19 @@ def get_keypair():
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/hashers.html b/docs/html/src/onionrcrypto/hashers.html similarity index 75% rename from docs/html/onionr/onionrcrypto/hashers.html rename to docs/html/src/onionrcrypto/hashers.html index 0271ad14..6b722cee 100644 --- a/docs/html/onionr/onionrcrypto/hashers.html +++ b/docs/html/src/onionrcrypto/hashers.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.hashers API documentation + +src.onionrcrypto.hashers API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.hashers

+

Module src.onionrcrypto.hashers

-Source code + +Expand source code +
import hashlib, nacl.hash
 def sha3_hash(data):
     try:
@@ -47,13 +49,15 @@ def blake2b_hash(data):
 

Functions

-
+
def blake2b_hash(data)
-Source code + +Expand source code +
def blake2b_hash(data):
     try:
         data = data.encode()
@@ -62,13 +66,15 @@ def blake2b_hash(data):
     return nacl.hash.blake2b(data)
-
+
def sha3_hash(data)
-Source code + +Expand source code +
def sha3_hash(data):
     try:
         data = data.encode()
@@ -92,20 +98,20 @@ def blake2b_hash(data):
 
 
 
diff --git a/docs/html/onionr/onionrcrypto/index.html b/docs/html/src/onionrcrypto/index.html similarity index 68% rename from docs/html/onionr/onionrcrypto/index.html rename to docs/html/src/onionrcrypto/index.html index 02f6115d..956501fc 100644 --- a/docs/html/onionr/onionrcrypto/index.html +++ b/docs/html/src/onionrcrypto/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto API documentation + +src.onionrcrypto API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.onionrcrypto

+

Module src.onionrcrypto

Onionr - Private P2P Communication

This file handles Onionr's cryptography.

-Source code + +Expand source code +
'''
     Onionr - Private P2P Communication
 
@@ -56,27 +58,27 @@ priv_key = keypair[1]

Sub-modules

-
onionr.onionrcrypto.cryptoutils
+
src.onionrcrypto.cryptoutils
-
onionr.onionrcrypto.encryption
+
src.onionrcrypto.encryption
-
onionr.onionrcrypto.generate
+
src.onionrcrypto.generate
-
onionr.onionrcrypto.getourkeypair
+
src.onionrcrypto.getourkeypair

Onionr - Private P2P Communication …

-
onionr.onionrcrypto.hashers
+
src.onionrcrypto.hashers
-
onionr.onionrcrypto.signing
+
src.onionrcrypto.signing
@@ -97,24 +99,24 @@ priv_key = keypair[1]
diff --git a/docs/html/onionr/onionrcrypto/signing/index.html b/docs/html/src/onionrcrypto/signing/index.html similarity index 75% rename from docs/html/onionr/onionrcrypto/signing/index.html rename to docs/html/src/onionrcrypto/signing/index.html index e527efb3..3d46430e 100644 --- a/docs/html/onionr/onionrcrypto/signing/index.html +++ b/docs/html/src/onionrcrypto/signing/index.html @@ -3,13 +3,13 @@ - -onionr.onionrcrypto.signing API documentation + +src.onionrcrypto.signing API documentation - + @@ -17,11 +17,13 @@
-

Module onionr.onionrcrypto.signing

+

Module src.onionrcrypto.signing

-Source code + +Expand source code +
import base64, binascii
 
 import unpaddedbase32
@@ -30,6 +32,7 @@ import nacl.encoding, nacl.signing, nacl.exceptions
 from onionrutils import bytesconverter
 from onionrutils import mnemonickeys
 import logger
+
 def ed_sign(data, key, encodeResult=False):
     '''Ed25519 sign data'''
     key = unpaddedbase32.repad(bytesconverter.str_to_bytes(key))
@@ -51,7 +54,6 @@ def ed_verify(data, key, sig, encodedData=True):
     try:
         key = nacl.signing.VerifyKey(key=key, encoder=nacl.encoding.Base32Encoder)
     except nacl.exceptions.ValueError:
-        #logger.debug('Signature by unknown key (cannot reverse hash)')
         return False
     except binascii.Error:
         logger.warn('Could not load key for verification, invalid padding')
@@ -62,16 +64,10 @@ def ed_verify(data, key, sig, encodedData=True):
         data = data.encode()
     except AttributeError:
         pass
-    if encodedData:
-        try:
-            retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
-        except nacl.exceptions.BadSignatureError:
-            pass
-    else:
-        try:
-            retData = key.verify(data, sig)
-        except nacl.exceptions.BadSignatureError:
-            pass
+    try:
+        retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
+    except nacl.exceptions.BadSignatureError:
+        pass
     return retData
@@ -82,13 +78,15 @@ def ed_verify(data, key, sig, encodedData=True):

Functions

-
+
def ed_sign(data, key, encodeResult=False)

Ed25519 sign data

-Source code + +Expand source code +
def ed_sign(data, key, encodeResult=False):
     '''Ed25519 sign data'''
     key = unpaddedbase32.repad(bytesconverter.str_to_bytes(key))
@@ -105,20 +103,21 @@ def ed_verify(data, key, sig, encodedData=True):
     return retData
-
+
def ed_verify(data, key, sig, encodedData=True)

Verify signed data (combined in nacl) to an ed25519 key

-Source code + +Expand source code +
def ed_verify(data, key, sig, encodedData=True):
     '''Verify signed data (combined in nacl) to an ed25519 key'''
     key = unpaddedbase32.repad(bytesconverter.str_to_bytes(key))
     try:
         key = nacl.signing.VerifyKey(key=key, encoder=nacl.encoding.Base32Encoder)
     except nacl.exceptions.ValueError:
-        #logger.debug('Signature by unknown key (cannot reverse hash)')
         return False
     except binascii.Error:
         logger.warn('Could not load key for verification, invalid padding')
@@ -129,16 +128,10 @@ def ed_verify(data, key, sig, encodedData=True):
         data = data.encode()
     except AttributeError:
         pass
-    if encodedData:
-        try:
-            retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
-        except nacl.exceptions.BadSignatureError:
-            pass
-    else:
-        try:
-            retData = key.verify(data, sig)
-        except nacl.exceptions.BadSignatureError:
-            pass
+    try:
+        retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
+    except nacl.exceptions.BadSignatureError:
+        pass
     return retData
@@ -155,20 +148,20 @@ def ed_verify(data, key, sig, encodedData=True):
diff --git a/docs/html/onionr/onionrexceptions.html b/docs/html/src/onionrexceptions.html similarity index 60% rename from docs/html/onionr/onionrexceptions.html rename to docs/html/src/onionrexceptions.html index c2a24ac7..913da13a 100644 --- a/docs/html/onionr/onionrexceptions.html +++ b/docs/html/src/onionrexceptions.html @@ -3,13 +3,13 @@ - -onionr.onionrexceptions API documentation + +src.onionrexceptions API documentation - + @@ -17,13 +17,15 @@
-

Module onionr.onionrexceptions

+

Module src.onionrexceptions

Onionr - Private P2P Communication

This file contains exceptions for onionr

-Source code + +Expand source code +
"""
     Onionr - Private P2P Communication
 
@@ -77,6 +79,9 @@ class SignatureError(Exception):
 class ReplayAttack(Exception):
     pass
 
+class InvalidUpdate(Exception):
+    pass
+
 class DifficultyTooLarge(Exception):
     pass
 
@@ -126,6 +131,19 @@ class MissingAddress(Exception):
 # Contact exceptions
 
 class ContactDeleted(Exception):
+    pass
+
+# Version Errors
+
+class PythonVersion(Exception):
+    pass
+
+# Auditing exceptions
+
+class NetworkLeak(Exception):
+    pass
+
+class ArbitraryCodeExec(Exception):
     pass
@@ -138,14 +156,35 @@ class ContactDeleted(Exception):

Classes

-
-class BlacklistedBlock -(*args, **kwargs) +
+class ArbitraryCodeExec +(...)

Common base class for all non-exit exceptions.

-Source code + +Expand source code + +
class ArbitraryCodeExec(Exception):
+    pass
+
+

Ancestors

+
    +
  • builtins.Exception
  • +
  • builtins.BaseException
  • +
+
+
+class BlacklistedBlock +(...) +
+
+

Common base class for all non-exit exceptions.

+
+ +Expand source code +
class BlacklistedBlock(Exception):
     pass
@@ -155,14 +194,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class ContactDeleted -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class ContactDeleted(Exception):
         pass
    @@ -172,14 +213,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class DataExists -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class DataExists(Exception):
         pass
    @@ -189,14 +232,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class DecryptionError -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class DecryptionError(Exception):
         pass
    @@ -206,14 +251,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class DifficultyTooLarge -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class DifficultyTooLarge(Exception):
         pass
    @@ -223,14 +270,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class DiskAllocationReached -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class DiskAllocationReached(Exception):
         pass
    @@ -240,14 +289,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class Invalid -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class Invalid(Exception):
         pass
    @@ -257,14 +308,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidAPIVersion -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class InvalidAPIVersion(Exception):
         pass
    @@ -274,14 +327,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidAddress -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class InvalidAddress(Exception):
         pass
    @@ -291,14 +346,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidHexHash -(*args, **kwargs) +(...)

    When a string is not a valid hex string of appropriate length for a hash value

    -Source code + +Expand source code +
    class InvalidHexHash(Exception):
         """When a string is not a valid hex string of appropriate length for a hash value"""
         pass
    @@ -309,14 +366,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidMetadata -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class InvalidMetadata(Exception):
         pass
    @@ -326,14 +385,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidProof -(*args, **kwargs) +(...)

    When a proof is invalid or inadequate

    -Source code + +Expand source code +
    class InvalidProof(Exception):
         """When a proof is invalid or inadequate"""
         pass
    @@ -344,14 +405,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class InvalidPubkey -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class InvalidPubkey(Exception):
         pass
    @@ -361,14 +424,35 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    -class KeyNotKnown -(*args, **kwargs) +
    +class InvalidUpdate +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code + +
    class InvalidUpdate(Exception):
    +    pass
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class KeyNotKnown +(...) +
    +
    +

    Common base class for all non-exit exceptions.

    +
    + +Expand source code +
    class KeyNotKnown(Exception):
         pass
    @@ -378,14 +462,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class MissingAddress -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class MissingAddress(Exception):
         pass
    @@ -395,14 +481,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class MissingPort -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class MissingPort(Exception):
         pass
    @@ -412,14 +500,35 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    -class NoDataAvailable -(*args, **kwargs) +
    +class NetworkLeak +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code + +
    class NetworkLeak(Exception):
    +    pass
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class NoDataAvailable +(...) +
    +
    +

    Common base class for all non-exit exceptions.

    +
    + +Expand source code +
    class NoDataAvailable(Exception):
         pass
    @@ -429,14 +538,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class NotFound -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class NotFound(Exception):
         pass
    @@ -446,14 +557,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class OnlinePeerNeeded -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class OnlinePeerNeeded(Exception):
         pass
    @@ -463,14 +576,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class PasswordStrengthError -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class PasswordStrengthError(Exception):
         pass
    @@ -480,14 +595,35 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    -class ReplayAttack -(*args, **kwargs) +
    +class PythonVersion +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code + +
    class PythonVersion(Exception):
    +    pass
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    +
    +class ReplayAttack +(...) +
    +
    +

    Common base class for all non-exit exceptions.

    +
    + +Expand source code +
    class ReplayAttack(Exception):
         pass
    @@ -497,14 +633,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class SignatureError -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class SignatureError(Exception):
         pass
    @@ -514,14 +652,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class Timeout -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class Timeout(Exception):
         pass
    @@ -531,14 +671,16 @@ class ContactDeleted(Exception):
  • builtins.BaseException
  • -
    +
    class Unknown -(*args, **kwargs) +(...)

    Common base class for all non-exit exceptions.

    -Source code + +Expand source code +
    class Unknown(Exception):
         pass
    @@ -559,82 +701,94 @@ class ContactDeleted(Exception):
    diff --git a/docs/html/onionr/onionrpeers/index.html b/docs/html/src/onionrpeers/index.html similarity index 70% rename from docs/html/onionr/onionrpeers/index.html rename to docs/html/src/onionrpeers/index.html index 9e145929..13e8df41 100644 --- a/docs/html/onionr/onionrpeers/index.html +++ b/docs/html/src/onionrpeers/index.html @@ -3,13 +3,13 @@ - -onionr.onionrpeers API documentation + +src.onionrpeers API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrpeers

    +

    Module src.onionrpeers

    -Source code + +Expand source code +
    from . import scoresortedpeerlist, peercleanup, peerprofiles
     get_score_sorted_peer_list = scoresortedpeerlist.get_score_sorted_peer_list
     peer_cleanup = peercleanup.peer_cleanup
    @@ -31,15 +33,15 @@ PeerProfiles = peerprofiles.PeerProfiles

    Sub-modules

    -
    onionr.onionrpeers.peercleanup
    +
    src.onionrpeers.peercleanup

    Onionr - Private P2P Communication …

    -
    onionr.onionrpeers.peerprofiles
    +
    src.onionrpeers.peerprofiles

    Onionr - Private P2P Communication …

    -
    onionr.onionrpeers.scoresortedpeerlist
    +
    src.onionrpeers.scoresortedpeerlist

    Onionr - Private P2P Communication …

    @@ -60,21 +62,21 @@ PeerProfiles = peerprofiles.PeerProfiles
    diff --git a/docs/html/onionr/onionrpeers/peercleanup.html b/docs/html/src/onionrpeers/peercleanup.html similarity index 80% rename from docs/html/onionr/onionrpeers/peercleanup.html rename to docs/html/src/onionrpeers/peercleanup.html index b281fad5..1879ac13 100644 --- a/docs/html/onionr/onionrpeers/peercleanup.html +++ b/docs/html/src/onionrpeers/peercleanup.html @@ -3,13 +3,13 @@ - -onionr.onionrpeers.peercleanup API documentation + +src.onionrpeers.peercleanup API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrpeers.peercleanup

    +

    Module src.onionrpeers.peercleanup

    Onionr - Private P2P Communication

    Cleanup the peer database

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -67,10 +69,8 @@ def peer_cleanup():
                 if peerprofiles.PeerProfiles(address).score < min_score:
                     keydb.removekeys.remove_address(address)
                     try:
    -                    if (int(epoch.get_epoch()) - int(keydb.transportinfo.get_address_info(address, 'lastConnect'))) >= 600:
    -                        expireTime = 600
    -                    else:
    -                        expireTime = 86400
    +                    lastConnect = int(keydb.transportinfo.get_address_info(address, 'lastConnect'))
    +                    expireTime = 86400 - int(epoch.get_epoch()) - lastConnect
                         blacklist.addToDB(address, dataType=1, expire=expireTime)
                     except sqlite3.IntegrityError: #TODO just make sure its not a unique constraint issue
                         pass
    @@ -89,13 +89,15 @@ def peer_cleanup():
     

    Functions

    -
    +
    def peer_cleanup()

    Removes peers who have been offline too long or score too low

    -Source code + +Expand source code +
    def peer_cleanup():
         '''Removes peers who have been offline too long or score too low'''
         logger.info('Cleaning peers...')
    @@ -113,10 +115,8 @@ def peer_cleanup():
                 if peerprofiles.PeerProfiles(address).score < min_score:
                     keydb.removekeys.remove_address(address)
                     try:
    -                    if (int(epoch.get_epoch()) - int(keydb.transportinfo.get_address_info(address, 'lastConnect'))) >= 600:
    -                        expireTime = 600
    -                    else:
    -                        expireTime = 86400
    +                    lastConnect = int(keydb.transportinfo.get_address_info(address, 'lastConnect'))
    +                    expireTime = 86400 - int(epoch.get_epoch()) - lastConnect
                         blacklist.addToDB(address, dataType=1, expire=expireTime)
                     except sqlite3.IntegrityError: #TODO just make sure its not a unique constraint issue
                         pass
    @@ -141,19 +141,19 @@ def peer_cleanup():
     
     
     
    diff --git a/docs/html/onionr/onionrpeers/peerprofiles.html b/docs/html/src/onionrpeers/peerprofiles.html similarity index 81% rename from docs/html/onionr/onionrpeers/peerprofiles.html rename to docs/html/src/onionrpeers/peerprofiles.html index 52016ea2..600daa7d 100644 --- a/docs/html/onionr/onionrpeers/peerprofiles.html +++ b/docs/html/src/onionrpeers/peerprofiles.html @@ -3,13 +3,13 @@ - -onionr.onionrpeers.peerprofiles API documentation + +src.onionrpeers.peerprofiles API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrpeers.peerprofiles

    +

    Module src.onionrpeers.peerprofiles

    Onionr - Private P2P Communication

    This file contains both the PeerProfiles class for network profiling of Onionr nodes

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -116,14 +118,16 @@ class PeerProfiles:
     

    Classes

    -
    +
    class PeerProfiles (address)

    PeerProfiles

    -Source code + +Expand source code +
    class PeerProfiles:
         '''
             PeerProfiles
    @@ -181,26 +185,30 @@ class PeerProfiles:
     

    Methods

    -
    +
    def addScore(self, toAdd)

    Add to the peer's score (can add negative)

    -Source code + +Expand source code +
    def addScore(self, toAdd):
         '''Add to the peer's score (can add negative)'''
         self.score += toAdd
         self.saveScore()
    -
    +
    def getConnectTime(self)

    set the connectTime variable for when we last connected to them, using the db value

    -Source code + +Expand source code +
    def getConnectTime(self):
         """set the connectTime variable for when we last connected to them, using the db value"""
         try:
    @@ -211,13 +219,15 @@ class PeerProfiles:
             return self.connectTime
    -
    +
    def loadScore(self)

    Load the node's score from the database

    -Source code + +Expand source code +
    def loadScore(self):
         '''Load the node's score from the database'''
         try:
    @@ -227,13 +237,15 @@ class PeerProfiles:
         self.score = self.success
    -
    +
    def saveScore(self)

    Save the node's score to the database

    -Source code + +Expand source code +
    def saveScore(self):
         '''Save the node's score to the database'''
         if epoch.get_epoch() - self.last_updated['score'] >= UPDATE_DELAY:
    @@ -242,13 +254,15 @@ class PeerProfiles:
         return
    -
    +
    def update_connect_time(self)
    -Source code + +Expand source code +
    def update_connect_time(self):
         if epoch.get_epoch() - self.last_updated['connect_time'] >= UPDATE_DELAY:
             self.last_updated['connect_time'] = epoch.get_epoch()
    @@ -268,19 +282,19 @@ class PeerProfiles:
     
    diff --git a/docs/html/onionr/onionrpeers/scoresortedpeerlist.html b/docs/html/src/onionrpeers/scoresortedpeerlist.html similarity index 81% rename from docs/html/onionr/onionrpeers/scoresortedpeerlist.html rename to docs/html/src/onionrpeers/scoresortedpeerlist.html index e7f1e675..bc77e865 100644 --- a/docs/html/onionr/onionrpeers/scoresortedpeerlist.html +++ b/docs/html/src/onionrpeers/scoresortedpeerlist.html @@ -3,13 +3,13 @@ - -onionr.onionrpeers.scoresortedpeerlist API documentation + +src.onionrpeers.scoresortedpeerlist API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrpeers.scoresortedpeerlist

    +

    Module src.onionrpeers.scoresortedpeerlist

    Onionr - Private P2P Communication

    Return a reliability score sorted list of peers

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -72,13 +74,15 @@ def get_score_sorted_peer_list():
     

    Functions

    -
    +
    def get_score_sorted_peer_list()
    -Source code + +Expand source code +
    def get_score_sorted_peer_list():
         peer_list = keydb.listkeys.list_adders()
         peer_scores = {}
    @@ -112,19 +116,19 @@ def get_score_sorted_peer_list():
     
     
     
    diff --git a/docs/html/onionr/onionrplugins/index.html b/docs/html/src/onionrplugins/index.html similarity index 76% rename from docs/html/onionr/onionrplugins/index.html rename to docs/html/src/onionrplugins/index.html index 4858d466..9c2446cf 100644 --- a/docs/html/onionr/onionrplugins/index.html +++ b/docs/html/src/onionrplugins/index.html @@ -3,13 +3,13 @@ - -onionr.onionrplugins API documentation + +src.onionrplugins API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrplugins

    +

    Module src.onionrplugins

    Onionr - Private P2P Communication

    This file deals with management of modules/plugins.

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -56,7 +58,7 @@ _pluginsfolder = dataDir + 'plugins/'
     _instances = dict()
     config.reload()
     
    -def reload(onionr = None, stop_event = True):
    +def reload(stop_event = True):
         '''
             Reloads all the plugins
         '''
    @@ -73,10 +75,10 @@ def reload(onionr = None, stop_event = True):
     
             if stop_event is True:
                 for plugin in enabled_plugins:
    -                stop(plugin, onionr)
    +                stop(plugin)
     
             for plugin in enabled_plugins:
    -            start(plugin, onionr)
    +            start(plugin)
     
             return True
         except:
    @@ -84,7 +86,7 @@ def reload(onionr = None, stop_event = True):
     
         return False
     
    -def enable(name, onionr = None, start_event = True):
    +def enable(name, start_event = True):
         '''
             Enables a plugin
         '''
    @@ -95,7 +97,7 @@ def enable(name, onionr = None, start_event = True):
             enabled_plugins = get_enabled_plugins()
             if not name in enabled_plugins:
                 try:
    -                events.call(get_plugin(name), 'enable', onionr)
    +                events.call(get_plugin(name), 'enable')
                 except ImportError as e: # Was getting import error on Gitlab CI test "data"
                     # NOTE: If you are experiencing issues with plugins not being enabled, it might be this resulting from an error in the module
                     # can happen inconsistently (especially between versions)
    @@ -118,7 +120,7 @@ def enable(name, onionr = None, start_event = True):
             return False
     
     
    -def disable(name, onionr = None, stop_event = True):
    +def disable(name, stop_event = True):
         '''
             Disables a plugin
         '''
    @@ -131,12 +133,12 @@ def disable(name, onionr = None, stop_event = True):
             config.set('plugins.enabled', enabled_plugins, True)
     
         if exists(name):
    -        events.call(get_plugin(name), 'disable', onionr)
    +        events.call(get_plugin(name), 'disable')
     
             if stop_event is True:
                 stop(name)
     
    -def start(name, onionr = None):
    +def start(name):
         '''
             Starts the plugin
         '''
    @@ -150,7 +152,7 @@ def start(name, onionr = None):
                 if plugin is None:
                     raise Exception('Failed to import module.')
                 else:
    -                events.call(plugin, 'start', onionr)
    +                events.call(plugin, 'start')
     
                 return plugin
             except:
    @@ -160,7 +162,7 @@ def start(name, onionr = None):
     
         return None
     
    -def stop(name, onionr = None):
    +def stop(name):
         '''
             Stops the plugin
         '''
    @@ -174,7 +176,7 @@ def stop(name, onionr = None):
                 if plugin is None:
                     raise Exception('Failed to import module.')
                 else:
    -                events.call(plugin, 'stop', onionr)
    +                events.call(plugin, 'stop')
     
                 return plugin
             except:
    @@ -298,11 +300,11 @@ def check():
     

    Sub-modules

    -
    onionr.onionrplugins.onionrevents
    +
    src.onionrplugins.onionrevents

    Onionr - Private P2P Communication …

    -
    onionr.onionrplugins.onionrpluginapi
    +
    src.onionrplugins.onionrpluginapi

    Onionr - Private P2P Communication …

    @@ -313,13 +315,15 @@ def check():

    Functions

    -
    +
    def check()

    Checks to make sure files exist

    -Source code + +Expand source code +
    def check():
         '''
             Checks to make sure files exist
    @@ -338,14 +342,16 @@ def check():
         return
    -
    -def disable(name, onionr=None, stop_event=True) +
    +def disable(name, stop_event=True)

    Disables a plugin

    -Source code -
    def disable(name, onionr = None, stop_event = True):
    +
    +Expand source code
    +
    +
    def disable(name, stop_event = True):
         '''
             Disables a plugin
         '''
    @@ -358,20 +364,22 @@ def check():
             config.set('plugins.enabled', enabled_plugins, True)
     
         if exists(name):
    -        events.call(get_plugin(name), 'disable', onionr)
    +        events.call(get_plugin(name), 'disable')
     
             if stop_event is True:
                 stop(name)
    -
    -def enable(name, onionr=None, start_event=True) +
    +def enable(name, start_event=True)

    Enables a plugin

    -Source code -
    def enable(name, onionr = None, start_event = True):
    +
    +Expand source code
    +
    +
    def enable(name, start_event = True):
         '''
             Enables a plugin
         '''
    @@ -382,7 +390,7 @@ def check():
             enabled_plugins = get_enabled_plugins()
             if not name in enabled_plugins:
                 try:
    -                events.call(get_plugin(name), 'enable', onionr)
    +                events.call(get_plugin(name), 'enable')
                 except ImportError as e: # Was getting import error on Gitlab CI test "data"
                     # NOTE: If you are experiencing issues with plugins not being enabled, it might be this resulting from an error in the module
                     # can happen inconsistently (especially between versions)
    @@ -405,13 +413,15 @@ def check():
             return False
    -
    +
    def exists(name)

    Return value indicates whether or not the plugin exists

    -Source code + +Expand source code +
    def exists(name):
         '''
             Return value indicates whether or not the plugin exists
    @@ -420,13 +430,15 @@ def check():
         return os.path.isdir(get_plugins_folder(str(name).lower()))
    -
    +
    def get_enabled_plugins()

    Returns a list of the enabled plugins

    -Source code + +Expand source code +
    def get_enabled_plugins():
         '''
             Returns a list of the enabled plugins
    @@ -437,13 +449,15 @@ def check():
         return list(config.get('plugins.enabled', list()))
    -
    +
    def get_plugin(name)

    Returns the instance of a module

    -Source code + +Expand source code +
    def get_plugin(name):
         '''
             Returns the instance of a module
    @@ -458,13 +472,15 @@ def check():
             return get_plugin(name)
    -
    +
    def get_plugin_data_folder(name, absolute=True)

    Returns the location of a plugin's data folder

    -Source code + +Expand source code +
    def get_plugin_data_folder(name, absolute = True):
         '''
             Returns the location of a plugin's data folder
    @@ -473,13 +489,15 @@ def check():
         return get_plugins_folder(name, absolute)
    -
    +
    def get_plugins()

    Returns a list of plugins (deprecated)

    -Source code + +Expand source code +
    def get_plugins():
         '''
             Returns a list of plugins (deprecated)
    @@ -488,13 +506,15 @@ def check():
         return _instances
    -
    +
    def get_plugins_folder(name=None, absolute=True)

    Returns the path to the plugins folder

    -Source code + +Expand source code +
    def get_plugins_folder(name = None, absolute = True):
         '''
             Returns the path to the plugins folder
    @@ -515,14 +535,16 @@ def check():
         return path + '/'
    -
    +
    def import_module_from_file(full_path_to_module)

    Import a module given the full path/filename of the .py file

    Python 3.4

    -Source code + +Expand source code +
    def import_module_from_file(full_path_to_module):
         """
         Import a module given the full path/filename of the .py file
    @@ -547,13 +569,15 @@ def check():
         return module
    -
    +
    def is_enabled(name)

    Return value indicates whether or not the plugin is enabled

    -Source code + +Expand source code +
    def is_enabled(name):
         '''
             Return value indicates whether or not the plugin is enabled
    @@ -562,14 +586,16 @@ def check():
         return name in get_enabled_plugins()
    -
    -def reload(onionr=None, stop_event=True) +
    +def reload(stop_event=True)

    Reloads all the plugins

    -Source code -
    def reload(onionr = None, stop_event = True):
    +
    +Expand source code
    +
    +
    def reload(stop_event = True):
         '''
             Reloads all the plugins
         '''
    @@ -586,10 +612,10 @@ def check():
     
             if stop_event is True:
                 for plugin in enabled_plugins:
    -                stop(plugin, onionr)
    +                stop(plugin)
     
             for plugin in enabled_plugins:
    -            start(plugin, onionr)
    +            start(plugin)
     
             return True
         except:
    @@ -598,14 +624,16 @@ def check():
         return False
    -
    -def start(name, onionr=None) +
    +def start(name)

    Starts the plugin

    -Source code -
    def start(name, onionr = None):
    +
    +Expand source code
    +
    +
    def start(name):
         '''
             Starts the plugin
         '''
    @@ -619,7 +647,7 @@ def check():
                 if plugin is None:
                     raise Exception('Failed to import module.')
                 else:
    -                events.call(plugin, 'start', onionr)
    +                events.call(plugin, 'start')
     
                 return plugin
             except:
    @@ -630,14 +658,16 @@ def check():
         return None
    -
    -def stop(name, onionr=None) +
    +def stop(name)

    Stops the plugin

    -Source code -
    def stop(name, onionr = None):
    +
    +Expand source code
    +
    +
    def stop(name):
         '''
             Stops the plugin
         '''
    @@ -651,7 +681,7 @@ def check():
                 if plugin is None:
                     raise Exception('Failed to import module.')
                 else:
    -                events.call(plugin, 'stop', onionr)
    +                events.call(plugin, 'stop')
     
                 return plugin
             except:
    @@ -675,38 +705,38 @@ def check():
     
     
     
    diff --git a/docs/html/onionr/onionrplugins/onionrevents.html b/docs/html/src/onionrplugins/onionrevents.html similarity index 80% rename from docs/html/onionr/onionrplugins/onionrevents.html rename to docs/html/src/onionrplugins/onionrevents.html index 0d885240..9360f07a 100644 --- a/docs/html/onionr/onionrplugins/onionrevents.html +++ b/docs/html/src/onionrplugins/onionrevents.html @@ -3,13 +3,13 @@ - -onionr.onionrplugins.onionrevents API documentation + +src.onionrplugins.onionrevents API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrplugins.onionrevents

    +

    Module src.onionrplugins.onionrevents

    Onionr - Private P2P Communication

    This file deals with configuration management.

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -58,7 +60,9 @@ def __event_caller(event_name, data = {}):
             DO NOT call this function, this is for threading code only.
             Instead, call onionrevents.event
         '''
    +    disabled = config.get('plugins.disabled')
         for plugin in plugins.get_enabled_plugins():
    +        if plugin in disabled: continue
             try:
                 call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(data))
             except ModuleNotFoundError as e:
    @@ -108,13 +112,15 @@ def call(plugin, event_name, data = None, pluginapi = None):
     

    Functions

    -
    +
    def call(plugin, event_name, data=None, pluginapi=None)

    Calls an event on a plugin if one is defined

    -Source code + +Expand source code +
    def call(plugin, event_name, data = None, pluginapi = None):
         '''
             Calls an event on a plugin if one is defined
    @@ -136,13 +142,15 @@ def call(plugin, event_name, data = None, pluginapi = None):
             return True
    -
    +
    def event(event_name, data={}, threaded=True)

    Calls an event on all plugins (if defined)

    -Source code + +Expand source code +
    def event(event_name, data = {}, threaded = True):
         '''
             Calls an event on all plugins (if defined)
    @@ -156,13 +164,15 @@ def call(plugin, event_name, data = None, pluginapi = None):
             __event_caller(event_name, data)
    -
    +
    def get_pluginapi(data)
    -Source code + +Expand source code +
    def get_pluginapi(data):
         return pluginapi.SharedAPI(data)
    @@ -180,21 +190,21 @@ def call(plugin, event_name, data = None, pluginapi = None):
    diff --git a/docs/html/onionr/onionrplugins/onionrpluginapi.html b/docs/html/src/onionrplugins/onionrpluginapi.html similarity index 64% rename from docs/html/onionr/onionrplugins/onionrpluginapi.html rename to docs/html/src/onionrplugins/onionrpluginapi.html index 5c23340d..5474711e 100644 --- a/docs/html/onionr/onionrplugins/onionrpluginapi.html +++ b/docs/html/src/onionrplugins/onionrpluginapi.html @@ -3,13 +3,13 @@ - -onionr.onionrplugins.onionrpluginapi API documentation + +src.onionrplugins.onionrpluginapi API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrplugins.onionrpluginapi

    +

    Module src.onionrplugins.onionrpluginapi

    Onionr - Private P2P Communication

    This file deals with the object that is passed with each event

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -46,7 +48,6 @@
     
     import onionrplugins, logger
     from onionrutils import localcommand
    -from coredb import daemonqueue
     
     class PluginAPI:
         def __init__(self, pluginapi):
    @@ -82,9 +83,6 @@ class PluginAPI:
         def get_data_folder(self, name, absolute = True):
             return onionrplugins.get_plugin_data_folder(name, absolute = absolute)
     
    -    def daemon_event(self, event, plugin = None):
    -        return # later make local command like /client/?action=makeEvent&event=eventname&module=modulename
    -
     class CommandAPI:
         def __init__(self, pluginapi):
             self.pluginapi = pluginapi
    @@ -116,14 +114,16 @@ class SharedAPI:
     

    Classes

    -
    +
    class CommandAPI (pluginapi)
    -Source code + +Expand source code +
    class CommandAPI:
         def __init__(self, pluginapi):
             self.pluginapi = pluginapi
    @@ -133,27 +133,31 @@ class SharedAPI:
     

    Methods

    -
    +
    def call(self, name)
    -Source code + +Expand source code +
    def call(self, name):
         self.pluginapi.get_onionr().execute(name)
    -
    +
    class PluginAPI (pluginapi)
    -Source code + +Expand source code +
    class PluginAPI:
         def __init__(self, pluginapi):
             self.pluginapi = pluginapi
    @@ -186,144 +190,152 @@ class SharedAPI:
             return onionrplugins.get_plugins_folder(name = name, absolute = absolute)
     
         def get_data_folder(self, name, absolute = True):
    -        return onionrplugins.get_plugin_data_folder(name, absolute = absolute)
    -
    -    def daemon_event(self, event, plugin = None):
    -        return # later make local command like /client/?action=makeEvent&event=eventname&module=modulename
    + return onionrplugins.get_plugin_data_folder(name, absolute = absolute)

    Methods

    -
    -def daemon_event(self, event, plugin=None) -
    -
    -
    -
    -Source code -
    def daemon_event(self, event, plugin = None):
    -    return # later make local command like /client/?action=makeEvent&event=eventname&module=modulename
    -
    -
    -
    +
    def disable(self, name)
    -Source code + +Expand source code +
    def disable(self, name):
         onionrplugins.disable(name)
    -
    +
    def enable(self, name)
    -Source code + +Expand source code +
    def enable(self, name):
         onionrplugins.enable(name)
    -
    +
    def event(self, name, data={})
    -Source code + +Expand source code +
    def event(self, name, data = {}):
         events.event(name, data = data)
    -
    +
    def get_data_folder(self, name, absolute=True)
    -Source code + +Expand source code +
    def get_data_folder(self, name, absolute = True):
         return onionrplugins.get_plugin_data_folder(name, absolute = absolute)
    -
    +
    def get_enabled_plugins(self)
    -Source code + +Expand source code +
    def get_enabled_plugins(self):
         return onionrplugins.get_enabled()
    -
    +
    def get_folder(self, name=None, absolute=True)
    -Source code + +Expand source code +
    def get_folder(self, name = None, absolute = True):
         return onionrplugins.get_plugins_folder(name = name, absolute = absolute)
    -
    +
    def is_enabled(self, name)
    -Source code + +Expand source code +
    def is_enabled(self, name):
         return onionrplugins.is_enabled(name)
    -
    +
    def reload(self, name)
    -Source code + +Expand source code +
    def reload(self, name):
         onionrplugins.reload(name)
    -
    +
    def start(self, name)
    -Source code + +Expand source code +
    def start(self, name):
         onionrplugins.start(name)
    -
    +
    def stop(self, name)
    -Source code + +Expand source code +
    def stop(self, name):
         onionrplugins.stop(name)
    -
    +
    class SharedAPI (data)
    -Source code + +Expand source code +
    class SharedAPI:
         def __init__(self, data):
             self.data = data
    @@ -340,35 +352,41 @@ class SharedAPI:
     

    Methods

    -
    +
    def get_daemonapi(self)
    -Source code + +Expand source code +
    def get_daemonapi(self):
         return self.daemon
    -
    +
    def get_data(self)
    -Source code + +Expand source code +
    def get_data(self):
         return self.data
    -
    +
    def get_pluginapi(self)
    -Source code + +Expand source code +
    def get_pluginapi(self):
         return self.plugins
    @@ -386,39 +404,38 @@ class SharedAPI:
    diff --git a/docs/html/src/onionrproofs/blocknoncestart.html b/docs/html/src/onionrproofs/blocknoncestart.html new file mode 100644 index 00000000..7a238569 --- /dev/null +++ b/docs/html/src/onionrproofs/blocknoncestart.html @@ -0,0 +1,59 @@ + + + + + + +src.onionrproofs.blocknoncestart API documentation + + + + + + + + + +
    +
    +
    +

    Module src.onionrproofs.blocknoncestart

    +
    +
    +
    + +Expand source code + +
    BLOCK_NONCE_START_INT = -10000000
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrproofs/index.html b/docs/html/src/onionrproofs/index.html similarity index 58% rename from docs/html/onionr/onionrproofs/index.html rename to docs/html/src/onionrproofs/index.html index f171c101..eaa1a233 100644 --- a/docs/html/onionr/onionrproofs/index.html +++ b/docs/html/src/onionrproofs/index.html @@ -3,13 +3,13 @@ - -onionr.onionrproofs API documentation + +src.onionrproofs API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrproofs

    +

    Module src.onionrproofs

    Onionr - Private P2P Communication

    Proof of work module

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -50,10 +52,12 @@ import config, logger
     from onionrblocks import onionrblockapi, storagecounter
     from onionrutils import bytesconverter
     from onionrcrypto import hashers
    +
    +from .blocknoncestart import BLOCK_NONCE_START_INT
     config.reload()
     
     def getDifficultyModifier():
    -    '''returns the difficulty modifier for block storage based 
    +    '''returns the difficulty modifier for block storage based
         on a variety of factors, currently only disk use.
         '''
         percentUse = storagecounter.StorageCounter().get_percent()
    @@ -96,90 +100,6 @@ def hashMeetsDifficulty(hexHash):
     
         return hashDifficulty >= expected
     
    -class DataPOW:
    -    def __init__(self, data, minDifficulty = 0, threadCount = 1):
    -        self.data = data
    -        self.threadCount = threadCount
    -        self.difficulty = max(minDifficulty, getDifficultyForNewBlock(data))
    -        self.rounds = 0
    -        self.hashing = False
    -        self.foundHash = False
    -
    -        try:
    -            self.data = self.data.encode()
    -        except AttributeError:
    -            pass
    -        
    -        self.data = nacl.hash.blake2b(self.data)
    -
    -        logger.info('Computing POW (difficulty: %s)...' % self.difficulty)
    -
    -        self.mainHash = '0' * 70
    -        self.puzzle = self.mainHash[0:min(self.difficulty, len(self.mainHash))]
    -        
    -        for i in range(max(1, threadCount)):
    -            t = threading.Thread(name = 'thread%s' % i, target = self.pow, args = (True,))
    -            t.start()
    -
    -    def pow(self, reporting = False):
    -        startTime = math.floor(time.time())
    -        self.hashing = True
    -        self.reporting = reporting
    -        iFound = False # if current thread is the one that found the answer
    -        
    -        while self.hashing:
    -            rand = nacl.utils.random()
    -            token = nacl.hash.blake2b(rand + self.data).decode()
    -            self.rounds += 1
    -            #print(token)
    -            if self.puzzle == token[0:self.difficulty]:
    -                self.hashing = False
    -                iFound = True
    -                break
    -                
    -        if iFound:
    -            endTime = math.floor(time.time())
    -            if self.reporting:
    -                logger.debug('Found token after %s seconds: %s' % (endTime - startTime, token), timestamp=True)
    -                logger.debug('Round count: %s' % (self.rounds,))
    -            self.result = (token, rand)
    -
    -    def shutdown(self):
    -        self.hashing = False
    -        self.puzzle = ''
    -
    -    def changeDifficulty(self, newDiff):
    -        self.difficulty = newDiff
    -
    -    def getResult(self):
    -        '''
    -            Returns the result then sets to false, useful to automatically clear the result
    -        '''
    -        
    -        try:
    -            retVal = self.result
    -        except AttributeError:
    -            retVal = False
    -            
    -        self.result = False
    -        return retVal
    -
    -    def waitForResult(self):
    -        '''
    -            Returns the result only when it has been found, False if not running and not found
    -        '''
    -        result = False
    -        try:
    -            while True:
    -                result = self.getResult()
    -                if not self.hashing:
    -                    break
    -                else:
    -                    time.sleep(1)
    -        except KeyboardInterrupt:
    -            self.shutdown()
    -            logger.warn('Got keyboard interrupt while waiting for POW result, stopping')
    -        return result
     
     class POW:
         def __init__(self, metadata, data, threadCount = 1, minDifficulty=0):
    @@ -196,13 +116,13 @@ class POW:
                 self.data = self.data.encode()
             except AttributeError:
                 pass
    -            
    +
             if minDifficulty > 0:
                 self.difficulty = minDifficulty
             else:
                 # Calculate difficulty. Dumb for now, may use good algorithm in the future.
                 self.difficulty = getDifficultyForNewBlock(bytes(json_metadata + b'\n' + self.data))
    -            
    +
             logger.info('Computing POW (difficulty: %s)...' % (self.difficulty,))
     
             self.mainHash = '0' * 64
    @@ -217,9 +137,8 @@ class POW:
             self.hashing = True
             self.reporting = reporting
             iFound = False # if current thread is the one that found the answer
    -        nonce = int(binascii.hexlify(nacl.utils.random(64)), 16)
    +        nonce = BLOCK_NONCE_START_INT
             while self.hashing:
    -            #token = nacl.hash.blake2b(rand + self.data).decode()
                 self.metadata['pow'] = nonce
                 payload = json.dumps(self.metadata).encode() + b'\n' + self.data
                 token = hashers.sha3_hash(payload)
    @@ -234,7 +153,7 @@ class POW:
                     self.result = payload
                     break
                 nonce += 1
    -                
    +
             if iFound:
                 endTime = math.floor(time.time())
                 if self.reporting:
    @@ -251,12 +170,12 @@ class POW:
             '''
                 Returns the result then sets to false, useful to automatically clear the result
             '''
    -        
    +
             try:
                 retVal = self.result
             except AttributeError:
                 retVal = False
    -            
    +
             self.result = False
             return retVal
     
    @@ -281,7 +200,11 @@ class POW:
     

    Sub-modules

    -
    onionr.onionrproofs.subprocesspow
    +
    src.onionrproofs.blocknoncestart
    +
    +
    +
    +
    src.onionrproofs.subprocesspow

    Onionr - Private P2P Communication …

    @@ -292,13 +215,15 @@ class POW:

    Functions

    -
    +
    def getDifficultyForNewBlock(data)

    Get difficulty for block. Accepts size in integer, Block instance, or str/bytes full block contents

    -Source code + +Expand source code +
    def getDifficultyForNewBlock(data):
         '''
         Get difficulty for block. Accepts size in integer, Block instance, or str/bytes full block contents
    @@ -316,16 +241,18 @@ class POW:
         return retData
    -
    +
    def getDifficultyModifier()

    returns the difficulty modifier for block storage based on a variety of factors, currently only disk use.

    -Source code + +Expand source code +
    def getDifficultyModifier():
    -    '''returns the difficulty modifier for block storage based 
    +    '''returns the difficulty modifier for block storage based
         on a variety of factors, currently only disk use.
         '''
         percentUse = storagecounter.StorageCounter().get_percent()
    @@ -334,13 +261,15 @@ on a variety of factors, currently only disk use.

    return difficultyIncrease
    -
    +
    def getHashDifficulty(h)

    Return the amount of leading zeroes in a hex hash string (hexHash)

    -Source code + +Expand source code +
    def getHashDifficulty(h: str):
         '''
             Return the amount of leading zeroes in a hex hash string (hexHash)
    @@ -348,13 +277,15 @@ on a variety of factors, currently only disk use.

    return len(h) - len(h.lstrip('0')) -
    +
    def hashMeetsDifficulty(hexHash)

    Return bool for a hash string to see if it meets pow difficulty defined in config

    -Source code + +Expand source code +
    def hashMeetsDifficulty(hexHash):
         '''
             Return bool for a hash string to see if it meets pow difficulty defined in config
    @@ -374,211 +305,16 @@ on a variety of factors, currently only disk use.

    Classes

    -
    -class DataPOW -(data, minDifficulty=0, threadCount=1) -
    -
    -
    -
    -Source code -
    class DataPOW:
    -    def __init__(self, data, minDifficulty = 0, threadCount = 1):
    -        self.data = data
    -        self.threadCount = threadCount
    -        self.difficulty = max(minDifficulty, getDifficultyForNewBlock(data))
    -        self.rounds = 0
    -        self.hashing = False
    -        self.foundHash = False
    -
    -        try:
    -            self.data = self.data.encode()
    -        except AttributeError:
    -            pass
    -        
    -        self.data = nacl.hash.blake2b(self.data)
    -
    -        logger.info('Computing POW (difficulty: %s)...' % self.difficulty)
    -
    -        self.mainHash = '0' * 70
    -        self.puzzle = self.mainHash[0:min(self.difficulty, len(self.mainHash))]
    -        
    -        for i in range(max(1, threadCount)):
    -            t = threading.Thread(name = 'thread%s' % i, target = self.pow, args = (True,))
    -            t.start()
    -
    -    def pow(self, reporting = False):
    -        startTime = math.floor(time.time())
    -        self.hashing = True
    -        self.reporting = reporting
    -        iFound = False # if current thread is the one that found the answer
    -        
    -        while self.hashing:
    -            rand = nacl.utils.random()
    -            token = nacl.hash.blake2b(rand + self.data).decode()
    -            self.rounds += 1
    -            #print(token)
    -            if self.puzzle == token[0:self.difficulty]:
    -                self.hashing = False
    -                iFound = True
    -                break
    -                
    -        if iFound:
    -            endTime = math.floor(time.time())
    -            if self.reporting:
    -                logger.debug('Found token after %s seconds: %s' % (endTime - startTime, token), timestamp=True)
    -                logger.debug('Round count: %s' % (self.rounds,))
    -            self.result = (token, rand)
    -
    -    def shutdown(self):
    -        self.hashing = False
    -        self.puzzle = ''
    -
    -    def changeDifficulty(self, newDiff):
    -        self.difficulty = newDiff
    -
    -    def getResult(self):
    -        '''
    -            Returns the result then sets to false, useful to automatically clear the result
    -        '''
    -        
    -        try:
    -            retVal = self.result
    -        except AttributeError:
    -            retVal = False
    -            
    -        self.result = False
    -        return retVal
    -
    -    def waitForResult(self):
    -        '''
    -            Returns the result only when it has been found, False if not running and not found
    -        '''
    -        result = False
    -        try:
    -            while True:
    -                result = self.getResult()
    -                if not self.hashing:
    -                    break
    -                else:
    -                    time.sleep(1)
    -        except KeyboardInterrupt:
    -            self.shutdown()
    -            logger.warn('Got keyboard interrupt while waiting for POW result, stopping')
    -        return result
    -
    -

    Methods

    -
    -
    -def changeDifficulty(self, newDiff) -
    -
    -
    -
    -Source code -
    def changeDifficulty(self, newDiff):
    -    self.difficulty = newDiff
    -
    -
    -
    -def getResult(self) -
    -
    -

    Returns the result then sets to false, useful to automatically clear the result

    -
    -Source code -
    def getResult(self):
    -    '''
    -        Returns the result then sets to false, useful to automatically clear the result
    -    '''
    -    
    -    try:
    -        retVal = self.result
    -    except AttributeError:
    -        retVal = False
    -        
    -    self.result = False
    -    return retVal
    -
    -
    -
    -def pow(self, reporting=False) -
    -
    -
    -
    -Source code -
    def pow(self, reporting = False):
    -    startTime = math.floor(time.time())
    -    self.hashing = True
    -    self.reporting = reporting
    -    iFound = False # if current thread is the one that found the answer
    -    
    -    while self.hashing:
    -        rand = nacl.utils.random()
    -        token = nacl.hash.blake2b(rand + self.data).decode()
    -        self.rounds += 1
    -        #print(token)
    -        if self.puzzle == token[0:self.difficulty]:
    -            self.hashing = False
    -            iFound = True
    -            break
    -            
    -    if iFound:
    -        endTime = math.floor(time.time())
    -        if self.reporting:
    -            logger.debug('Found token after %s seconds: %s' % (endTime - startTime, token), timestamp=True)
    -            logger.debug('Round count: %s' % (self.rounds,))
    -        self.result = (token, rand)
    -
    -
    -
    -def shutdown(self) -
    -
    -
    -
    -Source code -
    def shutdown(self):
    -    self.hashing = False
    -    self.puzzle = ''
    -
    -
    -
    -def waitForResult(self) -
    -
    -

    Returns the result only when it has been found, False if not running and not found

    -
    -Source code -
    def waitForResult(self):
    -    '''
    -        Returns the result only when it has been found, False if not running and not found
    -    '''
    -    result = False
    -    try:
    -        while True:
    -            result = self.getResult()
    -            if not self.hashing:
    -                break
    -            else:
    -                time.sleep(1)
    -    except KeyboardInterrupt:
    -        self.shutdown()
    -        logger.warn('Got keyboard interrupt while waiting for POW result, stopping')
    -    return result
    -
    -
    -
    -
    -
    +
    class POW (metadata, data, threadCount=1, minDifficulty=0)
    -Source code + +Expand source code +
    class POW:
         def __init__(self, metadata, data, threadCount = 1, minDifficulty=0):
             self.foundHash = False
    @@ -594,13 +330,13 @@ on a variety of factors, currently only disk use.

    self.data = self.data.encode() except AttributeError: pass - + if minDifficulty > 0: self.difficulty = minDifficulty else: # Calculate difficulty. Dumb for now, may use good algorithm in the future. self.difficulty = getDifficultyForNewBlock(bytes(json_metadata + b'\n' + self.data)) - + logger.info('Computing POW (difficulty: %s)...' % (self.difficulty,)) self.mainHash = '0' * 64 @@ -615,9 +351,8 @@ on a variety of factors, currently only disk use.

    self.hashing = True self.reporting = reporting iFound = False # if current thread is the one that found the answer - nonce = int(binascii.hexlify(nacl.utils.random(64)), 16) + nonce = BLOCK_NONCE_START_INT while self.hashing: - #token = nacl.hash.blake2b(rand + self.data).decode() self.metadata['pow'] = nonce payload = json.dumps(self.metadata).encode() + b'\n' + self.data token = hashers.sha3_hash(payload) @@ -632,7 +367,7 @@ on a variety of factors, currently only disk use.

    self.result = payload break nonce += 1 - + if iFound: endTime = math.floor(time.time()) if self.reporting: @@ -649,12 +384,12 @@ on a variety of factors, currently only disk use.

    ''' Returns the result then sets to false, useful to automatically clear the result ''' - + try: retVal = self.result except AttributeError: retVal = False - + self.result = False return retVal @@ -677,53 +412,58 @@ on a variety of factors, currently only disk use.

    Methods

    -
    +
    def changeDifficulty(self, newDiff)
    -Source code + +Expand source code +
    def changeDifficulty(self, newDiff):
         self.difficulty = newDiff
    -
    +
    def getResult(self)

    Returns the result then sets to false, useful to automatically clear the result

    -Source code + +Expand source code +
    def getResult(self):
         '''
             Returns the result then sets to false, useful to automatically clear the result
         '''
    -    
    +
         try:
             retVal = self.result
         except AttributeError:
             retVal = False
    -        
    +
         self.result = False
         return retVal
    -
    +
    def pow(self, reporting=False)
    -Source code + +Expand source code +
    def pow(self, reporting = False):
         startTime = math.floor(time.time())
         self.hashing = True
         self.reporting = reporting
         iFound = False # if current thread is the one that found the answer
    -    nonce = int(binascii.hexlify(nacl.utils.random(64)), 16)
    +    nonce = BLOCK_NONCE_START_INT
         while self.hashing:
    -        #token = nacl.hash.blake2b(rand + self.data).decode()
             self.metadata['pow'] = nonce
             payload = json.dumps(self.metadata).encode() + b'\n' + self.data
             token = hashers.sha3_hash(payload)
    @@ -738,32 +478,36 @@ on a variety of factors, currently only disk use.

    self.result = payload break nonce += 1 - + if iFound: endTime = math.floor(time.time()) if self.reporting: logger.debug('Found token after %s seconds: %s' % (endTime - startTime, token), timestamp=True)
    -
    +
    def shutdown(self)
    -Source code + +Expand source code +
    def shutdown(self):
         self.hashing = False
         self.puzzle = ''
    -
    +
    def waitForResult(self)

    Returns the result only when it has been found, False if not running and not found

    -Source code + +Expand source code +
    def waitForResult(self):
         '''
             Returns the result only when it has been found, False if not running and not found
    @@ -795,42 +539,33 @@ on a variety of factors, currently only disk use.

    diff --git a/docs/html/onionr/onionrproofs/subprocesspow.html b/docs/html/src/onionrproofs/subprocesspow.html similarity index 63% rename from docs/html/onionr/onionrproofs/subprocesspow.html rename to docs/html/src/onionrproofs/subprocesspow.html index 02a90812..55baa970 100644 --- a/docs/html/onionr/onionrproofs/subprocesspow.html +++ b/docs/html/src/onionrproofs/subprocesspow.html @@ -3,13 +3,13 @@ - -onionr.onionrproofs.subprocesspow API documentation + +src.onionrproofs.subprocesspow API documentation - + @@ -17,20 +17,35 @@
    -

    Module onionr.onionrproofs.subprocesspow

    +

    Module src.onionrproofs.subprocesspow

    Onionr - Private P2P Communication

    Multiprocess proof of work

    -Source code + +Expand source code +
    #!/usr/bin/env python3
    -'''
    +"""
         Onionr - Private P2P Communication
     
         Multiprocess proof of work
    -'''
    -'''
    +"""
    +
    +import os
    +from multiprocessing import Pipe, Process
    +import threading
    +import time
    +import json
    +
    +import logger
    +import onionrproofs
    +import onionrcrypto as crypto
    +from onionrutils import bytesconverter
    +from .blocknoncestart import BLOCK_NONCE_START_INT
    +
    +"""
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation, either version 3 of the License, or
    @@ -43,23 +58,20 @@
     
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
    -'''
    +"""
    +
     
    -import subprocess, os
    -import multiprocessing, threading, time, json
    -from multiprocessing import Pipe, Process
    -from onionrblocks import onionrblockapi
    -import config, onionrutils, logger, onionrproofs, onionrcrypto as crypto
    -from onionrutils import bytesconverter
     class SubprocessPOW:
         def __init__(self, data, metadata, subproc_count=None):
    -        '''
    +        """
                 Onionr proof of work using multiple processes
                 Accepts block data, block metadata
    -            if subproc_count is not set, os.cpu_count() is used to determine the number of processes
    +            if subproc_count is not set,
    +            os.cpu_count() is used to determine the number of processes
     
    -            Do to Python GIL multiprocessing or use of external libraries is necessary to accelerate CPU bound tasks
    -        '''
    +            Due to Python GIL multiprocessing/use of external libraries
    +            is necessary to accelerate CPU bound tasks
    +        """
             # No known benefit to using more processes than there are cores.
             # Note: os.cpu_count perhaps not always accurate
             if subproc_count is None:
    @@ -70,24 +82,31 @@ class SubprocessPOW:
             self.data = data
             self.metadata = metadata
     
    -        # dump dict to measure bytes of json metadata. Cannot reuse later because the pow token must be added
    +        """dump dict to measure bytes of json metadata
    +        Cannot reuse later bc the pow token must be added
    +        """
             json_metadata = json.dumps(metadata).encode()
     
             self.data = bytesconverter.str_to_bytes(data)
    -        # Calculate difficulty. Dumb for now, may use good algorithm in the future.
    -        self.difficulty = onionrproofs.getDifficultyForNewBlock(bytes(json_metadata + b'\n' + self.data))
    -        
    +
    +        compiled_data = bytes(json_metadata + b'\n' + self.data)
    +
    +        # Calculate difficulty. May use better algorithm in the future.
    +        self.difficulty = onionrproofs.getDifficultyForNewBlock(compiled_data)
    +
             logger.info('Computing POW (difficulty: %s)...' % (self.difficulty,))
     
    -        self.mainHash = '0' * 64
    -        self.puzzle = self.mainHash[0:min(self.difficulty, len(self.mainHash))]
    +        self.main_hash = '0' * 64
    +        self.puzzle = self.main_hash[0:min(self.difficulty,
    +                                           len(self.main_hash))]
             self.shutdown = False
             self.payload = None
     
         def start(self):
    +        """spawn the multiproc handler threads"""
             # Create a new thread for each subprocess
    -        for x in range(self.subproc_count):
    -            threading.Thread(target=self._spawn_proc).start()
    +        for _ in range(self.subproc_count): # noqa
    +            threading.Thread(target=self._spawn_proc, daemon=True).start()
             # Monitor the processes for a payload, shut them down when its found
             while True:
                 if self.payload is None:
    @@ -95,11 +114,12 @@ class SubprocessPOW:
                 else:
                     self.shutdown = True
                     return self.payload
    -    
    +
         def _spawn_proc(self):
    -        # Create a child proof of work process, wait for data and send shutdown signal when its found
    +        """Create a child proof of work process
    +        wait for data and send shutdown signal when its found"""
             parent_conn, child_conn = Pipe()
    -        p = Process(target=self.do_pow, args=(child_conn,))
    +        p = Process(target=self.do_pow, args=(child_conn,), daemon=True)
             p.start()
             p.join()
             payload = None
    @@ -116,8 +136,8 @@ class SubprocessPOW:
                 self.payload = payload
     
         def do_pow(self, pipe):
    -        nonce = -10000000 # Start nonce at negative 10 million so that the chosen nonce is likely to be small in length
    -        nonceStart = nonce
    +        """find partial hash colision generating nonce for a block"""
    +        nonce = BLOCK_NONCE_START_INT
             data = self.data
             metadata = self.metadata
             puzzle = self.puzzle
    @@ -130,14 +150,15 @@ class SubprocessPOW:
                 metadata['pow'] = nonce
                 # Serialize metadata, combine with block data
                 payload = json.dumps(metadata).encode() + b'\n' + data
    -            # Check sha3_256 hash of block, compare to puzzle. Send payload if puzzle finished
    +            # Check sha3_256 hash of block, compare to puzzle
    +            # Send payload if puzzle finished
                 token = crypto.hashers.sha3_hash(payload)
    -            token = bytesconverter.bytes_to_str(token) # ensure token is string
    +            # ensure token is string
    +            token = bytesconverter.bytes_to_str(token)
                 if puzzle == token[0:difficulty]:
                     pipe.send(payload)
                     break
    -            nonce += 1
    -        
    + nonce += 1
    @@ -149,26 +170,32 @@ class SubprocessPOW:

    Classes

    -
    +
    class SubprocessPOW (data, metadata, subproc_count=None)

    Onionr proof of work using multiple processes Accepts block data, block metadata -if subproc_count is not set, os.cpu_count() is used to determine the number of processes

    -

    Do to Python GIL multiprocessing or use of external libraries is necessary to accelerate CPU bound tasks

    +if subproc_count is not set, +os.cpu_count() is used to determine the number of processes

    +

    Due to Python GIL multiprocessing/use of external libraries +is necessary to accelerate CPU bound tasks

    -Source code + +Expand source code +
    class SubprocessPOW:
         def __init__(self, data, metadata, subproc_count=None):
    -        '''
    +        """
                 Onionr proof of work using multiple processes
                 Accepts block data, block metadata
    -            if subproc_count is not set, os.cpu_count() is used to determine the number of processes
    +            if subproc_count is not set,
    +            os.cpu_count() is used to determine the number of processes
     
    -            Do to Python GIL multiprocessing or use of external libraries is necessary to accelerate CPU bound tasks
    -        '''
    +            Due to Python GIL multiprocessing/use of external libraries
    +            is necessary to accelerate CPU bound tasks
    +        """
             # No known benefit to using more processes than there are cores.
             # Note: os.cpu_count perhaps not always accurate
             if subproc_count is None:
    @@ -179,24 +206,31 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
             self.data = data
             self.metadata = metadata
     
    -        # dump dict to measure bytes of json metadata. Cannot reuse later because the pow token must be added
    +        """dump dict to measure bytes of json metadata
    +        Cannot reuse later bc the pow token must be added
    +        """
             json_metadata = json.dumps(metadata).encode()
     
             self.data = bytesconverter.str_to_bytes(data)
    -        # Calculate difficulty. Dumb for now, may use good algorithm in the future.
    -        self.difficulty = onionrproofs.getDifficultyForNewBlock(bytes(json_metadata + b'\n' + self.data))
    -        
    +
    +        compiled_data = bytes(json_metadata + b'\n' + self.data)
    +
    +        # Calculate difficulty. May use better algorithm in the future.
    +        self.difficulty = onionrproofs.getDifficultyForNewBlock(compiled_data)
    +
             logger.info('Computing POW (difficulty: %s)...' % (self.difficulty,))
     
    -        self.mainHash = '0' * 64
    -        self.puzzle = self.mainHash[0:min(self.difficulty, len(self.mainHash))]
    +        self.main_hash = '0' * 64
    +        self.puzzle = self.main_hash[0:min(self.difficulty,
    +                                           len(self.main_hash))]
             self.shutdown = False
             self.payload = None
     
         def start(self):
    +        """spawn the multiproc handler threads"""
             # Create a new thread for each subprocess
    -        for x in range(self.subproc_count):
    -            threading.Thread(target=self._spawn_proc).start()
    +        for _ in range(self.subproc_count): # noqa
    +            threading.Thread(target=self._spawn_proc, daemon=True).start()
             # Monitor the processes for a payload, shut them down when its found
             while True:
                 if self.payload is None:
    @@ -204,11 +238,12 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
                 else:
                     self.shutdown = True
                     return self.payload
    -    
    +
         def _spawn_proc(self):
    -        # Create a child proof of work process, wait for data and send shutdown signal when its found
    +        """Create a child proof of work process
    +        wait for data and send shutdown signal when its found"""
             parent_conn, child_conn = Pipe()
    -        p = Process(target=self.do_pow, args=(child_conn,))
    +        p = Process(target=self.do_pow, args=(child_conn,), daemon=True)
             p.start()
             p.join()
             payload = None
    @@ -225,8 +260,8 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
                 self.payload = payload
     
         def do_pow(self, pipe):
    -        nonce = -10000000 # Start nonce at negative 10 million so that the chosen nonce is likely to be small in length
    -        nonceStart = nonce
    +        """find partial hash colision generating nonce for a block"""
    +        nonce = BLOCK_NONCE_START_INT
             data = self.data
             metadata = self.metadata
             puzzle = self.puzzle
    @@ -239,26 +274,38 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
                 metadata['pow'] = nonce
                 # Serialize metadata, combine with block data
                 payload = json.dumps(metadata).encode() + b'\n' + data
    -            # Check sha3_256 hash of block, compare to puzzle. Send payload if puzzle finished
    +            # Check sha3_256 hash of block, compare to puzzle
    +            # Send payload if puzzle finished
                 token = crypto.hashers.sha3_hash(payload)
    -            token = bytesconverter.bytes_to_str(token) # ensure token is string
    +            # ensure token is string
    +            token = bytesconverter.bytes_to_str(token)
                 if puzzle == token[0:difficulty]:
                     pipe.send(payload)
                     break
                 nonce += 1
    +

    Instance variables

    +
    +
    var metadata
    +
    +

    dump dict to measure bytes of json metadata +Cannot reuse later bc the pow token must be added

    +
    +

    Methods

    -
    +
    def do_pow(self, pipe)
    -
    +

    find partial hash colision generating nonce for a block

    -Source code + +Expand source code +
    def do_pow(self, pipe):
    -    nonce = -10000000 # Start nonce at negative 10 million so that the chosen nonce is likely to be small in length
    -    nonceStart = nonce
    +    """find partial hash colision generating nonce for a block"""
    +    nonce = BLOCK_NONCE_START_INT
         data = self.data
         metadata = self.metadata
         puzzle = self.puzzle
    @@ -271,26 +318,31 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
             metadata['pow'] = nonce
             # Serialize metadata, combine with block data
             payload = json.dumps(metadata).encode() + b'\n' + data
    -        # Check sha3_256 hash of block, compare to puzzle. Send payload if puzzle finished
    +        # Check sha3_256 hash of block, compare to puzzle
    +        # Send payload if puzzle finished
             token = crypto.hashers.sha3_hash(payload)
    -        token = bytesconverter.bytes_to_str(token) # ensure token is string
    +        # ensure token is string
    +        token = bytesconverter.bytes_to_str(token)
             if puzzle == token[0:difficulty]:
                 pipe.send(payload)
                 break
             nonce += 1
    -
    +
    def start(self)
    -
    +

    spawn the multiproc handler threads

    -Source code + +Expand source code +
    def start(self):
    +    """spawn the multiproc handler threads"""
         # Create a new thread for each subprocess
    -    for x in range(self.subproc_count):
    -        threading.Thread(target=self._spawn_proc).start()
    +    for _ in range(self.subproc_count): # noqa
    +        threading.Thread(target=self._spawn_proc, daemon=True).start()
         # Monitor the processes for a payload, shut them down when its found
         while True:
             if self.payload is None:
    @@ -313,16 +365,17 @@ if subproc_count is not set, os.cpu_count() is used to determine the number of p
     
    diff --git a/docs/html/onionr/onionrservices/bootstrapservice.html b/docs/html/src/onionrservices/bootstrapservice.html similarity index 88% rename from docs/html/onionr/onionrservices/bootstrapservice.html rename to docs/html/src/onionrservices/bootstrapservice.html index abb61ca1..9c45bb80 100644 --- a/docs/html/onionr/onionrservices/bootstrapservice.html +++ b/docs/html/src/onionrservices/bootstrapservice.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.bootstrapservice API documentation + +src.onionrservices.bootstrapservice API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.bootstrapservice

    +

    Module src.onionrservices.bootstrapservice

    Onionr - Private P2P Communication

    Bootstrap onion direct connections for the clients

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -149,13 +151,15 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300):
     

    Functions

    -
    +
    def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300)

    Bootstrap client services

    -Source code + +Expand source code +
    def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300):
         '''
             Bootstrap client services
    @@ -250,19 +254,19 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300):
     
     
     
    diff --git a/docs/html/onionr/onionrservices/connectionserver.html b/docs/html/src/onionrservices/connectionserver.html similarity index 87% rename from docs/html/onionr/onionrservices/connectionserver.html rename to docs/html/src/onionrservices/connectionserver.html index 98eeae93..558700f3 100644 --- a/docs/html/onionr/onionrservices/connectionserver.html +++ b/docs/html/src/onionrservices/connectionserver.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.connectionserver API documentation + +src.onionrservices.connectionserver API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.connectionserver

    +

    Module src.onionrservices.connectionserver

    Onionr - Private P2P Communication

    This module does the second part of the bootstrap block handshake and creates the API server

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -124,14 +126,16 @@ class ConnectionServer:
     

    Classes

    -
    +
    class ConnectionServer (peer, address, comm_inst=None)
    -Source code + +Expand source code +
    class ConnectionServer:
         def __init__(self, peer, address, comm_inst=None):
     
    @@ -204,13 +208,13 @@ class ConnectionServer:
     
    diff --git a/docs/html/onionr/onionrservices/httpheaders.html b/docs/html/src/onionrservices/httpheaders.html similarity index 82% rename from docs/html/onionr/onionrservices/httpheaders.html rename to docs/html/src/onionrservices/httpheaders.html index eafd2cf2..459af6e3 100644 --- a/docs/html/onionr/onionrservices/httpheaders.html +++ b/docs/html/src/onionrservices/httpheaders.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.httpheaders API documentation + +src.onionrservices.httpheaders API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.httpheaders

    +

    Module src.onionrservices.httpheaders

    Onionr - Private P2P Communication

    Set default onionr http headers

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -68,13 +70,15 @@ def set_default_onionr_http_headers(flask_response):
     

    Functions

    -
    +
    def set_default_onionr_http_headers(flask_response)

    Response headers

    -Source code + +Expand source code +
    def set_default_onionr_http_headers(flask_response):
         '''Response headers'''
         flask_response.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
    @@ -102,19 +106,19 @@ def set_default_onionr_http_headers(flask_response):
     
     
     
    diff --git a/docs/html/onionr/onionrservices/index.html b/docs/html/src/onionrservices/index.html similarity index 77% rename from docs/html/onionr/onionrservices/index.html rename to docs/html/src/onionrservices/index.html index e0318765..7a03fc81 100644 --- a/docs/html/onionr/onionrservices/index.html +++ b/docs/html/src/onionrservices/index.html @@ -3,13 +3,13 @@ - -onionr.onionrservices API documentation + +src.onionrservices API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices

    +

    Module src.onionrservices

    Onionr - Private P2P Communication

    Onionr services provide the server component to direct connections

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -93,27 +95,27 @@ class OnionrServices:
     

    Sub-modules

    -
    onionr.onionrservices.bootstrapservice
    +
    src.onionrservices.bootstrapservice

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.connectionserver
    +
    src.onionrservices.connectionserver

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.httpheaders
    +
    src.onionrservices.httpheaders

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.pool
    +
    src.onionrservices.pool

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.serverexists
    +
    src.onionrservices.serverexists

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.warden
    +
    src.onionrservices.warden
    @@ -126,13 +128,15 @@ class OnionrServices:

    Classes

    -
    +
    class OnionrServices

    Create a client or server for connecting to peer interfaces

    -Source code + +Expand source code +
    class OnionrServices:
         '''
             Create a client or server for connecting to peer interfaces
    @@ -175,13 +179,15 @@ class OnionrServices:
     

    Static methods

    -
    +
    def create_client(peer, comm_inst=None)
    -Source code + +Expand source code +
    @staticmethod
     def create_client(peer, comm_inst=None):
         # Create ephemeral onion service to bootstrap connection to server
    @@ -197,14 +203,16 @@ def create_client(peer, comm_inst=None):
     

    Methods

    -
    +
    def create_server(self, peer, address, comm_inst)

    When a client wants to connect, contact their bootstrap address and tell them our ephemeral address for our service by creating a new ConnectionServer instance

    -Source code + +Expand source code +
    def create_server(self, peer, address, comm_inst):
         '''
             When a client wants to connect, contact their bootstrap address and tell them our
    @@ -239,26 +247,26 @@ ephemeral address for our service by creating a new ConnectionServer instance

  • Super-module

  • Sub-modules

  • Classes

    @@ -267,7 +275,7 @@ ephemeral address for our service by creating a new ConnectionServer instance

  • diff --git a/docs/html/onionr/onionrservices/pool.html b/docs/html/src/onionrservices/pool.html similarity index 77% rename from docs/html/onionr/onionrservices/pool.html rename to docs/html/src/onionrservices/pool.html index b558e2f6..21c12c41 100644 --- a/docs/html/onionr/onionrservices/pool.html +++ b/docs/html/src/onionrservices/pool.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.pool API documentation + +src.onionrservices.pool API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.pool

    +

    Module src.onionrservices.pool

    Onionr - Private P2P Communication

    Holds active onionrservices clients and servers

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -64,13 +66,15 @@ class ServicePool:
     

    Classes

    -
    +
    class ServicePool
    -Source code + +Expand source code +
    class ServicePool:
         def __init__(self):
             self.servers = []
    @@ -82,13 +86,15 @@ class ServicePool:
     

    Methods

    -
    +
    def add_server(self, service)
    -Source code + +Expand source code +
    def add_server(self, service):
         self.servers.append((service, epoch.get_epoch()))
    @@ -106,15 +112,15 @@ class ServicePool:
    diff --git a/docs/html/onionr/onionrservices/serverexists.html b/docs/html/src/onionrservices/serverexists.html similarity index 80% rename from docs/html/onionr/onionrservices/serverexists.html rename to docs/html/src/onionrservices/serverexists.html index 2b7a6add..5d97a297 100644 --- a/docs/html/onionr/onionrservices/serverexists.html +++ b/docs/html/src/onionrservices/serverexists.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.serverexists API documentation + +src.onionrservices.serverexists API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.serverexists

    +

    Module src.onionrservices.serverexists

    Onionr - Private P2P Communication

    Function to check if an onion server is created for a peer or not

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -63,13 +65,15 @@ def server_exists(peer: str) -> bool:
     

    Functions

    -
    +
    def server_exists(peer)

    checks if an onion server is created for a peer or not

    -Source code + +Expand source code +
    def server_exists(peer: str) -> bool:
         '''checks if an onion server is created for a peer or not'''
         peer = bytesconverter.bytes_to_str(peer)
    @@ -91,19 +95,19 @@ def server_exists(peer: str) -> bool:
     
     
     
    diff --git a/docs/html/onionr/onionrservices/warden/bootstrap.html b/docs/html/src/onionrservices/warden/bootstrap.html similarity index 79% rename from docs/html/onionr/onionrservices/warden/bootstrap.html rename to docs/html/src/onionrservices/warden/bootstrap.html index 59ff7088..61b9978f 100644 --- a/docs/html/onionr/onionrservices/warden/bootstrap.html +++ b/docs/html/src/onionrservices/warden/bootstrap.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.warden.bootstrap API documentation + +src.onionrservices.warden.bootstrap API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrservices.warden.bootstrap

    +

    Module src.onionrservices.warden.bootstrap

    Onionr - Private P2P Communication

    Bootstrap warden monitors the bootstrap server

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -62,14 +64,14 @@
     
     
     
    diff --git a/docs/html/onionr/onionrservices/warden/client.html b/docs/html/src/onionrservices/warden/client.html similarity index 76% rename from docs/html/onionr/onionrservices/warden/client.html rename to docs/html/src/onionrservices/warden/client.html index c08abf6c..e4984067 100644 --- a/docs/html/onionr/onionrservices/warden/client.html +++ b/docs/html/src/onionrservices/warden/client.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.warden.client API documentation + +src.onionrservices.warden.client API documentation - + @@ -17,7 +17,7 @@
    diff --git a/docs/html/onionr/onionrservices/warden/index.html b/docs/html/src/onionrservices/warden/index.html similarity index 70% rename from docs/html/onionr/onionrservices/warden/index.html rename to docs/html/src/onionrservices/warden/index.html index 2a8d7ea7..8b6acc7f 100644 --- a/docs/html/onionr/onionrservices/warden/index.html +++ b/docs/html/src/onionrservices/warden/index.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.warden API documentation + +src.onionrservices.warden API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrservices.warden

    +

    Module src.onionrservices.warden

    -Source code + +Expand source code +
    from . import client # Client connection warden. Monitors & validates connection security.
     from . import server # Server connection warden. Monitors and validates server security
     #from . import watchdog # Watchdog. Oversees running services for statistic collection and TTL control
    @@ -30,15 +32,15 @@ from . import server # Server connection warden. Monitors and validates server s

    Sub-modules

    -
    onionr.onionrservices.warden.bootstrap
    +
    src.onionrservices.warden.bootstrap

    Onionr - Private P2P Communication …

    -
    onionr.onionrservices.warden.client
    +
    src.onionrservices.warden.client
    -
    onionr.onionrservices.warden.server
    +
    src.onionrservices.warden.server
    @@ -59,21 +61,21 @@ from . import server # Server connection warden. Monitors and validates server s
    diff --git a/docs/html/onionr/onionrservices/warden/server.html b/docs/html/src/onionrservices/warden/server.html similarity index 76% rename from docs/html/onionr/onionrservices/warden/server.html rename to docs/html/src/onionrservices/warden/server.html index fa572d8a..eed33b7f 100644 --- a/docs/html/onionr/onionrservices/warden/server.html +++ b/docs/html/src/onionrservices/warden/server.html @@ -3,13 +3,13 @@ - -onionr.onionrservices.warden.server API documentation + +src.onionrservices.warden.server API documentation - + @@ -17,7 +17,7 @@
    diff --git a/docs/html/onionr/onionrsetup/dbcreator.html b/docs/html/src/onionrsetup/dbcreator.html similarity index 79% rename from docs/html/onionr/onionrsetup/dbcreator.html rename to docs/html/src/onionrsetup/dbcreator.html index a5878dd7..79d01a4a 100644 --- a/docs/html/onionr/onionrsetup/dbcreator.html +++ b/docs/html/src/onionrsetup/dbcreator.html @@ -3,13 +3,13 @@ - -onionr.onionrsetup.dbcreator API documentation + +src.onionrsetup.dbcreator API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrsetup.dbcreator

    +

    Module src.onionrsetup.dbcreator

    Onionr - Private P2P Communication

    DBCreator, creates sqlite3 databases used by Onionr

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -176,18 +178,6 @@ def createForwardKeyDB():
         conn.close()
         return
     
    -def createDaemonDB():
    -    '''
    -        Create the daemon queue database
    -    '''
    -    if os.path.exists(dbfiles.daemon_queue_db):
    -        raise FileExistsError("Daemon queue db already exists")
    -    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=10)
    -    c = conn.cursor()
    -    # Create table
    -    c.execute('''CREATE TABLE commands (id integer primary key autoincrement, command text, data text, date text, responseID text)''')
    -    conn.commit()
    -    conn.close()
     
     def create_blacklist_db():
         if os.path.exists(dbfiles.blacklist_db):
    @@ -206,7 +196,9 @@ def create_blacklist_db():
         conn.close()
     
     
    -create_funcs = [createAddressDB, createPeerDB, createBlockDB, createBlockDataDB, createForwardKeyDB, createDaemonDB, create_blacklist_db]
    +create_funcs = [createAddressDB, createPeerDB, + createBlockDB, createBlockDataDB, + createForwardKeyDB, create_blacklist_db]
    @@ -216,7 +208,7 @@ create_funcs = [createAddressDB, createPeerDB, createBlockDB, createBlockDataDB,

    Functions

    -
    +
    def createAddressDB()
    @@ -226,7 +218,9 @@ create_funcs = [createAddressDB, createPeerDB, createBlockDB, createBlockDataDB, 2: Tor v2 (like facebookcorewwwi.onion) 3: Tor v3

    -Source code + +Expand source code +
    def createAddressDB():
         '''
             Generate the address database
    @@ -258,7 +252,7 @@ create_funcs = [createAddressDB, createPeerDB, createBlockDB, createBlockDataDB,
         conn.close()
    -
    +
    def createBlockDB()
    @@ -283,7 +277,9 @@ dateClaimed expire int - block expire date in epoch

    -Source code + +Expand source code +
    def createBlockDB():
         '''
             Create a database for blocks
    @@ -321,13 +317,15 @@ expire int
         return
    -
    +
    def createBlockDataDB()
    -Source code + +Expand source code +
    def createBlockDataDB():
         if os.path.exists(dbfiles.block_data_db):
             raise FileExistsError("Block data database already exists")
    @@ -345,34 +343,15 @@ expire int
         conn.close()
    -
    -def createDaemonDB() -
    -
    -

    Create the daemon queue database

    -
    -Source code -
    def createDaemonDB():
    -    '''
    -        Create the daemon queue database
    -    '''
    -    if os.path.exists(dbfiles.daemon_queue_db):
    -        raise FileExistsError("Daemon queue db already exists")
    -    conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=10)
    -    c = conn.cursor()
    -    # Create table
    -    c.execute('''CREATE TABLE commands (id integer primary key autoincrement, command text, data text, date text, responseID text)''')
    -    conn.commit()
    -    conn.close()
    -
    -
    -
    +
    def createForwardKeyDB()

    Create the forward secrecy key db (for OUR keys)

    -Source code + +Expand source code +
    def createForwardKeyDB():
         '''
             Create the forward secrecy key db (*for *OUR* keys*)
    @@ -394,13 +373,15 @@ expire int
         return
    -
    +
    def createPeerDB()

    Generate the peer sqlite3 database and populate it with the peers table.

    -Source code + +Expand source code +
    def createPeerDB():
         '''
             Generate the peer sqlite3 database and populate it with the peers table.
    @@ -429,13 +410,15 @@ expire int
         return
    -
    +
    def create_blacklist_db()
    -Source code + +Expand source code +
    def create_blacklist_db():
         if os.path.exists(dbfiles.blacklist_db):
             raise FileExistsError("Blacklist db already exists")
    @@ -466,25 +449,24 @@ expire int
     
     
     
    diff --git a/docs/html/onionr/onionrsetup/defaultpluginsetup.html b/docs/html/src/onionrsetup/defaultpluginsetup.html similarity index 82% rename from docs/html/onionr/onionrsetup/defaultpluginsetup.html rename to docs/html/src/onionrsetup/defaultpluginsetup.html index 7782b823..ce29bceb 100644 --- a/docs/html/onionr/onionrsetup/defaultpluginsetup.html +++ b/docs/html/src/onionrsetup/defaultpluginsetup.html @@ -3,13 +3,13 @@ - -onionr.onionrsetup.defaultpluginsetup API documentation + +src.onionrsetup.defaultpluginsetup API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrsetup.defaultpluginsetup

    +

    Module src.onionrsetup.defaultpluginsetup

    Onionr - Private P2P Communication

    Installs default plugins

    -Source code + +Expand source code +
    """
         Onionr - Private P2P Communication
     
    @@ -77,13 +79,15 @@ def setup_default_plugins():
     

    Functions

    -
    +
    def setup_default_plugins()
    -Source code + +Expand source code +
    def setup_default_plugins():
         # Copy default plugins into plugins folder
         if not os.path.exists(plugins.get_plugins_folder()):
    @@ -118,19 +122,19 @@ def setup_default_plugins():
     
     
     
    diff --git a/docs/html/onionr/onionrsetup/index.html b/docs/html/src/onionrsetup/index.html similarity index 70% rename from docs/html/onionr/onionrsetup/index.html rename to docs/html/src/onionrsetup/index.html index 645890d0..6390330e 100644 --- a/docs/html/onionr/onionrsetup/index.html +++ b/docs/html/src/onionrsetup/index.html @@ -3,13 +3,13 @@ - -onionr.onionrsetup API documentation + +src.onionrsetup API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrsetup

    +

    Module src.onionrsetup

    -Source code + +Expand source code +
    from . import defaultpluginsetup, setupconfig
     setup_default_plugins = defaultpluginsetup.setup_default_plugins
     setup_config = setupconfig.setup_config
    @@ -30,15 +32,15 @@ setup_config = setupconfig.setup_config

    Sub-modules

    -
    onionr.onionrsetup.dbcreator
    +
    src.onionrsetup.dbcreator

    Onionr - Private P2P Communication …

    -
    onionr.onionrsetup.defaultpluginsetup
    +
    src.onionrsetup.defaultpluginsetup

    Onionr - Private P2P Communication …

    -
    onionr.onionrsetup.setupconfig
    +
    src.onionrsetup.setupconfig

    Onionr - Private P2P Communication …

    @@ -59,21 +61,21 @@ setup_config = setupconfig.setup_config
    diff --git a/docs/html/onionr/onionrsetup/setupconfig.html b/docs/html/src/onionrsetup/setupconfig.html similarity index 87% rename from docs/html/onionr/onionrsetup/setupconfig.html rename to docs/html/src/onionrsetup/setupconfig.html index e03bf93a..60c0581a 100644 --- a/docs/html/onionr/onionrsetup/setupconfig.html +++ b/docs/html/src/onionrsetup/setupconfig.html @@ -3,13 +3,13 @@ - -onionr.onionrsetup.setupconfig API documentation + +src.onionrsetup.setupconfig API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrsetup.setupconfig

    +

    Module src.onionrsetup.setupconfig

    Onionr - Private P2P Communication

    Initialize Onionr configuration

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -118,13 +120,15 @@ def setup_config():
     

    Functions

    -
    +
    def setup_config()
    -Source code + +Expand source code +
    def setup_config():
         
         if not os.path.exists(config._configfile):
    @@ -200,19 +204,19 @@ def setup_config():
     
     
     
    diff --git a/docs/html/src/onionrstatistics/index.html b/docs/html/src/onionrstatistics/index.html new file mode 100644 index 00000000..5667b8cb --- /dev/null +++ b/docs/html/src/onionrstatistics/index.html @@ -0,0 +1,76 @@ + + + + + + +src.onionrstatistics API documentation + + + + + + + + + +
    + + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/serializeddata.html b/docs/html/src/onionrstatistics/serializeddata.html similarity index 72% rename from docs/html/onionr/serializeddata.html rename to docs/html/src/onionrstatistics/serializeddata.html index 1eafea5a..fb6a363c 100644 --- a/docs/html/onionr/serializeddata.html +++ b/docs/html/src/onionrstatistics/serializeddata.html @@ -3,13 +3,13 @@ - -onionr.serializeddata API documentation + +src.onionrstatistics.serializeddata API documentation - + @@ -17,19 +17,21 @@
    -

    Module onionr.serializeddata

    +

    Module src.onionrstatistics.serializeddata

    Onionr - Private P2P Communication

    This module serializes various data pieces for use in other modules, in particular the web api

    -Source code -
    '''
    +
    +Expand source code
    +
    +
    """
         Onionr - Private P2P Communication
     
         This module serializes various data pieces for use in other modules, in particular the web api
    -'''
    -'''
    +"""
    +"""
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation, either version 3 of the License, or
    @@ -42,32 +44,37 @@
     
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
    -'''
    +"""
    +
    +import json # noqa
    +import time # noqa
    +
    +from coredb import blockmetadb # noqa
    +import communicator # noqa
     
    -import json, time
    -from coredb import blockmetadb
    -import communicator
     class SerializedData:
         def __init__(self):
    -        '''
    +        """
             Serialized data is in JSON format:
             {
                 'success': bool,
                 'foo': 'bar',
                 etc
             }
    -        '''
    +        """
         
         def get_stats(self):
    -        '''Return statistics about our node'''
    +        """Return statistics about our node"""
             stats = {}
             try:
                 self._too_many
             except AttributeError:
                 time.sleep(1)
             comm_inst = self._too_many.get(communicator.OnionrCommunicatorDaemon, args=(self._too_many,))
    +        connected = []
    +        [connected.append(x) for x in comm_inst.onlinePeers if x not in connected] 
             stats['uptime'] = comm_inst.getUptime()
    -        stats['connectedNodes'] = '\n'.join(comm_inst.onlinePeers)
    +        stats['connectedNodes'] = '\n'.join(connected)
             stats['blockCount'] = len(blockmetadb.get_block_list())
             stats['blockQueueCount'] = len(comm_inst.blockQueue)
             return json.dumps(stats)
    @@ -82,7 +89,7 @@ class SerializedData:

    Classes

    -
    +
    class SerializedData
    @@ -93,51 +100,59 @@ class SerializedData: etc }

    -Source code + +Expand source code +
    class SerializedData:
         def __init__(self):
    -        '''
    +        """
             Serialized data is in JSON format:
             {
                 'success': bool,
                 'foo': 'bar',
                 etc
             }
    -        '''
    +        """
         
         def get_stats(self):
    -        '''Return statistics about our node'''
    +        """Return statistics about our node"""
             stats = {}
             try:
                 self._too_many
             except AttributeError:
                 time.sleep(1)
             comm_inst = self._too_many.get(communicator.OnionrCommunicatorDaemon, args=(self._too_many,))
    +        connected = []
    +        [connected.append(x) for x in comm_inst.onlinePeers if x not in connected] 
             stats['uptime'] = comm_inst.getUptime()
    -        stats['connectedNodes'] = '\n'.join(comm_inst.onlinePeers)
    +        stats['connectedNodes'] = '\n'.join(connected)
             stats['blockCount'] = len(blockmetadb.get_block_list())
             stats['blockQueueCount'] = len(comm_inst.blockQueue)
             return json.dumps(stats)

    Methods

    -
    +
    def get_stats(self)

    Return statistics about our node

    -Source code + +Expand source code +
    def get_stats(self):
    -    '''Return statistics about our node'''
    +    """Return statistics about our node"""
         stats = {}
         try:
             self._too_many
         except AttributeError:
             time.sleep(1)
         comm_inst = self._too_many.get(communicator.OnionrCommunicatorDaemon, args=(self._too_many,))
    +    connected = []
    +    [connected.append(x) for x in comm_inst.onlinePeers if x not in connected] 
         stats['uptime'] = comm_inst.getUptime()
    -    stats['connectedNodes'] = '\n'.join(comm_inst.onlinePeers)
    +    stats['connectedNodes'] = '\n'.join(connected)
         stats['blockCount'] = len(blockmetadb.get_block_list())
         stats['blockQueueCount'] = len(comm_inst.blockQueue)
         return json.dumps(stats)
    @@ -156,15 +171,15 @@ etc
    diff --git a/docs/html/onionr/netcontroller/rebuildtor.html b/docs/html/src/onionrstatistics/transports/index.html similarity index 68% rename from docs/html/onionr/netcontroller/rebuildtor.html rename to docs/html/src/onionrstatistics/transports/index.html index f3299927..73507efe 100644 --- a/docs/html/onionr/netcontroller/rebuildtor.html +++ b/docs/html/src/onionrstatistics/transports/index.html @@ -3,13 +3,13 @@ - -onionr.netcontroller.rebuildtor API documentation + +src.onionrstatistics.transports API documentation - + @@ -17,40 +17,31 @@
    -

    Module onionr.netcontroller.rebuildtor

    +

    Module src.onionrstatistics.transports

    -Source code -
    import time
    -from coredb import daemonqueue
    -
    -def rebuild():
    -    daemonqueue.daemon_queue_add('restartTor')
    + +Expand source code + +
    from . import tor
    -
    -
    -
    -
    -

    Functions

    +

    Sub-modules

    -
    -def rebuild() -
    +
    src.onionrstatistics.transports.tor
    -
    -
    -Source code -
    def rebuild():
    -    daemonqueue.daemon_queue_add('restartTor')
    -
    +

    Onionr - Private P2P Communication.

    +
    +
    +
    +
    diff --git a/docs/html/src/onionrstatistics/transports/tor/index.html b/docs/html/src/onionrstatistics/transports/tor/index.html new file mode 100644 index 00000000..bc58a106 --- /dev/null +++ b/docs/html/src/onionrstatistics/transports/tor/index.html @@ -0,0 +1,228 @@ + + + + + + +src.onionrstatistics.transports.tor API documentation + + + + + + + + + +
    +
    +
    +

    Module src.onionrstatistics.transports.tor

    +
    +
    +

    Onionr - Private P2P Communication.

    +
    + +Expand source code + +
    """Onionr - Private P2P Communication.
    +
    +
    +"""
    +import json
    +from gevent import sleep
    +
    +from stem import CircStatus
    +
    +from netcontroller.torcontrol.torcontroller import get_controller
    +
    +"""
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +
    +class TorStats:
    +    def __init__(self):
    +        self.circuits = {}
    +        self.json_data = ""
    +
    +    def get_json(self):
    +        """Refresh circuits then serialize them into form:
    +
    +        "nodes": list of tuples containing fingerprint and nickname strings"
    +        "purpose": https://stem.torproject.org/api/control.html#stem.CircPurpose
    +        """
    +        self.get_circuits()
    +        json_serialized = {}
    +        for circuit in self.circuits.keys():
    +            json_serialized[circuit] = {
    +                "nodes": [],
    +                "purpose": self.circuits[circuit][1]
    +            }
    +            for entry in self.circuits[circuit][0]:
    +                json_serialized[circuit]["nodes"].append({'finger': entry[0],
    +                                                         'nick': entry[1]})
    +        self.json_data = json.dumps(json_serialized)
    +        return self.json_data
    +
    +    def get_circuits(self):
    +        """Update the circuit dictionary"""
    +        circuits = {}
    +        for circ in list(sorted(get_controller().get_circuits())):
    +            if circ.status != CircStatus.BUILT:
    +                continue
    +            circuits[circ.id] = (circ.path, circ.purpose)
    +        self.circuits = circuits
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class TorStats +
    +
    +
    +
    + +Expand source code + +
    class TorStats:
    +    def __init__(self):
    +        self.circuits = {}
    +        self.json_data = ""
    +
    +    def get_json(self):
    +        """Refresh circuits then serialize them into form:
    +
    +        "nodes": list of tuples containing fingerprint and nickname strings"
    +        "purpose": https://stem.torproject.org/api/control.html#stem.CircPurpose
    +        """
    +        self.get_circuits()
    +        json_serialized = {}
    +        for circuit in self.circuits.keys():
    +            json_serialized[circuit] = {
    +                "nodes": [],
    +                "purpose": self.circuits[circuit][1]
    +            }
    +            for entry in self.circuits[circuit][0]:
    +                json_serialized[circuit]["nodes"].append({'finger': entry[0],
    +                                                         'nick': entry[1]})
    +        self.json_data = json.dumps(json_serialized)
    +        return self.json_data
    +
    +    def get_circuits(self):
    +        """Update the circuit dictionary"""
    +        circuits = {}
    +        for circ in list(sorted(get_controller().get_circuits())):
    +            if circ.status != CircStatus.BUILT:
    +                continue
    +            circuits[circ.id] = (circ.path, circ.purpose)
    +        self.circuits = circuits
    +
    +

    Methods

    +
    +
    +def get_circuits(self) +
    +
    +

    Update the circuit dictionary

    +
    + +Expand source code + +
    def get_circuits(self):
    +    """Update the circuit dictionary"""
    +    circuits = {}
    +    for circ in list(sorted(get_controller().get_circuits())):
    +        if circ.status != CircStatus.BUILT:
    +            continue
    +        circuits[circ.id] = (circ.path, circ.purpose)
    +    self.circuits = circuits
    +
    +
    +
    +def get_json(self) +
    +
    +

    Refresh circuits then serialize them into form:

    +

    "nodes": list of tuples containing fingerprint and nickname strings" +"purpose": https://stem.torproject.org/api/control.html#stem.CircPurpose

    +
    + +Expand source code + +
    def get_json(self):
    +    """Refresh circuits then serialize them into form:
    +
    +    "nodes": list of tuples containing fingerprint and nickname strings"
    +    "purpose": https://stem.torproject.org/api/control.html#stem.CircPurpose
    +    """
    +    self.get_circuits()
    +    json_serialized = {}
    +    for circuit in self.circuits.keys():
    +        json_serialized[circuit] = {
    +            "nodes": [],
    +            "purpose": self.circuits[circuit][1]
    +        }
    +        for entry in self.circuits[circuit][0]:
    +            json_serialized[circuit]["nodes"].append({'finger': entry[0],
    +                                                     'nick': entry[1]})
    +    self.json_data = json.dumps(json_serialized)
    +    return self.json_data
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrstorage/index.html b/docs/html/src/onionrstorage/index.html similarity index 74% rename from docs/html/onionr/onionrstorage/index.html rename to docs/html/src/onionrstorage/index.html index 45645fca..1059bd3d 100644 --- a/docs/html/onionr/onionrstorage/index.html +++ b/docs/html/src/onionrstorage/index.html @@ -3,13 +3,13 @@ - -onionr.onionrstorage API documentation + +src.onionrstorage API documentation - + @@ -17,18 +17,32 @@
    -

    Module onionr.onionrstorage

    +

    Module src.onionrstorage

    Onionr - Private P2P Communication

    This file handles block storage, providing an abstraction for storing blocks between file system and database

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
         This file handles block storage, providing an abstraction for storing blocks between file system and database
     '''
    +import sys
    +import sqlite3
    +import os
    +from onionrutils import bytesconverter
    +from onionrutils import stringvalidators
    +from coredb import dbfiles
    +import filepaths
    +import onionrcrypto
    +import onionrexceptions
    +from onionrsetup import dbcreator
    +from onionrcrypto import hashers
    +from . import setdata
     '''
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
    @@ -43,17 +57,13 @@
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
     '''
    -import sys, sqlite3, os
    -from onionrutils import bytesconverter, stringvalidators
    -from coredb import dbfiles
    -import filepaths, onionrcrypto, onionrexceptions
    -from onionrsetup import dbcreator
    -from onionrcrypto import hashers
    -from . import setdata
    -DB_ENTRY_SIZE_LIMIT = 10000 # Will be a config option
    +
    +
    +DB_ENTRY_SIZE_LIMIT = 10000  # Will be a config option
     
     set_data = setdata.set_data
     
    +
     def _dbInsert(blockHash, data):
         conn = sqlite3.connect(dbfiles.block_data_db, timeout=10)
         c = conn.cursor()
    @@ -62,6 +72,7 @@ def _dbInsert(blockHash, data):
         conn.commit()
         conn.close()
     
    +
     def _dbFetch(blockHash):
         conn = sqlite3.connect(dbfiles.block_data_db, timeout=10)
         c = conn.cursor()
    @@ -71,8 +82,9 @@ def _dbFetch(blockHash):
         conn.close()
         return None
     
    +
     def deleteBlock(blockHash):
    -    # You should call core.removeBlock if you automatically want to remove storage byte count
    +    # You should call removeblock.remove_block if you automatically want to remove storage byte count
         if os.path.exists('%s/%s.dat' % (filepaths.block_data_location, blockHash)):
             os.remove('%s/%s.dat' % (filepaths.block_data_location, blockHash))
             return True
    @@ -84,11 +96,13 @@ def deleteBlock(blockHash):
         conn.close()
         return True
     
    +
     def store(data, blockHash=''):
         if not stringvalidators.validate_hash(blockHash): raise ValueError
         ourHash = hashers.sha3_hash(data)
         if blockHash != '':
    -        if not ourHash == blockHash: raise ValueError('Hash specified does not meet internal hash check')
    +        if not ourHash == blockHash:
    +            raise ValueError('Hash specified does not meet internal hash check')
         else:
             blockHash = ourHash
         
    @@ -98,6 +112,7 @@ def store(data, blockHash=''):
             with open('%s/%s.dat' % (filepaths.block_data_location, blockHash), 'wb') as blockFile:
                 blockFile.write(data)
     
    +
     def getData(bHash):
         if not stringvalidators.validate_hash(bHash): raise ValueError
     
    @@ -108,24 +123,25 @@ def getData(bHash):
         # If no entry in either, raise an exception
         retData = None
         fileLocation = '%s/%s.dat' % (filepaths.block_data_location, bHash)
    +    not_found_msg = "Flock data not found for: "
         if os.path.exists(fileLocation):
             with open(fileLocation, 'rb') as block:
                 retData = block.read()
         else:
             retData = _dbFetch(bHash)
             if retData is None:
    -            raise onionrexceptions.NoDataAvailable("Block data for %s is not available" % [bHash])
    +            raise onionrexceptions.NoDataAvailable(not_found_msg + str(bHash))
         return retData

    Sub-modules

    -
    onionr.onionrstorage.removeblock
    +
    src.onionrstorage.removeblock
    -
    +

    Onionr - Private P2P Communication …

    -
    onionr.onionrstorage.setdata
    +
    src.onionrstorage.setdata
    @@ -136,15 +152,17 @@ def getData(bHash):

    Functions

    -
    +
    def deleteBlock(blockHash)
    -Source code + +Expand source code +
    def deleteBlock(blockHash):
    -    # You should call core.removeBlock if you automatically want to remove storage byte count
    +    # You should call removeblock.remove_block if you automatically want to remove storage byte count
         if os.path.exists('%s/%s.dat' % (filepaths.block_data_location, blockHash)):
             os.remove('%s/%s.dat' % (filepaths.block_data_location, blockHash))
             return True
    @@ -157,13 +175,15 @@ def getData(bHash):
         return True
    -
    +
    def getData(bHash)
    -Source code + +Expand source code +
    def getData(bHash):
         if not stringvalidators.validate_hash(bHash): raise ValueError
     
    @@ -174,28 +194,32 @@ def getData(bHash):
         # If no entry in either, raise an exception
         retData = None
         fileLocation = '%s/%s.dat' % (filepaths.block_data_location, bHash)
    +    not_found_msg = "Flock data not found for: "
         if os.path.exists(fileLocation):
             with open(fileLocation, 'rb') as block:
                 retData = block.read()
         else:
             retData = _dbFetch(bHash)
             if retData is None:
    -            raise onionrexceptions.NoDataAvailable("Block data for %s is not available" % [bHash])
    +            raise onionrexceptions.NoDataAvailable(not_found_msg + str(bHash))
         return retData
    -
    +
    def store(data, blockHash='')
    -Source code + +Expand source code +
    def store(data, blockHash=''):
         if not stringvalidators.validate_hash(blockHash): raise ValueError
         ourHash = hashers.sha3_hash(data)
         if blockHash != '':
    -        if not ourHash == blockHash: raise ValueError('Hash specified does not meet internal hash check')
    +        if not ourHash == blockHash:
    +            raise ValueError('Hash specified does not meet internal hash check')
         else:
             blockHash = ourHash
         
    @@ -219,27 +243,27 @@ def getData(bHash):
     
     
     
    diff --git a/docs/html/onionr/onionrstorage/removeblock.html b/docs/html/src/onionrstorage/removeblock.html similarity index 69% rename from docs/html/onionr/onionrstorage/removeblock.html rename to docs/html/src/onionrstorage/removeblock.html index 391152ad..11fb67d7 100644 --- a/docs/html/onionr/onionrstorage/removeblock.html +++ b/docs/html/src/onionrstorage/removeblock.html @@ -3,13 +3,13 @@ - -onionr.onionrstorage.removeblock API documentation - + +src.onionrstorage.removeblock API documentation + - + @@ -17,22 +17,46 @@
    -

    Module onionr.onionrstorage.removeblock

    +

    Module src.onionrstorage.removeblock

    +

    Onionr - Private P2P Communication.

    +

    remove onionr block from meta db

    -Source code -
    import sys, sqlite3
    +
    +Expand source code
    +
    +
    """Onionr - Private P2P Communication.
    +
    +remove onionr block from meta db
    +"""
    +import sys, sqlite3
     import onionrexceptions, onionrstorage
     from onionrutils import stringvalidators
     from coredb import dbfiles
     from onionrblocks import storagecounter
    +"""
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +
     def remove_block(block):
    -    '''
    +    """
             remove a block from this node (does not automatically blacklist)
     
             **You may want blacklist.addToDB(blockHash)
    -    '''
    +    """
     
         if stringvalidators.validate_hash(block):
             conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
    @@ -54,20 +78,22 @@ def remove_block(block):
     

    Functions

    -
    +
    def remove_block(block)

    remove a block from this node (does not automatically blacklist)

    **You may want blacklist.addToDB(blockHash)

    -Source code + +Expand source code +
    def remove_block(block):
    -    '''
    +    """
             remove a block from this node (does not automatically blacklist)
     
             **You may want blacklist.addToDB(blockHash)
    -    '''
    +    """
     
         if stringvalidators.validate_hash(block):
             conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30)
    @@ -95,19 +121,19 @@ def remove_block(block):
     
     
     
    diff --git a/docs/html/onionr/onionrstorage/setdata.html b/docs/html/src/onionrstorage/setdata.html similarity index 83% rename from docs/html/onionr/onionrstorage/setdata.html rename to docs/html/src/onionrstorage/setdata.html index e3ce2301..02c80914 100644 --- a/docs/html/onionr/onionrstorage/setdata.html +++ b/docs/html/src/onionrstorage/setdata.html @@ -3,13 +3,13 @@ - -onionr.onionrstorage.setdata API documentation + +src.onionrstorage.setdata API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrstorage.setdata

    +

    Module src.onionrstorage.setdata

    -Source code + +Expand source code +
    import sys, sqlite3
     import onionrstorage, onionrexceptions, onionrcrypto as crypto
     import filepaths
    @@ -73,13 +75,15 @@ def set_data(data)->str:
     

    Functions

    -
    +
    def set_data(data)

    Set the data assciated with a hash

    -Source code + +Expand source code +
    def set_data(data)->str:
         '''
             Set the data assciated with a hash
    @@ -131,19 +135,19 @@ def set_data(data)->str:
     
     
     
    diff --git a/docs/html/src/onionrtypes/index.html b/docs/html/src/onionrtypes/index.html new file mode 100644 index 00000000..54d2ace8 --- /dev/null +++ b/docs/html/src/onionrtypes/index.html @@ -0,0 +1,77 @@ + + + + + + +src.onionrtypes API documentation + + + + + + + + + +
    +
    +
    +

    Module src.onionrtypes

    +
    +
    +
    + +Expand source code + +
    from typing import NewType
    +
    +UserID = NewType('UserID', str)
    +UserIDSecretKey = NewType('UserIDSecretKey', str)
    +
    +DeterministicKeyPassphrase = NewType('DeterministicKeyPassphrase', str)
    +
    +BlockHash = NewType('BlockHash', str)
    +
    +OnboardingConfig = NewType('OnboardingConfig', str)
    +
    +# JSON serializable string. e.g. no raw bytes
    +JSONSerializable = NewType('JSONSerializable', str)
    +
    +# Return value of some functions or methods, denoting operation success
    +# Do not use for new code
    +BooleanSuccessState = NewType('BooleanSuccessState', bool)
    +
    +OnionAddressString = NewType('OnionAddressString', str)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrusers/contactmanager.html b/docs/html/src/onionrusers/contactmanager.html similarity index 78% rename from docs/html/onionr/onionrusers/contactmanager.html rename to docs/html/src/onionrusers/contactmanager.html index 0f3de3f2..5b87b7d6 100644 --- a/docs/html/onionr/onionrusers/contactmanager.html +++ b/docs/html/src/onionrusers/contactmanager.html @@ -3,13 +3,13 @@ - -onionr.onionrusers.contactmanager API documentation + +src.onionrusers.contactmanager API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrusers.contactmanager

    +

    Module src.onionrusers.contactmanager

    Onionr - Private P2P Communication

    Sets more abstract information related to a peer. Can be thought of as traditional 'contact' system

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -43,19 +45,21 @@
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
     '''
    -import os, json, onionrexceptions
    +import os, json
     import unpaddedbase32
    +import niceware
    +
    +import onionrexceptions
     from onionrusers import onionrusers
     from onionrutils import bytesconverter, epoch
     from utils import identifyhome
    -
    -import mnemonic
    +from onionrutils import mnemonickeys
     class ContactManager(onionrusers.OnionrUser):
         def __init__(self, publicKey, saveUser=False, recordExpireSeconds=5):
             try:
    -            if " " in publicKey:
    -                publicKey = mnemonic.Mnemonic('english').to_entropy(publicKey)
    -                publicKey = unpaddedbase32.b32encode(bytesconverter.str_to_bytes(publicKey))
    +            if mnemonickeys.DELIMITER in publicKey:
    +                publicKey = mnemonickeys.get_base32(publicKey)
    +                #publicKey = unpaddedbase32.b32encode(bytesconverter.str_to_bytes(publicKey))
             except ValueError:
                 pass
             publicKey = bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(publicKey)))
    @@ -119,7 +123,7 @@ class ContactManager(onionrusers.OnionrUser):
     

    Classes

    -
    +
    class ContactManager (publicKey, saveUser=False, recordExpireSeconds=5)
    @@ -128,13 +132,15 @@ class ContactManager(onionrusers.OnionrUser):

    Takes a base32 encoded ed25519 public key, and a bool saveUser saveUser determines if we should add a user to our peer database or not.

    -Source code + +Expand source code +
    class ContactManager(onionrusers.OnionrUser):
         def __init__(self, publicKey, saveUser=False, recordExpireSeconds=5):
             try:
    -            if " " in publicKey:
    -                publicKey = mnemonic.Mnemonic('english').to_entropy(publicKey)
    -                publicKey = unpaddedbase32.b32encode(bytesconverter.str_to_bytes(publicKey))
    +            if mnemonickeys.DELIMITER in publicKey:
    +                publicKey = mnemonickeys.get_base32(publicKey)
    +                #publicKey = unpaddedbase32.b32encode(bytesconverter.str_to_bytes(publicKey))
             except ValueError:
                 pass
             publicKey = bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(publicKey)))
    @@ -194,26 +200,30 @@ saveUser determines if we should add a user to our peer database or not.

    Methods

    -
    +
    def delete_contact(self)
    -Source code + +Expand source code +
    def delete_contact(self):
         self.deleted = True
         if os.path.exists(self.dataFile):
             os.remove(self.dataFile)
    -
    +
    def get_info(self, key, forceReload=False)
    -Source code + +Expand source code +
    def get_info(self, key, forceReload=False):
         if self.deleted:
             raise onionrexceptions.ContactDeleted
    @@ -226,13 +236,15 @@ saveUser determines if we should add a user to our peer database or not.

    -
    +
    def set_info(self, key, value, autoWrite=True)
    -Source code + +Expand source code +
    def set_info(self, key, value, autoWrite=True):
         if self.deleted:
             raise onionrexceptions.ContactDeleted
    @@ -256,17 +268,17 @@ saveUser determines if we should add a user to our peer database or not.

  • Super-module

  • Classes

    @@ -275,7 +287,7 @@ saveUser determines if we should add a user to our peer database or not.

  • diff --git a/docs/html/onionr/onionrusers/index.html b/docs/html/src/onionrusers/index.html similarity index 72% rename from docs/html/onionr/onionrusers/index.html rename to docs/html/src/onionrusers/index.html index de49e7d4..51c85db4 100644 --- a/docs/html/onionr/onionrusers/index.html +++ b/docs/html/src/onionrusers/index.html @@ -3,13 +3,13 @@ - -onionr.onionrusers API documentation + +src.onionrusers API documentation - + @@ -17,18 +17,18 @@
    diff --git a/docs/html/onionr/onionrusers/onionrusers.html b/docs/html/src/onionrusers/onionrusers.html similarity index 83% rename from docs/html/onionr/onionrusers/onionrusers.html rename to docs/html/src/onionrusers/onionrusers.html index abe5f7be..52eb15ad 100644 --- a/docs/html/onionr/onionrusers/onionrusers.html +++ b/docs/html/src/onionrusers/onionrusers.html @@ -3,13 +3,13 @@ - -onionr.onionrusers.onionrusers API documentation + +src.onionrusers.onionrusers API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrusers.onionrusers

    +

    Module src.onionrusers.onionrusers

    Onionr - Private P2P Communication

    Contains abstractions for interacting with users of Onionr

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -93,7 +95,7 @@ class OnionrUser:
             if saveUser:
                 try:
                     keydb.addkeys.add_peer(publicKey)
    -            except AssertionError:
    +            except (AssertionError, ValueError) as e:
                     pass
     
             self.trust = keydb.userinfo.get_user_info(self.publicKey, 'trust')
    @@ -262,13 +264,15 @@ class OnionrUser:
     

    Functions

    -
    +
    def deleteExpiredKeys()
    -Source code + +Expand source code +
    def deleteExpiredKeys():
         # Fetch the keys we generated for the peer, that are still around
         conn = sqlite3.connect(dbfiles.forward_keys_db, timeout=10)
    @@ -282,13 +286,15 @@ class OnionrUser:
         return
    -
    +
    def deleteTheirExpiredKeys(pubkey)
    -Source code + +Expand source code +
    def deleteTheirExpiredKeys(pubkey):
         conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10)
         c = conn.cursor()
    @@ -307,7 +313,7 @@ class OnionrUser:
     

    Classes

    -
    +
    class OnionrUser (publicKey, saveUser=False)
    @@ -316,7 +322,9 @@ class OnionrUser:

    Takes a base32 encoded ed25519 public key, and a bool saveUser saveUser determines if we should add a user to our peer database or not.

    -Source code + +Expand source code +
    class OnionrUser:
     
         def __init__(self, publicKey, saveUser=False):
    @@ -334,7 +342,7 @@ saveUser determines if we should add a user to our peer database or not.

    Static methods

    -
    +
    def list_friends()
    -Source code + +Expand source code +
    @classmethod
     def list_friends(cls):
         friendList = []
    @@ -515,13 +525,15 @@ def list_friends(cls):
     

    Methods

    -
    +
    def addForwardKey(self, newKey, expire=604800)
    -Source code + +Expand source code +
    def addForwardKey(self, newKey, expire=DEFAULT_KEY_EXPIRE):
         newKey = bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(newKey)))
         if not stringvalidators.validate_pub_key(newKey):
    @@ -553,37 +565,43 @@ def list_friends(cls):
         return True
    -
    +
    def decrypt(self, data)
    -Source code + +Expand source code +
    def decrypt(self, data):
         decrypted = onionrcrypto.encryption.pub_key_decrypt(data, self.publicKey, encodedData=True)
         return decrypted
    -
    +
    def encrypt(self, data)
    -Source code + +Expand source code +
    def encrypt(self, data):
         encrypted = onionrcrypto.encryption.pub_key_encrypt(data, self.publicKey, encodedData=True)
         return encrypted
    -
    +
    def forwardDecrypt(self, encrypted)
    -Source code + +Expand source code +
    def forwardDecrypt(self, encrypted):
         retData = ""
         for key in self.getGeneratedForwardKeys(False):
    @@ -598,13 +616,15 @@ def list_friends(cls):
         return retData
    -
    +
    def forwardEncrypt(self, data)
    -Source code + +Expand source code +
    def forwardEncrypt(self, data):
         deleteTheirExpiredKeys(self.publicKey)
         deleteExpiredKeys()
    @@ -618,13 +638,15 @@ def list_friends(cls):
         return (retData, forwardKey[0], forwardKey[1])
    -
    +
    def generateForwardKey(self, expire=604800)
    -Source code + +Expand source code +
    def generateForwardKey(self, expire=DEFAULT_KEY_EXPIRE):
     
         # Generate a forward secrecy key for the peer
    @@ -645,13 +667,15 @@ def list_friends(cls):
         return newPub
    -
    +
    def getGeneratedForwardKeys(self, genNew=True)
    -Source code + +Expand source code +
    def getGeneratedForwardKeys(self, genNew=True):
         # Fetch the keys we generated for the peer, that are still around
         conn = sqlite3.connect(dbfiles.forward_keys_db, timeout=10)
    @@ -671,13 +695,15 @@ def list_friends(cls):
         return list(keyList)
    -
    +
    def getName(self)
    -Source code + +Expand source code +
    def getName(self):
         retData = 'anonymous'
         name = keydb.userinfo.get_user_info(self.publicKey, 'name')
    @@ -689,26 +715,30 @@ def list_friends(cls):
         return retData
    -
    +
    def isFriend(self)
    -Source code + +Expand source code +
    def isFriend(self):
         if keydb.userinfo.set_peer_info(self.publicKey, 'trust') == 1:
             return True
         return False
    -
    +
    def setTrust(self, newTrust)

    Set the peers trust. 0 = not trusted, 1 = friend, 2 = ultimate

    -Source code + +Expand source code +
    def setTrust(self, newTrust):
         '''Set the peers trust. 0 = not trusted, 1 = friend, 2 = ultimate'''
         keydb.userinfo.set_user_info(self.publicKey, 'trust', newTrust)
    @@ -727,31 +757,31 @@ def list_friends(cls):
    diff --git a/docs/html/onionr/onionrutils/basicrequests.html b/docs/html/src/onionrutils/basicrequests.html similarity index 88% rename from docs/html/onionr/onionrutils/basicrequests.html rename to docs/html/src/onionrutils/basicrequests.html index ff20a54c..845f98e1 100644 --- a/docs/html/onionr/onionrutils/basicrequests.html +++ b/docs/html/src/onionrutils/basicrequests.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.basicrequests API documentation + +src.onionrutils.basicrequests API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.basicrequests

    +

    Module src.onionrutils.basicrequests

    Onionr - Private P2P Communication

    Do HTTP GET or POST requests through a proxy

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -128,13 +130,15 @@ def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, return
     

    Functions

    -
    +
    def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders=False, max_size=5242880)

    Do a get request through a local tor or i2p instance

    -Source code + +Expand source code +
    def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders=False, max_size=5242880):
         '''
         Do a get request through a local tor or i2p instance
    @@ -182,13 +186,15 @@ def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, return
             return retData
    -
    +
    def do_post_request(url, data={}, port=0, proxyType='tor', max_size=10000, content_type='')

    Do a POST request through a local tor or i2p instance

    -Source code + +Expand source code +
    def do_post_request(url, data={}, port=0, proxyType='tor', max_size=10000, content_type: str = ''):
         '''
         Do a POST request through a local tor or i2p instance
    @@ -230,20 +236,20 @@ def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, return
     
     
     
    diff --git a/docs/html/onionr/onionrutils/blockmetadata/fromdata.html b/docs/html/src/onionrutils/blockmetadata/fromdata.html similarity index 81% rename from docs/html/onionr/onionrutils/blockmetadata/fromdata.html rename to docs/html/src/onionrutils/blockmetadata/fromdata.html index bf8e7cf1..a7f814ff 100644 --- a/docs/html/onionr/onionrutils/blockmetadata/fromdata.html +++ b/docs/html/src/onionrutils/blockmetadata/fromdata.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.blockmetadata.fromdata API documentation + +src.onionrutils.blockmetadata.fromdata API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.blockmetadata.fromdata

    +

    Module src.onionrutils.blockmetadata.fromdata

    Onionr - Private P2P Communication

    Return a useful tuple of (metadata (header), meta, and data) by accepting raw block data

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -79,7 +81,7 @@ def get_block_metadata_from_data(block_data):
     

    Functions

    -
    +
    def get_block_metadata_from_data(block_data)
    @@ -87,7 +89,9 @@ def get_block_metadata_from_data(block_data): metadata, meta (meta being internal metadata, which will be returned as an encrypted base64 string if it is encrypted, dict if not).

    -Source code + +Expand source code +
    def get_block_metadata_from_data(block_data):
         '''
             accepts block contents as string, returns a tuple of 
    @@ -126,19 +130,19 @@ returned as an encrypted base64 string if it is encrypted, dict if not).

  • Super-module

  • Functions

  • diff --git a/docs/html/onionr/onionrutils/blockmetadata/hasblock.html b/docs/html/src/onionrutils/blockmetadata/hasblock.html similarity index 78% rename from docs/html/onionr/onionrutils/blockmetadata/hasblock.html rename to docs/html/src/onionrutils/blockmetadata/hasblock.html index f76f5f28..8026fa24 100644 --- a/docs/html/onionr/onionrutils/blockmetadata/hasblock.html +++ b/docs/html/src/onionrutils/blockmetadata/hasblock.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.blockmetadata.hasblock API documentation + +src.onionrutils.blockmetadata.hasblock API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.blockmetadata.hasblock

    +

    Module src.onionrutils.blockmetadata.hasblock

    Onionr - Private P2P Communication

    Returns a bool if a block is in the block metadata db or not

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -47,12 +49,13 @@ import sqlite3
     from coredb import dbfiles
     import onionrexceptions
     from .. import stringvalidators
    +from etc import onionrvalues
     
     def has_block(hash: str) -> bool:
         '''
             Check for new block in the block meta db
         '''
    -    conn = sqlite3.connect(dbfiles.block_meta_db)
    +    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         if not stringvalidators.validate_hash(hash):
             raise onionrexceptions.InvalidHexHash("Invalid hash")
    @@ -75,18 +78,20 @@ def has_block(hash: str) -> bool:
     

    Functions

    -
    +
    def has_block(hash)

    Check for new block in the block meta db

    -Source code + +Expand source code +
    def has_block(hash: str) -> bool:
         '''
             Check for new block in the block meta db
         '''
    -    conn = sqlite3.connect(dbfiles.block_meta_db)
    +    conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
         c = conn.cursor()
         if not stringvalidators.validate_hash(hash):
             raise onionrexceptions.InvalidHexHash("Invalid hash")
    @@ -115,19 +120,19 @@ def has_block(hash: str) -> bool:
     
     
     
    diff --git a/docs/html/onionr/onionrutils/blockmetadata/index.html b/docs/html/src/onionrutils/blockmetadata/index.html similarity index 73% rename from docs/html/onionr/onionrutils/blockmetadata/index.html rename to docs/html/src/onionrutils/blockmetadata/index.html index 09ab2d56..e491988d 100644 --- a/docs/html/onionr/onionrutils/blockmetadata/index.html +++ b/docs/html/src/onionrutils/blockmetadata/index.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.blockmetadata API documentation + +src.onionrutils.blockmetadata API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.blockmetadata

    +

    Module src.onionrutils.blockmetadata

    Onionr - Private P2P Communication

    Module to work with block metadata

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -53,15 +55,15 @@ get_block_metadata_from_data = fromdata.get_block_metadata_from_data

    Sub-modules

    -
    onionr.onionrutils.blockmetadata.fromdata
    +
    src.onionrutils.blockmetadata.fromdata

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.blockmetadata.hasblock
    +
    src.onionrutils.blockmetadata.hasblock

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.blockmetadata.process
    +
    src.onionrutils.blockmetadata.process

    Onionr - Private P2P Communication …

    @@ -82,21 +84,21 @@ get_block_metadata_from_data = fromdata.get_block_metadata_from_data
  • Super-module

  • Sub-modules

  • diff --git a/docs/html/onionr/onionrutils/blockmetadata/process.html b/docs/html/src/onionrutils/blockmetadata/process.html similarity index 84% rename from docs/html/onionr/onionrutils/blockmetadata/process.html rename to docs/html/src/onionrutils/blockmetadata/process.html index 77150364..f1fe0d12 100644 --- a/docs/html/onionr/onionrutils/blockmetadata/process.html +++ b/docs/html/src/onionrutils/blockmetadata/process.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.blockmetadata.process API documentation + +src.onionrutils.blockmetadata.process API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.blockmetadata.process

    +

    Module src.onionrutils.blockmetadata.process

    Onionr - Private P2P Communication

    Process block metadata with relevant actions

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -52,6 +54,7 @@ import logger
     from onionrplugins import onionrevents
     import onionrexceptions
     from onionrusers import onionrusers
    +from onionrutils import updater
     
     def process_block_metadata(blockHash: str):
         '''
    @@ -93,6 +96,7 @@ def process_block_metadata(blockHash: str):
                 expireTime = min(expireTime, curTime + onionrvalues.DEFAULT_EXPIRE)
                 blockmetadb.update_block_info(blockHash, 'expire', expireTime)
     
    +        if blockType == 'update': updater.update_event(myBlock)
             onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid})
    @@ -103,14 +107,16 @@ def process_block_metadata(blockHash: str):

    Functions

    -
    +
    def process_block_metadata(blockHash)

    Read metadata from a block and cache it to the block database

    blockHash -> sha3_256 hex formatted hash of Onionr block

    -Source code + +Expand source code +
    def process_block_metadata(blockHash: str):
         '''
             Read metadata from a block and cache it to the block database
    @@ -151,6 +157,7 @@ def process_block_metadata(blockHash: str):
                 expireTime = min(expireTime, curTime + onionrvalues.DEFAULT_EXPIRE)
                 blockmetadb.update_block_info(blockHash, 'expire', expireTime)
     
    +        if blockType == 'update': updater.update_event(myBlock)
             onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid})
    @@ -167,19 +174,19 @@ def process_block_metadata(blockHash: str):
    diff --git a/docs/html/onionr/onionrutils/bytesconverter.html b/docs/html/src/onionrutils/bytesconverter.html similarity index 75% rename from docs/html/onionr/onionrutils/bytesconverter.html rename to docs/html/src/onionrutils/bytesconverter.html index 54be16e6..89d5d31c 100644 --- a/docs/html/onionr/onionrutils/bytesconverter.html +++ b/docs/html/src/onionrutils/bytesconverter.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.bytesconverter API documentation + +src.onionrutils.bytesconverter API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrutils.bytesconverter

    +

    Module src.onionrutils.bytesconverter

    -Source code + +Expand source code +
    def str_to_bytes(data):
         '''Converts a string to bytes with .encode()'''
         try:
    @@ -45,13 +47,15 @@ def bytes_to_str(data):
     

    Functions

    -
    +
    def bytes_to_str(data)
    -Source code + +Expand source code +
    def bytes_to_str(data):
         try:
             data = data.decode('UTF-8')
    @@ -60,13 +64,15 @@ def bytes_to_str(data):
         return data
    -
    +
    def str_to_bytes(data)

    Converts a string to bytes with .encode()

    -Source code + +Expand source code +
    def str_to_bytes(data):
         '''Converts a string to bytes with .encode()'''
         try:
    @@ -89,20 +95,20 @@ def bytes_to_str(data):
     
     
     
    diff --git a/docs/html/onionr/onionrutils/checkcommunicator.html b/docs/html/src/onionrutils/checkcommunicator.html similarity index 80% rename from docs/html/onionr/onionrutils/checkcommunicator.html rename to docs/html/src/onionrutils/checkcommunicator.html index 80dda1a0..49eefd8c 100644 --- a/docs/html/onionr/onionrutils/checkcommunicator.html +++ b/docs/html/src/onionrutils/checkcommunicator.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.checkcommunicator API documentation + +src.onionrutils.checkcommunicator API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.checkcommunicator

    +

    Module src.onionrutils.checkcommunicator

    Onionr - Private P2P Communication

    Check if the communicator is running

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -72,13 +74,15 @@ def is_communicator_running(timeout = 5, interval = 0.1):
     

    Functions

    -
    +
    def is_communicator_running(timeout=5, interval=0.1)
    -Source code + +Expand source code +
    def is_communicator_running(timeout = 5, interval = 0.1):
         try:
             runcheck_file = filepaths.run_check_file
    @@ -112,19 +116,19 @@ def is_communicator_running(timeout = 5, interval = 0.1):
     
     
     
    diff --git a/docs/html/onionr/onionrutils/epoch.html b/docs/html/src/onionrutils/epoch.html similarity index 78% rename from docs/html/onionr/onionrutils/epoch.html rename to docs/html/src/onionrutils/epoch.html index 7a687fc8..14c217ab 100644 --- a/docs/html/onionr/onionrutils/epoch.html +++ b/docs/html/src/onionrutils/epoch.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.epoch API documentation + +src.onionrutils.epoch API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.epoch

    +

    Module src.onionrutils.epoch

    Onionr - Private P2P Communication

    Get floored epoch, or rounded epoch

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -63,25 +65,29 @@ def get_epoch():
     

    Functions

    -
    +
    def get_epoch()

    returns epoch

    -Source code + +Expand source code +
    def get_epoch():
         '''returns epoch'''
         return math.floor(time.time())
    -
    +
    def get_rounded_epoch(roundS=60)

    Returns the epoch, rounded down to given seconds (Default 60)

    -Source code + +Expand source code +
    def get_rounded_epoch(roundS=60):
         '''
             Returns the epoch, rounded down to given seconds (Default 60)
    @@ -103,20 +109,20 @@ def get_epoch():
     
     
     
    diff --git a/docs/html/onionr/onionrutils/escapeansi.html b/docs/html/src/onionrutils/escapeansi.html similarity index 79% rename from docs/html/onionr/onionrutils/escapeansi.html rename to docs/html/src/onionrutils/escapeansi.html index 720ac31d..46fd4fa5 100644 --- a/docs/html/onionr/onionrutils/escapeansi.html +++ b/docs/html/src/onionrutils/escapeansi.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.escapeansi API documentation + +src.onionrutils.escapeansi API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.onionrutils.escapeansi

    +

    Module src.onionrutils.escapeansi

    -Source code + +Expand source code +
    import re
     def escape_ANSI(line):
         '''
    @@ -41,7 +43,7 @@ def escape_ANSI(line):
     

    Functions

    -
    +
    def escape_ANSI(line)
    @@ -49,7 +51,9 @@ def escape_ANSI(line):

    adapted from: https://stackoverflow.com/a/38662876 by user https://stackoverflow.com/users/802365/%c3%89douard-lopez cc-by-sa-3 license https://creativecommons.org/licenses/by-sa/3.0/

    -Source code + +Expand source code +
    def escape_ANSI(line):
         '''
             Remove ANSI escape codes from a string with regex
    @@ -74,19 +78,19 @@ cc-by-sa-3 license htt
     
     
     
    diff --git a/docs/html/onionr/onionrutils/getclientapiserver.html b/docs/html/src/onionrutils/getclientapiserver.html similarity index 80% rename from docs/html/onionr/onionrutils/getclientapiserver.html rename to docs/html/src/onionrutils/getclientapiserver.html index 7e51e0c3..fd028a46 100644 --- a/docs/html/onionr/onionrutils/getclientapiserver.html +++ b/docs/html/src/onionrutils/getclientapiserver.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.getclientapiserver API documentation + +src.onionrutils.getclientapiserver API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.getclientapiserver

    +

    Module src.onionrutils.getclientapiserver

    Onionr - Private P2P Communication

    Return the client api server address and port, which is usually random

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -70,13 +72,15 @@ def get_client_API_server():
     

    Functions

    -
    +
    def get_client_API_server()
    -Source code + +Expand source code +
    def get_client_API_server():
         config.reload()
         retData = ''
    @@ -108,19 +112,19 @@ def get_client_API_server():
     
     
     
    diff --git a/docs/html/onionr/onionrutils/importnewblocks.html b/docs/html/src/onionrutils/importnewblocks.html similarity index 84% rename from docs/html/onionr/onionrutils/importnewblocks.html rename to docs/html/src/onionrutils/importnewblocks.html index 28bb6fb5..06542dc7 100644 --- a/docs/html/onionr/onionrutils/importnewblocks.html +++ b/docs/html/src/onionrutils/importnewblocks.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.importnewblocks API documentation + +src.onionrutils.importnewblocks API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.importnewblocks

    +

    Module src.onionrutils.importnewblocks

    Onionr - Private P2P Communication

    import new blocks from disk, providing transport agnosticism

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -84,13 +86,15 @@ import_new_blocks.onionr_help = f"Scans the Onionr data directory under {fil
     

    Functions

    -
    +
    def import_new_blocks(scanDir='')

    This function is intended to scan for new blocks ON THE DISK and import them

    -Source code + +Expand source code +
    def import_new_blocks(scanDir=''):
         '''
             This function is intended to scan for new blocks ON THE DISK and import them
    @@ -130,19 +134,19 @@ import_new_blocks.onionr_help = f"Scans the Onionr data directory under {fil
     
     
     
    diff --git a/docs/html/onionr/onionrutils/index.html b/docs/html/src/onionrutils/index.html similarity index 54% rename from docs/html/onionr/onionrutils/index.html rename to docs/html/src/onionrutils/index.html index d389bc96..43c0ceed 100644 --- a/docs/html/onionr/onionrutils/index.html +++ b/docs/html/src/onionrutils/index.html @@ -3,13 +3,13 @@ - -onionr.onionrutils API documentation + +src.onionrutils API documentation - + @@ -17,58 +17,62 @@
    -

    Module onionr.onionrutils

    +

    Module src.onionrutils

    Sub-modules

    -
    onionr.onionrutils.basicrequests
    +
    src.onionrutils.basicrequests

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.blockmetadata
    +
    src.onionrutils.blockmetadata

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.bytesconverter
    +
    src.onionrutils.bytesconverter
    -
    onionr.onionrutils.checkcommunicator
    +
    src.onionrutils.checkcommunicator

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.epoch
    +
    src.onionrutils.epoch

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.escapeansi
    +
    src.onionrutils.escapeansi
    -
    onionr.onionrutils.getclientapiserver
    +
    src.onionrutils.getclientapiserver

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.importnewblocks
    +
    src.onionrutils.importnewblocks

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.localcommand
    +
    src.onionrutils.localcommand

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.mnemonickeys
    +
    src.onionrutils.mnemonickeys

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.stringvalidators
    +
    src.onionrutils.stringvalidators

    Onionr - Private P2P Communication …

    -
    onionr.onionrutils.validatemetadata
    +
    src.onionrutils.updater
    +
    +
    +
    +
    src.onionrutils.validatemetadata

    Onionr - Private P2P Communication …

    @@ -89,30 +93,31 @@
    diff --git a/docs/html/onionr/onionrutils/localcommand.html b/docs/html/src/onionrutils/localcommand.html similarity index 70% rename from docs/html/onionr/onionrutils/localcommand.html rename to docs/html/src/onionrutils/localcommand.html index c4c4e360..288da4bf 100644 --- a/docs/html/onionr/onionrutils/localcommand.html +++ b/docs/html/src/onionrutils/localcommand.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.localcommand API documentation + +src.onionrutils.localcommand API documentation - + @@ -17,19 +17,31 @@
    -

    Module onionr.onionrutils.localcommand

    +

    Module src.onionrutils.localcommand

    Onionr - Private P2P Communication

    send a command to the local API server

    -Source code -
    '''
    +
    +Expand source code
    +
    +
    """
         Onionr - Private P2P Communication
     
         send a command to the local API server
    -'''
    -'''
    +"""
    +import urllib, time
    +import json
    +import functools
    +from typing import TYPE_CHECKING, Callable
    +
    +import requests
    +
    +import logger, config, deadsimplekv
    +from . import getclientapiserver
    +import filepaths
    +"""
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation, either version 3 of the License, or
    @@ -42,11 +54,7 @@
     
         You should have received a copy of the GNU General Public License
         along with this program. If not, see <https://www.gnu.org/licenses/>.
    -'''
    -import urllib, requests, time
    -import logger, config, deadsimplekv
    -from . import getclientapiserver
    -import filepaths
    +"""
     config.reload()
     
     cache = deadsimplekv.DeadSimpleKV(filepaths.cached_storage, refresh_seconds=1000)
    @@ -72,27 +80,45 @@ def get_hostname():
             else:
                 return hostname
     
    -def local_command(command, data='', silent = True, post=False, postData = {}, maxWait=20):
    -    '''
    +def local_command(command, data='', silent = True, post=False,
    +                  postData = {}, maxWait=20,
    +                  is_json=False
    +                  ):
    +    """
             Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.
    -    '''
    +    """
         # TODO: URL encode parameters, just as an extra measure. May not be needed, but should be added regardless.
         hostname = get_hostname()
         if hostname == False: return False
    +
         if data != '':
             data = '&data=' + urllib.parse.quote_plus(data)
         payload = 'http://%s/%s%s' % (hostname, command, data)
    +    if not config.get('client.webpassword'):
    +        config.reload()
     
         try:
             if post:
    -            ret_data = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, maxWait)).text
    +            if is_json:
    +                ret_data = requests.post(
    +                    payload,
    +                    json=postData,
    +                    headers={'token': config.get('client.webpassword'),
    +                             'Connection': 'close'},
    +                    timeout=(maxWait, maxWait)).text
    +            else:
    +                ret_data = requests.post(
    +                    payload,
    +                    data=postData,
    +                    headers={'token': config.get('client.webpassword'),
    +                             'Connection': 'close'},
    +                    timeout=(maxWait, maxWait)).text
             else:
                 ret_data = requests.get(payload, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, maxWait)).text
         except Exception as error:
             if not silent:
                 logger.error('Failed to make local request (command: %s):%s' % (command, error), terminal=True)
             ret_data = False
    -
         return ret_data
    @@ -103,13 +129,15 @@ def local_command(command, data='', silent = True, post=False, postData

    Functions

    -
    +
    def get_hostname()
    -Source code + +Expand source code +
    def get_hostname():
         hostname = ''
         waited = 0
    @@ -133,34 +161,54 @@ def local_command(command, data='', silent = True, post=False, postData
                 return hostname
    -
    -def local_command(command, data='', silent=True, post=False, postData={}, maxWait=20) +
    +def local_command(command, data='', silent=True, post=False, postData={}, maxWait=20, is_json=False)

    Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.

    -Source code -
    def local_command(command, data='', silent = True, post=False, postData = {}, maxWait=20):
    -    '''
    +
    +Expand source code
    +
    +
    def local_command(command, data='', silent = True, post=False,
    +                  postData = {}, maxWait=20,
    +                  is_json=False
    +                  ):
    +    """
             Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.
    -    '''
    +    """
         # TODO: URL encode parameters, just as an extra measure. May not be needed, but should be added regardless.
         hostname = get_hostname()
         if hostname == False: return False
    +
         if data != '':
             data = '&data=' + urllib.parse.quote_plus(data)
         payload = 'http://%s/%s%s' % (hostname, command, data)
    +    if not config.get('client.webpassword'):
    +        config.reload()
     
         try:
             if post:
    -            ret_data = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, maxWait)).text
    +            if is_json:
    +                ret_data = requests.post(
    +                    payload,
    +                    json=postData,
    +                    headers={'token': config.get('client.webpassword'),
    +                             'Connection': 'close'},
    +                    timeout=(maxWait, maxWait)).text
    +            else:
    +                ret_data = requests.post(
    +                    payload,
    +                    data=postData,
    +                    headers={'token': config.get('client.webpassword'),
    +                             'Connection': 'close'},
    +                    timeout=(maxWait, maxWait)).text
             else:
                 ret_data = requests.get(payload, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, maxWait)).text
         except Exception as error:
             if not silent:
                 logger.error('Failed to make local request (command: %s):%s' % (command, error), terminal=True)
             ret_data = False
    -
         return ret_data
    @@ -177,20 +225,20 @@ def local_command(command, data='', silent = True, post=False, postData
    diff --git a/docs/html/onionr/onionrutils/mnemonickeys.html b/docs/html/src/onionrutils/mnemonickeys.html similarity index 70% rename from docs/html/onionr/onionrutils/mnemonickeys.html rename to docs/html/src/onionrutils/mnemonickeys.html index 149314ad..26d23e13 100644 --- a/docs/html/onionr/onionrutils/mnemonickeys.html +++ b/docs/html/src/onionrutils/mnemonickeys.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.mnemonickeys API documentation + +src.onionrutils.mnemonickeys API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.mnemonickeys

    +

    Module src.onionrutils.mnemonickeys

    Onionr - Private P2P Communication

    convert a base32 string (intended for ed25519 user ids) to pgp word list

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -45,13 +47,13 @@
     '''
     import base64
     
    -import mnemonic
    +import niceware
     import unpaddedbase32
     
     import onionrcrypto
     from etc import onionrvalues
     
    -m = mnemonic.Mnemonic('english')
    +DELIMITER = '-'
     
     def get_human_readable_ID(pub=''):
         '''gets a human readable ID from a public key'''
    @@ -61,11 +63,18 @@ def get_human_readable_ID(pub=''):
         if not len(pub) == onionrvalues.MAIN_PUBLIC_KEY_SIZE:
             pub = base64.b32decode(pub)
         
    -    return m.to_mnemonic(pub).replace(' ', '-')
    +    return DELIMITER.join(niceware.bytes_to_passphrase(pub))
    +    #return niceware.bytes_to_passphrase(pub).replace(' ', DELIMITER)
     
     def get_base32(words):
         '''converts mnemonic to base32'''
    -    return unpaddedbase32.b32encode(m.to_entropy(words.replace('-', ' ')))
    + if DELIMITER not in words and not type(words) in (type(list), type(tuple)): return words + + try: + return unpaddedbase32.b32encode(niceware.passphrase_to_bytes(words.split(DELIMITER))) + except AttributeError: + ret = unpaddedbase32.b32encode(niceware.passphrase_to_bytes(words)) + return ret
    @@ -75,25 +84,35 @@ def get_base32(words):

    Functions

    -
    +
    def get_base32(words)

    converts mnemonic to base32

    -Source code + +Expand source code +
    def get_base32(words):
         '''converts mnemonic to base32'''
    -    return unpaddedbase32.b32encode(m.to_entropy(words.replace('-', ' ')))
    + if DELIMITER not in words and not type(words) in (type(list), type(tuple)): return words + + try: + return unpaddedbase32.b32encode(niceware.passphrase_to_bytes(words.split(DELIMITER))) + except AttributeError: + ret = unpaddedbase32.b32encode(niceware.passphrase_to_bytes(words)) + return ret
    -
    +
    def get_human_readable_ID(pub='')

    gets a human readable ID from a public key

    -Source code + +Expand source code +
    def get_human_readable_ID(pub=''):
         '''gets a human readable ID from a public key'''
         if pub == '':
    @@ -102,7 +121,7 @@ def get_base32(words):
         if not len(pub) == onionrvalues.MAIN_PUBLIC_KEY_SIZE:
             pub = base64.b32decode(pub)
         
    -    return m.to_mnemonic(pub).replace(' ', '-')
    + return DELIMITER.join(niceware.bytes_to_passphrase(pub))
    @@ -118,20 +137,20 @@ def get_base32(words):
    diff --git a/docs/html/onionr/onionrutils/stringvalidators.html b/docs/html/src/onionrutils/stringvalidators.html similarity index 83% rename from docs/html/onionr/onionrutils/stringvalidators.html rename to docs/html/src/onionrutils/stringvalidators.html index d0b95b9a..fb6dac54 100644 --- a/docs/html/onionr/onionrutils/stringvalidators.html +++ b/docs/html/src/onionrutils/stringvalidators.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.stringvalidators API documentation + +src.onionrutils.stringvalidators API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.onionrutils.stringvalidators

    +

    Module src.onionrutils.stringvalidators

    Onionr - Private P2P Communication

    validate various string data types

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -152,13 +154,15 @@ def is_integer_string(data):
     

    Functions

    -
    +
    def is_integer_string(data)

    Check if a string is a valid base10 integer (also returns true if already an int)

    -Source code + +Expand source code +
    def is_integer_string(data):
         '''Check if a string is a valid base10 integer (also returns true if already an int)'''
         try:
    @@ -169,14 +173,16 @@ def is_integer_string(data):
             return True
    -
    +
    def validate_hash(data, length=64)

    Validate if a string is a valid hash hex digest (does not compare, just checks length and charset)

    Length is only invalid if its more than the specified

    -Source code + +Expand source code +
    def validate_hash(data, length=64):
         '''
             Validate if a string is a valid hash hex digest (does not compare, just checks length and charset)
    @@ -198,13 +204,15 @@ def is_integer_string(data):
         return retVal
    -
    +
    def validate_pub_key(key)

    Validate if a string is a valid base32 encoded Ed25519 key

    -Source code + +Expand source code +
    def validate_pub_key(key):
         '''
             Validate if a string is a valid base32 encoded Ed25519 key
    @@ -226,13 +234,15 @@ def is_integer_string(data):
         return retVal
    -
    +
    def validate_transport(id)
    -Source code + +Expand source code +
    def validate_transport(id):
         try:
             idLength = len(id)
    @@ -296,22 +306,22 @@ def is_integer_string(data):
     
     
     
    diff --git a/docs/html/src/onionrutils/updater/index.html b/docs/html/src/onionrutils/updater/index.html new file mode 100644 index 00000000..2a1b532a --- /dev/null +++ b/docs/html/src/onionrutils/updater/index.html @@ -0,0 +1,88 @@ + + + + + + +src.onionrutils.updater API documentation + + + + + + + + + +
    +
    +
    +

    Module src.onionrutils.updater

    +
    +
    +
    + +Expand source code + +
    import notifier
    +
    +
    +def update_event(bl):
    +    """Show update notification if available, return bool of if update happened"""
    +    if not bl.isSigner(onionrvalues.UPDATE_SIGN_KEY): raise onionrexceptions.InvalidUpdate
    +    onionr.notifier.notify(message="A new Onionr update is available. Stay updated to remain secure.")
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def update_event(bl) +
    +
    +

    Show update notification if available, return bool of if update happened

    +
    + +Expand source code + +
    def update_event(bl):
    +    """Show update notification if available, return bool of if update happened"""
    +    if not bl.isSigner(onionrvalues.UPDATE_SIGN_KEY): raise onionrexceptions.InvalidUpdate
    +    onionr.notifier.notify(message="A new Onionr update is available. Stay updated to remain secure.")
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrutils/validatemetadata.html b/docs/html/src/onionrutils/validatemetadata.html similarity index 86% rename from docs/html/onionr/onionrutils/validatemetadata.html rename to docs/html/src/onionrutils/validatemetadata.html index 934d9523..d7530621 100644 --- a/docs/html/onionr/onionrutils/validatemetadata.html +++ b/docs/html/src/onionrutils/validatemetadata.html @@ -3,13 +3,13 @@ - -onionr.onionrutils.validatemetadata API documentation + +src.onionrutils.validatemetadata API documentation - + @@ -17,19 +17,21 @@
    -

    Module onionr.onionrutils.validatemetadata

    +

    Module src.onionrutils.validatemetadata

    Onionr - Private P2P Communication

    validate new block's metadata

    -Source code -
    '''
    +
    +Expand source code
    +
    +
    """
         Onionr - Private P2P Communication
     
         validate new block's metadata
    -'''
    -'''
    +"""
    +"""
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation, either version 3 of the License, or
    @@ -42,14 +44,15 @@
     
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
    -'''
    +"""
     import json
     import logger, onionrexceptions
     from etc import onionrvalues
    -from onionrutils import stringvalidators, epoch, bytesconverter
    +from . import stringvalidators, epoch, bytesconverter
     import config, filepaths, onionrcrypto
    +
     def validate_metadata(metadata, block_data) -> bool:
    -    '''Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string'''
    +    """Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string"""
     
         ret_data = False
         max_clock_difference = onionrvalues.MAX_BLOCK_CLOCK_SKEW
    @@ -85,7 +88,7 @@ def validate_metadata(metadata, block_data) -> bool:
                         break
                     isFuture = (metadata[i] - epoch.get_epoch())
                     if isFuture > max_clock_difference:
    -                    logger.warn('Block timestamp is skewed to the future over the max %s: %s' (max_clock_difference, isFuture))
    +                    logger.warn('Block timestamp is skewed to the future over the max %s: %s', (max_clock_difference, isFuture))
                         break
                     if (epoch.get_epoch() - metadata[i]) > maxAge:
                         logger.warn('Block is outdated: %s' % (metadata[i],))
    @@ -99,6 +102,8 @@ def validate_metadata(metadata, block_data) -> bool:
                 elif i == 'encryptType':
                     try:
                         if not metadata[i] in ('asym', 'sym', ''): raise ValueError
    +                    if not config.get('general.store_plaintext_blocks', True):
    +                        break
                     except ValueError:
                         logger.warn('Invalid encryption mode')
                         break
    @@ -149,15 +154,17 @@ def validate_metadata(metadata, block_data) -> bool:
     

    Functions

    -
    +
    def validate_metadata(metadata, block_data)

    Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string

    -Source code + +Expand source code +
    def validate_metadata(metadata, block_data) -> bool:
    -    '''Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string'''
    +    """Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string"""
     
         ret_data = False
         max_clock_difference = onionrvalues.MAX_BLOCK_CLOCK_SKEW
    @@ -193,7 +200,7 @@ def validate_metadata(metadata, block_data) -> bool:
                         break
                     isFuture = (metadata[i] - epoch.get_epoch())
                     if isFuture > max_clock_difference:
    -                    logger.warn('Block timestamp is skewed to the future over the max %s: %s' (max_clock_difference, isFuture))
    +                    logger.warn('Block timestamp is skewed to the future over the max %s: %s', (max_clock_difference, isFuture))
                         break
                     if (epoch.get_epoch() - metadata[i]) > maxAge:
                         logger.warn('Block is outdated: %s' % (metadata[i],))
    @@ -207,6 +214,8 @@ def validate_metadata(metadata, block_data) -> bool:
                 elif i == 'encryptType':
                     try:
                         if not metadata[i] in ('asym', 'sym', ''): raise ValueError
    +                    if not config.get('general.store_plaintext_blocks', True):
    +                        break
                     except ValueError:
                         logger.warn('Invalid encryption mode')
                         break
    @@ -263,19 +272,19 @@ def validate_metadata(metadata, block_data) -> bool:
     
     
     
    diff --git a/docs/html/src/runtests/index.html b/docs/html/src/runtests/index.html new file mode 100644 index 00000000..d3b12d41 --- /dev/null +++ b/docs/html/src/runtests/index.html @@ -0,0 +1,241 @@ + + + + + + +src.runtests API documentation + + + + + + + + + +
    +
    +
    +

    Module src.runtests

    +
    +
    +

    Onionr - Private P2P Communication.

    +

    Test Onionr as it is running

    +
    + +Expand source code + +
    """Onionr - Private P2P Communication.
    +
    +Test Onionr as it is running
    +"""
    +import os
    +
    +import logger
    +from onionrutils import epoch
    +
    +from . import uicheck, inserttest, stresstest
    +from . import ownnode
    +from .webpasstest import webpass_test
    +"""
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +RUN_TESTS = [uicheck.check_ui,
    +             inserttest.insert_bin_test,
    +             ownnode.test_tor_adder,
    +             ownnode.test_own_node,
    +             stresstest.stress_test_block_insert,
    +             webpass_test
    +             ]
    +
    +SUCCESS_FILE = os.path.dirname(os.path.realpath(__file__)) + '/../../tests/runtime-result.txt'
    +
    +
    +class OnionrRunTestManager:
    +    def __init__(self):
    +        self.success: bool = True
    +        self.run_date: int = 0
    +
    +    def run_tests(self):
    +        cur_time = epoch.get_epoch()
    +        logger.info(f"Doing runtime tests at {cur_time}")
    +
    +        try:
    +            os.remove(SUCCESS_FILE)
    +        except FileNotFoundError:
    +            pass
    +
    +        try:
    +            for i in RUN_TESTS:
    +                last = i
    +                i(self)
    +                logger.info("[RUNTIME TEST] " + last.__name__ + " passed")
    +        except (ValueError, AttributeError):
    +            logger.error(last.__name__ + ' failed')
    +        else:
    +            ep = str(epoch.get_epoch())
    +            logger.info(f'All runtime tests passed at {ep}')
    +            with open(SUCCESS_FILE, 'w') as f:
    +                f.write(ep)
    +
    +
    +
    +

    Sub-modules

    +
    +
    src.runtests.inserttest
    +
    +
    +
    +
    src.runtests.ownnode
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.runtests.stresstest
    +
    +
    +
    +
    src.runtests.uicheck
    +
    +
    +
    +
    src.runtests.webpasstest
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class OnionrRunTestManager +
    +
    +
    +
    + +Expand source code + +
    class OnionrRunTestManager:
    +    def __init__(self):
    +        self.success: bool = True
    +        self.run_date: int = 0
    +
    +    def run_tests(self):
    +        cur_time = epoch.get_epoch()
    +        logger.info(f"Doing runtime tests at {cur_time}")
    +
    +        try:
    +            os.remove(SUCCESS_FILE)
    +        except FileNotFoundError:
    +            pass
    +
    +        try:
    +            for i in RUN_TESTS:
    +                last = i
    +                i(self)
    +                logger.info("[RUNTIME TEST] " + last.__name__ + " passed")
    +        except (ValueError, AttributeError):
    +            logger.error(last.__name__ + ' failed')
    +        else:
    +            ep = str(epoch.get_epoch())
    +            logger.info(f'All runtime tests passed at {ep}')
    +            with open(SUCCESS_FILE, 'w') as f:
    +                f.write(ep)
    +
    +

    Methods

    +
    +
    +def run_tests(self) +
    +
    +
    +
    + +Expand source code + +
    def run_tests(self):
    +    cur_time = epoch.get_epoch()
    +    logger.info(f"Doing runtime tests at {cur_time}")
    +
    +    try:
    +        os.remove(SUCCESS_FILE)
    +    except FileNotFoundError:
    +        pass
    +
    +    try:
    +        for i in RUN_TESTS:
    +            last = i
    +            i(self)
    +            logger.info("[RUNTIME TEST] " + last.__name__ + " passed")
    +    except (ValueError, AttributeError):
    +        logger.error(last.__name__ + ' failed')
    +    else:
    +        ep = str(epoch.get_epoch())
    +        logger.info(f'All runtime tests passed at {ep}')
    +        with open(SUCCESS_FILE, 'w') as f:
    +            f.write(ep)
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/netcontroller/torcontroller.html b/docs/html/src/runtests/inserttest.html similarity index 65% rename from docs/html/onionr/netcontroller/torcontroller.html rename to docs/html/src/runtests/inserttest.html index e5f548f3..834967eb 100644 --- a/docs/html/onionr/netcontroller/torcontroller.html +++ b/docs/html/src/runtests/inserttest.html @@ -3,13 +3,13 @@ - -onionr.netcontroller.torcontroller API documentation + +src.runtests.inserttest API documentation - + @@ -17,19 +17,31 @@
    -

    Module onionr.netcontroller.torcontroller

    +

    Module src.runtests.inserttest

    -Source code -
    from stem.control import Controller
    +
    +Expand source code
    +
    +
    import os
    +import time
     
    -import config
    +import onionrblocks
    +import logger
    +import coredb
    +from communicator import peeraction
     
    -def get_controller():
    -    c = Controller.from_port(port=config.get('tor.controlPort'))
    -    c.authenticate(config.get('tor.controlpassword'))
    -    return c
    +def _check_remote_node(testmanager): + return + +def insert_bin_test(testmanager): + data = os.urandom(32) + b_hash = onionrblocks.insert(data, ) + + if not b_hash in coredb.blockmetadb.get_block_list(): + logger.error(str(b_hash) + 'is not in bl') + raise ValueError
    @@ -39,17 +51,22 @@ def get_controller():

    Functions

    -
    -def get_controller() +
    +def insert_bin_test(testmanager)
    -Source code -
    def get_controller():
    -    c = Controller.from_port(port=config.get('tor.controlPort'))
    -    c.authenticate(config.get('tor.controlpassword'))
    -    return c
    + +Expand source code + +
    def insert_bin_test(testmanager):
    +    data = os.urandom(32)
    +    b_hash = onionrblocks.insert(data, )
    +
    +    if not b_hash in coredb.blockmetadb.get_block_list():
    +        logger.error(str(b_hash) + 'is not in bl')
    +        raise ValueError
    @@ -65,19 +82,19 @@ def get_controller():
    diff --git a/docs/html/src/runtests/ownnode.html b/docs/html/src/runtests/ownnode.html new file mode 100644 index 00000000..d415f9bd --- /dev/null +++ b/docs/html/src/runtests/ownnode.html @@ -0,0 +1,165 @@ + + + + + + +src.runtests.ownnode API documentation + + + + + + + + + +
    +
    +
    +

    Module src.runtests.ownnode

    +
    +
    +

    Onionr - Private P2P Communication.

    +

    Test own Onionr node as it is running

    +
    + +Expand source code + +
    """Onionr - Private P2P Communication.
    +
    +Test own Onionr node as it is running
    +"""
    +import config
    +from onionrutils import basicrequests
    +from utils import identifyhome
    +from utils import gettransports
    +import logger
    +from onionrutils import localcommand
    +"""
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +
    +def test_own_node(test_manager):
    +    socks_port = localcommand.local_command('/gettorsocks')
    +    if config.get('general.security_level', 0) > 0:
    +        return
    +    own_tor_address = gettransports.get()[0]
    +    if 'this is an onionr node' \
    +            not in basicrequests.do_get_request('http://' + own_tor_address,
    +                                                port=socks_port, ignoreAPI=True).lower():
    +        logger.warn('Own node not reachable in test')
    +        raise ValueError
    +
    +
    +def test_tor_adder(test_manager):
    +    if config.get('general.security_level', 0) > 0:
    +        return
    +    with open(identifyhome.identify_home() + 'hs/hostname', 'r') as hs:
    +        hs = hs.read().strip()
    +    if not hs:
    +        logger.error('No Tor node address created yet')
    +        raise ValueError('No Tor node address created yet')
    +
    +    if hs not in gettransports.get():
    +        logger.error('gettransports Tor not same as file: %s %s' %
    +                     (hs, gettransports.get()))
    +        raise ValueError('gettransports Tor not same as file')
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def test_own_node(test_manager) +
    +
    +
    +
    + +Expand source code + +
    def test_own_node(test_manager):
    +    socks_port = localcommand.local_command('/gettorsocks')
    +    if config.get('general.security_level', 0) > 0:
    +        return
    +    own_tor_address = gettransports.get()[0]
    +    if 'this is an onionr node' \
    +            not in basicrequests.do_get_request('http://' + own_tor_address,
    +                                                port=socks_port, ignoreAPI=True).lower():
    +        logger.warn('Own node not reachable in test')
    +        raise ValueError
    +
    +
    +
    +def test_tor_adder(test_manager) +
    +
    +
    +
    + +Expand source code + +
    def test_tor_adder(test_manager):
    +    if config.get('general.security_level', 0) > 0:
    +        return
    +    with open(identifyhome.identify_home() + 'hs/hostname', 'r') as hs:
    +        hs = hs.read().strip()
    +    if not hs:
    +        logger.error('No Tor node address created yet')
    +        raise ValueError('No Tor node address created yet')
    +
    +    if hs not in gettransports.get():
    +        logger.error('gettransports Tor not same as file: %s %s' %
    +                     (hs, gettransports.get()))
    +        raise ValueError('gettransports Tor not same as file')
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/onionrcommands/parser/recommend.html b/docs/html/src/runtests/stresstest.html similarity index 62% rename from docs/html/onionr/onionrcommands/parser/recommend.html rename to docs/html/src/runtests/stresstest.html index 89644939..098c1cc5 100644 --- a/docs/html/onionr/onionrcommands/parser/recommend.html +++ b/docs/html/src/runtests/stresstest.html @@ -3,13 +3,13 @@ - -onionr.onionrcommands.parser.recommend API documentation + +src.runtests.stresstest API documentation - + @@ -17,26 +17,30 @@
    -

    Module onionr.onionrcommands.parser.recommend

    +

    Module src.runtests.stresstest

    -Source code -
    import sys
    -from difflib import SequenceMatcher
    -import logger
    -from . import arguments
    +
    +Expand source code
    +
    +
    import os
     
    -def recommend(print_default: bool = True):
    -    tried = sys.argv[1]
    -    args = arguments.get_arguments()
    -    print_message = 'Command not found:'
    -    for key in args.keys():
    -        for word in key:
    -            if SequenceMatcher(None, tried, word).ratio() >= 0.75:
    -                logger.warn('%s "%s", did you mean "%s"?' % (print_message, tried, word), terminal=True)
    -                return
    -    if print_default: logger.error('%s "%s"' % (print_message, tried), terminal=True)
    +import onionrblocks +import logger +import coredb +from onionrutils import epoch + +def stress_test_block_insert(testmanager): + return + start = epoch.get_epoch() + count = 100 + max_insert_speed = 120 + for x in range(count): onionrblocks.insert(os.urandom(32)) + speed = epoch.get_epoch() - start + if speed < max_insert_speed: + raise ValueError(f'{count} blocks inserted too fast, {max_insert_speed}, got {speed}') + logger.info(f'runtest stress block insertion: {count} blocks inserted in {speed}s')
    @@ -46,23 +50,25 @@ def recommend(print_default: bool = True):

    Functions

    -
    -def recommend(print_default=True) +
    +def stress_test_block_insert(testmanager)
    -Source code -
    def recommend(print_default: bool = True):
    -    tried = sys.argv[1]
    -    args = arguments.get_arguments()
    -    print_message = 'Command not found:'
    -    for key in args.keys():
    -        for word in key:
    -            if SequenceMatcher(None, tried, word).ratio() >= 0.75:
    -                logger.warn('%s "%s", did you mean "%s"?' % (print_message, tried, word), terminal=True)
    -                return
    -    if print_default: logger.error('%s "%s"' % (print_message, tried), terminal=True)
    + +Expand source code + +
    def stress_test_block_insert(testmanager):
    +    return
    +    start = epoch.get_epoch()
    +    count = 100
    +    max_insert_speed = 120
    +    for x in range(count): onionrblocks.insert(os.urandom(32))
    +    speed = epoch.get_epoch() - start
    +    if speed < max_insert_speed:
    +        raise ValueError(f'{count} blocks inserted too fast, {max_insert_speed}, got {speed}')
    +    logger.info(f'runtest stress block insertion: {count} blocks inserted in {speed}s')
    @@ -78,19 +84,19 @@ def recommend(print_default: bool = True):
    diff --git a/docs/html/src/runtests/uicheck.html b/docs/html/src/runtests/uicheck.html new file mode 100644 index 00000000..92cfaef5 --- /dev/null +++ b/docs/html/src/runtests/uicheck.html @@ -0,0 +1,94 @@ + + + + + + +src.runtests.uicheck API documentation + + + + + + + + + +
    +
    +
    +

    Module src.runtests.uicheck

    +
    +
    +
    + +Expand source code + +
    from onionrutils import localcommand
    +def check_ui(test_manager):
    +    endpoints = ['/', '/mail/', '/friends/', '/board/']
    +    for point in endpoints:
    +        result = localcommand.local_command(point)
    +        if not result: raise ValueError
    +        result = result.lower()
    +        if 'script' not in result:
    +            raise ValueError(f'uicheck failed on {point}')
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def check_ui(test_manager) +
    +
    +
    +
    + +Expand source code + +
    def check_ui(test_manager):
    +    endpoints = ['/', '/mail/', '/friends/', '/board/']
    +    for point in endpoints:
    +        result = localcommand.local_command(point)
    +        if not result: raise ValueError
    +        result = result.lower()
    +        if 'script' not in result:
    +            raise ValueError(f'uicheck failed on {point}')
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/utils/gettransports.html b/docs/html/src/runtests/webpasstest.html similarity index 65% rename from docs/html/onionr/utils/gettransports.html rename to docs/html/src/runtests/webpasstest.html index b404061c..e992078d 100644 --- a/docs/html/onionr/utils/gettransports.html +++ b/docs/html/src/runtests/webpasstest.html @@ -3,13 +3,13 @@ - -onionr.utils.gettransports API documentation + +src.runtests.webpasstest API documentation - + @@ -17,28 +17,24 @@
    -

    Module onionr.utils.gettransports

    +

    Module src.runtests.webpasstest

    -Source code -
    import filepaths, time
    +
    +Expand source code
    +
    +
    import requests
     
    -files = [filepaths.tor_hs_address_file]
    +from onionrutils import localcommand
     
    -def get():
    -        transports = []
    -        for file in files:
    -                try:
    -                        with open(file, 'r') as transport_file:
    -                                transports.append(transport_file.read().strip())
    -                except FileNotFoundError:
    -                        pass
    -                else:
    -                        break
    -        else:
    -                time.sleep(1)
    -        return list(transports)
    + +def webpass_test(test_manager): + if requests.get('http://' + localcommand.get_hostname() + '/ping') == \ + 'pong!': + raise ValueError + if localcommand.local_command('ping') != 'pong!': + raise ValueError('Could not ping with normal localcommand in webpasstest')
    @@ -48,26 +44,21 @@ def get():

    Functions

    -
    -def get() +
    +def webpass_test(test_manager)
    -Source code -
    def get():
    -        transports = []
    -        for file in files:
    -                try:
    -                        with open(file, 'r') as transport_file:
    -                                transports.append(transport_file.read().strip())
    -                except FileNotFoundError:
    -                        pass
    -                else:
    -                        break
    -        else:
    -                time.sleep(1)
    -        return list(transports)
    + +Expand source code + +
    def webpass_test(test_manager):
    +    if requests.get('http://' + localcommand.get_hostname() + '/ping') == \
    +        'pong!':
    +        raise ValueError
    +    if localcommand.local_command('ping') != 'pong!':
    +        raise ValueError('Could not ping with normal localcommand in webpasstest')
    @@ -83,19 +74,19 @@ def get():
    diff --git a/docs/html/onionr/etc/cleanup/index.html b/docs/html/src/utils/bettersleep.html similarity index 68% rename from docs/html/onionr/etc/cleanup/index.html rename to docs/html/src/utils/bettersleep.html index 6edffb1f..52d1a988 100644 --- a/docs/html/onionr/etc/cleanup/index.html +++ b/docs/html/src/utils/bettersleep.html @@ -3,13 +3,13 @@ - -onionr.etc.cleanup API documentation + +src.utils.bettersleep API documentation - + @@ -17,23 +17,22 @@
    -

    Module onionr.etc.cleanup

    +

    Module src.utils.bettersleep

    -Source code -
    import os, filepaths
    +
    +Expand source code
    +
    +
    from time import sleep
     
    -def _safe_remove(path):
    +
    +def better_sleep(wait: int):
    +    """Sleep catching ctrl c for wait seconds."""
         try:
    -        os.remove(path)
    -    except FileNotFoundError:
    -        pass
    -
    -def delete_run_files():
    -     _safe_remove(filepaths.public_API_host_file)
    -     _safe_remove(filepaths.private_API_host_file)
    -     _safe_remove(filepaths.daemon_mark_file)
    + sleep(wait) + except KeyboardInterrupt: + pass
    @@ -43,17 +42,21 @@ def delete_run_files():

    Functions

    -
    -def delete_run_files() +
    +def better_sleep(wait)
    -
    +

    Sleep catching ctrl c for wait seconds.

    -Source code -
    def delete_run_files():
    -     _safe_remove(filepaths.public_API_host_file)
    -     _safe_remove(filepaths.private_API_host_file)
    -     _safe_remove(filepaths.daemon_mark_file)
    + +Expand source code + +
    def better_sleep(wait: int):
    +    """Sleep catching ctrl c for wait seconds."""
    +    try:
    +        sleep(wait)
    +    except KeyboardInterrupt:
    +        pass
    @@ -69,19 +72,19 @@ def delete_run_files():
    diff --git a/docs/html/onionr/utils/cachedconfig/index.html b/docs/html/src/utils/cachedconfig/index.html similarity index 78% rename from docs/html/onionr/utils/cachedconfig/index.html rename to docs/html/src/utils/cachedconfig/index.html index a9fe6773..cbab6741 100644 --- a/docs/html/onionr/utils/cachedconfig/index.html +++ b/docs/html/src/utils/cachedconfig/index.html @@ -3,13 +3,13 @@ - -onionr.utils.cachedconfig API documentation + +src.utils.cachedconfig API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.utils.cachedconfig

    +

    Module src.utils.cachedconfig

    -Source code + +Expand source code +
    from onionrutils import localcommand
     import config
     config.reload()
    @@ -48,13 +50,15 @@ def config_get(key):
     

    Functions

    -
    +
    def config_get(key)
    -Source code + +Expand source code +
    def config_get(key):
         ret_data = False
         if running_detected or first_get:
    @@ -81,19 +85,19 @@ def config_get(key):
     
     
     
    diff --git a/docs/html/onionr/utils/createdirs.html b/docs/html/src/utils/createdirs.html similarity index 74% rename from docs/html/onionr/utils/createdirs.html rename to docs/html/src/utils/createdirs.html index 901c512f..14f6268e 100644 --- a/docs/html/onionr/utils/createdirs.html +++ b/docs/html/src/utils/createdirs.html @@ -3,13 +3,13 @@ - -onionr.utils.createdirs API documentation + +src.utils.createdirs API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.createdirs

    +

    Module src.utils.createdirs

    Onionr - Private P2P Communication

    Create required Onionr directories

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -45,18 +47,22 @@
     '''
     import os
     from . import identifyhome
    -from onionrsetup import dbcreator
     import filepaths
     home = identifyhome.identify_home()
     
    +
     def create_dirs():
    -    """Creates onionr data-related directories in order of the hardcoded list below,
    +    """Create onionr data-related directories in
    +    order of the hardcoded list below,
         then trigger creation of DBs"""
    -    gen_dirs = [home, filepaths.block_data_location, filepaths.contacts_location, filepaths.export_location]
    +    gen_dirs = [home, filepaths.block_data_location,
    +                filepaths.contacts_location, filepaths.export_location]
         for path in gen_dirs:
             if not os.path.exists(path):
                 os.mkdir(path)
     
    +    from onionrsetup import dbcreator
    +
         for db in dbcreator.create_funcs:
             try:
                 db()
    @@ -71,22 +77,29 @@ def create_dirs():
     

    Functions

    -
    +
    def create_dirs()
    -

    Creates onionr data-related directories in order of the hardcoded list below, +

    Create onionr data-related directories in +order of the hardcoded list below, then trigger creation of DBs

    -Source code + +Expand source code +
    def create_dirs():
    -    """Creates onionr data-related directories in order of the hardcoded list below,
    +    """Create onionr data-related directories in
    +    order of the hardcoded list below,
         then trigger creation of DBs"""
    -    gen_dirs = [home, filepaths.block_data_location, filepaths.contacts_location, filepaths.export_location]
    +    gen_dirs = [home, filepaths.block_data_location,
    +                filepaths.contacts_location, filepaths.export_location]
         for path in gen_dirs:
             if not os.path.exists(path):
                 os.mkdir(path)
     
    +    from onionrsetup import dbcreator
    +
         for db in dbcreator.create_funcs:
             try:
                 db()
    @@ -107,19 +120,19 @@ then trigger creation of DBs

    diff --git a/docs/html/onionr/utils/definewait.html b/docs/html/src/utils/definewait.html similarity index 80% rename from docs/html/onionr/utils/definewait.html rename to docs/html/src/utils/definewait.html index db677f31..2f1545c0 100644 --- a/docs/html/onionr/utils/definewait.html +++ b/docs/html/src/utils/definewait.html @@ -3,13 +3,13 @@ - -onionr.utils.definewait API documentation + +src.utils.definewait API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.definewait

    +

    Module src.utils.definewait

    Onionr - Private P2P Communication

    Waits for a key to become set in a dictionary, even to None, 0 or empty string

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -61,13 +63,15 @@ def define_wait(dictionary, key, delay: int = 0):
     

    Functions

    -
    +
    def define_wait(dictionary, key, delay=0)
    -Source code + +Expand source code +
    def define_wait(dictionary, key, delay: int = 0):
         while True:
             try:
    @@ -91,19 +95,19 @@ def define_wait(dictionary, key, delay: int = 0):
     
     
     
    diff --git a/docs/html/onionr/utils/getconsolewidth.html b/docs/html/src/utils/getconsolewidth.html similarity index 80% rename from docs/html/onionr/utils/getconsolewidth.html rename to docs/html/src/utils/getconsolewidth.html index cfc55903..9cc30222 100644 --- a/docs/html/onionr/utils/getconsolewidth.html +++ b/docs/html/src/utils/getconsolewidth.html @@ -3,13 +3,13 @@ - -onionr.utils.getconsolewidth API documentation + +src.utils.getconsolewidth API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.getconsolewidth

    +

    Module src.utils.getconsolewidth

    Onionr - Private P2P Communication

    Get the width of the terminal screen

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -67,13 +69,15 @@ def get_console_width():
     

    Functions

    -
    +
    def get_console_width()

    Returns an integer, the width of the terminal/cmd window

    -Source code + +Expand source code +
    def get_console_width():
         '''
             Returns an integer, the width of the terminal/cmd window
    @@ -103,19 +107,19 @@ def get_console_width():
     
     
     
    diff --git a/docs/html/onionr/utils/gethostname.html b/docs/html/src/utils/gethostname.html similarity index 79% rename from docs/html/onionr/utils/gethostname.html rename to docs/html/src/utils/gethostname.html index ace64e2d..f3cdd17b 100644 --- a/docs/html/onionr/utils/gethostname.html +++ b/docs/html/src/utils/gethostname.html @@ -3,13 +3,13 @@ - -onionr.utils.gethostname API documentation + +src.utils.gethostname API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.gethostname

    +

    Module src.utils.gethostname

    Onionr - Private P2P Communication

    Get the node's Tor hostname

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    @@ -47,6 +49,7 @@ from . import identifyhome
     import filepaths
     def get_hostname():
         try:
    +        print(identifyhome.identify_home())
             with open(identifyhome.identify_home() + '/hs/hostname', 'r') as hostname:
                 return hostname.read().strip()
         except FileNotFoundError:
    @@ -62,15 +65,18 @@ def get_hostname():
     

    Functions

    -
    +
    def get_hostname()
    -Source code + +Expand source code +
    def get_hostname():
         try:
    +        print(identifyhome.identify_home())
             with open(identifyhome.identify_home() + '/hs/hostname', 'r') as hostname:
                 return hostname.read().strip()
         except FileNotFoundError:
    @@ -92,19 +98,19 @@ def get_hostname():
     
     
     
    diff --git a/docs/html/src/utils/gettransports.html b/docs/html/src/utils/gettransports.html new file mode 100644 index 00000000..f533d9c2 --- /dev/null +++ b/docs/html/src/utils/gettransports.html @@ -0,0 +1,132 @@ + + + + + + +src.utils.gettransports API documentation + + + + + + + + + +
    +
    +
    +

    Module src.utils.gettransports

    +
    +
    +

    Onionr - Private P2P Communication.

    +

    return a list of strings of the user's transport addresses for the main +Onionr protocol

    +
    + +Expand source code + +
    """Onionr - Private P2P Communication.
    +
    +return a list of strings of the user's transport addresses for the main
    +Onionr protocol
    +"""
    +from gevent import time
    +
    +import filepaths
    +"""
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +files = [filepaths.tor_hs_address_file]
    +
    +
    +def get():
    +    transports = []
    +    for file in files:
    +        try:
    +            with open(file, 'r') as transport_file:
    +                transports.append(transport_file.read().strip())
    +        except FileNotFoundError:
    +            pass
    +        else:
    +            break
    +    else:
    +        time.sleep(1)
    +    return list(transports)
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def get() +
    +
    +
    +
    + +Expand source code + +
    def get():
    +    transports = []
    +    for file in files:
    +        try:
    +            with open(file, 'r') as transport_file:
    +                transports.append(transport_file.read().strip())
    +        except FileNotFoundError:
    +            pass
    +        else:
    +            break
    +    else:
    +        time.sleep(1)
    +    return list(transports)
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/utils/hastor.html b/docs/html/src/utils/hastor.html similarity index 76% rename from docs/html/onionr/utils/hastor.html rename to docs/html/src/utils/hastor.html index a8196205..cbef4dde 100644 --- a/docs/html/onionr/utils/hastor.html +++ b/docs/html/src/utils/hastor.html @@ -3,13 +3,13 @@ - -onionr.utils.hastor API documentation + +src.utils.hastor API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.utils.hastor

    +

    Module src.utils.hastor

    -Source code + +Expand source code +
    import netcontroller
     
     def has_tor():
    @@ -35,13 +37,15 @@ def has_tor():
     

    Functions

    -
    +
    def has_tor()
    -Source code + +Expand source code +
    def has_tor():
         return netcontroller.tor_binary() is not None
    @@ -59,19 +63,19 @@ def has_tor():
    diff --git a/docs/html/onionr/utils/identifyhome.html b/docs/html/src/utils/identifyhome.html similarity index 70% rename from docs/html/onionr/utils/identifyhome.html rename to docs/html/src/utils/identifyhome.html index aa864b20..126cb1b6 100644 --- a/docs/html/onionr/utils/identifyhome.html +++ b/docs/html/src/utils/identifyhome.html @@ -3,13 +3,13 @@ - -onionr.utils.identifyhome API documentation + +src.utils.identifyhome API documentation - + @@ -17,19 +17,22 @@
    -

    Module onionr.utils.identifyhome

    +

    Module src.utils.identifyhome

    -

    Onionr - Private P2P Communication

    +

    Onionr - Private P2P Communication.

    Identify a data directory for Onionr

    -Source code -
    '''
    -    Onionr - Private P2P Communication
    +
    +Expand source code
    +
    +
    """Onionr - Private P2P Communication.
     
    -    Identify a data directory for Onionr
    -'''
    -'''
    +Identify a data directory for Onionr
    +"""
    +import os
    +import platform
    +"""
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation, either version 3 of the License, or
    @@ -42,13 +45,20 @@
     
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
    -'''
    -import os, platform
    +"""
     
    -def identify_home():
     
    +def identify_home() -> str:
    +    """Return path of home directory.
    +
    +    Take env into account with sane OS defaults
    +    """
         path = os.environ.get('ONIONR_HOME', None)
     
    +    if path is not None and not os.getcwd().endswith('src') \
    +            and 'test' not in path:
    +        path = 'src/' + path
    +
         if path is None:
             system = platform.system()
             if system == 'Linux':
    @@ -56,7 +66,8 @@ def identify_home():
             elif system == 'Windows':
                 path = os.path.expanduser('~') + '\\AppData\\Local\\onionr\\'
             elif system == 'Darwin':
    -            path = os.path.expanduser('~' + '/Library/Application Support/onionr/')
    +            path = os.path.expanduser('~' +
    +                                      '/Library/Application Support/onionr/')
             else:
                 path = 'data/'
         else:
    @@ -74,17 +85,27 @@ def identify_home():
     

    Functions

    -
    +
    def identify_home()
    -
    +

    Return path of home directory.

    +

    Take env into account with sane OS defaults

    -Source code -
    def identify_home():
    +
    +Expand source code
    +
    +
    def identify_home() -> str:
    +    """Return path of home directory.
     
    +    Take env into account with sane OS defaults
    +    """
         path = os.environ.get('ONIONR_HOME', None)
     
    +    if path is not None and not os.getcwd().endswith('src') \
    +            and 'test' not in path:
    +        path = 'src/' + path
    +
         if path is None:
             system = platform.system()
             if system == 'Linux':
    @@ -92,7 +113,8 @@ def identify_home():
             elif system == 'Windows':
                 path = os.path.expanduser('~') + '\\AppData\\Local\\onionr\\'
             elif system == 'Darwin':
    -            path = os.path.expanduser('~' + '/Library/Application Support/onionr/')
    +            path = os.path.expanduser('~' +
    +                                      '/Library/Application Support/onionr/')
             else:
                 path = 'data/'
         else:
    @@ -116,19 +138,19 @@ def identify_home():
     
     
     
    diff --git a/docs/html/onionr/utils/index.html b/docs/html/src/utils/index.html similarity index 52% rename from docs/html/onionr/utils/index.html rename to docs/html/src/utils/index.html index c4080eec..c37e4117 100644 --- a/docs/html/onionr/utils/index.html +++ b/docs/html/src/utils/index.html @@ -3,13 +3,13 @@ - -onionr.utils API documentation + +src.utils API documentation - + @@ -17,66 +17,74 @@
    -

    Module onionr.utils

    +

    Module src.utils

    Sub-modules

    -
    onionr.utils.cachedconfig
    +
    src.utils.bettersleep
    -
    onionr.utils.createdirs
    -
    -

    Onionr - Private P2P Communication …

    -
    -
    onionr.utils.definewait
    -
    -

    Onionr - Private P2P Communication …

    -
    -
    onionr.utils.getconsolewidth
    -
    -

    Onionr - Private P2P Communication …

    -
    -
    onionr.utils.gethostname
    -
    -

    Onionr - Private P2P Communication …

    -
    -
    onionr.utils.gettransports
    +
    src.utils.cachedconfig
    -
    onionr.utils.hastor
    -
    -
    -
    -
    onionr.utils.identifyhome
    +
    src.utils.createdirs

    Onionr - Private P2P Communication …

    -
    onionr.utils.logoheader
    +
    src.utils.definewait
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.utils.getconsolewidth
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.utils.gethostname
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.utils.gettransports
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.utils.hastor
    -
    onionr.utils.netutils
    +
    src.utils.identifyhome
    +
    +

    Onionr - Private P2P Communication …

    +
    +
    src.utils.logoheader
    +
    +
    +
    +
    src.utils.netutils

    Onionr - P2P Microblogging Platform & Social network …

    -
    onionr.utils.networkmerger
    +
    src.utils.networkmerger

    Onionr - P2P Microblogging Platform & Social network …

    -
    onionr.utils.readstatic
    +
    src.utils.readstatic

    Onionr - Private P2P Communication …

    -
    onionr.utils.reconstructhash
    +
    src.utils.reconstructhash

    Onionr - Private P2P Communication …

    -
    onionr.utils.sizeutils
    +
    src.utils.safezip
    +
    +
    +
    +
    src.utils.sizeutils
    @@ -97,32 +105,34 @@
    diff --git a/docs/html/onionr/utils/logoheader.html b/docs/html/src/utils/logoheader.html similarity index 82% rename from docs/html/onionr/utils/logoheader.html rename to docs/html/src/utils/logoheader.html index 63d62b41..14bab9ba 100644 --- a/docs/html/onionr/utils/logoheader.html +++ b/docs/html/src/utils/logoheader.html @@ -3,13 +3,13 @@ - -onionr.utils.logoheader API documentation + +src.utils.logoheader API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.utils.logoheader

    +

    Module src.utils.logoheader

    -Source code + +Expand source code +
    import sys, os
     from . import readstatic
     import logger
    @@ -46,13 +48,15 @@ def header(message = logger.colors.fg.pink + logger.colors.bold + 'Onionr
     

    Functions

    -
    +
    def header(message='\x1b[95m\x1b[01mOnionr\x1b[0m\x1b[95m has started.')
    -Source code + +Expand source code +
    def header(message = logger.colors.fg.pink + logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink + ' has started.'):
         if onionrvalues.DEVELOPMENT_MODE:
             return
    @@ -79,19 +83,19 @@ def header(message = logger.colors.fg.pink + logger.colors.bold + 'Onionr
     
     
     
    diff --git a/docs/html/onionr/utils/netutils.html b/docs/html/src/utils/netutils.html similarity index 82% rename from docs/html/onionr/utils/netutils.html rename to docs/html/src/utils/netutils.html index ac991f16..ad135798 100644 --- a/docs/html/onionr/utils/netutils.html +++ b/docs/html/src/utils/netutils.html @@ -3,13 +3,13 @@ - -onionr.utils.netutils API documentation + +src.utils.netutils API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.netutils

    +

    Module src.utils.netutils

    Onionr - P2P Microblogging Platform & Social network

    OnionrUtils offers various useful functions to Onionr networking.

    -Source code + +Expand source code +
    '''
         Onionr - P2P Microblogging Platform & Social network
     
    @@ -69,13 +71,15 @@ def checkNetwork(torPort=0):
     

    Functions

    -
    +
    def checkNetwork(torPort=0)

    Check if we are connected to the internet (through Tor)

    -Source code + +Expand source code +
    def checkNetwork(torPort=0):
         '''Check if we are connected to the internet (through Tor)'''
         retData = False
    @@ -105,19 +109,19 @@ def checkNetwork(torPort=0):
     
     
     
    diff --git a/docs/html/onionr/utils/networkmerger.html b/docs/html/src/utils/networkmerger.html similarity index 84% rename from docs/html/onionr/utils/networkmerger.html rename to docs/html/src/utils/networkmerger.html index d7050d6c..40b0a7f8 100644 --- a/docs/html/onionr/utils/networkmerger.html +++ b/docs/html/src/utils/networkmerger.html @@ -3,13 +3,13 @@ - -onionr.utils.networkmerger API documentation + +src.utils.networkmerger API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.networkmerger

    +

    Module src.utils.networkmerger

    Onionr - P2P Microblogging Platform & Social network

    Merges peer and block lists

    -Source code + +Expand source code +
    '''
         Onionr - P2P Microblogging Platform & Social network
     
    @@ -80,13 +82,15 @@ def mergeAdders(newAdderList):
     

    Functions

    -
    +
    def mergeAdders(newAdderList)

    Merge peer adders list to our database

    -Source code + +Expand source code +
    def mergeAdders(newAdderList):
         '''
             Merge peer adders list to our database
    @@ -125,19 +129,19 @@ def mergeAdders(newAdderList):
     
     
     
    diff --git a/docs/html/onionr/utils/readstatic.html b/docs/html/src/utils/readstatic.html similarity index 77% rename from docs/html/onionr/utils/readstatic.html rename to docs/html/src/utils/readstatic.html index 5fe5d6a9..949b60fb 100644 --- a/docs/html/onionr/utils/readstatic.html +++ b/docs/html/src/utils/readstatic.html @@ -3,13 +3,13 @@ - -onionr.utils.readstatic API documentation + +src.utils.readstatic API documentation - + @@ -17,13 +17,15 @@
    -

    Module onionr.utils.readstatic

    +

    Module src.utils.readstatic

    Onionr - Private P2P Communication

    module to get static directory and read static data files

    -Source code + +Expand source code +
    """
         Onionr - Private P2P Communication
     
    @@ -56,7 +58,7 @@ def read_static(file:str, ret_bin:bool=False)->Union[str, bytes]:
             mode = 'rb'
         else:
             mode = 'r'
    -    with open(static_file, mode) as f:
    +    with open(static_file, mode, encoding='utf-8') as f:
             data = f.read()
         return data
    @@ -68,24 +70,28 @@ def read_static(file:str, ret_bin:bool=False)->Union[str, bytes]:

    Functions

    -
    +
    def get_static_dir()
    -Source code + +Expand source code +
    def get_static_dir()->str:
         return os.path.dirname(os.path.realpath(__file__)) + '/../../static-data/'
    -
    +
    def read_static(file, ret_bin=False)
    -Source code + +Expand source code +
    def read_static(file:str, ret_bin:bool=False)->Union[str, bytes]:
         static_file = get_static_dir() + file
     
    @@ -93,7 +99,7 @@ def read_static(file:str, ret_bin:bool=False)->Union[str, bytes]:
             mode = 'rb'
         else:
             mode = 'r'
    -    with open(static_file, mode) as f:
    +    with open(static_file, mode, encoding='utf-8') as f:
             data = f.read()
         return data
    @@ -111,20 +117,20 @@ def read_static(file:str, ret_bin:bool=False)->Union[str, bytes]:
    diff --git a/docs/html/onionr/utils/reconstructhash.html b/docs/html/src/utils/reconstructhash.html similarity index 68% rename from docs/html/onionr/utils/reconstructhash.html rename to docs/html/src/utils/reconstructhash.html index 648c5add..7dddbd01 100644 --- a/docs/html/onionr/utils/reconstructhash.html +++ b/docs/html/src/utils/reconstructhash.html @@ -3,13 +3,13 @@ - -onionr.utils.reconstructhash API documentation + +src.utils.reconstructhash API documentation - + @@ -17,18 +17,23 @@
    -

    Module onionr.utils.reconstructhash

    +

    Module src.utils.reconstructhash

    Onionr - Private P2P Communication

    -

    z-fill (zero fill) a string to a specific length, intended for reconstructing block hashes

    +

    z-fill (zero fill) a string to a specific length +intended for reconstructing block hashes

    -Source code + +Expand source code +
    '''
         Onionr - Private P2P Communication
     
    -    z-fill (zero fill) a string to a specific length, intended for reconstructing block hashes
    +    z-fill (zero fill) a string to a specific length
    +    intended for reconstructing block hashes
     '''
    +from typing import Union
     '''
         This program is free software: you can redistribute it and/or modify
         it under the terms of the GNU General Public License as published by
    @@ -43,10 +48,16 @@
         You should have received a copy of the GNU General Public License
         along with this program.  If not, see <https://www.gnu.org/licenses/>.
     '''
    -def reconstruct_hash(hex_hash, length=64):
    +
    +
    +def reconstruct_hash(hex_hash: Union[str, bytes],
    +                     length: int = 64) -> Union[str, bytes]:
    +    """Pad hash hex string with zeros, return result"""
         return hex_hash.zfill(length)
     
    -def deconstruct_hash(hex_hash):
    +
    +def deconstruct_hash(hex_hash: Union[str, bytes]) -> Union[str, bytes]:
    +    """Remove leading zeros from hex hash, return result"""
         new_hash = ''
         ret_bytes = False
         try:
    @@ -76,14 +87,17 @@ def deconstruct_hash(hex_hash):
     

    Functions

    -
    +
    def deconstruct_hash(hex_hash)
    -
    +

    Remove leading zeros from hex hash, return result

    -Source code -
    def deconstruct_hash(hex_hash):
    +
    +Expand source code
    +
    +
    def deconstruct_hash(hex_hash: Union[str, bytes]) -> Union[str, bytes]:
    +    """Remove leading zeros from hex hash, return result"""
         new_hash = ''
         ret_bytes = False
         try:
    @@ -106,14 +120,18 @@ def deconstruct_hash(hex_hash):
         return new_hash
    -
    +
    def reconstruct_hash(hex_hash, length=64)
    -
    +

    Pad hash hex string with zeros, return result

    -Source code -
    def reconstruct_hash(hex_hash, length=64):
    +
    +Expand source code
    +
    +
    def reconstruct_hash(hex_hash: Union[str, bytes],
    +                     length: int = 64) -> Union[str, bytes]:
    +    """Pad hash hex string with zeros, return result"""
         return hex_hash.zfill(length)
    @@ -130,20 +148,20 @@ def deconstruct_hash(hex_hash):
    diff --git a/docs/html/src/utils/safezip.html b/docs/html/src/utils/safezip.html new file mode 100644 index 00000000..dcd9d7e0 --- /dev/null +++ b/docs/html/src/utils/safezip.html @@ -0,0 +1,90 @@ + + + + + + +src.utils.safezip API documentation + + + + + + + + + +
    +
    +
    +

    Module src.utils.safezip

    +
    +
    +
    + +Expand source code + +
    # safe unzip https://stackoverflow.com/a/36583849
    +def safe_unzip(zip_file, extractpath='.'):
    +    with zipfile.ZipFile(zip_file, 'r') as zf:
    +        for member in zf.infolist():
    +            abspath = os.path.abspath(os.path.join(extractpath, member.filename))
    +            if abspath.startswith(os.path.abspath(extractpath)):
    +                zf.extract(member, extractpath)
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def safe_unzip(zip_file, extractpath='.') +
    +
    +
    +
    + +Expand source code + +
    def safe_unzip(zip_file, extractpath='.'):
    +    with zipfile.ZipFile(zip_file, 'r') as zf:
    +        for member in zf.infolist():
    +            abspath = os.path.abspath(os.path.join(extractpath, member.filename))
    +            if abspath.startswith(os.path.abspath(extractpath)):
    +                zf.extract(member, extractpath)
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/html/onionr/utils/sizeutils.html b/docs/html/src/utils/sizeutils.html similarity index 80% rename from docs/html/onionr/utils/sizeutils.html rename to docs/html/src/utils/sizeutils.html index fa8c73d0..045f8321 100644 --- a/docs/html/onionr/utils/sizeutils.html +++ b/docs/html/src/utils/sizeutils.html @@ -3,13 +3,13 @@ - -onionr.utils.sizeutils API documentation + +src.utils.sizeutils API documentation - + @@ -17,11 +17,13 @@
    -

    Module onionr.utils.sizeutils

    +

    Module src.utils.sizeutils

    -Source code + +Expand source code +
    import sqlite3, os
     from onionrutils import stringvalidators
     def human_size(num, suffix='B'):
    @@ -58,13 +60,15 @@ def size(path='.'):
     

    Functions

    -
    +
    def human_size(num, suffix='B')

    Converts from bytes to a human readable format.

    -Source code + +Expand source code +
    def human_size(num, suffix='B'):
         '''
             Converts from bytes to a human readable format.
    @@ -76,13 +80,15 @@ def size(path='.'):
         return "%.1f %s%s" % (num, 'Yi', suffix)
    -
    +
    def size(path='.')

    Returns the size of a folder's contents in bytes

    -Source code + +Expand source code +
    def size(path='.'):
         '''
             Returns the size of a folder's contents in bytes
    @@ -113,20 +119,20 @@ def size(path='.'):
     
     
     
    diff --git a/docs/html/src/vanityonionr/index.html b/docs/html/src/vanityonionr/index.html new file mode 100644 index 00000000..8024ebb6 --- /dev/null +++ b/docs/html/src/vanityonionr/index.html @@ -0,0 +1,225 @@ + + + + + + +src.vanityonionr API documentation + + + + + + + + + +
    +
    +
    +

    Module src.vanityonionr

    +
    +
    +

    Onionr Vanity address generator

    +

    Library to generate vanity ed25519 addresses in various encodings

    +
    + +Expand source code + +
    """
    +Onionr Vanity address generator
    +
    +Library to generate vanity ed25519 addresses in various encodings
    +"""
    +"""
    +Onionr Vanity Address Generator
    +Copyright (C) 2019 Kevin Froman
    +
    +This program is free software: you can redistribute it and/or modify
    +it under the terms of the GNU General Public License as published by
    +the Free Software Foundation, either version 3 of the License, or
    +(at your option) any later version.
    +
    +This program is distributed in the hope that it will be useful,
    +but WITHOUT ANY WARRANTY; without even the implied warranty of
    +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +GNU General Public License for more details.
    +
    +You should have received a copy of the GNU General Public License
    +along with this program.  If not, see <https://www.gnu.org/licenses/>.
    +"""
    +
    +import niceware
    +import nacl.signing, nacl.encoding
    +
    +import multiprocessing
    +from multiprocessing import Process, Pipe, Queue
    +import re, time
    +import threading
    +
    +wordlist = niceware.WORD_LIST
    +
    +def find_vanity_mnemonic(start_words: str, queue):
    +    key_pair = [b"", b""]
    +    vanity_key = ""
    +    check = 0
    +    while not vanity_key.startswith(start_words):
    +        key = nacl.signing.SigningKey.generate()
    +        key_pair[1] = key.encode(nacl.encoding.RawEncoder)
    +        key_pair[0] = key.verify_key.encode(encoder=nacl.encoding.RawEncoder)
    +        vanity_key = '-'.join(niceware.bytes_to_passphrase(key_pair[0]))
    +        check += 1
    +    else:
    +        queue.put(key_pair)
    +        #print("DONE", check, key_pair)
    +    return key_pair
    +
    +def _start(start_words, obj):
    +    done = False
    +    q = Queue()
    +    p = Process(target=find_vanity_mnemonic, args=[start_words, q])
    +    p.daemon = True
    +    p.start()
    +    rec = None
    +    while not done:
    +        try:
    +            if rec == None:
    +                rec = q.get(True, 1)
    +        except:
    +            rec = None
    +        if rec != None or obj.done:
    +            done = True
    +            obj.done = True
    +            obj.result = rec
    +    return rec
    +
    +def handler(start_words: str):
    +    obj = lambda test: None
    +    obj.done = False
    +    for x in range(multiprocessing.cpu_count()):
    +        threading.Thread(target=_start, args=[start_words, obj]).start()
    +    while not obj.done:
    +        time.sleep(1)
    +    return obj.result
    +
    +def find_multiprocess(start_words: str):
    +    start_words = start_words.strip()
    +    start_words = re.sub(' +', ' ', start_words)
    +    test_words = str(start_words)
    +
    +    for word in test_words.split(' '): 
    +        for validword in wordlist:
    +            if word == validword:
    +                break
    +        else:
    +            raise ValueError('%s not in wordlist' % (word,))
    +    return handler(start_words)
    +
    +
    +
    +
    +
    +
    +
    +

    Functions

    +
    +
    +def find_multiprocess(start_words) +
    +
    +
    +
    + +Expand source code + +
    def find_multiprocess(start_words: str):
    +    start_words = start_words.strip()
    +    start_words = re.sub(' +', ' ', start_words)
    +    test_words = str(start_words)
    +
    +    for word in test_words.split(' '): 
    +        for validword in wordlist:
    +            if word == validword:
    +                break
    +        else:
    +            raise ValueError('%s not in wordlist' % (word,))
    +    return handler(start_words)
    +
    +
    +
    +def find_vanity_mnemonic(start_words, queue) +
    +
    +
    +
    + +Expand source code + +
    def find_vanity_mnemonic(start_words: str, queue):
    +    key_pair = [b"", b""]
    +    vanity_key = ""
    +    check = 0
    +    while not vanity_key.startswith(start_words):
    +        key = nacl.signing.SigningKey.generate()
    +        key_pair[1] = key.encode(nacl.encoding.RawEncoder)
    +        key_pair[0] = key.verify_key.encode(encoder=nacl.encoding.RawEncoder)
    +        vanity_key = '-'.join(niceware.bytes_to_passphrase(key_pair[0]))
    +        check += 1
    +    else:
    +        queue.put(key_pair)
    +        #print("DONE", check, key_pair)
    +    return key_pair
    +
    +
    +
    +def handler(start_words) +
    +
    +
    +
    + +Expand source code + +
    def handler(start_words: str):
    +    obj = lambda test: None
    +    obj.done = False
    +    for x in range(multiprocessing.cpu_count()):
    +        threading.Thread(target=_start, args=[start_words, obj]).start()
    +    while not obj.done:
    +        time.sleep(1)
    +    return obj.result
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/static-data/bootstrap-nodes.txt b/static-data/bootstrap-nodes.txt index 26d17d37..e88890f1 100755 --- a/static-data/bootstrap-nodes.txt +++ b/static-data/bootstrap-nodes.txt @@ -1 +1 @@ -3msj7fgyxgpfsjvvtcji7a4tkjbna6jmpealv6mun7435jjyptctfxyd.onion,chz7aarrmhxnefa6jx7ai3h3f5oy4sz5x4o5bbhfcq4xr3zbvsynaoad.onion,llqcrrf5cdk7p277eynepnvoo4ggrnybmp2daqtsr2hshitlmvbipdqd.onion +3msj7fgyxgpfsjvvtcji7a4tkjbna6jmpealv6mun7435jjyptctfxyd.onion,chz7aarrmhxnefa6jx7ai3h3f5oy4sz5x4o5bbhfcq4xr3zbvsynaoad.onion,llqcrrf5cdk7p277eynepnvoo4ggrnybmp2daqtsr2hshitlmvbipdqd.onion,lqyhqt5mtsvu5bdatn4ntaplsfsrfxzp3j6gze77g4nptpxe36q7poad.onion diff --git a/static-data/default_config.json b/static-data/default_config.json index c68469a1..f2e30bd7 100755 --- a/static-data/default_config.json +++ b/static-data/default_config.json @@ -1,4 +1,7 @@ { + "advanced": { + "security_auditing": true + }, "allocations": { "blockCache": 5000000, "blockCacheTotal": 50000000, @@ -9,7 +12,6 @@ "announce_node": true, "dev_mode": false, "display_header": false, - "general.random_bind_ip": false, "hide_created_blocks": true, "insert_deniable_blocks": true, "max_block_age": 2678400,