{"id":29634255,"url":"https://github.com/esosaoh/playlifts","last_synced_at":"2026-04-12T15:54:40.630Z","repository":{"id":247806823,"uuid":"826878149","full_name":"esosaoh/Playlifts","owner":"esosaoh","description":"Transfer playlists between Youtube Music and Spotify","archived":false,"fork":false,"pushed_at":"2025-07-20T21:33:13.000Z","size":5597,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-20T23:29:31.557Z","etag":null,"topics":["celery","flask","oauth2","playlist","react","redis","spotify","youtube-music"],"latest_commit_sha":null,"homepage":"https://playlifts.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esosaoh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-10T15:00:12.000Z","updated_at":"2025-07-20T21:33:17.000Z","dependencies_parsed_at":"2024-07-10T19:18:43.109Z","dependency_job_id":"5063c6ce-89de-4958-a224-522f5841a6c0","html_url":"https://github.com/esosaoh/Playlifts","commit_stats":null,"previous_names":["esosaoh/listenup","esosaoh/playlifts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/esosaoh/Playlifts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosaoh%2FPlaylifts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosaoh%2FPlaylifts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosaoh%2FPlaylifts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosaoh%2FPlaylifts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esosaoh","download_url":"https://codeload.github.com/esosaoh/Playlifts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosaoh%2FPlaylifts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266324708,"owners_count":23911238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-21T11:47:31.412Z","response_time":64,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["celery","flask","oauth2","playlist","react","redis","spotify","youtube-music"],"created_at":"2025-07-21T15:15:55.360Z","updated_at":"2026-04-12T15:54:40.624Z","avatar_url":"https://github.com/esosaoh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Playlifts](https://playlifts.com)\n\nPlaylifts is a web application that allows users to transfer their music playlists between YouTube Music and Spotify.\n\n**Live Application**: [playlifts.com](https://playlifts.com)  \n**Playlifts API**: [api.playlifts.com](https://api.playlifts.com)\n\n![Playlifts Login Page](docs/screenshots/login-page.png)\n\n## Features\n\n- **Bidirectional Transfer**: Transfer playlists from YouTube Music to Spotify and vice versa\n- **Song Matching**: Intelligent matching between platforms using artist and track names\n- **Large Playlist Support**: Handle playlists of any size through asynchronous processing\n- **Real-time Progress**: Live progress tracking during transfers\n- **Error Handling**: Comprehensive error reporting and retry mechanisms\n- **Modern UI**: Beautiful, responsive interface with dark/light mode support\n- **OAuth Integration**: Secure authentication with both platforms\n\n## Tech Stack\n\n### Frontend\n- **React 18** \n- **TypeScript** \n- **Vite**\n- **Tailwind CSS**\n- **Framer Motion** \n- **React Router** \n- **Lucide React** \n- **React Testing Library** \n\n### Backend\n- **Flask** \n- **Celery**\n- **Redis** \n- **pytest** \n\n### Infrastructure\n- **Docker** \n- **Docker Compose** \n- **Nginx** \n- **AWS EC2** \n- **Vercel** \n\n### APIs \u0026 Services\n- **Spotify Web API** \n- **YouTube Data API** \n- **Google OAuth 2.0** \n- **Spotify OAuth 2.0** \n\n## Architecture\n\n\u003cimg src=\"docs/screenshots/playlifts_architecture.png\" alt=\"Playlifts Architecture\" width=\"600\"\u003e\n\n### Why Celery?\n\nProcessing playlists with hundreds of songs directly in API requests would cause timeouts. Both Spotify and YouTube APIs have rate limits that require careful pacing. Celery's asynchronous processing allows users to continue using the app while transfers happen in the background. Additionaly, failed transfers can be retried without affecting the user interface and multiple transfers can run concurrently without blocking each other.\n\n### System Flow\n\n1. **User Authentication**: OAuth 2.0 flow with Spotify and YouTube Music\n2. **Playlist Selection**: Users browse and select source playlists\n3. **Transfer Initiation**: Celery task is queued for processing\n4. **Background Processing**: Songs are matched and transferred asynchronously\n5. **Progress Updates**: Real-time status updates via WebSocket-like polling\n6. **Completion**: Results are stored and displayed to the user\n\n## Screenshots\n\n### YouTube to Spotify Transfer\n![YouTube to Spotify Transfer](docs/screenshots/youtube-to-spotify.png)\n*Transferring playlists from YouTube Music to Spotify with real-time progress*\n\n### Spotify Playlist Selection\n![Spotify Playlist Selection](docs/screenshots/spotify-playlist-selection.png)\n*Browsing and selecting Spotify playlists for transfer*\n\n### Authentication States\n![Only Logged in with Spotify](docs/screenshots/only-logged-in-with-spotify.png)\n*Interface when user is only authenticated with Spotify*\n\n![Only Logged in with YouTube](docs/screenshots/only-logged-in-with-youtube.png)\n*Interface when user is only authenticated with YouTube Music*\n\n## Getting Started\n\n### Prerequisites\n\n- Python 3.9+\n- Node.js 18+\n- Docker and Docker Compose\n- Redis server\n\n### Local Development Setup\n\n#### 1. Clone the Repository\n```bash\ngit clone https://github.com/esosaoh/playlifts.git\ncd playlifts\n```\n\n#### 2. Backend Setup\n```bash\ncd backend\npython -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\npip install -r requirements.txt\n```\n\n#### 3. Environment Configuration\n\u003e **Backend Configuration**: See [backend/README.md](backend/README.md) for detailed environment variables and API setup instructions.\n\nCreate `.env` files in both `backend/` and `frontend/` directories:\n\n**Frontend (.env)**\n```env\nVITE_API_URL=http://localhost:5000\n```\n\n#### 4. Start Services\n```bash\n# Start Celery worker\ncd backend\ncelery -A celery_config worker --loglevel=info\n\n# Start Flask backend\nflask run\n\n# Start React frontend (in new terminal)\ncd frontend\nnpm install\nnpm run dev\n```\n\n### API Access Setup\n\n\u003e [!IMPORTANT]  \n\u003e Due to [Spotify's API policy changes](https://developer.spotify.com/blog/2025-04-15-updating-the-criteria-for-web-api-extended-access), individual developers can no longer create public apps. Users must be manually added to your Spotify app.\n\n\u003e **Detailed Setup**: For complete API configuration instructions, see [backend/README.md](backend/README.md).\n\n#### Spotify Setup\n1. Create a Spotify app in the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard)\n2. Add your redirect URI: `http://localhost:8889/spotify/callback`\n3. **Manually add users** to your app through the dashboard\n4. Users will need to contact you to be added to the app\n\n#### YouTube Setup\n1. Create a Google Cloud project\n2. Enable YouTube Data API v3\n3. Create OAuth 2.0 credentials\n4. Add your redirect URI: `http://localhost:8889/youtube/callback`\n\n\u003e [!TIP]  \n\u003e For local development, you can use the YouTube API with generous quotas, but be mindful of rate limits for production use.\n\n## Testing\n\n### Frontend Testing\n```bash\ncd frontend\nnpm test                    # Run tests in watch mode\nnpm run test:run           # Run tests once\nnpm run test:ui            # Run tests with UI (if @vitest/ui installed)\n```\n\n**Test Coverage:**\n- Component rendering and user interactions\n- API integration with mocked responses\n- Error handling and loading states\n- Navigation and routing\n- Form validation and submission\n\n### Backend Testing\n```bash\ncd backend\npython -m pytest tests/    # Run all tests\npython -m pytest tests/ -v # Verbose output\npython -m pytest tests/ -k \"test_name\" # Run specific test\n```\n\n**Test Coverage:**\n- API endpoints and authentication\n- Celery task processing\n- Database operations\n- Error handling and edge cases\n- Spotify and YouTube client integrations\n\n## Deployment\n\n\u003e **Deployment Configuration**: See [./DEPLOYMENT.md](DEPLOYMENT.md) for detailed environment variables and API setup instructions.\n\n### Production Deployment\n```bash\n# Deploy to AWS EC2\n./scripts/deploy.sh\n```\n\n### Environment Variables\nEnsure all production environment variables are set:\n- Database credentials\n- API keys and secrets\n- Redis connection\n- Domain and SSL certificates\n\n\u003e **Backend API Documentation**: For complete API endpoint documentation, see [backend/README.md](backend/README.md).\n\n## API Limitations \u0026 Considerations\n\n### Spotify API\n- **Rate Limits**: 100 requests per second per user\n- **Playlist Limits**: 10,000 tracks per playlist\n- **App Approval**: Manual user addition required\n\n### YouTube Data API\n- **Daily Quota**: 10,000 units per day (free tier)\n- **Search Quota**: 100 units per search request\n- **Rate Limits**: 300 requests per 100 seconds per user\n\n\u003e **Local Development Advantage**: Local development allows you to work with your own API quotas and test thoroughly before production deployment.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Ensure your code is formatted (we use `black` for backend and `prettier` for frontend)\n4. Commit your changes \n5. Push to the branch\n6. Open a Pull Request\n\n## License\n\nThis project is licensed under the GNU GPL License - see the [LICENSE](LICENSE) file for details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesosaoh%2Fplaylifts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesosaoh%2Fplaylifts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesosaoh%2Fplaylifts/lists"}