# Raven Scott Music **Raven Scott Music** is a sophisticated, dark-themed web application designed to curate and display music playlists from SoundCloud across multiple genres: Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts. Built with Node.js, Express, and EJS, this project combines server-side rendering, efficient caching, pagination, and real-time updates via WebSockets to deliver a seamless music discovery experience. Whether you're a developer exploring the code or a music enthusiast browsing tracks, this app offers a robust, scalable foundation with a polished user interface. ## Table of Contents - [Features](#features) - [Live Demo](#live-demo) - [Prerequisites](#prerequisites) - [Installation](#installation) - [Usage](#usage) - [Technical Overview](#technical-overview) - [Backend](#backend) - [Frontend](#frontend) - [Caching Mechanism](#caching-mechanism) - [File Structure](#file-structure) - [Tech Stack Rationale](#tech-stack-rationale) - [Configuration](#configuration) - [Deployment](#deployment) - [Development](#development) - [Enhancement Ideas](#enhancement-ideas) - [Troubleshooting](#troubleshooting) ## Features - **Genre-Specific Playlists**: Dynamically fetches and displays tracks from SoundCloud playlists for Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts. - **Pagination**: Displays 4 tracks per page per genre, with Previous/Next buttons for efficient navigation. - **Real-Time Updates**: Uses Socket.IO for dynamic loading of paginated track data without full page reloads. - **Efficient Caching**: Stores playlist data in local JSON files, refreshing only after a week to minimize API calls and improve load times. - **Unique Slugs**: Ensures track slugs are unique within each genre to prevent URL conflicts. - **Responsive UI**: Leverages Bootstrap 4.5.2 and custom CSS for a mobile-friendly, dark-mode interface with orange accents. - **Track Pages**: Dedicated pages for each track with embedded SoundCloud players, titles, and descriptions. - **SEO Optimization**: Generates a `sitemap.xml` dynamically for better search engine visibility. - **JSON API**: Provides a RESTful endpoint (`/json/:genre`) for programmatic access to track data. - **Custom Styling**: Features a slim dark-mode scrollbar, animated navbar hover effects, and a cohesive aesthetic tailored for music lovers. - **Sorting Logic**: - Most genres: Tracks sorted by play count (descending), then publication date (newest first). - Cuts genre: Tracks sorted by EP number extracted from titles (ascending). ## Live Demo Explore the live site at [raven-scott.rocks](https://raven-scott.rocks). Navigate through Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts sections using pagination controls, dive into individual track pages, or inspect the sitemap at `/sitemap.xml`. ## Prerequisites To run this project locally, ensure you have: - **[Node.js](https://nodejs.org/)**: Version 14.x or higher (includes npm). - **[npm](https://www.npmjs.com/)**: Package manager for installing dependencies. - **SoundCloud Access**: The playlists specified in `music_site.js` must be public and accessible via the `soundcloud.ts` library. - **Git**: For cloning the repository (optional but recommended). ## Installation 1. **Clone the Repository**: ```bash git clone https://git.ssh.surf/snxraven/ravenscott-rocks.git cd ravenscott-rocks ``` 2. **Install Dependencies**: ```bash npm install ``` This installs `express`, `soundcloud.ts`, `ejs`, `socket.io`, and other required packages listed in `package.json`. 3. **Optional: Environment Variables**: - Create a `.env` file in the root directory to customize the port: ```bash PORT=6767 ``` - Alternatively, set the `PORT` variable in your terminal: ```bash export PORT=6767 # Linux/macOS set PORT=6767 # Windows ``` 4. **Start the Server**: ```bash node music_site.js ``` The app will run on `http://localhost:6767` (or your specified port). Open this URL in your browser to begin exploring. ## Usage - **Home Page (`/`)**: Displays paginated genre playlists with embedded SoundCloud players and "More Details" links. - **Genre Navigation (`/#genre`)**: Use the navbar to jump to specific genres (e.g., `#metal`, `#altrock`, `#rap`). - **Pagination**: Use Previous/Next buttons to navigate through tracks in each genre (4 tracks per page). - **Track Details (`/:genre/track/:slug`)**: Click "More Details" to view a track’s page with its SoundCloud player and description. - **JSON API (`/json/:genre`)**: Fetch raw track data for a genre (e.g., `http://localhost:6767/json/metal`) in JSON format. - **Sitemap (`/sitemap.xml`)**: Access a dynamically generated sitemap for SEO purposes. Example API response: ```json [ { "title": "Heavy Riffs", "description": "A brutal metal track.", "url": "https://soundcloud.com/snxraven/heavy-riffs", "embedUrl": "https://w.soundcloud.com/player/?url=https%3A//soundcloud.com/snxraven/heavy-riffs&color=%23ff5500&auto_play=false...", "playCount": 1200, "publishedAt": "2023-05-10T12:00:00Z", "slug": "heavy-riffs" } ] ``` ## Technical Overview ### Backend - **Framework**: Uses Express.js to handle routing, static file serving, and API endpoints. - **SoundCloud Integration**: The `soundcloud.ts` library fetches playlist data, including track titles, URLs, play counts, and publication dates. - **WebSockets**: Socket.IO enables real-time pagination, handling `request_page` events to deliver paginated track data. - **Routing**: - `/`: Renders the home page with paginated genre tracks. - `/:genre`: Redirects to the home page’s genre section (e.g., `/#metal`). - `/:genre/track/:slug`: Renders individual track pages using unique slugs. - `/json/:genre`: Returns all track data for a genre in JSON. - `/sitemap.xml`: Generates an XML sitemap with all track URLs. - **Slug Generation**: Creates unique, URL-friendly slugs per genre (e.g., "Heavy Riffs" → `heavy-riffs`) with conflict resolution. - **Pagination**: Limits to 4 tracks per page, with server-side logic to calculate total pages and track subsets. ### Frontend - **Templating**: EJS renders dynamic HTML with paginated track data. - **Styling**: - Bootstrap 4.5.2 (via CDN) provides the grid system and card components. - Custom CSS adds a dark theme, orange buttons, a fixed navbar with hover animations, a slim scrollbar, and pagination styling. - **Interactivity**: - Socket.IO client handles real-time page requests and updates. - Client-side caching stores rendered pages to minimize server requests. - Lazy-loaded iframes optimize performance by loading SoundCloud players only when in view. - **Scripts**: jQuery, Popper.js, Bootstrap JS, and Socket.IO (via CDN) enable navbar toggling, pagination, and WebSocket communication. ### Caching Mechanism - **Purpose**: Reduces API calls to SoundCloud by storing playlist data locally. - **Implementation**: - Cache files (`cache_metal.json`, etc.) store tracks and a timestamp. - The `getTracks` function checks if the cache is older than 1 week (configurable via `oneWeekInMs`). - If outdated or missing, it fetches fresh data and updates the cache. - **Sorting**: - Standard genres: Sort by play count (highest first), then publication date (newest first). - Cuts genre: Sort by EP number (ascending). ## File Structure ``` raven-scott-music/ ├── public/ # Static assets │ └── css/ # Custom CSS (currently empty; styles are inline in EJS) ├── views/ # EJS templates │ ├── index.ejs # Home page with paginated genre sections │ ├── layout.ejs # Base layout (not fully utilized in this setup) │ └── track.ejs # Individual track page ├── cache_metal.json # Cached Metal tracks (auto-generated) ├── cache_altrock.json # Cached Alt Rock tracks (auto-generated) ├── cache_rap.json # Cached Rap tracks (auto-generated) ├── cache_lofi.json # Cached Lo-Fi tracks (auto-generated) ├── cache_edm.json # Cached EDM tracks (auto-generated) ├── cache_cuts.json # Cached Cuts tracks (auto-generated) ├── music_site.js # Core server logic, routing, and WebSocket handling ├── package.json # Project metadata and dependencies ├── package-lock.json # Dependency lock file └── README.md # This documentation ``` ## Tech Stack Rationale - **Node.js & Express**: Lightweight and fast for building a server-side application with minimal overhead. - **soundcloud.ts**: Simplifies fetching public playlist data without requiring an official API key. - **Socket.IO**: Enables real-time pagination, improving user experience by avoiding full page reloads. - **EJS**: Offers server-side rendering with easy integration into Express, ideal for dynamic content like playlists. - **Bootstrap**: Speeds up development with pre-built components and ensures responsiveness. - **File-System Caching**: A simple, effective solution for persistence without a database. ## Configuration - **Playlists**: Modify the `playlists` object in `music_site.js`: ```javascript const playlists = { metal: { url: 'https://soundcloud.com/snxraven/sets/raven-scott-metal', ... }, // Add new genres here }; ``` - **Cache Refresh**: Adjust `oneWeekInMs` (in milliseconds) in `getTracks`: ```javascript const oneWeekInMs = 7 * 24 * 60 * 60 * 1000; // Change to 24 * 60 * 60 * 1000 for daily refresh ``` - **Pagination**: Modify `TRACKS_PER_PAGE` in `music_site.js`: ```javascript const TRACKS_PER_PAGE = 4; // Change to desired tracks per page ``` - **Port**: Set via `.env` or directly in `music_site.js`: ```javascript const PORT = process.env.PORT || 6767; ``` ## Deployment 1. **Prepare for Production**: - Set `NODE_ENV=production` to optimize Express. - Ensure `.env` includes the production port or use a platform-specific configuration. 2. **Example: Deploy to Render**: - Push the repository to a Git service (e.g., GitHub). - Create a new Web Service on Render, linking to your repository. - Set environment variables: ```bash PORT=6767 NODE_ENV=production ``` - Configure the start command: `node music_site.js`. 3. **Verify**: - Check the deployed URL for functionality. - Monitor logs for errors related to SoundCloud fetching or caching. ## Development ### Getting Started 1. Fork and clone the repo. 2. Install dependencies (`npm install`). 3. Run locally (`node music_site.js`). 4. Make changes and test in your browser. ### Enhancement Ideas - **Database Integration**: Replace file caching with MongoDB or SQLite for scalability. - **Search Functionality**: Add a search bar to filter tracks by title or description. - **User Accounts**: Implement authentication (e.g., with Passport.js) for favoriting tracks. - **Additional Platforms**: Integrate Spotify or YouTube using their APIs. - **Analytics**: Track page views or play counts with Google Analytics. - **Infinite Scroll**: Replace pagination with infinite scroll for seamless track loading. ## Troubleshooting - **SoundCloud Fetch Fails**: - Verify playlist URLs in `music_site.js` are correct and public. - Update `soundcloud.ts` (`npm install soundcloud.ts@latest`). - **Cache Issues**: - Delete `cache_*.json` files and restart the server to force a refresh. - Check file permissions if cache files aren’t being written. - **WebSocket Errors**: - Ensure Socket.IO client and server versions match (`npm install socket.io@latest`). - Check browser console for connection issues (e.g., CORS or port mismatches). - **Pagination Problems**: - Verify `TRACKS_PER_PAGE` is set correctly. - Check server logs for errors in `getTracks` or WebSocket handlers. - **Port Conflicts**: - Change the `PORT` value or kill the conflicting process: ```bash lsof -i :6767 # Linux/macOS kill -9 ``` - **404 Errors**: - Ensure genre or slug matches the data (case-sensitive). - Check console logs for errors during playlist fetching or slug generation. - **Styling Problems**: - Clear browser cache if CSS changes don’t appear. - Verify CDN links for Bootstrap, jQuery, and Socket.IO are accessible.