initial re-implementation of basic debugging
This commit is contained in:
parent
afff3d1161
commit
0face72fd4
188
main.py
188
main.py
@ -303,7 +303,38 @@ class IcecastBot:
|
||||
Returns:
|
||||
bool: True if the song should be announced, False if it matches any ignore patterns.
|
||||
"""
|
||||
return not any(pattern.lower() in song.lower() for pattern in self.ignore_patterns)
|
||||
try:
|
||||
if not song:
|
||||
print("Empty song title, not announcing")
|
||||
return False
|
||||
|
||||
if not self.ignore_patterns:
|
||||
print("No ignore patterns configured, announcing all songs")
|
||||
return True
|
||||
|
||||
# Check each pattern
|
||||
for pattern in self.ignore_patterns:
|
||||
try:
|
||||
if not pattern:
|
||||
continue
|
||||
if not isinstance(pattern, str):
|
||||
print(f"Invalid ignore pattern (not a string): {pattern}")
|
||||
continue
|
||||
if pattern.lower() in song.lower():
|
||||
print(f"Song '{song}' matched ignore pattern '{pattern}', not announcing")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Error checking ignore pattern '{pattern}': {str(e)}")
|
||||
continue
|
||||
|
||||
print(f"Song '{song}' passed all ignore patterns, will announce")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Exception in should_announce_song: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
# Default to not announcing if there's an error
|
||||
return False
|
||||
|
||||
def setup_handlers(self):
|
||||
"""Set up all IRC event handlers and command patterns.
|
||||
@ -731,6 +762,7 @@ class IcecastBot:
|
||||
str: The current song title, or an error message if fetching failed.
|
||||
"""
|
||||
try:
|
||||
print(f"Fetching metadata from {self.stream_url}/{self.stream_endpoint}")
|
||||
# Try different URL patterns
|
||||
base_urls = [
|
||||
self.stream_url, # Original URL
|
||||
@ -741,33 +773,53 @@ class IcecastBot:
|
||||
for base_url in base_urls:
|
||||
try:
|
||||
url = f"{base_url}/status-json.xsl"
|
||||
print(f"Trying URL: {url}")
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as response:
|
||||
async with session.get(url, timeout=10) as response:
|
||||
if response.status == 200:
|
||||
data = await response.text()
|
||||
print(f"Received response from {url}")
|
||||
|
||||
try:
|
||||
json_data = json.loads(data)
|
||||
if 'icestats' in json_data:
|
||||
sources = json_data['icestats'].get('source', [])
|
||||
if not isinstance(sources, list):
|
||||
sources = [sources]
|
||||
|
||||
# Find our stream
|
||||
for src in sources:
|
||||
if src.get('listenurl', '').endswith(self.stream_endpoint):
|
||||
title = src.get('title') or src.get('song') or src.get('current_song')
|
||||
if title:
|
||||
print(f"Found title: {title}")
|
||||
return title
|
||||
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"JSON decode error for {url}: {str(e)}")
|
||||
continue
|
||||
|
||||
json_data = json.loads(data)
|
||||
if 'icestats' in json_data:
|
||||
sources = json_data['icestats'].get('source', [])
|
||||
if not isinstance(sources, list):
|
||||
sources = [sources]
|
||||
|
||||
# Find our stream
|
||||
for src in sources:
|
||||
if src.get('listenurl', '').endswith(self.stream_endpoint):
|
||||
title = src.get('title') or src.get('song') or src.get('current_song')
|
||||
if title:
|
||||
return title
|
||||
|
||||
except aiohttp.ClientError as e:
|
||||
print(f"Client error for {url}: {str(e)}")
|
||||
continue
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"JSON decode error for {url}: {str(e)}")
|
||||
continue
|
||||
except asyncio.TimeoutError:
|
||||
print(f"Timeout fetching metadata from {url}")
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"Unexpected error fetching from {url}: {str(e)}")
|
||||
continue
|
||||
|
||||
print("All URL patterns failed, returning 'Unable to fetch metadata'")
|
||||
return "Unable to fetch metadata"
|
||||
except Exception as e:
|
||||
return "Error fetching metadata"
|
||||
print(f"Exception in fetch_json_metadata: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return f"Error fetching metadata: {str(e)}"
|
||||
|
||||
async def monitor_metadata(self):
|
||||
"""Monitor the Icecast stream for metadata changes.
|
||||
@ -826,14 +878,45 @@ class IcecastBot:
|
||||
|
||||
# Look for metadata marker but fetch from JSON
|
||||
if b"StreamTitle='" in buffer:
|
||||
new_song = await self.fetch_json_metadata()
|
||||
if new_song and new_song != self.current_song and "Unable to fetch metadata" not in new_song:
|
||||
self.current_song = new_song
|
||||
await self.announce_song(new_song)
|
||||
try:
|
||||
print("Detected StreamTitle marker in buffer, fetching metadata")
|
||||
new_song = await self.fetch_json_metadata()
|
||||
|
||||
# Check if we should announce the song
|
||||
if new_song and new_song != self.current_song and "Unable to fetch metadata" not in new_song:
|
||||
print(f"Song changed from '{self.current_song}' to '{new_song}'")
|
||||
self.current_song = new_song
|
||||
|
||||
# Try to announce the song
|
||||
try:
|
||||
await self.announce_song(new_song)
|
||||
except Exception as e:
|
||||
print(f"Error announcing song: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
# No song change or unable to fetch metadata
|
||||
print(f"No song change detected or unable to fetch metadata: {new_song}")
|
||||
|
||||
# Clear buffer after metadata marker
|
||||
buffer = buffer[buffer.find(b"';", buffer.find(b"StreamTitle='")) + 2:]
|
||||
last_json_check = current_time
|
||||
# Clear buffer after metadata marker
|
||||
marker_pos = buffer.find(b"StreamTitle='")
|
||||
end_pos = buffer.find(b"';", marker_pos)
|
||||
if end_pos > marker_pos:
|
||||
buffer = buffer[end_pos + 2:]
|
||||
print("Buffer cleared after metadata marker")
|
||||
else:
|
||||
print(f"Could not find end of metadata marker, truncating buffer")
|
||||
buffer = buffer[-8192:] # Keep last 8KB to avoid losing the end marker
|
||||
|
||||
# Update last check time
|
||||
last_json_check = current_time
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing metadata marker: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
# Reset buffer to avoid getting stuck in a loop
|
||||
buffer = b""
|
||||
|
||||
# Keep buffer size reasonable
|
||||
if len(buffer) > 65536:
|
||||
@ -841,14 +924,34 @@ class IcecastBot:
|
||||
|
||||
# Fallback JSON check if ICY updates aren't coming through
|
||||
if current_time - last_json_check >= json_check_interval:
|
||||
new_song = await self.fetch_json_metadata()
|
||||
if "Unable to fetch metadata" in new_song:
|
||||
if time.time() - last_data_received > data_timeout:
|
||||
break
|
||||
if new_song and new_song != self.current_song:
|
||||
self.current_song = new_song
|
||||
await self.announce_song(new_song)
|
||||
last_json_check = current_time
|
||||
try:
|
||||
print("Performing fallback JSON check")
|
||||
new_song = await self.fetch_json_metadata()
|
||||
|
||||
if "Unable to fetch metadata" in new_song:
|
||||
print("Unable to fetch metadata in fallback check")
|
||||
if time.time() - last_data_received > data_timeout:
|
||||
print("Data timeout exceeded, breaking loop")
|
||||
break
|
||||
elif new_song and new_song != self.current_song:
|
||||
print(f"Song changed in fallback check from '{self.current_song}' to '{new_song}'")
|
||||
self.current_song = new_song
|
||||
try:
|
||||
await self.announce_song(new_song)
|
||||
except Exception as e:
|
||||
print(f"Error announcing song in fallback check: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
print(f"No song change detected in fallback check: {new_song}")
|
||||
|
||||
last_json_check = current_time
|
||||
except Exception as e:
|
||||
print(f"Error in fallback JSON check: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
# Still update the check time to avoid rapid retries
|
||||
last_json_check = current_time
|
||||
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
@ -888,12 +991,31 @@ class IcecastBot:
|
||||
- The announcement format is configured
|
||||
"""
|
||||
try:
|
||||
print(f"Attempting to announce song: {song}")
|
||||
if self.channel and self.should_announce_song(song):
|
||||
print(f"Song passed filters, preparing to announce")
|
||||
# Use the stored channel object directly
|
||||
if hasattr(self.channel, 'name') and self.channel.name.startswith('#'):
|
||||
await self.channel.message(self.reply.format(song=song))
|
||||
try:
|
||||
formatted_message = self.reply.format(song=song)
|
||||
print(f"Sending message to channel {self.channel.name}: {formatted_message}")
|
||||
await self.channel.message(self.reply.format(song=song))
|
||||
print(f"Successfully announced song: {song}")
|
||||
except Exception as e:
|
||||
print(f"Error sending message to channel: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
print(f"Channel object invalid or not a channel: {self.channel}")
|
||||
else:
|
||||
if not self.channel:
|
||||
print("Channel object is None or invalid")
|
||||
elif not self.should_announce_song(song):
|
||||
print(f"Song '{song}' matched ignore patterns, not announcing")
|
||||
except Exception as e:
|
||||
pass
|
||||
print(f"Exception in announce_song: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
async def start(self):
|
||||
"""Start the IRC bot and begin processing events."""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user