From ce5175d8db67cb1e3662e7081380125b31ea3b58 Mon Sep 17 00:00:00 2001 From: Nate Emmert Date: Mon, 17 Nov 2025 08:08:20 -0500 Subject: [PATCH] Add desktop GUI application with system tray support - Created PySide6-based desktop application - Added system tray integration for Windows and Linux - Built-in log viewer and configuration wizard - Easy setup and automatic playlist updates - Cross-platform compatibility - Updated README with comprehensive instructions --- README.md | 213 ++++++++++++++++++-- create_icon.py | 33 +++ icon.png | Bin 0 -> 566 bytes journey_fm_app.py | 500 ++++++++++++++++++++++++++++++++++++++++++++++ journey_fm_app.sh | 14 ++ main.py | 12 +- requirements.txt | 3 +- run_app.bat | 14 ++ 8 files changed, 760 insertions(+), 29 deletions(-) create mode 100644 create_icon.py create mode 100644 icon.png create mode 100644 journey_fm_app.py create mode 100644 journey_fm_app.sh create mode 100644 run_app.bat diff --git a/README.md b/README.md index dc8f2d7..81d3fc5 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,205 @@ # Journey FM Playlist Creator -This script automates the process of creating a Plex playlist from recently played songs on My Journey FM radio station. +A cross-platform desktop application that automatically creates Plex playlists from recently played songs on My Journey FM radio station. -## Features +![Application Screenshot](screenshot.png) -- Scrapes recently played songs from https://www.myjourneyfm.com/recently-played/ -- Checks your local music library for matching songs -- Creates a playlist in Plex with the found songs +## ✨ Features -## Setup +- **System Tray Integration**: Runs minimized in the taskbar/system tray +- **Automatic Updates**: Configurable automatic playlist updates +- **Cross-Platform**: Works on Windows and Linux +- **Log Viewer**: Built-in log viewer for monitoring updates +- **Easy Setup**: Guided setup wizard for initial configuration +- **Duplicate Prevention**: Smart duplicate detection and prevention +- **Artist Matching**: Handles featured artists, punctuation, and name variations -1. Install dependencies: `pip install -r requirements.txt` -2. Configure the script: - - Set `PLEX_URL` to your Plex server URL - - Set `PLEX_TOKEN` to your Plex authentication token - - Set `MUSIC_LIBRARY_PATH` to the path of your music library -3. Run the script: `python main.py` +## 🚀 Quick Start -## Requirements +### Windows -- Python 3.6+ -- Plex server -- Local music library with ID3 tags +1. **Install Dependencies** + ```bash + pip install -r requirements.txt + ``` -## Note +2. **Create Application Icon** + ```bash + python create_icon.py + ``` -The HTML scraping part may need adjustment based on the actual structure of the website. Inspect the page to find the correct selectors for artist and title. \ No newline at end of file +3. **Run the Application** + ```bash + python journey_fm_app.py + ``` + Or use the batch file: `run_app.bat` + +### Linux + +1. **Install Dependencies** + ```bash + pip install -r requirements.txt + ``` + +2. **Make Scripts Executable** + ```bash + chmod +x journey_fm_app.sh + ``` + +3. **Run the Application** + ```bash + ./journey_fm_app.sh + ``` + +## ⚙️ Configuration + +### First-Time Setup + +When you first run the application, a setup wizard will guide you through: + +1. **Plex Token**: Get this from https://plex.tv/claim +2. **Server IP**: Your Plex server's local IP address +3. **Playlist Name**: Name for your Journey FM playlist +4. **Auto-Update Settings**: Enable automatic updates and set intervals + +### Manual Configuration + +You can also edit settings anytime through the Settings menu in the application. + +## 📱 System Tray Features + +- **Minimize to Tray**: The app minimizes to system tray instead of closing +- **Right-click Menu**: + - Show: Restore the main window + - Update Now: Manually trigger playlist update + - Quit: Exit the application +- **Double-click**: Restore the main window +- **Notifications**: Get notified when automatic updates complete + +## 📋 Log Viewer + +The built-in log viewer shows: +- Update timestamps +- Songs added to playlist +- Error messages +- Update duration +- Connection status + +Logs are automatically saved to `playlist_log.txt` for external viewing. + +## 🔄 Automatic Updates + +Configure automatic updates to run every: +- 5-120 minutes +- Hours (up to several hours) + +The app will: +- Run in the background +- Show tray notifications when updates complete +- Prevent duplicate songs +- Handle connection errors gracefully + +## 🛠️ Troubleshooting + +### Common Issues + +**"Server not found"** +- Ensure your Plex server is running +- Check that you've claimed the server at http://[SERVER_IP]:32400/web +- Verify the server IP address in settings + +**"No matching tracks found"** +- Ensure your music library is properly scanned in Plex +- Check that song metadata matches (artist names, titles) +- The app handles variations like "&" vs "and", featured artists, etc. + +**System tray not working** +- On Linux, ensure you have a system tray (like KDE/GNOME) +- Some desktop environments may need additional packages + +### Manual Testing + +Test the core functionality: +```bash +python main.py +``` + +This runs the update once without the GUI. + +## 📁 Project Structure + +``` +journey-fm-playlist/ +├── journey_fm_app.py # Main GUI application +├── main.py # Core update logic +├── create_icon.py # Icon generator +├── run_app.bat # Windows launcher +├── journey_fm_app.sh # Linux launcher +├── requirements.txt # Python dependencies +├── config.json # Configuration (auto-generated) +├── playlist_log.txt # Update logs +├── icon.png # Application icon +└── README.md # This file +``` + +## 🔧 Development + +### Adding Features + +The application is built with PyQt6 for cross-platform compatibility. Key components: + +- `MainWindow`: Main application window +- `SystemTrayApp`: Tray icon and menu +- `SetupWizard`: Configuration wizard +- `LogViewer`: Log display widget +- `UpdateWorker`: Background update thread + +### Building Standalone Executables + +**Windows (PyInstaller)** +```bash +pip install pyinstaller +pyinstaller --onefile --windowed --icon=icon.ico journey_fm_app.py +``` + +**Linux (PyInstaller)** +```bash +pip install pyinstaller +pyinstaller --onefile --icon=icon.png journey_fm_app.py +``` + +## 📋 Requirements + +- **Python**: 3.8+ +- **PyQt6**: GUI framework +- **Selenium**: Web scraping +- **PlexAPI**: Plex integration +- **BeautifulSoup4**: HTML parsing + +### System Requirements + +- **Windows**: 10+ with system tray support +- **Linux**: Modern desktop environment with system tray +- **Plex Server**: Local or remote Plex server access + +## 🤝 Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test on both Windows and Linux +5. Submit a pull request + +## 📄 License + +This project is open source. Feel free to use and modify as needed. + +## 🆘 Support + +If you encounter issues: +1. Check the application logs +2. Verify your Plex server connection +3. Ensure all dependencies are installed +4. Test with `python main.py` first + +For bugs or feature requests, please create an issue on GitHub. \ No newline at end of file diff --git a/create_icon.py b/create_icon.py new file mode 100644 index 0000000..592a601 --- /dev/null +++ b/create_icon.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +""" +Create application icon +""" +from PySide6.QtGui import QIcon, QPixmap, QPainter, QColor, QFont +from PySide6.QtCore import QSize + +def create_icon(): + """Create a simple application icon""" + pixmap = QPixmap(64, 64) + pixmap.fill(QColor(30, 144, 255)) # Dodger blue background + + painter = QPainter(pixmap) + painter.setPen(QColor(255, 255, 255)) + painter.setFont(QFont("Arial", 32, QFont.Weight.Bold)) + + # Draw music note symbol + painter.drawText(16, 48, "♪") + + painter.end() + + icon = QIcon(pixmap) + return icon + +if __name__ == "__main__": + from PySide6.QtWidgets import QApplication + import sys + + app = QApplication(sys.argv) + icon = create_icon() + pixmap = icon.pixmap(QSize(64, 64)) + pixmap.save("icon.png") + print("Icon created: icon.png") \ No newline at end of file diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..092888f0e20bacc8e3d00fdf6724f098768f36f2 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$&H|6fVg?4jBOuH;Rhv(mfr0Ub zr;B4qM&sLAyS-%sMcVDz15Y%aSd}XxC@5ZIveAe|=a3RdQ}0v-r$54Pj+{E=ByBkL z#t|nMr&+E(9Sf$mnknrHYd*DzF~0lMsSUT*bQ~<5d9(WYj)Hx8a(~YKoKZc4J@{MU zv&Nuf6Y~~Cgg8ivPHuv1$(Bo%4zASw3{Efs>>5LtADG~hMni0 zS3WxJ^Sx+pS{OvT>r!5c+2eD_al<`P5Y}lCH0?pcV@#bkA;)} z3ZLRhiL}}WZLH-L;*Rcjm=dvYdhvIo2xG?$1|^Y`o<9rz{4ieO?9JK7_bS)zf2}$t(QxMf z700i{>vd(E(0816;e2RX{BEw9+{fxZ{9ScpUQM9bhkC{KZ)$BxCGH24-_O`u8|Jse o^lrRk6W1Q;FNuB_;atg5@;P=ggU~t&U_xN /dev/null && pwd )" + +# Activate virtual environment if it exists +if [ -d "$DIR/.venv" ]; then + source "$DIR/.venv/bin/activate" +fi + +# Run the application +cd "$DIR" +python journey_fm_app.py \ No newline at end of file diff --git a/main.py b/main.py index c3c0c52..39e61fa 100644 --- a/main.py +++ b/main.py @@ -53,7 +53,6 @@ def scrape_recently_played(): html = driver.page_source driver.quit() - tweet = scrape(tweet_code) # Optional: save HTML to file for debugging (comment out if not needed) # with open('page.html', 'w', encoding='utf-8') as f: # f.write(html) @@ -259,15 +258,8 @@ def main(): SERVER_IP = config.get('SERVER_IP', SERVER_IP) PLAYLIST_NAME = config.get('PLAYLIST_NAME', PLAYLIST_NAME) else: - config = prompt_for_config() - PLEX_TOKEN = config['PLEX_TOKEN'] - SERVER_IP = config['SERVER_IP'] - PLAYLIST_NAME = config['PLAYLIST_NAME'] - - # Prompt for scheduler setup - sched_params = prompt_for_scheduler() - if sched_params: - setup_scheduler(sched_params) + # If no config file, use defaults (GUI should handle this) + pass # Log start time start_time = datetime.now() diff --git a/requirements.txt b/requirements.txt index 755059f..c2349f6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ beautifulsoup4 plexapi mutagen selenium -webdriver-manager \ No newline at end of file +webdriver-manager +PySide6 \ No newline at end of file diff --git a/run_app.bat b/run_app.bat new file mode 100644 index 0000000..b209686 --- /dev/null +++ b/run_app.bat @@ -0,0 +1,14 @@ +@echo off +REM Journey FM Playlist Creator - Windows Launcher + +cd /d "%~dp0" + +REM Activate virtual environment if it exists +if exist .venv\Scripts\activate.bat ( + call .venv\Scripts\activate.bat +) + +REM Run the application +python journey_fm_app.py + +pause \ No newline at end of file