mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-04-03 22:15:40 +00:00
- Implemented a configuration option for enabling or disabling commands across multiple command classes. - Each command now checks its enabled state before execution, improving control over command availability. - Updated the configuration loading mechanism to retrieve the enabled state from the config file for commands like Advert, AQI, Catfact, and others.
180 lines
7.2 KiB
Python
180 lines
7.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Moon Command - Provides moon phase and position information
|
|
"""
|
|
|
|
from .base_command import BaseCommand
|
|
from ..solar_conditions import get_moon
|
|
from ..models import MeshMessage
|
|
|
|
|
|
class MoonCommand(BaseCommand):
|
|
"""Command to get moon information"""
|
|
|
|
# Plugin metadata
|
|
name = "moon"
|
|
keywords = ['moon']
|
|
description = "Get moon phase, rise/set times and position"
|
|
category = "solar"
|
|
|
|
def __init__(self, bot):
|
|
"""Initialize the moon command.
|
|
|
|
Args:
|
|
bot: The bot instance.
|
|
"""
|
|
super().__init__(bot)
|
|
self.moon_enabled = self.get_config_value('Moon_Command', 'enabled', fallback=True, value_type='bool')
|
|
|
|
def can_execute(self, message: MeshMessage) -> bool:
|
|
"""Check if this command can be executed with the given message.
|
|
|
|
Args:
|
|
message: The message triggering the command.
|
|
|
|
Returns:
|
|
bool: True if command is enabled and checks pass, False otherwise.
|
|
"""
|
|
if not self.moon_enabled:
|
|
return False
|
|
return super().can_execute(message)
|
|
|
|
async def execute(self, message: MeshMessage) -> bool:
|
|
"""Execute the moon command.
|
|
|
|
Args:
|
|
message: The message triggering the command.
|
|
|
|
Returns:
|
|
bool: True if executed successfully, False otherwise.
|
|
"""
|
|
try:
|
|
# Get moon information using default location
|
|
moon_info = get_moon()
|
|
|
|
# Format the response to be more compact and readable
|
|
response = self._format_moon_response(moon_info)
|
|
|
|
# Use the unified send_response method
|
|
await self.send_response(message, response)
|
|
return True
|
|
|
|
except Exception as e:
|
|
error_msg = self.translate('commands.moon.error', error=str(e))
|
|
await self.send_response(message, error_msg)
|
|
return False
|
|
|
|
def _translate_phase_name(self, phase_name: str) -> str:
|
|
"""Translate English phase name to localized version.
|
|
|
|
Args:
|
|
phase_name: The English phase name (e.g., 'New Moon').
|
|
|
|
Returns:
|
|
str: The translated phase name, or original if not found.
|
|
"""
|
|
# Map English phase names (with or without emoji) to translation keys
|
|
phase_mapping = {
|
|
'New Moon': 'new_moon',
|
|
'Waxing Crescent': 'waxing_crescent',
|
|
'First Quarter': 'first_quarter',
|
|
'Waxing Gibbous': 'waxing_gibbous',
|
|
'Full Moon': 'full_moon',
|
|
'Waning Gibbous': 'waning_gibbous',
|
|
'Last Quarter': 'last_quarter',
|
|
'Waning Crescent': 'waning_crescent'
|
|
}
|
|
|
|
# Remove emoji if present (they're in the translation)
|
|
phase_clean = phase_name
|
|
for emoji in ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘']:
|
|
phase_clean = phase_clean.replace(emoji, '').strip()
|
|
|
|
# Find matching translation key
|
|
for english_name, translation_key in phase_mapping.items():
|
|
if english_name in phase_clean:
|
|
translated = self.translate(f'commands.moon.phases.{translation_key}')
|
|
# If translation found (not just the key), return it
|
|
if translated != f'commands.moon.phases.{translation_key}':
|
|
return translated
|
|
|
|
# Fallback: return original if no translation found
|
|
return phase_name
|
|
|
|
def _format_moon_response(self, moon_info: str) -> str:
|
|
"""Format moon information to be more compact and readable.
|
|
|
|
Args:
|
|
moon_info: The raw moon info string.
|
|
|
|
Returns:
|
|
str: The formatted response string.
|
|
"""
|
|
try:
|
|
# Parse the moon info string to extract key information
|
|
lines = moon_info.split('\n')
|
|
moon_data = {}
|
|
|
|
for line in lines:
|
|
if ':' in line:
|
|
key, value = line.split(':', 1)
|
|
moon_data[key.strip()] = value.strip()
|
|
|
|
# Create a more compact format while keeping essential details
|
|
if 'MoonRise' in moon_data and 'Set' in moon_data and 'Phase' in moon_data:
|
|
# Keep day info but make it more compact
|
|
rise_info = moon_data['MoonRise'] # e.g., "Thu 04 06:47PM"
|
|
set_info = moon_data['Set'] # e.g., "Fri 05 03:43AM"
|
|
|
|
# Extract phase and illumination
|
|
phase_info = moon_data.get('Phase', self.translate('commands.moon.unknown_phase'))
|
|
if '@:' in phase_info:
|
|
phase, illum = phase_info.split('@:')
|
|
phase = phase.strip()
|
|
illum = illum.strip()
|
|
# Translate the phase name
|
|
phase = self._translate_phase_name(phase)
|
|
else:
|
|
phase = phase_info
|
|
phase = self._translate_phase_name(phase)
|
|
illum = self.translate('commands.moon.unknown_illum')
|
|
|
|
# Add next full and new moon dates (compact format)
|
|
if 'FullMoon' in moon_data and 'NewMoon' in moon_data:
|
|
full_moon = moon_data['FullMoon'] # e.g., "Sun Sep 07 11:08AM"
|
|
new_moon = moon_data['NewMoon'] # e.g., "Sun Sep 21 12:54PM"
|
|
|
|
# Extract just the essential date/time parts
|
|
full_parts = full_moon.split()
|
|
new_parts = new_moon.split()
|
|
|
|
if len(full_parts) >= 3 and len(new_parts) >= 3:
|
|
# Format: "Sep 07 11:08AM" and "Sep 21 12:54PM"
|
|
full_compact = f"{full_parts[1]} {full_parts[2]} {full_parts[3]}"
|
|
new_compact = f"{new_parts[1]} {new_parts[2]} {new_parts[3]}"
|
|
# Create compact response with full/new moon dates
|
|
return self.translate('commands.moon.format_with_dates',
|
|
phase=phase, illum=illum,
|
|
rise=rise_info, set=set_info,
|
|
full=full_compact, new=new_compact)
|
|
|
|
# Create compact response without full/new moon dates
|
|
return self.translate('commands.moon.format',
|
|
phase=phase, illum=illum,
|
|
rise=rise_info, set=set_info)
|
|
else:
|
|
# Fallback to original format if parsing fails
|
|
return self.translate('commands.moon.fallback', info=moon_info)
|
|
|
|
except Exception as e:
|
|
# Fallback to original format if formatting fails
|
|
return self.translate('commands.moon.fallback', info=moon_info)
|
|
|
|
def get_help_text(self) -> str:
|
|
"""Get help text for this command.
|
|
|
|
Returns:
|
|
str: The help text for this command.
|
|
"""
|
|
return self.description
|