diff --git a/Makefile b/Makefile index 043d546..93ee40c 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ PREFIX=/usr/local +PYTHON_EXE_MSYS=${PREFIX}/bin/python3.bash LOCAL_DOCTEST=${PREFIX}/bin/toxcore_run_doctest3.bash DOCTEST=${LOCAL_DOCTEST} MOD=exclude_badExits - check:: sh python3.sh -c "import ${MOD}" @@ -16,7 +16,10 @@ install:: rsync:: bash .rsync.sh -test:: doctest + test:: + ${PYTHON_EXE_MSYS} exclude_badExits.py --help + TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/torcontactinfo.py + doctest:: export PYTHONPATH=${PWD}/src/${MOD} ${DOCTEST} ${MOD}.txt diff --git a/README.md b/README.md index 3a1a2f6..0fee17c 100644 --- a/README.md +++ b/README.md @@ -132,10 +132,12 @@ To be "good" the ContactInfo must: ```--torrc_output``` will write a file of the commands that it sends to the Tor controller, so you can include it in a ```/etc/toc/torrc```. -```--relays_output write the download relays in json to a file. The relays +```--relays_output``` write the download relays in json to a file. The relays are downloaded from https://onionoo.torproject.org/details -For usage, do ```python3 exclude_badExits.py --help` -See [exclude_badExits.txt](./exclude_badExits.txt) +For usage, do ```python3 exclude_badExits.py --help``` + +See [exclude_badExits.hlp](./exclude_badExits.hlp) +or there's a doctest file in [exclude_badExits.txt](./exclude_badExits.txt) diff --git a/exclude_badExits.bash b/exclude_badExits.bash index a6c9b0f..eeea54d 100644 --- a/exclude_badExits.bash +++ b/exclude_badExits.bash @@ -7,11 +7,15 @@ SOCKS_HOST=127.0.0.1 CAFILE=/etc/ssl/certs/ca-certificates.crt # you may have a special python for installed packages EXE=`which python3.bash` - -[ -f exclude_badExits.hlp ] || \ - $EXE exclude_badExits.py --help > exclude_badExits.hlp -[ -f README.md ] || \ - $EXE -c 'from exclude_badExits import __doc__; print(__doc__)' > README.md +MOD=exclude_badExits + +[ -f exclude_badExits.hlp -a exclude_badExits.hlp -nt src/exclude_badExits/exclude_badExits.py] || \ + PYTHONPATH=$PWD/src \ + $EXE src/${MOD}/exclude_badExits.py --help > exclude_badExits.hlp +[ -f README.md -a README.md -nt src/exclude_badExits/exclude_badExits.py] || \ + PYTHONPATH=$PWD/src \ + $EXE -c 'from exclude_badExits.exclude_badExits import __doc__; print(__doc__)' \ + > README.md # an example of running exclude_badExits with full debugging # expected to 20 minutes or so declare -a LARGS diff --git a/exclude_badExits.txt b/exclude_badExits.txt index 7a41210..fa6677f 100644 --- a/exclude_badExits.txt +++ b/exclude_badExits.txt @@ -82,4 +82,6 @@ This may take a while: >>> lArgs = ['--proxy_ctl', '9051'] >>> exclude_badExits.iMain(lArgs) - \ No newline at end of file + +There is a doctest test document in exclude_badExits.txt + diff --git a/setup.py.dst b/setup.py.dst deleted file mode 100644 index fd17f6c..0000000 --- a/setup.py.dst +++ /dev/null @@ -1,47 +0,0 @@ -# -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -* - -import re -from setuptools import setup, find_packages - -with open("qasync/__init__.py") as f: - version = re.search(r'__version__\s+=\s+"(.*)"', f.read()).group(1) - -long_description = "\n\n".join([ - open("README.md").read(), - ]) - -if __name__ == '__main__': - setup( - name="exclude_badExits", - version=__version__, - description="""A program to exclude bad exits on the Tor network""", - long_description=long_description, - author="Nusenu (originally)", - author_email='', - license="1clause BSD", - packages = find_packages(exclude=['test*']), - # url="", - # download_url="https://", - keywords=['exit nodes', 'Tor', 'tor onion controller'], - # maybe less - nothing fancy - python_requires="~=3.6", - # probably works on PyQt6 and PySide2 but untested - # https://github.com/CabbageDevelopment/qasync/ - install_requires=['cryptography', - 'rsa', - 'stem', - 'urllib3', - 'yaml'], - entry_points={ - 'console_scripts': ['exclude_badExits = exclude_badExits.__main__:iMain', ]}, - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Topic :: Security', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - ) diff --git a/src/exclude_badExits/exclude_utils.py b/src/exclude_badExits/exclude_utils.py index dcaa109..12aa3ea 100644 --- a/src/exclude_badExits/exclude_utils.py +++ b/src/exclude_badExits/exclude_utils.py @@ -224,51 +224,6 @@ def vwritefinale(oargs, lNOT_IN_RELAYS_DB) -> None: LOG.info(f"For info on relays, try: https://onionoo.torproject.org/details") # https://onionoo.torproject.org/details -def alt_vsetup_logging(theLOG, log_level, logfile='', stream=sys.stderr) -> None: - global LOG - LOG = theLOG - add = True - - logging._defaultFormatter = logging.Formatter(datefmt='%m-%d %H:%M:%S') - logging._defaultFormatter.default_time_format = '%m-%d %H:%M:%S' - logging._defaultFormatter.default_msec_format = '' - - if logfile: - add = logfile.startswith('+') - sub = logfile.startswith('-') - if add or sub: - logfile = logfile[1:] - kwargs['filename'] = logfile - - if coloredlogs: - coloredlogs.DEFAULT_LEVEL_STYLES['info']=dict(color='white',bold=True) - coloredlogs.DEFAULT_LEVEL_STYLES['debug']=dict(color='cyan') - coloredlogs.DEFAULT_LEVEL_STYLES['warn']=dict(color='yellow',bold=True) - coloredlogs.DEFAULT_LEVEL_STYLES['error']=dict(color='red',bold=True) - coloredlogs.DEFAULT_FIELD_STYLES['levelname=']=dict(color='green', bold=True), - # https://pypi.org/project/coloredlogs/ - aKw = dict(level=log_level, - logger=LOG, - stream=stream, - fmt='%(levelname)s %(message)s', - isatty=True, - milliseconds=False, - ) - coloredlogs.install(**aKw) - if logfile: - oHandler = logging.FileHandler(logfile) - LOG.addHandler(oHandler) - LOG.info(f"Setting coloured log_level to {log_level} {stream}") - else: - kwargs = dict(level=log_level, - force=True, - format='%(levelname)s %(message)s') - logging.basicConfig(**kwargs) - if add and logfile: - oHandler = logging.StreamHandler(stream) - LOG.addHandler(oHandler) - LOG.info(f"SSetting log_level to {log_level!s}") - def vsetup_logging(theLOG, log_level, logfile='', stream=sys.stdout) -> None: global LOG LOG = theLOG diff --git a/src/exclude_badExits/torcontactinfo.py b/src/exclude_badExits/torcontactinfo.py index e098543..624ffef 100644 --- a/src/exclude_badExits/torcontactinfo.py +++ b/src/exclude_badExits/torcontactinfo.py @@ -20,6 +20,8 @@ import os import re import sys import json +import logging +import warnings import requests import textwrap try: @@ -33,11 +35,9 @@ except ImportError: # rprint = print HAS_RICH = False -import logging -import warnings warnings.filterwarnings('ignore') -from exclude_utils import vsetup_logging +from exclude_badExits.exclude_utils import vsetup_logging class TorContactInfoParser(object): email_regex = "^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$" @@ -518,6 +518,13 @@ def oparser(): {sys.argv[0]} parse -np -j "Privex Inc. email:noc[]privex.io url:https://www.privex.io proof:uri-rsa pgp:288DD1632F6E8951 keybase:privexinc twitter:PrivexInc" {{"email": "noc@privex.io", "url": "https://www.privex.io", "proof": "uri-rsa", "pgp": null, "keybase": "privexinc", "twitter": "PrivexInc"}} """)) + cparser.add_argument('--relays_output', type=str, + dest='relays_output', + default=os.path.join(ETC_DIR, 'relays.json'), + help="Write the download relays in json to a file") + cparser.add_argument('-j', '--json', action='store_true', + default=False, dest='json', + help="Output real JSON, not Python dict format.") cparser.set_defaults(func=cmd_scan, json=False, pretty=False) subparse = cparser.add_subparsers() subparse.required = False @@ -527,13 +534,6 @@ def oparser(): sp_parse.add_argument('-np', '--no-pretty', action='store_false', default=False, dest='pretty', help="Disable pretty printing JSON") - sp_parse.add_argument('--relays_output', type=str, - dest='relays_output', - default=os.path.join(ETC_DIR, 'relays.json'), - help="Write the download relays in json to a file") - sp_parse.add_argument('-j', '--json', action='store_true', - default=False, dest='json', - help="Output real JSON, not Python dict format.") sp_parse.set_defaults(func=cmd_parse) sp_scan = subparse.add_parser('scan', help="Parse all contacts from https://onionoo.torproject.org/details") @@ -544,6 +544,15 @@ def oparser(): return cparser +def iMain(lArgs=None) + cparser = oparser() + opts = cparser.parse_args(lArgs) + data = None + if opts.relays_output and os.path.exists(opts.relays_output): + data = open(opts.relays_output, 'rt').read() + i = cmd_scan(opts, data) + return i + if __name__ == "__main__": if os.environ.get('DEBUG', ''): log_level = 10 @@ -552,16 +561,11 @@ if __name__ == "__main__": LOG = logging.getLogger() vsetup_logging(LOG, log_level) try: - cparser = oparser() - opts = cparser.parse_args(sys.argv[1:]) - data = None - if opts.relays_output and os.path.exists(opts.relays_output): - data = open(opts.relays_output, 'rt').read() - i = cmd_scan(opts, data) + i = iMain(sys.argv[1:]) except KeyboardInterrupt as e: i = 0 except (requests.exceptions.ProxyError, Exception,) as e: - LOG.error(f"{e}") + LOG.exception(f"Exception: {e}", exc_info=True) i = 0 sys.exit(i)