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,
|
||||
|
||||