TuneHub.online is a web application for users to stream music and follow artists. Inspired by Bandcamp, TuneHub allows users to browse artist pages, listen to their tracks, follow those artists, and discover other artists.
TuneHub is a personal project by Nathan Johnson.
Users can quickly sign up and be assured that their password is encrypted (hashed through BCrypt). Prospective users can demo the site using the a guest user profile with pre-seeded artists. Login is required to access site features.
Users can stream music in real time and control volume through a handy play bar locked to the bottom of the screen.
Each artist has its own page for viewing a sample album, cover, followers, and genre.
A search bar on the main page allows for quick lookup of your favorite artists.
Fans can follow artists of their choice, consolidating them in a group on the fan's page.
TuneHub was designed and built in a week and a half.
A proposal was drafted to help provide an implementation timeline during the development process.
A database schema was prepared alongside the design proposal.
TuneHub is a single-page application built on Rails and React.js, with many dependencies in both the backend and the frontend.
- Backend technology
- Frontend technology
- [File storage][file storage] via Amazon Cloudinary
To run the app in development, open a terminal in the project root and type:
npm install bundle install rails s npm run watch
Visit the app at localhost:3000.
Make changes and iterate, save files, and watch as the app updates and hot reloads in real time.
- User authentication based on hashed password (BCrypt) for high level database security.
- Unique session token (SecureRandom) for each user during each session protects user's data, so no one has access to anyone's notes but their own
# User model
def self.find_by_credentials(username, password)
user = User.find_by_username(username)
if user && user.is_password?(password)
return user
end
nil
end
def password=(password)
self.password_digest = BCrypt::Password.create(password)
@password = password
end
def is_password?(password)
BCrypt::Password.new(password_digest).is_password?(password)
end
def reset_session_token
self.session_token = SecureRandom::urlsafe_base64(16)
self.save
self.session_token
end
private
def ensure_session_token
self.session_token ||= reset_session_token
end
This vast collection of artists and tracks was taken straight from Spotify by use of the RSpotify gem. I created a list of about 500 artists' names, and used RSpotify's Artist method to select the first search result for each artist name and populate data for sample album, sample tracks, artwork, name, and genres.
@list.each do |artist|
begin
artists = RSpotify::Artist.search(artist)
artist = artists.first
name = artist.name
genres = artist.genres.join(" ")
sample_album = artist.albums.first
sample_image = sample_album.images.first["url"]
tracks = sample_album.tracks
sample_artist = User.create(name: name, description: genres, user_type: "artist",
username: artist.name, password: 123456, image_url: sample_image)
tracks.each do |track|
preview_url = track.preview_url
Track.create(track_url: preview_url, name: track.name, artist_id: sample_artist.id)
end
rescue
next
end
end
The features that will be added are listed in the future implementations outline.