auth fallback as wawi plugin sometimes forgets passwords

This commit is contained in:
2026-04-11 11:34:39 -04:00
parent f8300c9a1f
commit ebfb990aca
3 changed files with 33 additions and 5 deletions

View File

@@ -85,6 +85,9 @@ busctl --user call org.mpris.MediaPlayer2.winamp /org/mpris/MediaPlayer2 org.mpr
- **`winamp_mpris_old.py`**: A previous iteration of the bridge. - **`winamp_mpris_old.py`**: A previous iteration of the bridge.
- **`sample_Winamp Web Interface.html`**: A sample of the HTML returned by the Winamp Web Interface, used for reference in parsing logic. - **`sample_Winamp Web Interface.html`**: A sample of the HTML returned by the Winamp Web Interface, used for reference in parsing logic.
> [!NOTE]
> The source code in `Wawi Source/` and `gen_httpSrv_systray/` is provided for reference only. The bridge currently interacts with the compiled binaries.
## Development Conventions ## Development Conventions
- **D-Bus Interface:** Defined via XML introspection string within the `WinampMPRIS` class. - **D-Bus Interface:** Defined via XML introspection string within the `WinampMPRIS` class.

1
bridge.pid Normal file
View File

@@ -0,0 +1 @@
3051439

View File

@@ -14,6 +14,7 @@ from bs4 import BeautifulSoup
# --- CONFIGURATION & XDG PATHS --- # --- CONFIGURATION & XDG PATHS ---
BASE_URL = "http://localhost:5666" BASE_URL = "http://localhost:5666"
AUTH = ('winamp', 'llama') AUTH = ('winamp', 'llama')
POSSIBLE_CREDS = [('winamp', 'llama'), ('winamp', ''), None]
APP_ID = "org.mpris.MediaPlayer2.winamp" APP_ID = "org.mpris.MediaPlayer2.winamp"
DEFAULT_ART = "https://webamp.org/favicon.ico" DEFAULT_ART = "https://webamp.org/favicon.ico"
@@ -39,6 +40,29 @@ logging.basicConfig(
) )
logger = logging.getLogger("winamp-mpris") logger = logging.getLogger("winamp-mpris")
def authenticated_get(url, timeout=2):
"""Helper to perform GET with authentication fallback."""
global AUTH
try:
r = requests.get(url, auth=AUTH, timeout=timeout)
if r.status_code != 401:
return r
except requests.RequestException as e:
raise e
for cred in POSSIBLE_CREDS:
if cred == AUTH:
continue
try:
r = requests.get(url, auth=cred, timeout=timeout)
if r.status_code != 401:
logger.info(f"Authentication fallback successful: switched to {cred}")
AUTH = cred
return r
except requests.RequestException:
continue
return r
def write_pid_file(): def write_pid_file():
try: try:
with open(PID_FILE, "w") as f: with open(PID_FILE, "w") as f:
@@ -127,9 +151,9 @@ class WinampMPRIS:
def _request(self, endpoint): def _request(self, endpoint):
logger.info(f"COMMAND RECEIVED: {endpoint}") logger.info(f"COMMAND RECEIVED: {endpoint}")
try: try:
r = requests.get(f"{BASE_URL}/{endpoint}", auth=AUTH, timeout=2) r = authenticated_get(f"{BASE_URL}/{endpoint}", timeout=2)
if r.status_code == 401: if r.status_code == 401:
msg = "401 Unauthorized: Check gen_httpsrv.dll plugin config. Ensure user 'winamp' has correct password and 'Play' permissions in Users tab." msg = "401 Unauthorized: All authentication attempts failed (winamp:llama, winamp:, anon). Check plugin config."
logger.warning(f"ERROR: {msg}") logger.warning(f"ERROR: {msg}")
subprocess.run(["notify-send", "-u", "critical", "-t", "10000", "Winamp Bridge Auth Error", msg]) subprocess.run(["notify-send", "-u", "critical", "-t", "10000", "Winamp Bridge Auth Error", msg])
elif r.status_code != 200: elif r.status_code != 200:
@@ -334,7 +358,7 @@ def update_loop(player):
# 2. Poll Web UI (Status and Time source) # 2. Poll Web UI (Status and Time source)
try: try:
r = requests.get(f"{BASE_URL}/main", auth=AUTH, timeout=1) r = authenticated_get(f"{BASE_URL}/main", timeout=1)
if r.status_code == 200: if r.status_code == 200:
offline_logged = False offline_logged = False
auth_error_logged = False auth_error_logged = False
@@ -396,12 +420,12 @@ def update_loop(player):
player._album = "" player._album = ""
elif r.status_code == 401: elif r.status_code == 401:
if not auth_error_logged: if not auth_error_logged:
msg = "401 Unauthorized: Check gen_httpsrv.dll plugin config. Ensure user 'winamp' has correct password and 'Play' permissions in Users tab." msg = "401 Unauthorized: All authentication attempts failed (winamp:llama, winamp:, anon). Check plugin config."
logger.warning(f"ERROR: {msg}") logger.warning(f"ERROR: {msg}")
subprocess.run(["notify-send", "-u", "critical", "-t", "10000", "Winamp Bridge Auth Error", msg]) subprocess.run(["notify-send", "-u", "critical", "-t", "10000", "Winamp Bridge Auth Error", msg])
auth_error_logged = True auth_error_logged = True
player._status = "Stopped" player._status = "Stopped"
except requests.exceptions.RequestException: except requests.RequestException:
if not window_title: if not window_title:
if not offline_logged: if not offline_logged:
logger.info("Winamp Web Interface offline and no window found.") logger.info("Winamp Web Interface offline and no window found.")