The AccessiWeather sound pack system provides customizable audio notifications for weather events and application interactions. This system is designed with accessibility in mind, offering users the ability to choose from different sound themes or create their own custom sound packs.
The sound pack system consists of several key components:
- Sound Player (
sound_player.py) - Core functionality for playing sounds - Sound Pack Manager Dialog (
soundpack_manager_dialog.py) - GUI for managing sound packs - Sound Pack Installer (
sound_pack_installer.py) - Installation and management utilities - Built-in Sound Packs - Default pack ships with the app; additional packs are available via the Sound Pack Manager
Each sound pack is a directory containing:
pack.json- Metadata and sound file mappings- Audio files (
.wavformat recommended)
{
"name": "Display Name",
"author": "Author Name",
"description": "Pack description",
"version": "1.0.0",
"sounds": {
"alert": "alert_sound.wav",
"notify": "notification_sound.wav",
"error": "error_sound.wav",
"success": "success_sound.wav"
}
}Soundpack creators can specify default volume levels for individual sounds. This is particularly useful for accessibility, allowing critical alerts to be balanced with screen reader output.
Volume values range from 0.0 (silent) to 1.0 (full volume). If not specified, sounds default to 1.0.
Inline Format - Volume specified directly in the sound entry:
{
"name": "Accessible Pack",
"sounds": {
"alert": {"file": "alert.wav", "volume": 0.8},
"critical_alert": {"file": "critical_alert.wav", "volume": 0.7},
"notify": "notify.wav"
}
}Separate Volumes Section - Volume specified in a separate volumes object:
{
"name": "Accessible Pack",
"sounds": {
"alert": "alert.wav",
"critical_alert": "critical_alert.wav",
"notify": "notify.wav"
},
"volumes": {
"alert": 0.8,
"critical_alert": 0.7
}
}Both formats can be mixed - inline volume takes precedence if specified.
Note: Volume control requires the sound_lib backend. If only playsound3 is available, volume settings are logged but not applied.
alert- Weather alerts and important notificationsnotify- General notificationserror- Error conditions and failuressuccess- Successful operationsstartup- Application startup soundexit- Application exit sound
AccessiWeather supports specific sound mappings for different types of weather alerts:
tornado_warning- Tornado warnings (highest priority)thunderstorm_warning- Severe thunderstorm warningsflood_warning- Flood warningsheat_advisory- Heat advisories and excessive heat warningswinter_storm_warning- Winter storm warningshurricane_warning- Hurricane warningswind_warning- High wind warningsfire_warning- Fire weather warningsair_quality_alert- Air quality alertsfog_advisory- Dense fog advisoriesice_warning- Ice storm warningssnow_warning- Heavy snow warningsdust_warning- Dust storm warningswarning- Generic severe weather warningswatch- Generic weather watches
Only the Default pack ships with the app. You can install additional packs (including nature and minimal) via the Sound Pack Manager or by importing ZIP files.
- Standard system sounds
- Balanced volume and tone
- Suitable for most users
- Bird chirps for alerts
- Water drops for notifications
- Distant thunder for errors
- Gentle rain for success
- Subtle beeps and chimes
- Low volume, unobtrusive
- Ideal for quiet environments
from accessiweather.notifications.sound_player import play_notification_sound
# Play an alert sound using the default pack
play_notification_sound("alert", "default")
# Play a notification sound using the nature pack
play_notification_sound("notify", "nature")from accessiweather.notifications.sound_pack_installer import SoundPackInstaller
from pathlib import Path
installer = SoundPackInstaller(Path("soundpacks"))
# Install from ZIP file
success, message = installer.install_from_zip(Path("my_pack.zip"), "my_pack")
# Create a new pack template
pack_info = {
"name": "My Custom Pack",
"author": "Your Name",
"description": "Custom sound pack"
}
success, message = installer.create_pack_template("custom", pack_info)
# List installed packs
packs = installer.list_installed_packs()
# Export a pack
success, message = installer.export_pack("my_pack", Path("exported.zip"))
# Uninstall a pack
success, message = installer.uninstall_pack("my_pack")from accessiweather.notifications.sound_player import get_available_sound_packs
packs = get_available_sound_packs()
for pack_id, pack_info in packs.items():
print(f"{pack_info['name']} by {pack_info['author']}")The sound pack system is integrated into the main application settings:
- Sound Pack Selection - Dropdown to choose active sound pack
- Preview Button - Test sounds from selected pack
- Manage Sound Packs - Opens the sound pack manager dialog
The sound pack manager provides a GUI for:
- Viewing installed sound packs
- Previewing sounds from different packs
- Selecting the active sound pack
- Installing new packs from ZIP files
- Deleting unwanted packs
- Viewing pack information and sound lists
- Use
SoundPackInstaller.create_pack_template()to create a basic structure - Replace the placeholder
.wavfiles with your custom sounds - Update the
pack.jsonmetadata as needed
- Create a new directory in the soundpacks folder
- Add a
pack.jsonfile with required metadata - Add audio files referenced in the sounds mapping
- Ensure all sound files exist and are playable
- Create a ZIP file containing
pack.jsonand audio files - Use the sound pack manager or installer to import the ZIP
- The system will validate and install the pack automatically
AccessiWeather features a frictionless community submission system that allows users to share their custom sound packs with the community without requiring any GitHub account setup or authentication barriers.
The community submission system is designed to be completely barrier-free:
- No GitHub Account Required: Users can submit packs without creating external accounts
- No Authentication Setup: No tokens, passwords, or OAuth flows required
- One-Click Sharing: Simple "Share with Community" button in the sound pack manager
- Optional Attribution: Users can provide their name/email for recognition or submit completely anonymously
- Create Your Pack: Build a custom sound pack using any of the creation methods above
- Open Sound Pack Manager: Access the pack manager from the main settings
- Select Your Pack: Choose the custom pack you want to share
- Click "Share with Community": No setup or authentication required
- Optional Attribution: Dialog appears asking for optional name/email for community recognition
- Submit: Pack is automatically submitted to the community repository
The frictionless experience is powered by GitHub App authentication that handles all technical complexity:
- AccessiBot Integration: Uses AccessiBot (GitHub App) credentials for all GitHub operations
- Secure Backend Auth: JWT-based authentication with GitHub's App API
- Professional Workflow: Creates proper pull requests with full attribution and documentation
- Automated Processing: Handles fork creation, branch management, file uploads, and PR creation
The community submission is handled by the PackSubmissionService class, which provides two main methods:
from accessiweather.services.pack_submission_service import PackSubmissionService
service = PackSubmissionService(
repo_owner="orinks",
repo_name="accessiweather-soundpacks",
dest_subdir="packs",
config_manager=config_manager
)
# Submit pack with GitHub App authentication
pr_url = await service.submit_pack(pack_path, pack_metadata)# Submit pack anonymously with optional attribution
pr_url = await service.submit_pack_anonymous(
pack_path,
pack_metadata,
submitter_name="John Doe", # Optional
submitter_email="john@example.com", # Optional
progress_callback=progress_callback
)The submission service uses GitHubAppClient for secure authentication:
from accessiweather.services.github_app_client import GitHubAppClient
# Create GitHub App client
client = GitHubAppClient(
app_id=app_id,
private_key_pem=private_key,
installation_id=installation_id,
user_agent="AccessiWeather/0.9.4-dev"
)
# Perform authenticated API requests
repo_info = await client.github_request("GET", "/repos/accessiweather-community/soundpacks")- JWT Generation: Creates signed JWT token using GitHub App private key
- Installation Token: Exchanges JWT for installation access token via
/app/installations/{id}/access_tokens - Resource Access: Uses installation token for all repository operations
- Proper Auth Schemes:
Authorization: Bearer <jwt>for GitHub App endpointsAuthorization: token <token>for resource endpoints
The community submission system maintains strong security practices:
- Optional Attribution: Users choose whether to provide identifying information
- Clear Privacy Messaging: Users understand exactly how attribution information is used
- Anonymous Submission Support: Complete anonymity option available
- No User Credentials: No storage or transmission of user GitHub credentials
- Backend Authentication: All GitHub operations use secure App authentication
- Validation: Comprehensive pack validation before submission
- Duplicate Detection: Prevents submission of existing packs
- Pack Completeness: Ensures all required sounds and metadata are present
- Content Quality: Validates audio files and pack structure
- User-Friendly Messages: Clear guidance on improving pack quality rather than technical errors
- Connection Issues: Clear messaging when GitHub is unavailable
- Validation Failures: Specific guidance on fixing pack issues
- Cancellation Support: Users can cancel submission at any point
The community submission system includes comprehensive testing:
- GitHub App Authentication: Mock JWT generation and token exchange
- Anonymous Submission Flow: Full workflow testing with attribution metadata
- Error Scenarios: Validation failures, network issues, cancellation
- Fork Management: Installation-based fork creation and management
- Duplicate Detection: Preflight checks for existing packs
# Test community submission functionality
pytest tests/test_sound_pack_system_submission.py
# Test with verbose output
pytest tests/test_sound_pack_system_submission.py -v
# Test specific scenarios
pytest tests/test_sound_pack_system_submission.py::test_submit_pack_anonymous_comprehensive- Format: WAV files recommended for best compatibility
- Duration: Keep sounds short (1-3 seconds) for notifications
- Volume: Normalize volume levels across all sounds in a pack
- Quality: 16-bit, 44.1kHz recommended for good quality/size balance
The sound pack system includes robust error handling:
- Missing Sound Files: Falls back to default pack
- Invalid pack.json: Logs error and uses default pack
- Corrupted Audio: Gracefully handles playback failures
- Missing Packs: Always provides default pack as fallback
- Screen Reader Support: All UI elements properly labeled
- Keyboard Navigation: Full keyboard access to all functions
- Sound Previews: Test sounds before applying changes
- Clear Feedback: Status messages for all operations
- Fallback Behavior: Ensures sounds always work
The sound pack system includes comprehensive tests covering all functionality:
- Unit Tests: Individual component testing
- Integration Tests: End-to-end workflow testing
- Dialog Tests: UI component testing with Toga dummy backend
- Error Handling Tests: Validation and fallback testing
- GitHub App Authentication: JWT generation and installation token exchange
- Anonymous Submission Flow: Full workflow with attribution metadata
- Error Scenarios: Validation failures, network issues, and cancellation
- Fork Management: Installation-based repository operations
- Duplicate Detection: Preflight checks for existing community packs
# Core sound pack system tests
pytest tests/test_sound_pack_system.py
pytest tests/test_sound_pack_installer.py
pytest tests/test_sound_pack_integration.py
# Community submission tests
pytest tests/test_sound_pack_system_submission.py
# Run all sound pack tests
pytest tests/test_sound_pack*.py
# Verbose output for debugging
pytest tests/test_sound_pack_system_submission.py -v- Sound Packs:
soundpacks/ - Core Module:
src/accessiweather/notifications/sound_player.py - Manager Dialog:
src/accessiweather/dialogs/soundpack_manager_dialog.py - Installer:
src/accessiweather/notifications/sound_pack_installer.py
- Submission Service:
src/accessiweather/services/pack_submission_service.py - GitHub App Client:
src/accessiweather/services/github_app_client.py
- Core Tests:
tests/test_sound_pack_*.py - Submission Tests:
tests/test_sound_pack_system_submission.py
- playsound: Audio playback functionality
- toga: GUI framework for dialogs
- pathlib: File system operations
- json: Pack metadata handling
- zipfile: Pack import/export functionality
- httpx: HTTP client for GitHub API requests
- cryptography: JWT signing for GitHub App authentication
- asyncio: Asynchronous operation support
Potential improvements for the sound pack system:
- Online Pack Repository: Download packs from a central repository
- Volume Controls: Per-pack volume adjustment
- Sound Mixing: Layer multiple sounds for complex notifications
- Format Support: Support for MP3, OGG, and other audio formats
- Pack Validation: More comprehensive validation rules
- Pack Signing: Digital signatures for trusted packs
- Accessibility Enhancements: Audio descriptions for sound packs
- Localization: Multi-language pack descriptions
Sounds not playing:
- Check if playsound is installed:
pip install playsound - Verify audio files exist and are not corrupted
- Check system audio settings and volume
Pack installation fails:
- Ensure ZIP file contains valid pack.json
- Check that all referenced sound files exist in the ZIP
- Verify pack.json has required fields (name, sounds)
Dialog not opening:
- Check for Toga installation issues
- Verify all UI components are properly initialized
- Look for error messages in application logs
Enable debug logging to troubleshoot issues:
import logging
logging.getLogger('accessiweather.notifications').setLevel(logging.DEBUG)This will provide detailed information about sound pack loading, file operations, and error conditions.