This is an old revision of the document!
Table of Contents
ELF - Elfish Log Factory
Overview
ELF (Elfish Log Factory) is a modern, web-based commercial traffic scheduling system designed specifically for broadcast radio stations. It provides comprehensive tools for managing advertisers, campaigns, commercials, and daily schedules with seamless integration to Rivendell Radio Automation.
The project was created to provide small and medium-sized radio stations with a free, professional-grade traffic scheduling solution that can be self-hosted or offered as a cloud-based SaaS service. ELF handles the complete workflow from campaign creation through auto-scheduling to exporting logs in Rivendell-compatible formats.
Key Capabilities:
- Multi-station management with separate configurations
- Advertiser and campaign management
- Intelligent auto-scheduling with rotation and separation rules
- Rivendell cart inventory synchronization
- Export logs in column-aligned ASCII format for Rivendell import
- Daypart-based scheduling (Morning Drive, Midday, etc.)
- Competitive separation rules to prevent conflicts
- RESTful API for all operations
Status
| Item | Value |
|---|---|
| Current Phase | Active Development (MVP Phase 1) |
| Platform | Cross-platform (Linux primary, Ubuntu 24.04 recommended) |
| Backend Language | Python 3.11+ (Django 5.0) |
| Frontend Language | JavaScript (React 18) |
| Database | PostgreSQL 16 |
| License | MIT (intended for open-source release) |
| Version | 1.0.0-alpha |
| Primary Integration | Rivendell Radio Automation |
Goals
Primary Goals
- Free Traffic System: Provide small/medium radio stations with professional traffic scheduling at no cost
- Rivendell Integration: Seamless bi-directional integration with Rivendell automation systems
- Ease of Use: Modern, intuitive web interface requiring minimal training
- Multi-Station Support: Single installation can manage multiple radio stations
Secondary Goals
- Auto-Scheduling Intelligence: Smart algorithms for optimal commercial placement
- Separation Rules: Automatic enforcement of competitive separation policies
- Hybrid Deployment: Support both self-hosted and cloud-based SaaS models
- Extensibility: Plugin architecture for additional music schedulers and automation systems
Long-Term Goals
- Network Scheduling: Chain-wide campaign management across multiple markets
- Advanced Analytics: Performance reporting and business intelligence
- Music Scheduler Integration: Support for MusicMaster, Selector, and other systems
- Mobile Applications: Native iOS/Android apps for on-the-go management
- AI-Powered Optimization: Machine learning for schedule optimization and recommendations
Architecture
System Design
ELF follows a modern, decoupled three-tier architecture:
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β React βββββββΆβ Django βββββββΆβ PostgreSQL β
β Frontend β HTTP β REST API β SQL β Database β
β (Port 5173)ββββββββ (Port 9000) ββββββββ β
βββββββββββββββ JSON ββββββββββββββββ βββββββββββββββ
β
β MySQL
βΌ
ββββββββββββββββ
β Rivendell β
β Database β
ββββββββββββββββ
β
βΌ
ββββββββββββββββ
β Export Logs β
β (ASCII) β
ββββββββββββββββ
Technology Stack
Backend:
- Framework: Django 5.0 with Django REST Framework
- Database: PostgreSQL 16 (primary), MySQL client (Rivendell sync)
- Authentication: JWT tokens with session fallback
- Server: Gunicorn (production), Django dev server (development)
- API Documentation: DRF Spectacular (OpenAPI/Swagger)
Frontend:
- Framework: React 18 with Vite build tool
- UI Library: Tailwind CSS for styling
- Routing: React Router DOM
- State Management: TanStack Query (React Query)
- HTTP Client: Axios
Infrastructure:
- Web Server: Nginx (reverse proxy)
- Containerization: Docker & Docker Compose
- OS: Ubuntu 24.04 LTS (primary target)
- Deployment: Rumble Cloud (planned for SaaS)
Database Schema
Core Models:
- Station: Radio station configuration, Rivendell connection settings
- Advertiser: Client/agency information, industry categorization
- Campaign: Flight dates, spot count, contract tracking
- Commercial: Individual spots with cart numbers and lengths
- DayPart: Time segments (Morning Drive, Midday, etc.)
- DailySchedule: Container for each day's schedule
- ScheduledSpot: Individual spot placements with times
- RivendellCart: Synced cart inventory from Rivendell
- SchedulingRule: Auto-scheduling rules (daypart, separation)
- SeparationRule: Competitive separation policies
API Structure
RESTful Endpoints:
Stations: /api/stations/ Advertisers: /api/advertisers/ Campaigns: /api/campaigns/ Commercials: /api/commercials/ DayParts: /api/dayparts/ Daily Schedules: /api/daily-schedules/ Scheduled Spots: /api/scheduled-spots/ Rivendell Carts: /api/rivendell-carts/ Separation Rules: /api/separation-rules/ Custom Actions: POST /api/sync-rivendell/ - Sync cart inventory POST /api/export-log/ - Export daily log POST /api/auto-schedule/ - Auto-schedule campaign
Rivendell Integration
Cart Synchronization:
- Connects to Rivendell MySQL database
- Reads CART table for commercial inventory
- Syncs cart numbers, titles, lengths, groups
- Can filter by group (e.g., βCOMMβ for commercials)
Export Format (Column-Aligned ASCII):
HH:MM:SS CCCCCC TITLE_60_CHARS_WIDE MM:SS 08:15:00 001234 Joe's Pizza - February Special 00:30 08:47:00 001235 Smith Auto - Winter Clearance Sale 01:00 09:23:00 001236 Main Street Restaurant - Lunch Special 00:30
Import Process:
- ELF exports to configured path (e.g., /var/elf/exports/20240208.txt)
- Rivendell's RDLogManager imports via configured template
- Merges with music schedule from RDLibrary
Development
Prerequisites
System Requirements:
- Ubuntu 24.04 LTS (or similar Linux distribution)
- Python 3.11 or higher
- Node.js 18 or higher
- PostgreSQL 16
- Nginx (for production)
- Git
Optional:
- Docker & Docker Compose (for containerized deployment)
- Rivendell Radio Automation (for testing integration)
Quick Start
Clone and Setup:
# Clone repository git clone <repository-url> cd elf-project # Run quick start script chmod +x quickstart.sh ./quickstart.sh # Start backend (Terminal 1) cd backend source venv/bin/activate python manage.py runserver 0.0.0.0:9000 # Start frontend (Terminal 2) cd frontend npm run dev
Access Points:
- Frontend: http://localhost:5173
- Backend API: http://localhost:9000/api
- Django Admin: http://localhost:9000/admin
- API Documentation: http://localhost:9000/api/docs
Development Setup
Backend Setup:
cd backend # Create virtual environment python3 -m venv venv source venv/bin/activate # Install dependencies pip install -r requirements.txt # Configure database cp .env.example .env # Edit .env with your settings # Initialize database python manage.py migrate python manage.py createsuperuser python manage.py collectstatic --noinput
Frontend Setup:
cd frontend # Install dependencies npm install # Configure API endpoint echo "VITE_API_URL=http://localhost:9000/api" > .env.local # Start development server npm run dev
Project Structure
elf-project/ βββ backend/ # Django backend β βββ config/ # Django configuration β β βββ settings.py # Application settings β β βββ urls.py # URL routing β β βββ wsgi.py # WSGI configuration β βββ elf/ # Main application β β βββ models.py # Database models β β βββ api/ # REST API layer β β β βββ serializers.py # Data serialization β β β βββ views.py # API endpoints β β βββ services/ # Business logic β β βββ rivendell_service.py # Rivendell sync β β βββ export_service.py # Log export β β βββ scheduling_service.py # Auto-scheduler β βββ requirements.txt # Python dependencies β βββ manage.py # Django CLI βββ frontend/ # React frontend β βββ src/ β β βββ components/ # Reusable components β β βββ pages/ # Page components β β βββ services/ # API client β β βββ App.jsx # Main application β βββ package.json # Node dependencies β βββ vite.config.js # Build configuration βββ docker-compose.yml # Docker orchestration βββ README.md # Project overview βββ SETUP_GUIDE.md # Installation guide βββ DEVELOPMENT_GUIDE.md # Developer documentation βββ TODO.md # Development roadmap
Coding Standards
Python (Backend):
- Follow PEP 8 style guide
- Use type hints for function parameters and returns
- Docstrings for all classes and public methods
- Maximum line length: 100 characters
- Use Django ORM best practices (select_related, prefetch_related)
JavaScript (Frontend):
- ES6+ syntax with modern features
- Functional components with React Hooks
- Descriptive variable names (camelCase)
- Component files use PascalCase
- Use async/await for asynchronous operations
Database:
- Always create migrations for model changes
- Use database indexes for frequently queried fields
- Foreign keys with appropriate on_delete behavior
- Unique constraints where applicable
Testing
Backend Tests:
# Run all tests python manage.py test # Run specific test python manage.py test elf.tests.test_models # With coverage coverage run manage.py test coverage report
Frontend Tests:
# Run tests npm run test # Run with coverage npm run test:coverage
Common Commands
Database Management:
# Create migrations python manage.py makemigrations # Apply migrations python manage.py migrate # Access database shell python manage.py dbshell
Rivendell Integration:
# Sync cart inventory python manage.py sync_rivendell_carts --station 1 --group-name COMM # Export daily log python manage.py export_log --date 2024-02-08 --station 1
Roadmap
Phase 1: MVP Foundation (Current)
Status: In Progress
- [β] Core database models (11 models)
- [β] RESTful API with full CRUD operations
- [β] Rivendell cart synchronization
- [β] Log export service (column-aligned ASCII)
- [β] Basic auto-scheduling algorithm
- [β] Django admin interface
- [β] React frontend structure
- [β] API client and routing
- [ ] Complete UI implementation
- [ ] User authentication system
- [ ] Comprehensive API tests
Phase 2: Core Features (Next 2 Months)
Status: Planned
Scheduling Enhancements:
- Advanced rotation algorithms
- Hourly spot limits
- Fixed-position spots (ROS vs. fixed time)
- Makegood tracking and automatic rescheduling
- Schedule conflict detection and resolution
User Interface:
- Full CRUD interfaces for all entities
- Drag-and-drop schedule editor
- Calendar-based schedule view
- Real-time validation
- Dashboard analytics
Integration:
- Multiple Rivendell import format support
- Two-way sync (import as-played data)
- Music scheduler integration prep
Phase 3: Advanced Features (Months 3-6)
Status: Planned
Business Features:
- Multi-user roles and permissions
- Agency portal access
- Rate card management
- Automated billing integration
- Contract and proposal generation
Reporting:
- Affidavits (proof of performance)
- Performance analytics
- Advertiser dashboards
- Comparative analysis reports
- Custom report builder
Scheduling Intelligence:
- Multi-station scheduling from single campaign
- Network-wide campaign management
- Inventory forecasting
- AI-powered optimization suggestions
Phase 4: Cloud & SaaS (Months 6-12)
Status: Future
Infrastructure:
- Multi-tenancy architecture
- Rumble Cloud deployment
- Auto-scaling configuration
- Comprehensive monitoring (Prometheus/Grafana)
- Automated backup and disaster recovery
SaaS Features:
- Subscription management system
- Payment processing (Stripe integration)
- Usage-based billing
- Station onboarding wizard
- Self-service customer portal
- Support ticketing system
Mobile:
- Progressive Web App (PWA)
- React Native mobile application
- Offline capability
- Push notifications
Future Enhancements
Additional Integrations:
- MusicMaster scheduler
- Selector scheduler
- NexGen automation
- WideOrbit traffic system
- Accounting software (QuickBooks, etc.)
Advanced Features:
- Voice recognition for commercial detection
- Real-time collaboration features
- Slack/Teams notifications
- API webhooks for third-party integration
- Machine learning for schedule optimization
- Predictive analytics for inventory management
Notes
Design Decisions
Why Django + React?
- Django: Mature, βbatteries includedβ framework with excellent ORM and admin interface. Strong security features and extensive ecosystem.
- React: Component-based architecture perfect for complex UIs. Large community and extensive library ecosystem.
- Decoupled Architecture: Allows independent scaling and development of frontend/backend. Enables future mobile apps using same API.
Why PostgreSQL?
- Advanced query capabilities for complex scheduling logic
- Better support for concurrent writes than SQLite
- JSON field support for flexible data structures
- Excellent performance for reporting queries
- Industry standard for web applications
Why Column-Aligned ASCII Export?
- Standard format supported by Rivendell and legacy systems
- Human-readable for debugging and verification
- Easy to parse by various import tools
- Compatible with older radio automation systems
Auto-Scheduling Algorithm:
- Current implementation uses weighted random selection with separation rules
- Future versions will implement more sophisticated algorithms:
- Dynamic programming for optimal placement
- Machine learning for pattern recognition
- Genetic algorithms for complex constraint satisfaction
Technical Constraints
Database Connections:
- Rivendell MySQL connection is read-only by default for safety
- Cart sync runs on-demand, not real-time, to minimize database load
- Connection pooling configured for optimal performance
Port Configuration:
- Backend uses port 9000 (configurable in settings)
- Frontend dev server uses port 5173 (Vite default)
- Avoids conflicts with other common services
File System:
- Export path must be accessible by both ELF and Rivendell
- Recommend shared network mount or direct file system access
- Exports use date-based filenames (YYYYMMDD.txt)
Historical Context
Project Origin:
- Created to address lack of affordable traffic systems for small stations
- Inspired by proprietary systems costing $10,000+ per station
- Designed specifically for Rivendell users (open-source automation)
- Intended for free self-hosted use or affordable SaaS offering
Development Philosophy:
- Open-source community benefit
- User-driven feature development
- Professional quality for zero cost
- Extensible architecture for future growth
Known Issues
Current Limitations:
- Auto-scheduler uses basic algorithm (sophisticated version planned)
- No actual authentication implemented yet (security risk in current state)
- Separation rules partially implemented
- Export path validation needed
- Time zone handling requires additional testing
- No multi-user concurrency protection yet
Workarounds:
- Run behind firewall until authentication completed
- Use Django admin for user management temporarily
- Manual schedule review before export recommended
- Test exports thoroughly before going live
Contributing
How to Contribute:
- Fork the repository on GitHub
- Create feature branch from main
- Follow coding standards outlined above
- Write tests for new features
- Submit pull request with detailed description
- Update documentation as needed
Priority Areas:
- Frontend UI implementation
- Test coverage improvements
- Documentation and tutorials
- Additional import/export formats
- Mobile-responsive design enhancements
Contact & Support
Project Resources:
- Website: https://www.amigaz.org/elf
- Documentation: See SETUP_GUIDE.md and DEVELOPMENT_GUIDE.md
- Issue Tracking: GitHub Issues (when repository public)
- Email: [contact information]
Related Projects:
- Rivendell Radio Automation: https://github.com/ElvishArtisan/rivendell
- Rivendell Wiki: https://rivendellaudio.wiki/
References
Documentation:
- Django Documentation: https://docs.djangoproject.com/
- Django REST Framework: https://www.django-rest-framework.org/
- React Documentation: https://react.dev/
- Rivendell Operations Guide: https://opsguide.rivendellaudio.org/
Standards:
- PEP 8 - Python Style Guide
- REST API Design Best Practices
- PostgreSQL Best Practices
- React Hooks Best Practices
Last Updated: February 19, 2024 Version: 1.0.0-alpha Maintainer: Rich Lawrence

