211 lines
9.4 KiB
Markdown
211 lines
9.4 KiB
Markdown
# Raven Scott Music
|
||
|
||
**Raven Scott Music** is a sophisticated, dark-themed web application designed to curate and display music playlists from SoundCloud across three genres: Metal, Alt Rock, and Rap. Built with Node.js, Express, and EJS, this project combines server-side rendering, efficient caching, and a responsive front-end to deliver a seamless music discovery experience. Whether you're a developer looking to explore the code or a music enthusiast browsing tracks, this app offers a robust foundation with plenty of room for customization.
|
||
|
||
## 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)
|
||
- [License](#license)
|
||
- [Acknowledgments](#acknowledgments)
|
||
|
||
## Features
|
||
|
||
- **Genre-Specific Playlists**: Dynamically fetches and displays tracks from SoundCloud playlists for Metal, Alt Rock, and Rap.
|
||
- **Efficient Caching**: Stores playlist data in local JSON files, refreshing only after a week to minimize API calls and improve load times.
|
||
- **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**: Tracks are sorted by play count (descending) and then by publication date (newest first) for a curated experience.
|
||
|
||
## Live Demo
|
||
|
||
Explore the live site at [raven-scott.rocks](https://raven-scott.rocks). Check out the Metal, Alt Rock, and Rap sections, 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-scraper` 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-scraper`, `ejs`, 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 all 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`).
|
||
- **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",
|
||
"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-scraper` library fetches playlist data, including track titles, URLs, play counts, and publication dates.
|
||
- **Routing**:
|
||
- `/`: Renders the home page with all genres.
|
||
- `/:genre`: Redirects to the home page’s genre section (e.g., `/#metal`).
|
||
- `/:genre/track/:slug`: Renders individual track pages.
|
||
- `/json/:genre`: Returns track data in JSON.
|
||
- `/sitemap.xml`: Generates an XML sitemap.
|
||
- **Slug Generation**: Converts track titles into URL-friendly slugs (e.g., "Heavy Riffs" → `heavy-riffs`).
|
||
|
||
### Frontend
|
||
- **Templating**: EJS renders dynamic HTML with data from the backend.
|
||
- **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, and a slim scrollbar.
|
||
- **Scripts**: jQuery, Popper.js, and Bootstrap JS (via CDN) enable navbar toggling and other interactive elements.
|
||
|
||
### 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**: Tracks are sorted by play count (highest first) and then by publication date (newest first).
|
||
|
||
## 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 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)
|
||
├── music_site.js # Core server logic and routing
|
||
├── 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-scraper**: Chosen for its simplicity and ability to scrape public playlist data without requiring an official API key.
|
||
- **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 out of the box.
|
||
- **File-System Caching**: A simple, effective solution for persistence without the complexity of 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
|
||
```
|
||
- **Port**: Set via `.env` or directly in `music_site.js`:
|
||
```javascript
|
||
const PORT = process.env.PORT || 6767;
|
||
```
|
||
|
||
## 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 a tool like Google Analytics.
|
||
- **Lazy Loading**: Optimize the home page by loading tracks incrementally.
|
||
|
||
## Troubleshooting
|
||
|
||
- **SoundCloud Fetch Fails**:
|
||
- Verify playlist URLs in `music_site.js` are correct and public.
|
||
- Update `soundcloud-scraper` (`npm install soundcloud-scraper@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.
|
||
- **Port Conflicts**:
|
||
- Change the `PORT` value or kill the conflicting process:
|
||
```bash
|
||
lsof -i :6767 # Linux/macOS
|
||
kill -9 <PID>
|
||
```
|
||
- **404 Errors**:
|
||
- Ensure genre or slug matches the data (case-sensitive).
|
||
- Check console logs for errors during playlist fetching.
|
||
- **Styling Problems**:
|
||
- Clear browser cache if CSS changes don’t appear.
|
||
- Verify CDN links for Bootstrap and jQuery are accessible.
|