Removed crappy logger and replaced it with a sane built in logging logger
This commit is contained in:
parent
2eea681e98
commit
e9efffff34
12
AUTHORS.MD
12
AUTHORS.MD
@ -1,12 +0,0 @@
|
||||
# Incomplete List of Contributors
|
||||
|
||||
Onionr is created by a team of hard working volunteers.
|
||||
|
||||
In no order of importance, these people make Onionr happen:
|
||||
|
||||
* [Beardog (Kevin Froman)](https://www.chaoswebs.net/) - Project founder, owner and core developer
|
||||
* [InvisaMage](https://invisamage.com/) - Web UI Bulma design
|
||||
* [Arinerron](https://arinerron.com/) - Logger and config modules, testing and other contributions
|
||||
* [Anhar Ismail](https://github.com/anharismail) - Created Onionr's logo
|
||||
|
||||
+ Other contributors and testers
|
@ -64,6 +64,8 @@ def sigusr_stacktrace(signum, frame):
|
||||
|
||||
signal.signal(signal.SIGUSR1, sigusr_stacktrace)
|
||||
|
||||
# Importing initailzes logging
|
||||
from logger import log as logging
|
||||
|
||||
ran_as_script = False
|
||||
if __name__ == "__main__": ran_as_script = True
|
||||
|
@ -2,7 +2,7 @@ from typing import Set
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from .deleteblock import delete_block
|
||||
from .getblocks import get_blocks_after_timestamp
|
||||
@ -18,7 +18,7 @@ def clean_block_database():
|
||||
Block(block.id, block.raw, auto_verify=True)
|
||||
except ValueError: # block expired
|
||||
remove_set.add(block)
|
||||
|
||||
|
||||
if len(remove_set):
|
||||
logger.info(f"Cleaning {len(remove_set)} blocks", terminal=True)
|
||||
logging.info(f"Cleaning {len(remove_set)} blocks")
|
||||
[i for i in map(delete_block, remove_set)]
|
||||
|
@ -6,7 +6,7 @@ import os
|
||||
from json import JSONDecodeError
|
||||
|
||||
import ujson as json
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import filepaths
|
||||
|
||||
"""
|
||||
@ -106,7 +106,7 @@ def save():
|
||||
with open(get_config_file(), 'w', encoding="utf8") as configfile:
|
||||
json.dump(get_config(), configfile, indent=2)
|
||||
except JSONDecodeError:
|
||||
logger.warn('Failed to write to configuration file.')
|
||||
logging.warn('Failed to write to configuration file.')
|
||||
|
||||
|
||||
def reload():
|
||||
@ -117,7 +117,7 @@ def reload():
|
||||
set_config(json.loads(configfile.read()))
|
||||
except (FileNotFoundError, JSONDecodeError) as e:
|
||||
pass
|
||||
#logger.debug('Failed to parse configuration file.')
|
||||
#logging.debug('Failed to parse configuration file.')
|
||||
|
||||
|
||||
def get_config():
|
||||
|
@ -1,6 +1,7 @@
|
||||
import threading
|
||||
from time import sleep
|
||||
from typing import TYPE_CHECKING, Set, Tuple
|
||||
from logger import log as logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ordered_set import OrderedSet
|
||||
@ -11,7 +12,6 @@ if TYPE_CHECKING:
|
||||
|
||||
from onionrthreads import add_onionr_thread
|
||||
import onionrplugins
|
||||
import logger
|
||||
|
||||
from .connectpeer import connect_peer
|
||||
from .client import start_gossip_client
|
||||
@ -56,4 +56,4 @@ def start_gossip_threads():
|
||||
sleep(60)
|
||||
if len(gossip_peer_set):
|
||||
return
|
||||
logger.error("Could not connect to any peers :(", terminal=True)
|
||||
logging.error("Could not connect to any peers :(")
|
||||
|
@ -21,7 +21,7 @@ if TYPE_CHECKING:
|
||||
from ..peer import Peer
|
||||
from ordered_set import OrderedSet
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import config
|
||||
import onionrplugins
|
||||
from ..commands import GossipCommands
|
||||
@ -61,20 +61,20 @@ def block_queue_processing():
|
||||
while not len(gossip_peer_set):
|
||||
sleep(1)
|
||||
if dandelion_phase.remaining_time() <= 15:
|
||||
#logger.debug("Sleeping", terminal=True)
|
||||
#logging.debug("Sleeping")
|
||||
sleep(dandelion_phase.remaining_time())
|
||||
if dandelion_phase.is_stem_phase() and config.get('security.dandelion.enabled', True):
|
||||
logger.debug("Entering stem phase", terminal=True)
|
||||
logging.debug("Entering stem phase")
|
||||
try:
|
||||
# Stem out blocks for (roughly) remaining epoch time
|
||||
asyncio.run(stem_out(dandelion_phase))
|
||||
except TimeoutError:
|
||||
pass
|
||||
except Exception:
|
||||
logger.error(traceback.format_exc(), terminal=True)
|
||||
logging.error(traceback.format_exc())
|
||||
pass
|
||||
else:
|
||||
#logger.debug("Entering fluff phase", terminal=True)
|
||||
#logging.debug("Entering fluff phase")
|
||||
# Add block to primary block db, where the diffuser can read it
|
||||
sleep(0.1)
|
||||
store_blocks(dandelion_phase)
|
||||
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from .. import Peer
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import onionrplugins
|
||||
|
||||
from ..commands import GossipCommands, command_to_byte
|
||||
@ -28,7 +28,7 @@ def do_announce():
|
||||
sock.sendall(command_to_byte(GossipCommands.ANNOUNCE))
|
||||
sock.sendall(our_transport_address)
|
||||
if int.from_bytes(sock.recv(1), 'big') != 1:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f"Could not announce with {announce_peer.transport_address}")
|
||||
sock.close()
|
||||
|
||||
|
@ -11,7 +11,7 @@ from ordered_set import OrderedSet
|
||||
import config
|
||||
from onionrthreads import add_delayed_thread
|
||||
from blockdb import add_block_to_db
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from ...constants import BLACKHOLE_EVADE_TIMER_SECS, OUTBOUND_DANDELION_EDGES
|
||||
from ...commands import GossipCommands, command_to_byte
|
||||
@ -45,9 +45,9 @@ async def _setup_edge(
|
||||
try:
|
||||
s = peer.get_socket(12)
|
||||
except TimeoutError:
|
||||
logger.debug(f"{peer.transport_address} timed out when trying stemout")
|
||||
logging.debug(f"{peer.transport_address} timed out when trying stemout")
|
||||
except Exception:
|
||||
logger.debug(traceback.format_exc())
|
||||
logging.debug(traceback.format_exc())
|
||||
return
|
||||
|
||||
try:
|
||||
@ -56,18 +56,18 @@ async def _setup_edge(
|
||||
if s.recv(1) == dandelion.StemAcceptResult.DENY:
|
||||
raise StemConnectionDenied
|
||||
except TimeoutError:
|
||||
logger.debug(
|
||||
"Peer timed out when establishing stem connection", terminal=True)
|
||||
logger.debug(traceback.format_exc())
|
||||
logging.debug(
|
||||
"Peer timed out when establishing stem connection")
|
||||
logging.debug(traceback.format_exc())
|
||||
except StemConnectionDenied:
|
||||
logger.debug(
|
||||
logging.debug(
|
||||
"Stem connection denied (peer has too many) " +
|
||||
f"{peer.transport_address}")
|
||||
logger.debug(traceback.format_exc())
|
||||
logging.debug(traceback.format_exc())
|
||||
except Exception:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
"Error asking peer to establish stem connection" +
|
||||
traceback.format_exc(), terminal=True)
|
||||
traceback.format_exc())
|
||||
else:
|
||||
# Return peer socket if it is in stem reception mode successfully
|
||||
return s
|
||||
@ -113,10 +113,10 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
||||
await _setup_edge(gossip_peer_set, tried_edges))
|
||||
except NotEnoughEdges:
|
||||
# No possible edges at this point (edges < OUTBOUND_DANDELION_EDGE)
|
||||
#logger.debug(
|
||||
#logging.debug(
|
||||
# "Making too few edges for stemout " +
|
||||
# "this is bad for anonymity if frequent.",
|
||||
# terminal=True)
|
||||
# )
|
||||
if strict_dandelion:
|
||||
not_enough_edges = True
|
||||
else:
|
||||
@ -133,10 +133,10 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
||||
else:
|
||||
# Ran out of time for stem phase
|
||||
if not d_phase.is_stem_phase() or d_phase.remaining_time() < 5:
|
||||
logger.error(
|
||||
logging.error(
|
||||
"Did not stem out any blocks in time, " +
|
||||
"if this happens regularly you may be under attack",
|
||||
terminal=False)
|
||||
)
|
||||
for s in peer_sockets:
|
||||
if s:
|
||||
s.close()
|
||||
@ -155,7 +155,7 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
||||
except Empty:
|
||||
pass
|
||||
except Exception:
|
||||
logger.warn(traceback.format_exc())
|
||||
logging.warn(traceback.format_exc())
|
||||
else:
|
||||
# stream routine exited early
|
||||
pass
|
||||
|
@ -4,7 +4,7 @@ from queue import Empty
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from ...constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -22,7 +22,7 @@ async def do_stem_stream(
|
||||
remaining_time = d_phase.remaining_time()
|
||||
my_phase_id = d_phase.phase_id
|
||||
|
||||
|
||||
|
||||
while remaining_time > 1 and my_phase_id == d_phase.phase_id:
|
||||
# Primary client component that communicate's with gossip.server.acceptstem
|
||||
remaining_time = d_phase.remaining_time()
|
||||
@ -35,7 +35,7 @@ async def do_stem_stream(
|
||||
await sleep(1)
|
||||
else:
|
||||
break
|
||||
logger.info("Sending block over dandelion++", terminal=True)
|
||||
logging.info("Sending block over dandelion++")
|
||||
|
||||
block_size = str(len(bl.raw)).zfill(BLOCK_SIZE_LEN)
|
||||
def _send_it():
|
||||
|
@ -6,7 +6,7 @@ if TYPE_CHECKING:
|
||||
from socket import socket
|
||||
|
||||
from onionrplugins import onionrevents
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from socks import GeneralProxyError
|
||||
|
||||
@ -23,9 +23,9 @@ def _do_ask_peer(peer):
|
||||
try:
|
||||
_ask_peer(peer)
|
||||
except TimeoutError:
|
||||
logger.debug("Timed out when asking for new peers")
|
||||
logging.debug("Timed out when asking for new peers")
|
||||
except Exception:
|
||||
logger.error(format_exc(), terminal=True)
|
||||
logging.error(format_exc())
|
||||
|
||||
def _ask_peer(peer):
|
||||
s: 'socket' = peer.get_socket(12)
|
||||
@ -46,14 +46,14 @@ def _ask_peer(peer):
|
||||
'address': peer,
|
||||
'callback': connectpeer.connect_peer
|
||||
}
|
||||
#logger.info("Got new peer from exchange " + peer.decode('utf-8'), terminal=True)
|
||||
#logging.info("Got new peer from exchange " + peer.decode('utf-8'))
|
||||
onionrevents.event('announce_rec', data=connect_data, threaded=True)
|
||||
s.close()
|
||||
|
||||
|
||||
def get_new_peers():
|
||||
if not len(gossip_peer_set):
|
||||
logger.debug("Peer set empty, cannot get new peers")
|
||||
logging.debug("Peer set empty, cannot get new peers")
|
||||
return
|
||||
|
||||
# Deep copy the peer list
|
||||
|
@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from ordered_set import OrderedSet
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
import onionrblocks
|
||||
from ...peerset import gossip_peer_set
|
||||
@ -71,7 +71,7 @@ def stream_from_peers():
|
||||
need_socket_lock.release()
|
||||
return
|
||||
except Exception:
|
||||
logger.warn(traceback.format_exc(), terminal=True)
|
||||
logging.warn(traceback.format_exc())
|
||||
need_socket_lock.release()
|
||||
return
|
||||
try:
|
||||
@ -83,7 +83,7 @@ def stream_from_peers():
|
||||
|
||||
while stream_times >= stream_counter:
|
||||
stream_counter += 1
|
||||
#logger.debug("Reading block of id in stream with " + peer.transport_address, terminal=True)
|
||||
#logging.debug("Reading block of id in stream with " + peer.transport_address)
|
||||
sock.settimeout(5)
|
||||
block_id = sock.recv(BLOCK_ID_SIZE)
|
||||
if blockdb.has_block(block_id):
|
||||
@ -91,12 +91,12 @@ def stream_from_peers():
|
||||
continue
|
||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||
|
||||
#logger.debug("Reading block size in stream", terminal=True)
|
||||
#logging.debug("Reading block size in stream")
|
||||
|
||||
sock.settimeout(5)
|
||||
block_size = int(sock.recv(BLOCK_SIZE_LEN))
|
||||
if block_size > BLOCK_MAX_SIZE or block_size <= 0:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f"Peer {peer.transport_address} " +
|
||||
"reported block size out of range")
|
||||
break
|
||||
@ -104,9 +104,9 @@ def stream_from_peers():
|
||||
sock.settimeout(5)
|
||||
block_data = sock.recv(block_size)
|
||||
|
||||
#logger.debug(
|
||||
#logging.debug(
|
||||
# "We got a block from stream, assuming it is valid",
|
||||
# terminal=True)
|
||||
# )
|
||||
try:
|
||||
blockdb.add_block_to_db(
|
||||
onionrblocks.Block(
|
||||
@ -120,10 +120,10 @@ def stream_from_peers():
|
||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||
except (BrokenPipeError, TimeoutError, ConnectionError) as e:
|
||||
pass
|
||||
#logger.debug(f"{e} when streaming from peers", terminal=True)
|
||||
#logger.debug(traceback.format_exc())
|
||||
#logging.debug(f"{e} when streaming from peers")
|
||||
#logging.debug(traceback.format_exc())
|
||||
except Exception:
|
||||
logger.warn(traceback.format_exc(), terminal=True)
|
||||
logging.warn(traceback.format_exc())
|
||||
finally:
|
||||
sock.close()
|
||||
need_socket_lock.release()
|
||||
|
@ -2,7 +2,7 @@ import traceback
|
||||
from gossip.commands import GossipCommands, command_to_byte
|
||||
from .peerset import gossip_peer_set
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
|
||||
def connect_peer(peer):
|
||||
@ -11,12 +11,12 @@ def connect_peer(peer):
|
||||
try:
|
||||
s = peer.get_socket(120)
|
||||
except Exception:
|
||||
logger.warn(f"Could not connect to {peer.transport_address}")
|
||||
logger.warn(traceback.format_exc())
|
||||
logging.warn(f"Could not connect to {peer.transport_address}")
|
||||
logging.warn(traceback.format_exc())
|
||||
else:
|
||||
with s:
|
||||
s.sendall(command_to_byte(GossipCommands.PING))
|
||||
|
||||
if s.recv(4).decode('utf-8') == 'PONG':
|
||||
gossip_peer_set.add(peer)
|
||||
logger.info(f"connected to {peer.transport_address}", terminal=True)
|
||||
logging.info(f"connected to {peer.transport_address}")
|
||||
|
@ -12,7 +12,7 @@ from gossip import constants
|
||||
from ..connectpeer import connect_peer
|
||||
|
||||
from onionrplugins import onionrevents
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
@ -88,9 +88,9 @@ def gossip_server():
|
||||
try:
|
||||
await diffuse_blocks(reader, writer)
|
||||
except Exception:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f"Err streaming blocks\n{traceback.format_exc()}",
|
||||
terminal=True)
|
||||
)
|
||||
case GossipCommands.PUT_BLOCKS:
|
||||
# Pick block queue & append stemmed blocks to it
|
||||
try:
|
||||
@ -99,18 +99,18 @@ def gossip_server():
|
||||
inbound_dandelion_edge_count)
|
||||
except asyncio.exceptions.TimeoutError:
|
||||
pass
|
||||
logger.debug(
|
||||
logging.debug(
|
||||
"Inbound edge timed out when steming blocks to us",
|
||||
terminal=True)
|
||||
)
|
||||
except asyncio.exceptions.IncompleteReadError:
|
||||
pass
|
||||
logger.debug(
|
||||
logging.debug(
|
||||
"Inbound edge timed out (Incomplete Read) when steming blocks to us",
|
||||
terminal=True)
|
||||
)
|
||||
except Exception:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f"Err accepting stem blocks\n{traceback.format_exc()}",
|
||||
terminal=True)
|
||||
)
|
||||
# Subtract dandelion edge, make sure >=0
|
||||
inbound_dandelion_edge_count[0] = \
|
||||
max(inbound_dandelion_edge_count[0] - 1, 0)
|
||||
|
@ -5,7 +5,7 @@ from asyncio import wait_for
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from ..dandelion import StemAcceptResult
|
||||
from ..constants import BLOCK_ID_SIZE, BLOCK_SIZE_LEN, BLOCK_MAX_SIZE
|
||||
from ..constants import MAX_INBOUND_DANDELION_EDGE, MAX_STEM_BLOCKS_PER_STREAM
|
||||
@ -35,13 +35,13 @@ async def accept_stem_blocks(
|
||||
|
||||
for _ in range(MAX_STEM_BLOCKS_PER_STREAM):
|
||||
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
||||
#logger.debug(f"Reading block id in stem server", terminal=True)
|
||||
#logging.debug(f"Reading block id in stem server")
|
||||
block_id = await wait_for(read_routine, base_wait_timeout)
|
||||
block_id = block_id.decode('utf-8')
|
||||
if not block_id:
|
||||
break
|
||||
|
||||
#logger.debug(f"Reading block size in stem server", terminal=True)
|
||||
#logging.debug(f"Reading block size in stem server")
|
||||
block_size = (await wait_for(
|
||||
reader.readexactly(BLOCK_SIZE_LEN),
|
||||
base_wait_timeout)).decode('utf-8')
|
||||
@ -54,14 +54,14 @@ async def accept_stem_blocks(
|
||||
if block_size > BLOCK_MAX_SIZE:
|
||||
raise ValueError("Max block size")
|
||||
|
||||
#logger.debug(f"Reading block of size {block_size} in stem server", terminal=True)
|
||||
#logging.debug(f"Reading block of size {block_size} in stem server")
|
||||
|
||||
raw_block: bytes = await wait_for(
|
||||
reader.readexactly(block_size), base_wait_timeout * 6)
|
||||
if not raw_block:
|
||||
break
|
||||
|
||||
logger.debug("Got a stem block, put into queue", terminal=True)
|
||||
logging.debug("Got a stem block, put into queue")
|
||||
block_queue_to_use.put(
|
||||
Block(block_id, raw_block, auto_verify=True)
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
||||
from ..constants import BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||
from ..constants import BLOCK_STREAM_OFFSET_DIGITS
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import blockdb
|
||||
from blockdb import get_blocks_after_timestamp, block_storage_observers
|
||||
"""
|
||||
@ -103,5 +103,5 @@ async def diffuse_blocks(reader: 'StreamReader', writer: 'StreamWriter'):
|
||||
except ConnectionResetError:
|
||||
pass
|
||||
except Exception:
|
||||
logger.warn(traceback.format_exc(), terminal=True)
|
||||
logging.warn(traceback.format_exc())
|
||||
|
||||
|
@ -1,71 +1,91 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
"""
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
This file handles all operations involving logging
|
||||
'''
|
||||
'''
|
||||
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.
|
||||
We use built in logging but with a custom formatter for colors and such
|
||||
"""
|
||||
import logging
|
||||
|
||||
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.
|
||||
from filepaths import log_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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
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.
|
||||
|
||||
import sys, traceback
|
||||
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 . import colors, readline, log, raw, confirm, colors, settings
|
||||
colors = colors.Colors
|
||||
readline = readline.readline
|
||||
log = log.log
|
||||
raw = raw.raw
|
||||
confirm = confirm.confirm
|
||||
# credit: https://stackoverflow.com/a/384076
|
||||
# license: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
class ConsoleFormatter(logging.Formatter):
|
||||
|
||||
# debug: when there is info that could be useful for debugging purposes only
|
||||
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)
|
||||
if not error is None:
|
||||
debug('Error: ' + str(error) + parse_error())
|
||||
grey = "\x1b[38;20m"
|
||||
green = "\x1b[38;5;82m"
|
||||
yellow = "\x1b[33;20m"
|
||||
red = "\x1b[31;20m"
|
||||
bold_red = "\x1b[31;1m"
|
||||
reset = "\x1b[0m"
|
||||
format_default = "%(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
||||
format_info = "%(message)s - (%(filename)s:%(lineno)d)"
|
||||
|
||||
# info: when there is something to notify the user of, such as the success of a process
|
||||
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)
|
||||
FORMATS = {
|
||||
logging.DEBUG: grey + format_default + reset,
|
||||
logging.INFO: green + format_info + reset,
|
||||
logging.WARNING: yellow + format_default + reset,
|
||||
logging.ERROR: red + format_default + reset,
|
||||
logging.CRITICAL: bold_red + format_default + reset
|
||||
}
|
||||
|
||||
# warn: when there is a potential for something bad to happen
|
||||
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())
|
||||
if settings.get_level() <= level:
|
||||
log('!', data, colors.fg.orange, timestamp = timestamp, prompt = prompt, terminal = terminal)
|
||||
def format(self, record):
|
||||
log_fmt = self.FORMATS.get(record.levelno)
|
||||
formatter = logging.Formatter(log_fmt)
|
||||
return formatter.format(record)
|
||||
|
||||
# error: when only one function, module, or process of the program encountered a problem and must stop
|
||||
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)
|
||||
if not error is None:
|
||||
debug('Error: ' + str(error) + parse_error())
|
||||
class FileFormatter(logging.Formatter):
|
||||
|
||||
# fatal: when the something so bad has happened that the program must stop
|
||||
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)
|
||||
if settings.get_level() <= level:
|
||||
log('#', data, colors.bg.red + colors.fg.green + colors.bold, timestamp = timestamp, fd = sys.stderr, prompt = prompt, terminal = terminal)
|
||||
|
||||
# returns a formatted error message
|
||||
def parse_error():
|
||||
details = traceback.extract_tb(sys.exc_info()[2])
|
||||
output = ''
|
||||
format_default = "%(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
||||
format_info = "%(message)s - (%(filename)s:%(lineno)d)"
|
||||
|
||||
for line in details:
|
||||
output += '\n ... module %s in %s:%i' % (line[2], line[0], line[1])
|
||||
FORMATS = {
|
||||
logging.DEBUG: format_default,
|
||||
logging.INFO: format_info,
|
||||
logging.WARNING: format_default,
|
||||
logging.ERROR: format_default,
|
||||
logging.CRITICAL: format_default
|
||||
}
|
||||
|
||||
return output
|
||||
def format(self, record):
|
||||
log_fmt = self.FORMATS.get(record.levelno)
|
||||
formatter = logging.Formatter(log_fmt)
|
||||
return formatter.format(record)
|
||||
|
||||
|
||||
#logging.basicConfig(level=logging.ERROR, format='%(message)s ')
|
||||
log = logging.getLogger('onionr')
|
||||
log.setLevel(logging.INFO)
|
||||
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.INFO)
|
||||
|
||||
ch.setFormatter(ConsoleFormatter())
|
||||
|
||||
|
||||
def enable_file_logging():
|
||||
fh = logging.FileHandler(log_file)
|
||||
fh.setLevel(logging.INFO)
|
||||
fh.setFormatter(FileFormatter())
|
||||
log.addHandler(fh)
|
||||
|
||||
def disable_console_logging():
|
||||
log.removeHandler(ch)
|
||||
|
||||
def enable_console_logging():
|
||||
log.addHandler(ch)
|
||||
enable_console_logging()
|
||||
|
@ -1,60 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
class to access ANSI control codes
|
||||
'''
|
||||
'''
|
||||
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 re
|
||||
class Colors:
|
||||
'''
|
||||
This class allows you to set the color if ANSI codes are supported
|
||||
'''
|
||||
reset='\033[0m'
|
||||
bold='\033[01m'
|
||||
disable='\033[02m'
|
||||
underline='\033[04m'
|
||||
reverse='\033[07m'
|
||||
strikethrough='\033[09m'
|
||||
invisible='\033[08m'
|
||||
italics='\033[3m'
|
||||
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'
|
||||
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'
|
||||
@staticmethod
|
||||
def filter(data):
|
||||
return re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]').sub('', str(data))
|
@ -1,54 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
confirm y/n cli prompt
|
||||
'''
|
||||
'''
|
||||
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
|
||||
from . import colors, settings
|
||||
colors = colors.Colors
|
||||
def confirm(default = 'y', message = 'Are you sure %s? '):
|
||||
'''
|
||||
Displays an "Are you sure" message, returns True for Y and False for N
|
||||
message: The confirmation message, use %s for (y/n)
|
||||
default: which to prefer-- y or n
|
||||
'''
|
||||
|
||||
color = colors.fg.green + colors.bold
|
||||
|
||||
default = default.lower()
|
||||
confirm = colors.bold
|
||||
if default.startswith('y'):
|
||||
confirm += '(Y/n)'
|
||||
else:
|
||||
confirm += '(y/N)'
|
||||
confirm += colors.reset + color
|
||||
|
||||
output = colors.reset + str(color) + '... ' + colors.reset + str(message) + colors.reset
|
||||
|
||||
if not get_settings() & settings.USE_ANSI:
|
||||
output = colors.filter(output)
|
||||
|
||||
sys.stdout.write(output.replace('%s', confirm))
|
||||
|
||||
inp = input().lower()
|
||||
|
||||
if 'y' in inp:
|
||||
return True
|
||||
if 'n' in inp:
|
||||
return False
|
||||
else:
|
||||
return default == 'y'
|
@ -1,38 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
god log function
|
||||
'''
|
||||
'''
|
||||
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, time
|
||||
from . import colors, raw, settings
|
||||
colors = colors.Colors
|
||||
def log(prefix, data, color = '', timestamp=True, fd = sys.stdout, prompt = True, terminal = False):
|
||||
'''
|
||||
Logs the data
|
||||
prefix : The prefix to the output
|
||||
data : The actual data to output
|
||||
color : The color to output before the data
|
||||
'''
|
||||
curTime = ''
|
||||
if timestamp:
|
||||
curTime = time.strftime("%m-%d %H:%M:%S") + ' '
|
||||
|
||||
output = colors.reset + str(color) + ('[' + colors.bold + str(prefix) + colors.reset + str(color) + '] ' if prompt is True else '') + curTime + str(data) + colors.reset
|
||||
if not settings.get_settings() & settings.USE_ANSI:
|
||||
output = colors.filter(output)
|
||||
|
||||
raw.raw(output, fd = fd, terminal = terminal)
|
@ -1,54 +0,0 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Output raw data to file or terminal
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
from . import settings, colors
|
||||
"""
|
||||
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/>.
|
||||
"""
|
||||
colors = colors.Colors
|
||||
|
||||
|
||||
def raw(data, fd = sys.stdout, terminal = False):
|
||||
"""
|
||||
Outputs raw data to console without formatting
|
||||
"""
|
||||
|
||||
if terminal and (settings.get_settings() & settings.OUTPUT_TO_CONSOLE):
|
||||
try:
|
||||
ts = fd.write('%s\n' % data)
|
||||
except OSError:
|
||||
pass
|
||||
if settings.get_settings() & settings.OUTPUT_TO_FILE:
|
||||
fdata = ''
|
||||
try:
|
||||
for _ in range(5):
|
||||
try:
|
||||
with open(settings._outputfile, 'r') as file:
|
||||
fdata = file.read()
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
fdata = fdata + '\n' + data
|
||||
fdata = fdata.split('\n')
|
||||
if len(fdata) >= settings.MAX_LOG_FILE_LINES:
|
||||
fdata.pop(0)
|
||||
fdata = '\n'.join(fdata)
|
||||
with open(settings._outputfile, 'w') as file:
|
||||
file.write(fdata)
|
@ -1,37 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
get a line of input from stdin
|
||||
'''
|
||||
'''
|
||||
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
|
||||
from . import colors, settings
|
||||
colors = colors.Colors
|
||||
def readline(message = ''):
|
||||
'''
|
||||
Takes in input from the console, not stored in logs
|
||||
message: The message to display before taking input
|
||||
'''
|
||||
|
||||
color = colors.fg.green + colors.bold
|
||||
output = colors.reset + str(color) + '... ' + colors.reset + str(message) + colors.reset
|
||||
|
||||
if not settings.get_settings() & settings.USE_ANSI:
|
||||
output = colors.filter(output)
|
||||
|
||||
sys.stdout.write(output)
|
||||
|
||||
return input()
|
@ -1,89 +0,0 @@
|
||||
'''
|
||||
Onionr - Private P2P Communication
|
||||
|
||||
logger settings
|
||||
'''
|
||||
'''
|
||||
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
|
||||
from utils import identifyhome
|
||||
import filepaths
|
||||
|
||||
data_home = os.environ.get('ONIONR_LOG_DIR', identifyhome.identify_home())
|
||||
# Use the bitwise operators to merge these settings
|
||||
USE_ANSI = 0b100
|
||||
if os.name == 'nt':
|
||||
USE_ANSI = 0b000
|
||||
OUTPUT_TO_CONSOLE = 0b010
|
||||
OUTPUT_TO_FILE = 0b001
|
||||
|
||||
LEVEL_DEBUG = 1
|
||||
LEVEL_INFO = 2
|
||||
LEVEL_WARN = 3
|
||||
LEVEL_ERROR = 4
|
||||
LEVEL_FATAL = 5
|
||||
LEVEL_IMPORTANT = 6
|
||||
|
||||
MAX_LOG_FILE_LINES = 10000
|
||||
|
||||
_type = OUTPUT_TO_CONSOLE | USE_ANSI # the default settings for logging
|
||||
_level = LEVEL_DEBUG # the lowest level to log
|
||||
# the file to log to
|
||||
_outputfile = filepaths.log_file
|
||||
|
||||
def set_settings(type):
|
||||
'''
|
||||
Set the settings for the logger using bitwise operators
|
||||
'''
|
||||
|
||||
global _type
|
||||
_type = type
|
||||
|
||||
def get_settings():
|
||||
'''
|
||||
Get settings from the logger
|
||||
'''
|
||||
|
||||
return _type
|
||||
|
||||
def set_level(level):
|
||||
'''
|
||||
Set the lowest log level to output
|
||||
'''
|
||||
|
||||
global _level
|
||||
_level = level
|
||||
|
||||
def get_level()->int:
|
||||
'''
|
||||
Get the lowest log level currently being outputted
|
||||
'''
|
||||
|
||||
return _level
|
||||
|
||||
def set_file(outputfile):
|
||||
'''
|
||||
Set the file to output to, if enabled
|
||||
'''
|
||||
|
||||
global _outputfile
|
||||
_outputfile = outputfile
|
||||
|
||||
def get_file():
|
||||
'''
|
||||
Get the file to output to
|
||||
'''
|
||||
|
||||
return _outputfile
|
@ -8,13 +8,14 @@ import sys
|
||||
import platform
|
||||
import signal
|
||||
from threading import Thread
|
||||
from logger import log as logging
|
||||
from logger import enable_file_logging
|
||||
|
||||
import filenuke
|
||||
import psutil
|
||||
|
||||
import config
|
||||
|
||||
import logger
|
||||
from onionrplugins import onionrevents as events
|
||||
|
||||
from utils import identifyhome
|
||||
@ -59,16 +60,19 @@ def delete_run_files():
|
||||
_safe_remove(filepaths.pid_file)
|
||||
|
||||
def _show_info_messages():
|
||||
version.version(verbosity=5, function=logger.info)
|
||||
logger.debug('Python version %s' % platform.python_version())
|
||||
version.version(verbosity=5, function=logging.info)
|
||||
logging.debug('Python version %s' % platform.python_version())
|
||||
|
||||
if onionrvalues.DEVELOPMENT_MODE:
|
||||
logger.warn('Development mode enabled', timestamp=False, terminal=True)
|
||||
logging.warn('Development mode enabled')
|
||||
|
||||
|
||||
def daemon():
|
||||
"""Start Onionr's primary threads for communicator, API server, node, and LAN."""
|
||||
|
||||
if config.get('log.file.output', False):
|
||||
enable_file_logging()
|
||||
|
||||
def _handle_sig_term(signum, frame):
|
||||
sys.exit(0)
|
||||
|
||||
@ -83,8 +87,8 @@ def daemon():
|
||||
security_level = config.get('general.security_level', 1)
|
||||
|
||||
_show_info_messages()
|
||||
logger.info(
|
||||
f"Onionr daemon is running under pid {os.getpid()}", terminal=True)
|
||||
logging.info(
|
||||
f"Onionr daemon is running under pid {os.getpid()}")
|
||||
events.event('init', threaded=False)
|
||||
events.event('afterinit', threaded=False)
|
||||
events.event('daemon_start')
|
||||
@ -117,33 +121,25 @@ def start(override: bool = False):
|
||||
Error exit if there is and its not overridden
|
||||
"""
|
||||
if os.path.exists(filepaths.lock_file) and not override:
|
||||
if os.path.exists(filepaths.restarting_indicator):
|
||||
try:
|
||||
os.remove(filepaths.restarting_indicator)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
else:
|
||||
return
|
||||
with open(filepaths.lock_file, 'r') as lock_file:
|
||||
try:
|
||||
proc = psutil.Process(int(lock_file.read())).name()
|
||||
except psutil.NoSuchProcess:
|
||||
proc = ""
|
||||
if not proc.startswith("python"):
|
||||
logger.warn(
|
||||
f"Detected stale run file, deleting {filepaths.lock_file}",
|
||||
terminal=True)
|
||||
logging.warn(
|
||||
f"Detected stale run file, deleting {filepaths.lock_file}")
|
||||
try:
|
||||
os.remove(filepaths.lock_file)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
start(override=True)
|
||||
return
|
||||
logger.fatal('Cannot start. Daemon is already running,'
|
||||
logging.error('Cannot start. Daemon is already running,'
|
||||
+ ' or it did not exit cleanly.\n'
|
||||
+ ' (if you are sure that there is not a daemon running,'
|
||||
+ f' delete {filepaths.lock_file} & try again).',
|
||||
terminal=True)
|
||||
)
|
||||
else:
|
||||
if not onionrvalues.DEVELOPMENT_MODE:
|
||||
lock_file = open(filepaths.lock_file, 'w')
|
||||
|
@ -6,7 +6,7 @@ import os
|
||||
from signal import SIGTERM
|
||||
|
||||
from filepaths import pid_file
|
||||
import logger
|
||||
from logger import log as logging
|
||||
"""
|
||||
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
|
||||
@ -29,9 +29,9 @@ def kill_daemon():
|
||||
with open(pid_file, 'r') as pid:
|
||||
os.kill(int(pid.read()), SIGTERM)
|
||||
except FileNotFoundError:
|
||||
logger.error("Daemon not running/pid file missing")
|
||||
logger.warn('Stopping the running daemon, if one exists...', timestamp=False,
|
||||
terminal=True)
|
||||
logging.error("Daemon not running/pid file missing")
|
||||
logging.warn('Stopping the running daemon, if one exists...', timestamp=False,
|
||||
)
|
||||
|
||||
|
||||
kill_daemon.onionr_help = "Gracefully stops the " # type: ignore
|
||||
|
@ -5,11 +5,12 @@ Show nice logo
|
||||
import os
|
||||
|
||||
import config
|
||||
import logger
|
||||
|
||||
from .quotes import QUOTE
|
||||
from utils.boxprint import bordered
|
||||
from utils import logoheader
|
||||
|
||||
from utils import readstatic
|
||||
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
|
||||
@ -25,28 +26,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/>.
|
||||
"""
|
||||
|
||||
def header():
|
||||
if onionrvalues.DEVELOPMENT_MODE:
|
||||
return
|
||||
|
||||
pink_ansi = '\033[95m'
|
||||
green_ansi = '\033[92m'
|
||||
reset_ansi = '\x1b[0m'
|
||||
|
||||
logo = readstatic.read_static('header.txt', ret_bin=False)
|
||||
logo = logo.replace('P', pink_ansi).replace('G', green_ansi).replace('W', reset_ansi)
|
||||
print(reset_ansi + logo)
|
||||
|
||||
def show_logo():
|
||||
logger.raw('', terminal=True)
|
||||
try:
|
||||
terminal_size = os.get_terminal_size().columns
|
||||
except OSError: # Generally thrown if not in terminal
|
||||
terminal_size = 120
|
||||
# print nice header thing :)
|
||||
if config.get('general.display_header', True):
|
||||
logoheader.header("")
|
||||
header()
|
||||
if terminal_size >= 120:
|
||||
if QUOTE[1]: # If there is an author to show for the quote
|
||||
logger.info(
|
||||
"\u001b[33m\033[F" + bordered(QUOTE[0] + '\n -' + QUOTE[1]),
|
||||
terminal=True)
|
||||
print("\u001b[33m\033[F" + bordered(QUOTE[0] + '\n -' + QUOTE[1]))
|
||||
else:
|
||||
logger.info(
|
||||
"\u001b[33m\033[F" + bordered(QUOTE[0]), terminal=True)
|
||||
print("\u001b[33m\033[F" + bordered(QUOTE[0]))
|
||||
else:
|
||||
if QUOTE[1]:
|
||||
logger.info("\u001b[33m\033[F" + QUOTE[0] + '\n -' + QUOTE[1],
|
||||
terminal=True)
|
||||
print("\u001b[33m\033[F" + QUOTE[0] + '\n -' + QUOTE[1])
|
||||
else:
|
||||
logger.info("\u001b[33m\033[F" + QUOTE[0], terminal=True)
|
||||
print("\u001b[33m\033[F" + QUOTE[0])
|
||||
|
||||
|
@ -1,141 +0,0 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This module defines commands to show stats/details about the local node
|
||||
"""
|
||||
import os
|
||||
import logger
|
||||
from utils import sizeutils, getconsolewidth, identifyhome
|
||||
import config
|
||||
import onionrvalues
|
||||
from filepaths import lock_file
|
||||
|
||||
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 _is_running():
|
||||
script = onionrvalues.SCRIPT_NAME
|
||||
if os.path.isfile(lock_file):
|
||||
for process in psutil.process_iter():
|
||||
if process.name() == script:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def show_stats():
|
||||
"""Print/log statistic info about our Onionr install."""
|
||||
try:
|
||||
# define stats messages here
|
||||
home = identifyhome.identify_home()
|
||||
|
||||
|
||||
messages = {
|
||||
# info about local client
|
||||
|
||||
# This line is inaccurate if dev mode is enabled
|
||||
'Onionr Daemon Status':
|
||||
((logger.colors.fg.green + 'Online') \
|
||||
if _is_running() \
|
||||
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.db')),
|
||||
'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,
|
||||
'Enabled Plugins':
|
||||
str(len(config.get('plugins.enabled', list()))) + ' / ' +
|
||||
str(len(os.listdir(home + 'plugins/')))
|
||||
}
|
||||
|
||||
# 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 = {
|
||||
'Data directory': identifyhome.identify_home(),
|
||||
}
|
||||
|
||||
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:"
|
||||
|
||||
show_stats.onionr_help = "Shows statistics for your Onionr " # type: ignore
|
||||
show_stats.onionr_help += "node. Slow if Onionr is not running" # type: ignore
|
@ -11,7 +11,7 @@ try:
|
||||
except (KeyError, IndexError) as _:
|
||||
pass
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import onionrexceptions
|
||||
import onionrplugins
|
||||
from onionrplugins import onionrpluginapi
|
||||
@ -48,10 +48,6 @@ def register_plugin_commands(cmd) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _show_term(msg: str):
|
||||
logger.info(msg, terminal=True)
|
||||
|
||||
|
||||
def register():
|
||||
"""Register commands and handles help command processing."""
|
||||
def get_help_message(cmd: str,
|
||||
@ -80,7 +76,7 @@ def register():
|
||||
try:
|
||||
cmd = sys.argv[1]
|
||||
except IndexError:
|
||||
logger.info('Run with --help to see available commands', terminal=True)
|
||||
logging.info('Run with --help to see available commands')
|
||||
sys.exit(10)
|
||||
|
||||
is_help_cmd = False
|
||||
@ -102,29 +98,28 @@ def register():
|
||||
sys.argv[2]
|
||||
except IndexError:
|
||||
for i in arguments.get_arguments():
|
||||
_show_term('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i),
|
||||
logging.info('%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:
|
||||
_show_term('%s commands:' % (pl.plugin_name,))
|
||||
logging.info('%s commands:' % (pl.plugin_name,))
|
||||
except AttributeError:
|
||||
_show_term('%s commands:' % (pl.__name__,))
|
||||
logging.info('%s commands:' % (pl.__name__,))
|
||||
for plugin_cmd in pl.ONIONR_COMMANDS:
|
||||
_show_term('%s %s: %s' %
|
||||
logging.info('%s %s: %s' %
|
||||
(PROGRAM_NAME,
|
||||
plugin_cmd,
|
||||
get_help_message(plugin_cmd)),)
|
||||
print('')
|
||||
else:
|
||||
try:
|
||||
_show_term('%s %s: %s' % (PROGRAM_NAME,
|
||||
logging.info('%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)
|
||||
logging.error('%s: command does not exist.' % [sys.argv[2]])
|
||||
sys.exit(3)
|
||||
return
|
||||
|
@ -4,7 +4,7 @@ Sets CLI arguments for Onionr
|
||||
"""
|
||||
from typing import Callable
|
||||
|
||||
from .. import onionrstatistics, version, daemonlaunch
|
||||
from .. import version, daemonlaunch
|
||||
from .. import resetplugins # command to reinstall default plugins
|
||||
|
||||
|
||||
@ -32,8 +32,6 @@ def get_arguments() -> dict:
|
||||
dynamically modify them with plugins
|
||||
"""
|
||||
args = {
|
||||
('details', 'info'): onionrstatistics.show_details,
|
||||
('stats', 'statistics'): onionrstatistics.show_stats,
|
||||
('version',): version.version,
|
||||
('start', 'daemon'): daemonlaunch.start,
|
||||
('stop', 'kill'): daemonlaunch.kill_daemon,
|
||||
|
@ -4,7 +4,7 @@ Try to provide recommendations for invalid Onionr commands
|
||||
"""
|
||||
import sys
|
||||
from difflib import SequenceMatcher
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from . import arguments
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@ -30,9 +30,9 @@ def recommend(print_default: bool = True):
|
||||
for key in args.keys():
|
||||
for word in key:
|
||||
if SequenceMatcher(None, tried, word).ratio() >= 0.75:
|
||||
logger.warn(f'{print_message} "{tried}", '
|
||||
logging.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)
|
||||
logging.error('%s "%s"' % (print_message, tried))
|
||||
|
@ -6,7 +6,7 @@ import os
|
||||
import shutil
|
||||
|
||||
from utils import identifyhome
|
||||
import logger
|
||||
from logger import log as logging
|
||||
"""
|
||||
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
|
||||
@ -32,7 +32,7 @@ def reset():
|
||||
if os.path.exists(plugin_dir):
|
||||
shutil.rmtree(plugin_dir)
|
||||
|
||||
logger.info('Default plugins have been reset.', terminal=True)
|
||||
logging.info('Default plugins have been reset.')
|
||||
|
||||
|
||||
reset.onionr_help = "reinstalls default Onionr plugins" # type: ignore
|
||||
|
@ -5,7 +5,7 @@ Command to show version info
|
||||
import platform
|
||||
from utils import identifyhome
|
||||
import onionrvalues
|
||||
import logger
|
||||
from logger import log as logging
|
||||
"""
|
||||
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
|
||||
@ -22,23 +22,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def version(verbosity=5, function=logger.info):
|
||||
def version(verbosity=5, function=logging.info):
|
||||
"""Display the Onionr version."""
|
||||
function('Onionr v%s (%s)' % (onionrvalues.ONIONR_VERSION,
|
||||
platform.machine()),
|
||||
terminal=True)
|
||||
platform.machine()))
|
||||
if verbosity >= 1:
|
||||
function(onionrvalues.ONIONR_TAGLINE, terminal=True)
|
||||
function(onionrvalues.ONIONR_TAGLINE)
|
||||
if verbosity >= 2:
|
||||
pf = platform.platform()
|
||||
release = platform.release()
|
||||
python_imp = platform.python_implementation()
|
||||
python_version = platform.python_version()
|
||||
function(
|
||||
f'{python_imp} {python_version} on {pf} {release}',
|
||||
terminal=True)
|
||||
f'{python_imp} {python_version} on {pf} {release}')
|
||||
function('Onionr data dir: %s' %
|
||||
identifyhome.identify_home(), terminal=True)
|
||||
identifyhome.identify_home())
|
||||
|
||||
|
||||
version.onionr_help = 'Shows environment details including ' # type: ignore
|
||||
|
@ -22,7 +22,7 @@ import traceback
|
||||
|
||||
from . import onionrevents as events
|
||||
from .pluginapis import plugin_apis
|
||||
import config, logger
|
||||
import config, logging
|
||||
from utils import identifyhome
|
||||
|
||||
# set data dir
|
||||
@ -43,9 +43,9 @@ def reload(stop_event = True):
|
||||
enabled_plugins = get_enabled_plugins()
|
||||
|
||||
if stop_event is True:
|
||||
logger.debug('Reloading all plugins...')
|
||||
logging.debug('Reloading all plugins...')
|
||||
else:
|
||||
logger.debug('Loading all plugins...')
|
||||
logging.debug('Loading all plugins...')
|
||||
|
||||
if stop_event is True:
|
||||
for plugin in enabled_plugins:
|
||||
@ -56,7 +56,7 @@ def reload(stop_event = True):
|
||||
|
||||
return True
|
||||
except:
|
||||
logger.error('Failed to reload plugins.')
|
||||
logging.error('Failed to reload plugins.')
|
||||
|
||||
return False
|
||||
|
||||
@ -73,8 +73,8 @@ def enable(name, start_event = True):
|
||||
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)
|
||||
logger.error('Failed to enable module:', terminal=True)
|
||||
logger.error(traceback.format_exc(), terminal=True)
|
||||
logging.error('Failed to enable module:')
|
||||
logging.error(traceback.format_exc())
|
||||
return False
|
||||
else:
|
||||
enabled_plugins.append(name)
|
||||
@ -86,8 +86,8 @@ def enable(name, start_event = True):
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
logger.error('Failed to enable plugin \"%s\", disabling plugin.' % name, terminal=True)
|
||||
logger.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower()), terminal=True)
|
||||
logging.error('Failed to enable plugin \"%s\", disabling plugin.' % name)
|
||||
logging.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower()))
|
||||
disable(name)
|
||||
|
||||
return False
|
||||
@ -129,9 +129,9 @@ def start(name):
|
||||
|
||||
return plugin
|
||||
except:
|
||||
logger.error('Failed to start module \"%s\".' % name)
|
||||
logging.error('Failed to start module \"%s\".' % name)
|
||||
else:
|
||||
logger.error('Failed to start nonexistant module \"%s\".' % name)
|
||||
logging.error('Failed to start nonexistant module \"%s\".' % name)
|
||||
|
||||
return None
|
||||
|
||||
@ -153,9 +153,9 @@ def stop(name):
|
||||
|
||||
return plugin
|
||||
except:
|
||||
logger.error('Failed to stop module \"%s\".' % name)
|
||||
logging.error('Failed to stop module \"%s\".' % name)
|
||||
else:
|
||||
logger.error('Failed to stop nonexistant module \"%s\".' % name)
|
||||
logging.error('Failed to stop nonexistant module \"%s\".' % name)
|
||||
|
||||
return None
|
||||
|
||||
@ -258,11 +258,11 @@ def check():
|
||||
"""
|
||||
|
||||
if not config.is_set('plugins'):
|
||||
logger.debug('Generating plugin configuration data...')
|
||||
logging.debug('Generating plugin configuration data...')
|
||||
config.set('plugins', {'enabled': []}, True)
|
||||
|
||||
if not os.path.exists(os.path.dirname(get_plugins_folder())):
|
||||
logger.debug('Generating plugin data folder...')
|
||||
logging.debug('Generating plugin data folder...')
|
||||
try:
|
||||
os.makedirs(os.path.dirname(get_plugins_folder()))
|
||||
except FileExistsError:
|
||||
|
@ -7,7 +7,7 @@ from threading import Thread
|
||||
|
||||
import traceback
|
||||
|
||||
import config, logger
|
||||
import config, logging
|
||||
import onionrplugins as plugins
|
||||
from . import onionrpluginapi as pluginapi
|
||||
"""
|
||||
@ -41,11 +41,11 @@ def __event_caller(event_name, data = {}):
|
||||
try:
|
||||
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(data))
|
||||
except ModuleNotFoundError as _:
|
||||
logger.warn('Disabling nonexistant plugin "%s"...' % plugin, terminal=True)
|
||||
logging.warn('Disabling nonexistant plugin "%s"...' % plugin)
|
||||
plugins.disable(plugin, stop_event = False)
|
||||
except Exception as _:
|
||||
logger.error('Event "%s" failed for plugin "%s".' % (event_name, plugin), terminal=True)
|
||||
logger.error('\n' + traceback.format_exc(), terminal=True)
|
||||
logging.error('Event "%s" failed for plugin "%s".' % (event_name, plugin))
|
||||
logging.error('\n' + traceback.format_exc())
|
||||
|
||||
def event(event_name, data = {}, threaded = True):
|
||||
"""Call an event on all plugins (if defined)"""
|
||||
|
@ -18,7 +18,7 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
|
||||
import onionrplugins, logger
|
||||
import onionrplugins, logging
|
||||
|
||||
|
||||
class PluginAPI:
|
||||
|
@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import os, shutil
|
||||
|
||||
import onionrplugins as plugins
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import filepaths
|
||||
from utils.readstatic import get_static_dir
|
||||
|
||||
@ -38,9 +38,9 @@ def setup_default_plugins():
|
||||
if not name in plugins.get_enabled_plugins():
|
||||
plugins.enable(name)
|
||||
else:
|
||||
logger.error(
|
||||
logging.error(
|
||||
"Plugin source directory does not exist!" +
|
||||
"Onionr needs plugins to be useful", terminal=True)
|
||||
"Onionr needs plugins to be useful")
|
||||
|
||||
|
||||
for name in plugins.get_enabled_plugins():
|
||||
@ -50,5 +50,5 @@ def setup_default_plugins():
|
||||
except FileExistsError:
|
||||
pass
|
||||
except Exception as e:
|
||||
#logger.warn('Error enabling plugin: ' + str(e), terminal=True)
|
||||
#logging.warn('Error enabling plugin: ' + str(e))
|
||||
plugins.disable(name, stop_event = False)
|
||||
|
@ -8,9 +8,8 @@ import base64
|
||||
import ujson as json
|
||||
|
||||
import config
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import onionrvalues
|
||||
from logger.settings import *
|
||||
from utils import readstatic
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@ -37,42 +36,3 @@ def setup_config():
|
||||
config.save()
|
||||
|
||||
config.reload()
|
||||
|
||||
settings = 0b000
|
||||
if config.get('log.console.color', True):
|
||||
settings = settings | USE_ANSI
|
||||
if config.get('log.console.output', True):
|
||||
settings = settings | OUTPUT_TO_CONSOLE
|
||||
if config.get('log.file.output', True):
|
||||
settings = settings | OUTPUT_TO_FILE
|
||||
set_settings(settings)
|
||||
|
||||
verbosity = str(config.get('log.verbosity', 'default')).lower().strip()
|
||||
if not verbosity in ['default', 'null', 'none', 'nil']:
|
||||
map = {
|
||||
str(LEVEL_DEBUG) : LEVEL_DEBUG,
|
||||
'verbose' : LEVEL_DEBUG,
|
||||
'debug' : LEVEL_DEBUG,
|
||||
str(LEVEL_INFO) : LEVEL_INFO,
|
||||
'info' : LEVEL_INFO,
|
||||
'information' : LEVEL_INFO,
|
||||
str(LEVEL_WARN) : LEVEL_WARN,
|
||||
'warn' : LEVEL_WARN,
|
||||
'warning' : LEVEL_WARN,
|
||||
'warnings' : LEVEL_WARN,
|
||||
str(LEVEL_ERROR) : LEVEL_ERROR,
|
||||
'err' : LEVEL_ERROR,
|
||||
'error' : LEVEL_ERROR,
|
||||
'errors' : LEVEL_ERROR,
|
||||
str(LEVEL_FATAL) : LEVEL_FATAL,
|
||||
'fatal' : LEVEL_FATAL,
|
||||
str(LEVEL_IMPORTANT) : LEVEL_IMPORTANT,
|
||||
'silent' : LEVEL_IMPORTANT,
|
||||
'quiet' : LEVEL_IMPORTANT,
|
||||
'important' : LEVEL_IMPORTANT
|
||||
}
|
||||
|
||||
if verbosity in map:
|
||||
set_level(map[verbosity])
|
||||
else:
|
||||
logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity)
|
||||
|
@ -6,7 +6,7 @@ from threading import Thread
|
||||
from uuid import uuid4
|
||||
from time import sleep
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
|
||||
def _onionr_thread(func: Callable,
|
||||
@ -18,10 +18,10 @@ def _onionr_thread(func: Callable,
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
except Exception as _: # noqa
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f"Onionr thread exception in {thread_id} \n" +
|
||||
traceback.format_exc(),
|
||||
terminal=True)
|
||||
)
|
||||
sleep(sleep_secs)
|
||||
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
import sys, os
|
||||
from . import readstatic
|
||||
import logger
|
||||
import onionrvalues
|
||||
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
|
||||
header_path = readstatic.get_static_dir() + 'header.txt'
|
||||
if os.path.exists(header_path) and logger.settings.get_level() <= logger.settings.LEVEL_INFO:
|
||||
with open(header_path, 'rb') as file:
|
||||
# only to stdout, not file or log or anything
|
||||
sys.stderr.write(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n').replace('B', logger.colors.bold))
|
||||
|
||||
if message:
|
||||
logger.info(logger.colors.fg.lightgreen + '-> ' + str(message) + logger.colors.reset + logger.colors.fg.lightgreen + ' <-\n', terminal=True)
|
@ -11,11 +11,10 @@
|
||||
"file": {
|
||||
"output": true,
|
||||
"remove_on_exit": false
|
||||
},
|
||||
"verbosity": "default"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"disabled": ["unixtransport", "repl", "bigbrother"],
|
||||
"disabled": ["unixtransport", "repl", "bigbrother", "example"],
|
||||
"enabled": []
|
||||
},
|
||||
"security": {
|
||||
|
@ -1,16 +0,0 @@
|
||||
'''
|
||||
$name plugin template file.
|
||||
Generated on $date by $user.
|
||||
'''
|
||||
|
||||
plugin_name = '$name'
|
||||
|
||||
def on_init(api, data = None):
|
||||
'''
|
||||
This event is called after Onionr is initialized, but before the command
|
||||
inputted is executed. Could be called when daemon is starting or when
|
||||
just the client is running.
|
||||
'''
|
||||
|
||||
pluginapi = api
|
||||
|
@ -18,9 +18,9 @@ P ::: :::: ::::::: :::: :::: W:: :: :: ::: :: :: :: :: :::: :::::
|
||||
P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: :::
|
||||
P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: ::
|
||||
P :::: :::::: :::::: ::::
|
||||
P :::: :::::::::::: :::: GPB
|
||||
P :::: :::::::::::: ::::
|
||||
P ::::: :::::::: ::::
|
||||
P ::::: :::::
|
||||
P ::::::::::::::::
|
||||
P :::::::
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ import sys
|
||||
import os
|
||||
from typing import Iterable
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@ -49,5 +49,5 @@ def enable_ministries(disable_hooks: Iterable = None):
|
||||
|
||||
def on_init(api, data=None):
|
||||
enable_ministries()
|
||||
logger.info(
|
||||
"Big brother enabled, blocking unsafe Python code.", terminal=True)
|
||||
logging.info(
|
||||
"Big brother enabled, blocking unsafe Python code.")
|
||||
|
@ -4,7 +4,7 @@ Ensure sockets don't get made to non localhost
|
||||
"""
|
||||
import ipaddress
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from onionrexceptions import NetworkLeak
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@ -37,12 +37,12 @@ def detect_socket_leaks(socket_event):
|
||||
try:
|
||||
ip_address = ipaddress.ip_address(ip_address)
|
||||
except ValueError:
|
||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
logging.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.is_loopback and not ip_address.is_multicast \
|
||||
and not ip_address.is_private:
|
||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
logging.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
|
||||
|
@ -3,7 +3,7 @@
|
||||
Log (not block) read/write of non-user data files and non-python lib files
|
||||
"""
|
||||
from utils.identifyhome import identify_home
|
||||
import logger
|
||||
from logger import log as logging
|
||||
"""
|
||||
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
|
||||
@ -33,4 +33,4 @@ def detect_disk_access(info):
|
||||
|
||||
if identify_home() not in info[0]:
|
||||
if 'proc' not in info[0]: # if it is, it is onionr stats
|
||||
logger.warn(f'[DISK MINISTRY] {info}')
|
||||
logging.warn(f'[DISK MINISTRY] {info}')
|
||||
|
@ -5,7 +5,7 @@ Prevent eval/exec/os.system and log it
|
||||
import base64
|
||||
import platform
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from utils import identifyhome
|
||||
from onionrexceptions import ArbitraryCodeExec
|
||||
"""
|
||||
@ -27,8 +27,8 @@ untrusted_exec = True
|
||||
|
||||
def block_system(cmd):
|
||||
"""Prevent os.system except for whitelisted commands+contexts."""
|
||||
logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
|
||||
logger.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
|
||||
logging.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS')
|
||||
logging.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
|
||||
raise ArbitraryCodeExec('os.system command not in whitelist')
|
||||
|
||||
|
||||
@ -57,8 +57,8 @@ def block_exec(event, info):
|
||||
if '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}')
|
||||
logging.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS')
|
||||
logging.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
|
||||
logging.warn('Prevented exec/eval. Report this with the sample below')
|
||||
logging.warn(f'{event} code in base64 format: {code_b64}')
|
||||
raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
|
||||
|
@ -6,14 +6,12 @@ import sys
|
||||
import os
|
||||
import locale
|
||||
from time import sleep
|
||||
import traceback
|
||||
from logger import log as logging
|
||||
from typing import Set, TYPE_CHECKING
|
||||
from threading import Thread, local
|
||||
|
||||
import blockdb
|
||||
from gossip.peerset import gossip_peer_set
|
||||
|
||||
import logger
|
||||
|
||||
import onionrblocks
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
@ -58,5 +56,5 @@ def on_printtest_cmd(api, data=None):
|
||||
|
||||
|
||||
def on_init(api, data=None):
|
||||
logger.info(
|
||||
f"Example Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
||||
logging.info(
|
||||
f"Example Plugin v{PLUGIN_VERSION} enabled")
|
||||
|
@ -21,6 +21,8 @@ from code import InteractiveConsole
|
||||
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||
# import after path insert
|
||||
|
||||
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
|
||||
@ -42,6 +44,7 @@ PLUGIN_VERSION = '0.0.0'
|
||||
|
||||
def on_primary_loop(event_name, data):
|
||||
"""Run a REPL on the primary loop"""
|
||||
logger.disable_console_logging()
|
||||
header = """You are now in the Onionr REPL. Type 'exit()' to exit.
|
||||
|
||||
Enter repl_locals to see the (default) special locals available to you.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import config
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from gossip.peerset import gossip_peer_set
|
||||
|
||||
from getsocks import get_socks
|
||||
@ -24,6 +24,6 @@ def on_announce_rec(api, data=None):
|
||||
return
|
||||
|
||||
|
||||
logger.info(f"Peer {announced} announced to us.", terminal=True)
|
||||
logging.info(f"Peer {announced} announced to us.")
|
||||
|
||||
data['callback'](TorPeer(socks_address, socks_port, announced))
|
||||
|
@ -9,7 +9,7 @@ from typing import Callable
|
||||
from gossip.peer import Peer
|
||||
from gossip.peerset import gossip_peer_set
|
||||
from utils.identifyhome import identify_home
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import config
|
||||
from getsocks import get_socks
|
||||
|
||||
@ -47,7 +47,7 @@ def on_bootstrap(api, data):
|
||||
except FileNotFoundError:
|
||||
bootstrap_nodes = set()
|
||||
except Exception as _:
|
||||
logger.warn(traceback.format_exc(), terminal=True)
|
||||
logging.warn(traceback.format_exc())
|
||||
return
|
||||
else:
|
||||
return
|
||||
@ -60,7 +60,7 @@ def on_bootstrap(api, data):
|
||||
try:
|
||||
config.reload()
|
||||
except Exception:
|
||||
logger.error(traceback.format_exc(), terminal=True)
|
||||
logging.error(traceback.format_exc())
|
||||
|
||||
socks_address, socks_port = get_socks()[0]
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
hc5qc2vfuq2rkz4mjrrobcjgdjnsni6rovhfkbpc7huupbuiztx6wiid
|
@ -8,13 +8,12 @@ import locale
|
||||
from time import sleep
|
||||
import traceback
|
||||
from typing import Set, TYPE_CHECKING
|
||||
import base64
|
||||
from logger import log as logging
|
||||
from threading import Thread
|
||||
|
||||
import stem
|
||||
from stem.control import Controller
|
||||
|
||||
import logger
|
||||
from utils import readstatic
|
||||
import config
|
||||
from filepaths import gossip_server_socket_file
|
||||
@ -58,8 +57,8 @@ class OnionrTor:
|
||||
|
||||
|
||||
def on_init(api, data=None):
|
||||
logger.info(
|
||||
f"Tor Transport Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
||||
logging.info(
|
||||
f"Tor Transport Plugin v{PLUGIN_VERSION} enabled")
|
||||
|
||||
|
||||
def on_get_our_transport(api, data=None):
|
||||
@ -75,10 +74,11 @@ def on_gossip_start(api, data: Set[Peer] = None):
|
||||
starttor.start_tor()
|
||||
|
||||
with Controller.from_socket_file(control_socket) as controller:
|
||||
controller
|
||||
controller.authenticate()
|
||||
logger.info(
|
||||
logging.info(
|
||||
"Tor socks is listening on " +
|
||||
f"{controller.get_listeners('SOCKS')[0]}", terminal=True)
|
||||
f"{controller.get_listeners('SOCKS')[0]}")
|
||||
key = config.get('tor.key')
|
||||
new_address = ''
|
||||
if not key:
|
||||
@ -98,12 +98,10 @@ def on_gossip_start(api, data: Set[Peer] = None):
|
||||
key_content=key, key_type='ED25519-V3',
|
||||
detached=True, await_publication=True)
|
||||
except stem.ProtocolError:
|
||||
logger.error(
|
||||
logging.error(
|
||||
"Could not start Tor transport. Try restarting Onionr",
|
||||
terminal=True)
|
||||
)
|
||||
config.set('tor.key', '', savefile=True)
|
||||
return
|
||||
logger.info(
|
||||
f'{new_address}Tor transport address {add_onion_resp.service_id}' +
|
||||
'.onion',
|
||||
terminal=True)
|
||||
logging.info(
|
||||
f'{new_address}Tor transport address {add_onion_resp.service_id}.onion')
|
||||
|
@ -1,7 +1,7 @@
|
||||
import socks
|
||||
|
||||
from gossip.peerset import gossip_peer_set
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
|
||||
class HandleRevc:
|
||||
@ -48,9 +48,9 @@ class TorPeer:
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
logger.debug(
|
||||
logging.debug(
|
||||
f"Could not create socket to peer {self.transport_address}",
|
||||
terminal=True)
|
||||
)
|
||||
raise TimeoutError
|
||||
mock_recv = HandleRevc(s)
|
||||
s.recv = mock_recv.recv
|
||||
|
@ -6,7 +6,7 @@ import sys
|
||||
import os
|
||||
import locale
|
||||
from time import sleep
|
||||
import traceback
|
||||
from logger import log as logging
|
||||
from typing import Set, TYPE_CHECKING
|
||||
from threading import Thread
|
||||
import shelve
|
||||
@ -14,7 +14,6 @@ import shelve
|
||||
import stem
|
||||
from stem.control import Controller
|
||||
|
||||
import logger
|
||||
from utils import readstatic
|
||||
import config
|
||||
from filepaths import gossip_server_socket_file
|
||||
@ -59,10 +58,10 @@ def on_shutdown_event(api, data=None):
|
||||
db[peer.transport_address] = peer
|
||||
|
||||
def on_init(api, data=None):
|
||||
logger.info(
|
||||
f"Unix Transport Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
||||
logger.info(
|
||||
f"Peers can connect to {gossip_server_socket_file}", terminal=True)
|
||||
logging.info(
|
||||
f"Unix Transport Plugin v{PLUGIN_VERSION} enabled")
|
||||
logging.info(
|
||||
f"Peers can connect to {gossip_server_socket_file}")
|
||||
|
||||
def on_get_our_transport(api, data=None):
|
||||
callback_func = data['callback']
|
||||
|
@ -1,5 +1,5 @@
|
||||
import config
|
||||
import logger
|
||||
from logger import log as logging
|
||||
from gossip.server import gossip_server_socket_file
|
||||
|
||||
from unixpeer import UnixPeer
|
||||
@ -19,6 +19,6 @@ def on_announce_rec(api, data=None):
|
||||
if announced == gossip_server_socket_file:
|
||||
return
|
||||
|
||||
logger.info(f"Peer {announced} announced to us.", terminal=True)
|
||||
logging.info(f"Peer {announced} announced to us.")
|
||||
|
||||
data['callback'](UnixPeer(announced))
|
||||
|
@ -10,7 +10,7 @@ from gossip.server import gossip_server_socket_file
|
||||
from gossip.peer import Peer
|
||||
from gossip.peerset import gossip_peer_set
|
||||
from utils.identifyhome import identify_home
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import config
|
||||
|
||||
from unixpeer import UnixPeer
|
||||
@ -46,7 +46,7 @@ def on_bootstrap(api, data=None):
|
||||
except FileNotFoundError:
|
||||
bootstrap_nodes = set()
|
||||
except Exception as e:
|
||||
logger.warn(traceback.format_exc(), terminal=True)
|
||||
logging.warn(traceback.format_exc())
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
@ -11,7 +11,7 @@ from threading import Thread, local
|
||||
from gossip.peerset import gossip_peer_set
|
||||
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
import onionrplugins
|
||||
|
||||
@ -41,8 +41,8 @@ from wot.loadfromblocks import load_identities_from_blocks
|
||||
|
||||
|
||||
def on_init(api, data=None):
|
||||
logger.info(
|
||||
f"Web of Trust Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
||||
logging.info(
|
||||
f"Web of Trust Plugin v{PLUGIN_VERSION} enabled")
|
||||
#onionrplugins.plugin_apis['wot'] = wot_test
|
||||
|
||||
list(map(lambda x: identities.add(x), load_identities_from_blocks()))
|
||||
|
@ -1,4 +1,4 @@
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from nacl.signing import VerifyKey
|
||||
|
||||
@ -10,8 +10,8 @@ def process_identity_announce(identity_announce_payload):
|
||||
|
||||
# verify that this is a signature for an announce command
|
||||
if identity_announce_payload[0] != WotCommand.ANNOUNCE:
|
||||
logger.warn(
|
||||
f'Invalid command in signature' , terminal=True)
|
||||
logging.warn(
|
||||
f'Invalid command in signature' )
|
||||
return
|
||||
iden = Identity.deserialize(identity_announce_payload[1:])
|
||||
identities.add(iden)
|
@ -1,4 +1,4 @@
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from nacl.signing import VerifyKey
|
||||
|
||||
@ -9,13 +9,13 @@ from wot.identity.identityset import identities
|
||||
def process_identity_revoke(revoke_payload: bytes):
|
||||
wot_cmd = revoke_payload[0].to_bytes(1, 'big')
|
||||
if revoke_payload[0] != WotCommand.REVOKE:
|
||||
logger.warn(
|
||||
f'Invalid command in signature', terminal=True)
|
||||
logging.warn(
|
||||
f'Invalid command in signature')
|
||||
return
|
||||
revoked_identity = revoke_payload[1:33]
|
||||
signature = revoke_payload[33:]
|
||||
|
||||
# raises nacl.exceptions.BadSignatureError if bad signature
|
||||
VerifyKey(revoked_identity).verify(wot_cmd + revoked_identity, signature)
|
||||
|
||||
|
||||
identities.remove(Identity(revoked_identity, "etc"))
|
||||
|
@ -2,7 +2,7 @@ import traceback
|
||||
|
||||
from nacl.signing import VerifyKey
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from wot.getbykey import get_identity_by_key
|
||||
from wot.blockprocessingevent import WotCommand
|
||||
@ -10,14 +10,14 @@ from wot.blockprocessingevent import WotCommand
|
||||
|
||||
def process_revoke_signature(revoke_signature_payload):
|
||||
if len(revoke_signature_payload) != 129:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f'Signature size is invalid for revoking an identity',
|
||||
terminal=True)
|
||||
)
|
||||
|
||||
# verify that this is a signature for a trust command
|
||||
if revoke_signature_payload[0] != WotCommand.REVOKE_TRUST:
|
||||
logger.warn(
|
||||
f'Invalid command in signature' , terminal=True)
|
||||
logging.warn(
|
||||
f'Invalid command in signature' )
|
||||
return
|
||||
# signer is first 32 bytes
|
||||
signer = VerifyKey(revoke_signature_payload[1:33])
|
||||
|
@ -1,5 +1,5 @@
|
||||
import traceback
|
||||
import logger
|
||||
from logger import log as logging
|
||||
|
||||
from nacl.signing import VerifyKey
|
||||
|
||||
@ -9,13 +9,13 @@ from wot.blockprocessingevent import WotCommand
|
||||
|
||||
def process_trust_signature(sig_payload: bytes):
|
||||
if len(sig_payload) != 129:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f'Signature size is invalid for a signed identity')
|
||||
return
|
||||
|
||||
# verify that this is a signature for a trust command
|
||||
if sig_payload[0] != WotCommand.TRUST:
|
||||
logger.warn(
|
||||
logging.warn(
|
||||
f'Invalid command in signature')
|
||||
return
|
||||
# signer is first 32 bytes
|
||||
|
@ -4,7 +4,7 @@ import traceback
|
||||
from nacl.signing import VerifyKey
|
||||
import nacl.exceptions
|
||||
|
||||
import logger
|
||||
from logger import log as logging
|
||||
import blockdb
|
||||
|
||||
from wot.identity import Identity, identities
|
||||
@ -33,5 +33,5 @@ def load_signatures_from_blocks() -> None:
|
||||
# noop if already signed
|
||||
processtrustsignature.process_trust_signature(block.data)
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
logger.warn('Bad signature in block:')
|
||||
logger.warn(traceback.format_exc())
|
||||
logging.warn('Bad signature in block:')
|
||||
logging.warn(traceback.format_exc())
|
||||
|
Loading…
Reference in New Issue
Block a user