diff --git a/build/debian/makedist_debian.sh b/build/debian/makedist_debian.sh index 2ea71e7a6af..fec31a0346b 100755 --- a/build/debian/makedist_debian.sh +++ b/build/debian/makedist_debian.sh @@ -19,10 +19,16 @@ rm -rf build/debian/tribler/usr/share/tribler python3 build/update_version_from_git.py -# ----- Install pip dependencies before the build +# ----- Prepare venv & install dependencies before the build + +python3 -m venv build-env +. ./build-env/bin/activate +python3 -m pip install --upgrade pip python3 -m pip install --upgrade -r requirements.txt -python3 -m PyInstaller tribler.spec +# ----- Build + +python3 -m PyInstaller tribler.spec --log-level=DEBUG cp -r dist/tribler build/debian/tribler/usr/share/tribler diff --git a/build/mac/makedist_macos.sh b/build/mac/makedist_macos.sh index 343ae882504..cff24fca150 100755 --- a/build/mac/makedist_macos.sh +++ b/build/mac/makedist_macos.sh @@ -12,12 +12,17 @@ export RESOURCES=build/mac/resources # ----- Clean up /bin/rm -rf dist -# ----- Build -# ----- Install pip dependencies before the build +# ----- Prepare venv & install dependencies before the build + +python3 -m venv build-env +. ./build-env/bin/activate +python3 -m pip install --upgrade pip python3 -m pip install --upgrade -r requirements.txt +# ----- Build + PI=pyinstaller -$PI tribler.spec +$PI tribler.spec --log-level=DEBUG mkdir -p dist/installdir mv dist/$APPNAME.app dist/installdir diff --git a/build/win/makedist_win.bat b/build/win/makedist_win.bat index d9d59dffa7b..6272309e017 100644 --- a/build/win/makedist_win.bat +++ b/build/win/makedist_win.bat @@ -16,15 +16,6 @@ REM Arno: Add . to find our core SET PYTHONPATH=.;%PYTHONHOME% ECHO PYTHONPATH SET TO %PYTHONPATH% -REM ----- Check for PyInstaller - -IF NOT EXIST %PYTHONHOME%\Scripts\pyinstaller.exe ( - ECHO . - ECHO Could not locate pyinstaller in %PYTHONHOME%\Scripts. - ECHO Please modify this script or install PyInstaller [www.pyinstaller.org] - EXIT /b -) - REM ----- Check for NSIS installer SET NSIS="C:\Program Files\NSIS\makensis.exe" @@ -40,10 +31,15 @@ REM ----- Clean up call build\win\clean.bat -REM ----- Build +REM ----- Prepare venv & install dependencies before the build -REM ----- Install pip dependencies before the build +python3 -m venv build-env +./build-env/Scripts/activate.bat +python3 -m pip install --upgrade pip python3 -m pip install --upgrade -r requirements.txt +python3 -m pip install --upgrade PyInstaller + +REM ----- Build REM Arno: When adding files here, make sure tribler.nsi actually REM packs them in the installer .EXE diff --git a/build/win/requirements.txt b/build/win/requirements.txt index 3dd795b4eb5..0e568918991 100644 --- a/build/win/requirements.txt +++ b/build/win/requirements.txt @@ -1,4 +1,4 @@ --no-binary :all: -typing_extensions==3.10.0.2 -pydantic==1.8.2 \ No newline at end of file +typing_extensions==4.2.0 +pydantic==1.9.0 diff --git a/requirements-core.txt b/requirements-core.txt index ea35c5499d4..2e08099766c 100644 --- a/requirements-core.txt +++ b/requirements-core.txt @@ -11,16 +11,15 @@ lz4==3.1.3 marshmallow==3.14.1 netifaces==0.11.0 networkx==2.6.3 -pony==0.7.14 +pony==0.7.16 psutil==5.8.0 pyasn1==0.4.8 -pydantic==1.8.2 +pydantic==1.9.0 PyOpenSSL==21.0.0 pyyaml==6.0 sentry-sdk==1.5.0 service-identity==21.1.0 yappi==1.3.3 yarl==1.7.2 # keep this dependency higher than 1.6.3. See: https://github.com/aio-libs/yarl/issues/517 -Faker==9.8.2 -sentry-sdk==1.5.0 -pyipv8==2.8.0 \ No newline at end of file +pyipv8==2.8.0 +libtorrent==1.2.15 diff --git a/requirements-test.txt b/requirements-test.txt index 6402c6ffb51..eed40540517 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,14 +1,14 @@ -r requirements.txt -pytest==6.2.5 -pytest-aiohttp==0.3.0 -pytest-asyncio==0.16.0 -pytest-cov==3.0.0 -pytest-mock==3.6.1 -pytest-randomly==3.10.2 -pytest-timeout==2.0.1 -pytest-xdist==2.4.0 +pytest==7.1.2 +pytest-aiohttp==1.0.4 +pytest-asyncio==0.18.3 +pytest-mock==3.7.0 +pytest-randomly==3.11.0 +pytest-timeout==2.1.0 pytest-freezegun==0.4.2 -freezegun==1.1.0 +freezegun==1.2.1 +coverage==6.3.2 +looptime==0.2 -asynctest==0.13.0 +asynctest==0.13.0 # this library has to be installed to properly work with ipv8 TestBase. \ No newline at end of file diff --git a/src/tribler/core/logger/logger.py b/src/tribler/core/logger/logger.py index a6f66cabe95..042ed0cff20 100644 --- a/src/tribler/core/logger/logger.py +++ b/src/tribler/core/logger/logger.py @@ -63,5 +63,14 @@ def setup_logging(app_mode, log_dir: Path, config_path: Path): logging.config.dictConfig(config) logger.info(f'Config loaded for app_mode={app_mode}') except Exception as e: # pylint: disable=broad-except - print('Error in loading logger config. Using default configs. Error:', e, file=sys.stderr) + error_description = format_error_description(e) + print('Error in loading logger config. Using default configs. ', error_description, file=sys.stderr) logging.basicConfig(level=logging.INFO, stream=sys.stdout) + + +def format_error_description(e: Exception): + result = f'{e.__class__.__name__}: {e}' + cause = e.__cause__ + if cause: + result += f'. Cause: {cause.__class__.__name__}: {cause}' + return result diff --git a/src/tribler/core/logger/logger_streams.py b/src/tribler/core/logger/logger_streams.py index 1ca37ab6df6..0e7008964db 100644 --- a/src/tribler/core/logger/logger_streams.py +++ b/src/tribler/core/logger/logger_streams.py @@ -11,7 +11,10 @@ def __init__(self, stream: TextIO): self.stream = stream def flush(self): - self.stream.flush() + try: + self.stream.flush() + except: + pass def write(self, s: str): try: @@ -22,7 +25,10 @@ def write(self, s: str): self.stream.write(s2) def close(self): - self.stream.close() + try: + self.stream.close() + except: + pass stdout_wrapper = StreamWrapper(sys.stdout) # specified in logger.yaml for `console` handler diff --git a/src/tribler/gui/code_executor.py b/src/tribler/gui/code_executor.py index eee80d8e50e..68ecb2477f1 100644 --- a/src/tribler/gui/code_executor.py +++ b/src/tribler/gui/code_executor.py @@ -27,15 +27,26 @@ class CodeExecutor: def __init__(self, port, shell_variables=None): self.logger = logging.getLogger(self.__class__.__name__) + self.port = port self.tcp_server = QTcpServer() self.sockets = [] self.stack_trace = None - if not self.tcp_server.listen(port=port): + self.shell = Console(locals=shell_variables or {}, logger=self.logger) + self.started = False + + def on_core_connected(self, _): + self.logger.info('Core connected, starting code executor') + + if self.started: + return + + if not self.tcp_server.listen(port=self.port): self.logger.error("Unable to start code execution socket! Error: %s", self.tcp_server.errorString()) else: connect(self.tcp_server.newConnection, self._on_new_connection) - self.shell = Console(locals=shell_variables or {}, logger=self.logger) + self.started = True + self.logger.info('Code executor started') def _on_new_connection(self): self.logger.info("CodeExecutor has new connection") @@ -60,7 +71,7 @@ def run_code(self, code, task_id): pass if self.shell.last_traceback: - self.on_crash(self.shell.last_traceback) + self.on_crash(f'{self.shell.last_traceback}\n\ntask_id: {task_id!r}\ncode:\n{code}\n\n(end of code)') return self.logger.info("Code execution with task %s finished:", task_id) @@ -84,10 +95,12 @@ def _on_socket_read_ready(self): try: code = b64decode(parts[0]).decode('utf8') - task_id = parts[1].replace(b'\n', b'') - self.run_code(code, task_id) except binascii.Error: self.logger.error("Invalid base64 code string received!") + return + + task_id = parts[1].replace(b'\n', b'') + self.run_code(code, task_id) def _on_socket_disconnect(self, socket): def on_socket_disconnect_handler(): diff --git a/src/tribler/gui/tribler_app.py b/src/tribler/gui/tribler_app.py index 51eeddb12b8..97a5ddadf19 100644 --- a/src/tribler/gui/tribler_app.py +++ b/src/tribler/gui/tribler_app.py @@ -50,8 +50,10 @@ def parse_sys_args(self, args): variables.update(locals()) variables['window'] = self.tribler_window self.code_executor = CodeExecutor(5500, shell_variables=variables) + connect(self.tribler_window.events_manager.core_connected, self.code_executor.on_core_connected) connect(self.tribler_window.tribler_crashed, self.code_executor.on_crash) + if '--testnet' in sys.argv[1:]: os.environ['TESTNET'] = "YES" if '--trustchain-testnet' in sys.argv[1:]: diff --git a/src/tribler/gui/tribler_window.py b/src/tribler/gui/tribler_window.py index 4d8b59ebefa..943a331996b 100644 --- a/src/tribler/gui/tribler_window.py +++ b/src/tribler/gui/tribler_window.py @@ -199,8 +199,8 @@ def __init__( self.core_env = core_env error_handler = ErrorHandler(self) - events_manager = EventRequestManager(api_port, api_key, error_handler) - self.core_manager = CoreManager(self.root_state_dir, api_port, api_key, app_manager, events_manager) + self.events_manager = EventRequestManager(api_port, api_key, error_handler) + self.core_manager = CoreManager(self.root_state_dir, api_port, api_key, app_manager, self.events_manager) self.version_history = VersionHistory(self.root_state_dir) self.upgrade_manager = UpgradeManager(self.version_history) self.pending_requests = {} diff --git a/tribler.spec b/tribler.spec index 963a013ebdf..9b1cd071d25 100644 --- a/tribler.spec +++ b/tribler.spec @@ -13,13 +13,7 @@ from PyInstaller.utils.hooks import collect_data_files, collect_submodules root_dir = os.path.abspath(os.path.dirname(__name__)) src_dir = os.path.join(root_dir, "src") - -tribler_components = [ - os.path.join(src_dir, "tribler"), -] - -for component in tribler_components: - sys.path.append(str(component)) +sys.path.append(src_dir) from tribler.core.version import version_id version_str = version_id.split('-')[0] @@ -90,6 +84,7 @@ hiddenimports = [ 'csv', 'dataclasses', # https://github.com/pyinstaller/pyinstaller/issues/5432 'ecdsa', + 'ipv8', 'PIL', 'pkg_resources', # 'pkg_resources.py2_warn', # Workaround PyInstaller & SetupTools, https://github.com/pypa/setuptools/issues/1963 'pyaes', @@ -102,6 +97,7 @@ hiddenimports = [ 'requests', 'scrypt', '_scrypt', 'sqlalchemy', 'sqlalchemy.ext.baked', 'sqlalchemy.ext.declarative', + 'tribler.core.logger.logger_streams', 'typing_extensions', ] + widget_files + pony_deps + get_sentry_hooks()