In: Computer Science
Using Ruby
Your extended Text Based Music Application must add the following functionality:
Display a menu that offers the user the following options:
1. Read in Albums
2. Display Albums
3. Select an Album to play
4. Update an existing Album
5. Exit the application
Menu option 1 should prompt the user to enter a filename of a file that contains the following information:
·The number of albums
·The first album name
·The first artist name
·The genre of the album
·The number of tracks (up to a maximum of 15)
·The name and file location (path) of each track.
·The album information for the remaining albums.
Menu option 2 should allow the user to either display all albums or all albums for a particular genre. The albums should be listed with a unique album number which can be used in Option 3 to select an album to play. The album number should serve the role of a ‘primary key’ for locating an album. But it is allocated internally by your program, not by the user.
Menu option 3 should prompt the user to enter the primary key (or album number) for an album as listed using Menu option 2.If the album is found the program should list all the tracks for the album, along with track numbers. The user should then be prompted to enter a track number. If the track number exists, then the system should display the message “Playing track ” then the track name, “ from album ” then the album name. You may or may not call an external program to play the track, but if not the system should delay for several seconds before returning to the main menu.
Menu option 4 should allow the user to enter a unique album number and change its title or genre. The updated album should then be displayed to the user and the user prompted to press enter to return to the main menu (you do not need to update the file at this level)..
At this level minimum validation is required. Just make sure your program does not crash if incorrect values are entered and that all fields have an expected value (eg: perhaps have a default genre of “unknown” in case the user enters and incorrect value for genre).
basic_music_player.rb
require './input_functions'
require 'ffi'
module Genre
POP, CLASSIC, JAZZ, ROCK = *1..4
end
module VLC
extend FFI::Library
ffi_lib 'vlc'
attach_function :version, :libvlc_get_version, [], :string
attach_function :new, :libvlc_new, [:int, :int], :pointer
attach_function :libvlc_media_new_path, [:pointer, :string],
:pointer
attach_function :libvlc_media_player_new_from_media, [:pointer],
:pointer
attach_function :play, :libvlc_media_player_play, [:pointer],
:int
attach_function :stop, :libvlc_media_player_stop, [:pointer],
:int
attach_function :pause, :libvlc_media_player_pause, [:pointer],
:int
end
$genre_names = ['Null', 'Pop', 'Classic', 'Jazz', 'Rock']
$album_file = nil
class Album
attr_accessor :title, :artist, :genre, :tracks
def initialize (title, artist, genre, tracks)
@title = title
@artist = artist
@genre = genre
@tracks = tracks
end
end
class Track
attr_accessor :name, :location
def initialize (name, location)
@name = name
@location = location
end
end
# 5 Write Changes
def write_track track, music_file
music_file.puts track.name
music_file.puts track.location
end
def write_tracks tracks, music_file
count = tracks.length
music_file.puts(count)
i = 0
while (i < count)
write_track(tracks[i], music_file)
i += 1
end
end
def write_album album, music_file
music_file.puts album.title
music_file.puts album.artist
music_file.puts album.genre
write_tracks(album.tracks, music_file)
end
def write_albums albums, music_file
count = albums.length
music_file.puts(count)
i = 0
while (i < count)
write_album albums[i], music_file
i += 1
end
end
def write_changes albums
if $album_file
music_file = File.new($album_file, "w")
if music_file
write_albums albums, music_file
music_file.close()
else
puts "Unable to open file to read!" # this doesn't work when
incorrect value given
end
else
puts 'Unable to read filename'
end
puts 'Music Library Overwritten'
end
# 4 Update Album
def update_album_genre album
puts('The current album genre is: ',
$genre_names[album.genre])
puts('Select New Genre')
puts('1 Pop, 2 Classic, 3 Jazz & 4 Rock')
new_genre = read_integer('Enter number: ')
album.genre = new_genre
end
def update_album_title album
puts('The current album title is: ', album.title)
title = read_string('Enter a new title for the album')
album.title = title
end
def update_album_artist album
puts('The current album title is: ', album.artist)
artist = read_string('Enter a new artist for the album')
album.artist = artist
end
def update_track_title track
title = read_string('Enter a new title for the track')
track.title = title
end
def update_track_location track
location = read_string('Enter a new location for the track')
track.location = location
end
def update_album_track track
print_track
finished = false
begin
puts 'Update Track:'
puts '1 - Update Track Title'
puts '2 - Update Track Location'
choice = read_integer_in_range("Option: ", 1, 2)
case choice
when 1
update_track_title track
when 2
update_track_location track
end
finished = read_string('Press ENTER...')
end until finished
end
def update_album_tracks album
print_title_tracks album.tracks
puts('Select Track ID')
track_id = read_integer_in_range('Enter number: ', 0,
tracks.count-1)
update_album_track album.tracks[track_id]
end
def update_album album
finished = false
begin
puts 'Update Albums:'
puts '1 - Update Album Artist'
puts '2 - Update Album Title'
puts '3 - Update Album Genre'
choice = read_integer_in_range("Option: ", 1, 3)
case choice
when 1
update_album_artist album
when 2
update_album_title album
when 3
update_album_genre album
when 4
update_album_tracks album
end
finished = read_string('Press ENTER...')
end until finished
end
def update_albums albums
finished = false
album = nil
begin
puts 'Update Albums:'
puts '1 - Search by ID'
puts '2 - Search by genre/name'
choice = read_integer_in_range("Option: ", 1, 2)
case choice
when 1
update_album search_by_id albums
when 2
update_album search_album albums
else
puts 'Please select again'
end
finished = read_string('Press ENTER...')
end until finished
end
# 3.2 Search < 3 Play Album
def search_albums_by_genre albums
print_album_genres(albums)
puts('Select Album ID')
id = read_integer_in_range('Enter number: ', 0, albums.count-1
)
print_album_title_and_tracks(albums[id])
return albums[id]
end
def search_albums_by_name albums
album_title = read_string('Enter Album Name to Search: ')
count = albums.length
i = 0
while (i < count)
if album_title == albums[i].title
print_album_title_and_tracks albums[i]
return albums[i]
end
end
end
def search_album albums
finished = false
begin
puts 'Search Albums:'
puts '1 - Search by Genre'
puts '2 - Search by Name'
choice = read_integer_in_range("Option: ", 1, 2)
case choice
when 1
return search_albums_by_genre(albums)
when 2
return search_albums_by_name(albums)
else
puts 'Please select again'
end
finished = read_string('Press ENTER...')
end until finished
end
# 3.1 Play by ID < 3 Play Album
def print_title_track track
puts('Track title is: ' + track.name)
puts('Track file location is: ' +
track.location)
end
def print_title_tracks tracks
count = tracks.length
i = 0
while (i < count)
puts('Track id is: ' + i.to_s)
print_title_track(tracks[i]) # use: tracks[x] to
access each track.
i += 1
end
end
def print_album_title_and_tracks album
puts album.title.to_s
# print out the tracks
print_title_tracks(album.tracks)
end
def print_albums_id_tracks albums
count = albums.length
i = 0
while (i < count)
print ' ID is ' + i.to_s + " for: "
print_album_title_and_tracks(albums[i]) # use: tracks[x] to access
each track.
i += 1
end
end
def print_album_title album
puts album.title.to_s
end
def print_albums_id albums
count = albums.length
i = 0
while (i < count)
print ' ID is ' + i.to_s + " for: "
print_album_title(albums[i]) # use: tracks[x] to access each
track.
i += 1
end
end
def search_by_id(albums)
print_albums_id(albums)
puts('Select Album ID')
id = read_integer_in_range('Enter number: ', 0, albums.count-1
)
print_album_title_and_tracks(albums[id])
return albums[id]
end
# 3 Play Album
def play_tracks tracks
puts('Select Track ID')
track_id = read_integer_in_range('Enter number: ', 0,
tracks.count-1)
trackname = File.join(Dir.pwd, tracks[track_id].location)
trackname = trackname.split(".mp3")[0] + ".mp3"
vlc = VLC.new(0, 0)
media = VLC.libvlc_media_new_path(vlc, trackname)
player = VLC.libvlc_media_player_new_from_media(media)
VLC.play(player)
begin
finished = false
finished = read_string('Press ENTER to stop...')
end until finished
VLC.stop(player)
end
def play_album(albums)
finished = false
album = nil
begin
puts 'Play Albums:'
puts '1 - Play by ID'
puts '2 - Search'
choice = read_integer_in_range("Option: ", 1, 2)
case choice
when 1
album = search_by_id(albums)
play_tracks(album.tracks)
when 2
album = search_album(albums)
play_tracks(album.tracks)
else
puts 'Please select again'
end
finished = read_string('Press ENTER...')
end until finished
end
# 2.2 Print Ablum Genre < 2 Menu Display Albums
def print_album_genres albums
puts('Select Genre')
puts('1 Pop, 2 Classic, 3 Jazz & 4 Rock')
search_genre = read_integer('Enter number: ')
i = 0
while i < albums.length
if search_genre == albums[i].genre
print_album(albums[i])
end
i += 1
end
end
# 2.1 Print albums, album, tracks and track < 2 Menu Display
Albums
def print_track track
puts('Track title is: ' + track.name)
puts('Track file location is: ' +
track.location)
end
def print_tracks tracks
count = tracks.length
i = 0
while (i < count)
print_track(tracks[i]) # use: tracks[x] to access each
track.
i += 1
end
end
def print_album album
puts 'Artist is: ' + album.artist.to_s
puts 'Title is: ' + album.title.to_s
puts 'Genre is ' + $genre_names[album.genre]
# print out the tracks
print_tracks(album.tracks)
end
def print_albums albums
count = albums.length
i = 0
puts 'Album Count ID is: ' + albums.length.to_s
while (i < count)
print_album(albums[i]) # use: tracks[x] to access each
track.
i += 1
end
end
# 2 Menu Display Albums
def display_albums(albums)
finished = false
begin
puts 'Display Albums:'
puts '1 - Display All'
puts '2 - Display Genre'
choice = read_integer_in_range("Option: ", 1, 2)
case choice
when 1
print_albums(albums)
when 2
print_album_genres(albums)
else
puts 'Please select again'
end
finished = read_string('Press ENTER...')
end until finished
end
# 1.1 Read albums, album, tracks and track < 1 Menu Read
Album File
def read_track music_file
name = music_file.gets.chomp
location = music_file.gets
track = Track.new(name, location)
return track
end
def read_tracks music_file
count = music_file.gets().to_i
tracks = Array.new
while (0 < count)
track = read_track(music_file)
tracks << track
count -= 1
end
return tracks
end
def read_album music_file
album_artist =
music_file.gets
album_title = music_file.gets
album_genre =
music_file.gets.to_i
tracks = read_tracks(music_file) #
tracks or music_file
album = Album.new(album_artist,
album_title, album_genre, tracks)
return album
end
def read_albums music_file
count = music_file.gets().to_i
albums = Array.new
while (0 < count)
album = read_album(music_file)
albums << album
count -= 1
end
return albums
end
# 1 Menu Read Album File
def read_album_file
finished = false
begin
$album_file = read_string('Enter File Name ( aka album.txt):
')
music_file = File.new($album_file, "r")
if music_file
albums = read_albums(music_file)
music_file.close()
else
puts "Unable to open file to read!" # this doesn't work when
incorrect value given
end
puts 'Music Library Loaded'
finished = read_string('Press ENTER...')
end until finished
return albums
end
# 0 Main Menu
def main_menu_albums
finished = false
begin
puts 'Main Menu:'
puts '1 - Read Album File'
puts '2 - Display Album Info'
puts '3 - Play Album'
puts '4 - Update Album'
puts '5 - Exit'
choice = read_integer_in_range("Option: ", 1, 5)
case choice
when 1
albums = read_album_file
when 2
display_albums(albums)
when 3
play_album(albums)
when 4
update_albums(albums)
when 5
write_changes albums
finished = true
else
puts 'Please select again'
end
end until finished
end
def main
main_menu_albums
end
main
input_functions.rb
# Display the prompt and return the read string
def read_string prompt
puts prompt
value = gets.chomp
end
# Display the prompt and return the read float
def read_float prompt
value = read_string(prompt)
value.to_f
end
# Display the prompt and return the read integer
def read_integer prompt
value = read_string(prompt)
value.to_i
end
# Read an integer between min and max, prompting with the string provided
def read_integer_in_range(prompt, min, max)
value = read_integer(prompt)
while (value < min or value > max)
puts "Please enter a value between
" + min.to_s + " and " + max.to_s + ": "
value = read_integer(prompt);
end
value
end
# Display the prompt and return the read Boolean
def read_boolean prompt
value = read_string(prompt)
case value
when 'y', 'yes', 'Yes', 'YES'
true
else
false
end
end
def continue_any_char
print "press any key"
STDIN.getch
print " \r" # extra space to overwrite in case next sentence is
short
end
# Test the functions above
=begin
def main
puts "String entered is: " + read_string("Enter a
String: ")
puts "Boolean is: " + read_boolean("Enter yes or
no:").to_s
puts "Float is: " + read_float("Enter a floating point
number: ").to_s
puts "Integer is: " + read_integer_in_range("Enter an
integer between 3 and 6: ", 3, 6).to_s
end
main
=end