linux: fix URLs not opening in PyInstaller package

Because PyInstaller modifies the LD_LIBRARY_PATH environment variable
to make things work correctly on Linux, when we try to launch any
subprocess (such as the web browser), that modified variable gets
picked up as well, causing things to go south.

To work around this Linux-only problem, we have to:

1. Save the current value of LD_LIBRARY_PATH
2. Move the value of LD_LIBRARY_PATH_ORIG to LD_LIBRARY_PATH
3. Launch subprocess
4. Restore the saved LD_LIBRARY_PATH again

Reference:

https://pyinstaller.org/en/stable/runtime-information.html#ld-library-path-libpath-considerations

Co-authored-by: DevilXD <bartosz.peszek@gmail.com>
This commit is contained in:
guihkxandDevilXD authored and DevilXD committed 2023-06-11 16:58:18 +02:00
1 parent e31dcd85b4
commit 5162e5c553
2 files changed
+32 -8

No files matched your search

+3 -7
View File
@@ -6,7 +6,6 @@ import sys
import ctypes
import asyncio
import logging
import webbrowser
import tkinter as tk
from pathlib import Path
from collections import abc
@@ -32,7 +31,7 @@ if sys.platform == "win32":
from translate import _
from cache import ImageCache
from exceptions import ExitRequest
from utils import resource_path, set_root_icon, Game, _T
from utils import resource_path, set_root_icon, webopen, Game, _T
from constants import (
SELF_PATH, OUTPUT_FORMATTER, WS_TOPICS_LIMIT, MAX_WEBSOCKETS, WINDOW_TITLE, State
)
@@ -344,10 +343,7 @@ class LinkLabel(ttk.Label):
# W, N, E, S
kwargs["padding"] = (0, 2, 0, 2)
super().__init__(*args, **kwargs)
self.bind("<ButtonRelease-1>", self.webopen(self._link))
def webopen(self, url: str):
return lambda e: webbrowser.open_new_tab(url)
self.bind("<ButtonRelease-1>", lambda e: webopen(self._link))
class SelectMenu(tk.Menubutton, Generic[_T]):
@@ -558,7 +554,7 @@ class LoginForm:
self._manager.print(_("gui", "login", "request"))
await self.wait_for_login_press()
self._manager.print(f"Enter this code on the Twitch's device activation page: {user_code}")
webbrowser.open_new_tab("https://www.twitch.tv/activate")
webopen("https://www.twitch.tv/activate")
def update(self, status: str, user_id: int | None):
if user_id is not None:
+29 -1
View File
@@ -1,11 +1,14 @@
from __future__ import annotations
import os
import sys
import json
import random
import string
import asyncio
import logging
import traceback
import webbrowser
import tkinter as tk
from enum import Enum
from pathlib import Path
@@ -21,7 +24,7 @@ import yarl
from PIL.ImageTk import PhotoImage
from PIL import Image as Image_module
from constants import JsonType
from constants import JsonType, IS_PACKAGED
from exceptions import ExitRequest, ReloadRequest
from constants import _resource_path as resource_path # noqa
@@ -213,6 +216,31 @@ def json_save(path: Path, contents: Mapping[Any, Any], *, sort: bool = False) ->
json.dump(contents, file, default=_serialize, sort_keys=sort, indent=4)
def webopen(url: str):
if IS_PACKAGED and sys.platform == "linux":
# https://pyinstaller.org/en/stable/
# runtime-information.html#ld-library-path-libpath-considerations
# NOTE: All 4 cases need to be handled here: either of the two values can be there or not.
ld_env = "LD_LIBRARY_PATH"
ld_path_curr = os.environ.get(ld_env)
ld_path_orig = os.environ.get(f"{ld_env}_ORIG")
if ld_path_orig is not None:
os.environ[ld_env] = ld_path_orig
elif ld_path_curr is not None:
# pop current
os.environ.pop(ld_env)
webbrowser.open_new_tab(url)
if ld_path_curr is not None:
os.environ[ld_env] = ld_path_curr
elif ld_path_orig is not None:
# pop original
os.environ.pop(ld_env)
else:
webbrowser.open_new_tab(url)
class ExponentialBackoff:
def __init__(
self,