spotify_rec 1.1 → 1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/spotify_rec +32 -25
- data/lib/login.rb +151 -117
- data/lib/menu.rb +90 -67
- data/lib/my_list.rb +153 -137
- data/lib/playlist.rb +98 -67
- data/lib/rec.rb +56 -44
- data/lib/user.rb +89 -69
- data/public/users.json +1 -13
- metadata +3 -4
- data/lib/run.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 832dfdbb67807131538f45562b49208797c83e0b11604cbbaa72891af354daab
|
4
|
+
data.tar.gz: cc7abdbdc29cda735fb491e2eb30c35957dd60be465f30f9e253d6c4fe8f294a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc61791f2c2d5065b66010f991f5c625db257209562648f917f05832e8dcadb4545fe452e9c75eb30e9ff021a54e4e1be2dc97fd7f99bba0826cd65f5afb33fb
|
7
|
+
data.tar.gz: 528555fb05397d6d5106f724324d56da3e2eed96a003eed0a3ce9270640beba67f6dfb8d46724202007df0d6d059dab152945a396d2d82281523a3662f289a11
|
data/bin/spotify_rec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# gems
|
4
5
|
require 'rspotify'
|
@@ -15,12 +16,14 @@ require_relative '../lib/login'
|
|
15
16
|
require_relative '../lib/rec'
|
16
17
|
require_relative '../lib/menu'
|
17
18
|
require_relative '../lib/my_list'
|
19
|
+
require_relative '../lib/tutorial'
|
20
|
+
require_relative '../lib/error'
|
18
21
|
|
19
|
-
#modules
|
22
|
+
# modules
|
20
23
|
include Login
|
24
|
+
include Tutorial
|
21
25
|
|
22
|
-
RSpotify.authenticate(
|
23
|
-
$prompt = TTY::Prompt.new
|
26
|
+
RSpotify.authenticate('712ff89a218a4e6dbe1f169e06f949b9', 'e9e0517f405b4a01a1be8823126459b7')
|
24
27
|
|
25
28
|
VERSION = 1.0
|
26
29
|
|
@@ -28,27 +31,31 @@ ARGV << '--run' if ARGV.empty?
|
|
28
31
|
|
29
32
|
options = {}
|
30
33
|
parser = OptionParser.new do |opts|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
opts.banner = 'Welcome to Spotify Recommendations! Usage: spotify_rec [options]'.colorize(:light_green)
|
35
|
+
|
36
|
+
opts.on('-v', '--version', 'Display the version') do
|
37
|
+
puts "Spotify Recommendations version #{VERSION}".colorize(:light_green)
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-h', '--help', 'Display the help message') do
|
41
|
+
puts opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-t', '--tutorial', 'View a brief tutorial') do
|
46
|
+
Tutorial.start
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('-qGENRE', '--quick=GENRE', 'Generate a quick recommendation with the chosen genre') do |genre|
|
50
|
+
recommendations = RSpotify::Recommendations.generate(limit: 5, seed_genres: [genre])
|
51
|
+
cleaned_recs = recommendations.tracks.map { |t| "#{t.name} by #{t.artists[0].name}" }
|
52
|
+
puts '》 RECOMMENDATIONS 《'.colorize(:light_green)
|
53
|
+
cleaned_recs.each { |track| puts track }
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on('-r', '--run', 'Run the application') do
|
57
|
+
Login.login
|
58
|
+
end
|
52
59
|
end
|
53
60
|
|
54
|
-
parser.parse!
|
61
|
+
parser.parse!
|
data/lib/login.rb
CHANGED
@@ -1,117 +1,151 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'menu'
|
4
|
+
|
5
|
+
module Login
|
6
|
+
@prompt = TTY::Prompt.new
|
7
|
+
@count = 0
|
8
|
+
|
9
|
+
# Login Logic Section
|
10
|
+
def initial_login
|
11
|
+
clear
|
12
|
+
ascii_art
|
13
|
+
puts '》 Welcome to the Spotify Recommendations App! 《'.colorize(:light_green)
|
14
|
+
puts
|
15
|
+
@prompt.select("Are you a new or returning user? \n", %w[New Returning])
|
16
|
+
end
|
17
|
+
|
18
|
+
def login
|
19
|
+
new_returning = initial_login.downcase
|
20
|
+
new_user if new_returning == 'new'
|
21
|
+
returning_user if new_returning == 'returning'
|
22
|
+
end
|
23
|
+
|
24
|
+
# New user
|
25
|
+
|
26
|
+
def new_user
|
27
|
+
system('clear')
|
28
|
+
File.open(userdata, 'w') { |f| f.write([].to_json) } unless File.exist?(userdata)
|
29
|
+
puts 'Welcome! Please register for an account to continue.'.colorize(:light_green)
|
30
|
+
username = @prompt.ask('Username >')
|
31
|
+
raise RequirementError.new, 'Requirements not met' if username.match?(/[!@#$%^&*(),.?":{}|<>]/)
|
32
|
+
|
33
|
+
new_user_password(username)
|
34
|
+
rescue RequirementError
|
35
|
+
puts 'Username cannot contain special characters. Please try again!'.colorize(:light_red)
|
36
|
+
new_user
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_user_password(username)
|
40
|
+
password = @prompt.mask('Password >')
|
41
|
+
raise RequirementError.new, 'Requirements not met' if password.match?(/[!@#$%^&*(),.?":{}|<>]/)
|
42
|
+
|
43
|
+
@user = User.new(username, password, gen_uid)
|
44
|
+
@user_playlist = Playlist.new(@user)
|
45
|
+
store_user
|
46
|
+
rescue RequirementError
|
47
|
+
puts 'Password cannot contain special characters. Please try again!'.colorize(:light_red)
|
48
|
+
end
|
49
|
+
|
50
|
+
def store_user
|
51
|
+
data = load_data
|
52
|
+
user_details = {
|
53
|
+
'id' => @user.uid.to_s,
|
54
|
+
'username' => @user.username,
|
55
|
+
'password' => @user.password,
|
56
|
+
'playlist' => @user.playlist,
|
57
|
+
'mylist' => @user.mylist
|
58
|
+
}
|
59
|
+
data << user_details
|
60
|
+
write_user(data)
|
61
|
+
end
|
62
|
+
|
63
|
+
def write_user(data)
|
64
|
+
File.open(userdata, 'w') do |f|
|
65
|
+
f.puts JSON.pretty_generate(data)
|
66
|
+
end
|
67
|
+
puts "You're now registered! Logging you in..".colorize(:light_green)
|
68
|
+
sleep(1)
|
69
|
+
go_to_menu
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returning user
|
73
|
+
|
74
|
+
def returning_user
|
75
|
+
system('clear')
|
76
|
+
File.open(userdata, 'w') { |f| f.write([].to_json) } unless File.exist?(userdata)
|
77
|
+
puts 'Welcome back! Please login to continue.'.colorize(:light_green)
|
78
|
+
username = @prompt.ask('Username >')
|
79
|
+
user_password = @prompt.mask('Password >')
|
80
|
+
authenticate(username, user_password)
|
81
|
+
end
|
82
|
+
|
83
|
+
def authenticate(username, user_password)
|
84
|
+
data_arr = load_data
|
85
|
+
user_data(data_arr, username, user_password)
|
86
|
+
end
|
87
|
+
|
88
|
+
def user_data(data, username, user_password)
|
89
|
+
data.each do |hash|
|
90
|
+
next unless hash['username'].downcase == username.downcase
|
91
|
+
|
92
|
+
next unless hash['password'] == user_password
|
93
|
+
|
94
|
+
@user = User.new(username, user_password, hash['id'], hash['playlist'], hash['mylist'])
|
95
|
+
go_to_menu
|
96
|
+
end
|
97
|
+
@count += 1
|
98
|
+
no_auth
|
99
|
+
end
|
100
|
+
|
101
|
+
def no_auth
|
102
|
+
puts 'Incorrect username or password!'.colorize(:red)
|
103
|
+
sleep(1)
|
104
|
+
if @count >= 3
|
105
|
+
puts 'You have tried too many times! The application will now close..'.colorize(:light_red)
|
106
|
+
exit
|
107
|
+
end
|
108
|
+
returning_user
|
109
|
+
end
|
110
|
+
|
111
|
+
# Helper Module Methods
|
112
|
+
|
113
|
+
def user
|
114
|
+
@user
|
115
|
+
end
|
116
|
+
|
117
|
+
def gen_uid
|
118
|
+
load_data.length + 1
|
119
|
+
end
|
120
|
+
|
121
|
+
def userdata
|
122
|
+
path = File.join(File.dirname(File.dirname(File.absolute_path(__FILE__))))
|
123
|
+
"#{path}/public/users.json"
|
124
|
+
end
|
125
|
+
|
126
|
+
def load_data
|
127
|
+
file = File.read(userdata)
|
128
|
+
JSON.parse(file)
|
129
|
+
end
|
130
|
+
|
131
|
+
def clear
|
132
|
+
system('clear')
|
133
|
+
end
|
134
|
+
|
135
|
+
def go_to_menu
|
136
|
+
menu = Menu.new(@user)
|
137
|
+
menu.menu_router
|
138
|
+
end
|
139
|
+
|
140
|
+
def ascii_art
|
141
|
+
puts " ;;;;;;;;;;;;;;;;;;;
|
142
|
+
; ;
|
143
|
+
; ;
|
144
|
+
; ;
|
145
|
+
; ;
|
146
|
+
; ;
|
147
|
+
,;;;;; ,;;;;;
|
148
|
+
;;;;;; ;;;;;;
|
149
|
+
`;;;;' `;;;;'\n".colorize(:light_green)
|
150
|
+
end
|
151
|
+
end
|
data/lib/menu.rb
CHANGED
@@ -1,67 +1,90 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
@
|
6
|
-
@
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
case selection
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Menu
|
4
|
+
def initialize(user)
|
5
|
+
@user = user
|
6
|
+
@prompt = TTY::Prompt.new
|
7
|
+
@playlist = Playlist.new(@user)
|
8
|
+
end
|
9
|
+
|
10
|
+
def display_menu
|
11
|
+
system('clear')
|
12
|
+
arr = ['My List', 'Recommendations', 'Playlist', 'Account Details', 'Exit']
|
13
|
+
@prompt.select("》 MAIN MENU 《\n".colorize(:light_green), arr)
|
14
|
+
end
|
15
|
+
|
16
|
+
def menu_router
|
17
|
+
selection = display_menu
|
18
|
+
case selection
|
19
|
+
when 'My List'
|
20
|
+
my_list
|
21
|
+
when 'Recommendations'
|
22
|
+
recommendation = Rec.new(@user)
|
23
|
+
recommendation.amount_of_suggestions
|
24
|
+
else
|
25
|
+
case_menu(selection)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def case_menu(selection)
|
30
|
+
case selection
|
31
|
+
when 'Playlist'
|
32
|
+
@playlist.menu
|
33
|
+
when 'Account Details'
|
34
|
+
account_details
|
35
|
+
when 'Exit'
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def my_list
|
41
|
+
system('clear')
|
42
|
+
selection = @prompt.select("》 MY LIST 《\n".colorize(:light_green), %w[Display Add Remove Back])
|
43
|
+
mylist = MyList.new(@user)
|
44
|
+
case_my_list(selection, mylist)
|
45
|
+
end
|
46
|
+
|
47
|
+
def case_my_list(selection, mylist)
|
48
|
+
case selection
|
49
|
+
when 'Display'
|
50
|
+
mylist.list
|
51
|
+
when 'Add'
|
52
|
+
mylist.add_to_list
|
53
|
+
when 'Remove'
|
54
|
+
mylist.remove_from_list
|
55
|
+
when 'Back'
|
56
|
+
menu_router
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def account_details_select
|
61
|
+
system('clear')
|
62
|
+
arr = ['View Details', 'Change Username', 'Change Password', 'Delete Account', 'Back']
|
63
|
+
@prompt.select('》 ACCOUNT DETAILS 《\n'.colorize(:light_green), arr)
|
64
|
+
end
|
65
|
+
|
66
|
+
def account_details
|
67
|
+
selection = account_details_select
|
68
|
+
case selection
|
69
|
+
when 'View Details'
|
70
|
+
@user.details
|
71
|
+
when 'Change Username'
|
72
|
+
username = @prompt.ask('Please enter your new username >')
|
73
|
+
@user.change_username(username)
|
74
|
+
else
|
75
|
+
case_account_details(selection)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def case_account_details(selection)
|
80
|
+
case selection
|
81
|
+
when 'Change Password'
|
82
|
+
password = @prompt.ask('Please enter your new password >')
|
83
|
+
@user.change_password(password)
|
84
|
+
when 'Delete Account'
|
85
|
+
@user.delete_account
|
86
|
+
when 'Back'
|
87
|
+
menu_router
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|