soundly 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/Rainbow.md +224 -0
- data/lib/.DS_Store +0 -0
- data/lib/soundly.rb +9 -6
- data/lib/soundly/cli.rb +80 -65
- data/lib/soundly/tracks.rb +17 -22
- data/lib/soundly/version.rb +1 -1
- data/rspotify.md +255 -0
- data/soundly.gemspec +6 -5
- metadata +29 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 982a1a80bc9696fc2a87fde99ad336371b01b04a
|
4
|
+
data.tar.gz: 630fbde11a7f552b0ea8b5338bf70ca1abb2cf88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6b97db82e320dd6c264765a491cc3ea490ae4ebaf7171f50329523923af41507ff1279900df2528a801e72df92376a138c55b08462572e8ee82fee97c3f0095
|
7
|
+
data.tar.gz: a0ed2fb4a3b79a8fa58575c525bfe5fa3188cb8b5e8dd0f7fe22d1c7f0afbaa7d33f0c1429e91d638a3e025f75856854388d0e73023596451d646ec1aa96f147
|
data/.DS_Store
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/Rainbow.md
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
# Rainbow
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/rainbow.svg)](https://rubygems.org/gems/rainbow)
|
4
|
+
[![Build Status](https://travis-ci.org/sickill/rainbow.svg?branch=master)](https://travis-ci.org/sickill/rainbow)
|
5
|
+
[![Build status](https://ci.appveyor.com/api/projects/status/vq4acb2c38642s5q?svg=true)](https://ci.appveyor.com/project/sickill/rainbow)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/sickill/rainbow.svg)](https://codeclimate.com/github/sickill/rainbow)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/sickill/rainbow/badge.svg)](https://coveralls.io/r/sickill/rainbow)
|
8
|
+
|
9
|
+
Rainbow is a ruby gem for colorizing printed text on ANSI terminals.
|
10
|
+
|
11
|
+
It provides a string presenter object, which adds several methods to your
|
12
|
+
strings for wrapping them in [ANSI escape
|
13
|
+
codes](http://en.wikipedia.org/wiki/ANSI_escape_code). These codes when printed
|
14
|
+
in a terminal change text attributes like text color, background color,
|
15
|
+
intensity etc.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
To make your string colored wrap it with `Rainbow()` presenter and call
|
20
|
+
`.color(<color name>)` on it.
|
21
|
+
|
22
|
+
### Example
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'rainbow'
|
26
|
+
|
27
|
+
puts Rainbow("this is red").red + " and " + Rainbow("this on yellow bg").bg(:yellow) + " and " + Rainbow("even bright underlined!").underline.bright
|
28
|
+
|
29
|
+
# => "\e[31mthis is red\e[0m and \e[43mthis on yellow bg\e[0m and \e[4m\e[1meven bright underlined!\e[0m"
|
30
|
+
```
|
31
|
+
|
32
|
+
Or, [watch this video example](https://asciinema.org/a/J928KpHoUQ0sl54ulOSOLE71E?rows=20&speed=2.5)
|
33
|
+
|
34
|
+
### Rainbow presenter API
|
35
|
+
|
36
|
+
Rainbow presenter adds the following methods to presented string:
|
37
|
+
|
38
|
+
* `color(c)` (with `foreground`, and `fg` aliases)
|
39
|
+
* `background(c)` (with `bg` alias)
|
40
|
+
* `bright`
|
41
|
+
* `underline`
|
42
|
+
* `blink`
|
43
|
+
* `inverse`
|
44
|
+
* `hide`
|
45
|
+
* `faint` (not well supported by terminal emulators)
|
46
|
+
* `italic` (not well supported by terminal emulators)
|
47
|
+
|
48
|
+
Text color can also be changed by calling a method named by a color:
|
49
|
+
|
50
|
+
* `black`
|
51
|
+
* `red`
|
52
|
+
* `green`
|
53
|
+
* `yellow`
|
54
|
+
* `blue`
|
55
|
+
* `magenta`
|
56
|
+
* `cyan`
|
57
|
+
* `white`
|
58
|
+
* `aqua`
|
59
|
+
* `silver`
|
60
|
+
* `aliceblue`
|
61
|
+
* `indianred`
|
62
|
+
|
63
|
+
All of the methods return `self` (the presenter object) so you can chain method
|
64
|
+
calls:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
Rainbow("hola!").blue.bright.underline
|
68
|
+
```
|
69
|
+
|
70
|
+
### Refinement
|
71
|
+
|
72
|
+
If you want to use the Refinements version, you can:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require 'rainbow/refinement'
|
76
|
+
using Rainbow
|
77
|
+
puts "Hi!".green
|
78
|
+
```
|
79
|
+
|
80
|
+
Here's an IRB session example:
|
81
|
+
|
82
|
+
```
|
83
|
+
>> 'Hello, World!'.blue.bright.underline
|
84
|
+
NoMethodError: undefined method `blue' for "Hello, World!":String
|
85
|
+
(ripl):1:in `<main>'
|
86
|
+
>> using Rainbow
|
87
|
+
=> main
|
88
|
+
>> 'Hello, World!'.blue.bright.underline
|
89
|
+
=> "\e[34m\e[1m\e[4mHello, World!\e[0m"
|
90
|
+
```
|
91
|
+
|
92
|
+
### Color specification
|
93
|
+
|
94
|
+
Both `color` and `background` accept color specified in any
|
95
|
+
of the following ways:
|
96
|
+
|
97
|
+
* ANSI color number (where 0 is black, 1 is red, 2 is green and so on):
|
98
|
+
`Rainbow("hello").color(1)`
|
99
|
+
|
100
|
+
* [ANSI color](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) name or [X11 color](https://en.wikipedia.org/wiki/X11_color_names) name as a symbol:
|
101
|
+
`Rainbow("hello").color(:yellow)`.
|
102
|
+
This can be simplified to `Rainbow("hello").yellow`
|
103
|
+
|
104
|
+
See [Color list](#user-content-color-list) for all available color names.
|
105
|
+
Note that ANSI colors can be changed in accordance with terminal setting.
|
106
|
+
But X11 color is just a syntax sugar for RGB triplet. So you always see what you specified.
|
107
|
+
|
108
|
+
* RGB triplet as separate values in the range 0-255:
|
109
|
+
`Rainbow("hello").color(115, 23, 98)`
|
110
|
+
|
111
|
+
* RGB triplet as a hex string:
|
112
|
+
`Rainbow("hello").color("FFC482")` or `Rainbow("hello").color("#FFC482")`
|
113
|
+
|
114
|
+
When you specify a color with a RGB triplet rainbow finds the nearest match
|
115
|
+
from 256 colors palette. Note that it requires a 256-colors capable terminal to
|
116
|
+
display correctly.
|
117
|
+
|
118
|
+
#### Example: Choose a random color
|
119
|
+
|
120
|
+
You can pick a random color with Rainbow, it's a one-liner:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
colors = Range.new(0,7).to_a
|
124
|
+
"whoop dee doop".chars.map { |char| Rainbow(char).color(colors.sample) }.join
|
125
|
+
# => "\e[36mw\e[0m\e[37mh\e[0m\e[34mo\e[0m\e[34mo\e[0m\e[37mp\e[0m\e[34m \e[0m\e[36md\e[0m\e[33me\e[0m\e[34me\e[0m\e[37m \e[0m\e[32md\e[0m\e[35mo\e[0m\e[33mo\e[0m\e[36mp\e[0m"
|
126
|
+
|
127
|
+
colors = [:aliceblue, :antiquewhite, :aqua, :aquamarine, :azure, :beige, :bisque, :blanchedalmond, :blueviolet]
|
128
|
+
"whoop dee doop".chars.map { |char| Rainbow(char).color(colors.sample) }.join
|
129
|
+
# => "\e[38;5;135mw\e[0m\e[38;5;230mh\e[0m\e[38;5;231mo\e[0m\e[38;5;135mo\e[0m\e[38;5;231mp\e[0m\e[38;5;231m \e[0m\e[38;5;122md\e[0m\e[38;5;231me\e[0m\e[38;5;231me\e[0m\e[38;5;230m \e[0m\e[38;5;122md\e[0m\e[38;5;51mo\e[0m\e[38;5;51mo\e[0m\e[38;5;51mp\e[0m"
|
130
|
+
```
|
131
|
+
|
132
|
+
### Configuration
|
133
|
+
|
134
|
+
Rainbow can be enabled/disabled globally by setting:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
Rainbow.enabled = true/false
|
138
|
+
```
|
139
|
+
|
140
|
+
When disabled all the methods return an unmodified string
|
141
|
+
(`Rainbow("hello").red == "hello"`).
|
142
|
+
|
143
|
+
It's enabled by default, unless STDOUT/STDERR is not a TTY or a terminal is
|
144
|
+
dumb.
|
145
|
+
|
146
|
+
### Advanced usage
|
147
|
+
|
148
|
+
`Rainbow()` and `Rainbow.enabled` operate on the global Rainbow wrapper
|
149
|
+
instance. If you would like to selectively enable/disable coloring in separate
|
150
|
+
parts of your application you can get a new Rainbow wrapper instance for each
|
151
|
+
of them and control the state of coloring during the runtime.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
rainbow_one = Rainbow.new
|
155
|
+
rainbow_two = Rainbow.new
|
156
|
+
|
157
|
+
rainbow_one.enabled = false
|
158
|
+
|
159
|
+
Rainbow("hello").red # => "\e[31mhello\e[0m" ("hello" if not on TTY)
|
160
|
+
rainbow_one.wrap("hello").red # => "hello"
|
161
|
+
rainbow_two.wrap("hello").red # => "\e[31mhello\e[0m" ("hello" if not on TTY)
|
162
|
+
```
|
163
|
+
|
164
|
+
By default each new instance inherits enabled/disabled state from the global
|
165
|
+
`Rainbow.enabled`.
|
166
|
+
|
167
|
+
This feature comes handy for example when you have multiple output formatters
|
168
|
+
in your application and some of them print to a terminal but others write to a
|
169
|
+
file. Normally rainbow would detect that STDIN/STDERR is a TTY and would
|
170
|
+
colorize all the strings, even the ones that go through file writing
|
171
|
+
formatters. You can easily solve that by disabling coloring for the Rainbow
|
172
|
+
instances that are used by formatters with file output.
|
173
|
+
|
174
|
+
## Installation
|
175
|
+
|
176
|
+
Add it to your Gemfile:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
gem 'rainbow'
|
180
|
+
```
|
181
|
+
|
182
|
+
Or just install it via rubygems:
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
gem install rainbow
|
186
|
+
```
|
187
|
+
|
188
|
+
## Color list
|
189
|
+
|
190
|
+
### ANSI colors
|
191
|
+
|
192
|
+
`black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`
|
193
|
+
|
194
|
+
### X11 colors
|
195
|
+
|
196
|
+
`aliceblue`, `antiquewhite`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`,
|
197
|
+
`blanchedalmond`, `blueviolet`, `brown`, `burlywood`, `cadetblue`, `chartreuse`,
|
198
|
+
`chocolate`, `coral`, `cornflower`, `cornsilk`, `crimson`, `darkblue`,
|
199
|
+
`darkcyan`, `darkgoldenrod`, `darkgray`, `darkgreen`, `darkkhaki`,
|
200
|
+
`darkmagenta`, `darkolivegreen`, `darkorange`, `darkorchid`, `darkred`,
|
201
|
+
`darksalmon`, `darkseagreen`, `darkslateblue`, `darkslategray`, `darkturquoise`,
|
202
|
+
`darkviolet`, `deeppink`, `deepskyblue`, `dimgray`, `dodgerblue`, `firebrick`,
|
203
|
+
`floralwhite`, `forestgreen`, `fuchsia`, `gainsboro`, `ghostwhite`, `gold`,
|
204
|
+
`goldenrod`, `gray`, `greenyellow`, `honeydew`, `hotpink`, `indianred`,
|
205
|
+
`indigo`, `ivory`, `khaki`, `lavender`, `lavenderblush`, `lawngreen`,
|
206
|
+
`lemonchiffon`, `lightblue`, `lightcoral`, `lightcyan`, `lightgoldenrod`,
|
207
|
+
`lightgray`, `lightgreen`, `lightpink`, `lightsalmon`, `lightseagreen`,
|
208
|
+
`lightskyblue`, `lightslategray`, `lightsteelblue`, `lightyellow`, `lime`,
|
209
|
+
`limegreen`, `linen`, `maroon`, `mediumaquamarine`, `mediumblue`,
|
210
|
+
`mediumorchid`, `mediumpurple`, `mediumseagreen`, `mediumslateblue`,
|
211
|
+
`mediumspringgreen`, `mediumturquoise`, `mediumvioletred`, `midnightblue`,
|
212
|
+
`mintcream`, `mistyrose`, `moccasin`, `navajowhite`, `navyblue`, `oldlace`,
|
213
|
+
`olive`, `olivedrab`, `orange`, `orangered`, `orchid`, `palegoldenrod`,
|
214
|
+
`palegreen`, `paleturquoise`, `palevioletred`, `papayawhip`, `peachpuff`,
|
215
|
+
`peru`, `pink`, `plum`, `powderblue`, `purple`, `rebeccapurple`, `rosybrown`,
|
216
|
+
`royalblue`, `saddlebrown`, `salmon`, `sandybrown`, `seagreen`, `seashell`,
|
217
|
+
`sienna`, `silver`, `skyblue`, `slateblue`, `slategray`, `snow`, `springgreen`,
|
218
|
+
`steelblue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`,
|
219
|
+
`webgray`, `webgreen`, `webmaroon`, `webpurple`, `wheat`, `whitesmoke`,
|
220
|
+
`yellowgreen`
|
221
|
+
|
222
|
+
## Authors
|
223
|
+
|
224
|
+
[Marcin Kulik](http://ku1ik.com/) and [great open-source contributors](https://github.com/sickill/rainbow/graphs/contributors).
|
data/lib/.DS_Store
CHANGED
Binary file
|
data/lib/soundly.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
#Environment
|
2
|
-
require_relative "./soundly/version.rb"
|
3
|
-
require_relative "./soundly/cli.rb"
|
4
|
-
require_relative "soundly/tracks.rb"
|
5
|
-
|
6
2
|
require 'pry'
|
3
|
+
require 'rainbow'
|
4
|
+
require 'net/ping'
|
7
5
|
require 'rspotify'
|
8
|
-
|
9
|
-
|
6
|
+
require 'dotenv/load'
|
7
|
+
|
8
|
+
module Soundly
|
9
|
+
require_relative "./soundly/version.rb"
|
10
|
+
require_relative "./soundly/cli.rb"
|
11
|
+
require_relative "soundly/tracks.rb"
|
12
|
+
end
|
data/lib/soundly/cli.rb
CHANGED
@@ -1,59 +1,93 @@
|
|
1
|
-
require 'rspotify'
|
2
|
-
require 'pry'
|
3
|
-
require_relative 'tracks'
|
4
|
-
|
5
1
|
class Soundly::CLI
|
2
|
+
def up?
|
3
|
+
if Net::Ping::External.new("www.google.com").ping? == true
|
4
|
+
true
|
5
|
+
end
|
6
|
+
end
|
7
|
+
def pass_go
|
8
|
+
if !up?
|
9
|
+
puts "You need an internet connection to run this program..."
|
10
|
+
puts "As if I needed to tell you that."
|
11
|
+
puts "Good bye for now, human."
|
12
|
+
exit
|
13
|
+
else
|
14
|
+
@@pills = Soundly::Tracks.new
|
15
|
+
menu
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
6
19
|
def call
|
7
|
-
|
8
|
-
greetings
|
9
|
-
menu
|
10
|
-
goodbye
|
20
|
+
pass_go
|
11
21
|
end
|
12
22
|
|
13
|
-
def
|
14
|
-
|
23
|
+
def menu
|
24
|
+
user_input = nil
|
25
|
+
|
26
|
+
greetings
|
27
|
+
puts Rainbow("Main Menu").green
|
28
|
+
puts Rainbow("Blue Pill").blue + " or" + Rainbow(" Red Pill").red + " or Exit?"
|
29
|
+
|
30
|
+
while user_input != "exit"
|
31
|
+
user_input = gets.strip.downcase
|
32
|
+
if user_input == "exit" || user_input == "3"
|
33
|
+
goodbye
|
34
|
+
elsif user_input == "blue" || user_input == "blue pill" || user_input == "1"
|
35
|
+
blue_pill
|
36
|
+
elsif user_input == "red" || user_input == "red pill" || user_input == "2"
|
37
|
+
red_pill
|
38
|
+
else
|
39
|
+
puts "Come again?"
|
40
|
+
end
|
41
|
+
end
|
15
42
|
end
|
16
43
|
|
17
44
|
def greetings
|
18
|
-
|
19
|
-
print
|
20
|
-
|
45
|
+
puts %Q(Hey there...)
|
46
|
+
print %Q(You like music?)
|
47
|
+
puts %Q( Cool, me too.)
|
21
48
|
print "\n"
|
22
|
-
printf %Q(• The blue pill, allows you to sample a playlist shaped by your fellow homosapien's listening habits (top 50 currently trending songs on spotify).)
|
23
|
-
print "\n"
|
24
|
-
printf %Q(• Take the red pill, you get to sample an ever evolving playlist of sounds I fancy.)
|
25
49
|
end
|
26
50
|
|
27
|
-
def
|
28
|
-
puts
|
29
|
-
puts %Q(Heres what I am currently listening to.)
|
30
|
-
@@pills.red_songs.each.with_index(1) {|object, index| puts "#{index}. #{object.name} by #{object.artists[0].name} \n"}
|
51
|
+
def inner_playlist_options
|
52
|
+
puts " "
|
31
53
|
puts %Q(Type a song's listing number to learn more.)
|
32
54
|
puts %Q(Type "Menu" to head back to the main menu.)
|
55
|
+
puts %Q(Type exit to peace out.)
|
56
|
+
puts " "
|
57
|
+
end
|
58
|
+
|
59
|
+
def red_playlist
|
60
|
+
puts " "
|
61
|
+
puts %Q(Heres what I am currently listening to.)
|
62
|
+
@@pills.red_songs.each.with_index(1) do |song, song_index|
|
63
|
+
puts "#{song_index}. #{song.name} by #{song.artists[0].name} \n"
|
64
|
+
end
|
65
|
+
inner_playlist_options
|
33
66
|
end
|
34
67
|
|
35
68
|
def blue_playlist
|
36
|
-
puts %Q(
|
69
|
+
puts %Q(America's top 50, coming up...)
|
37
70
|
puts "\n"
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
puts %Q(Type "Menu" to head back to the main menu.)
|
71
|
+
@@pills.blue_songs.each.with_index(1) do |song, song_index|
|
72
|
+
puts "#{song_index}. #{song.name} by #{song.artists[0].name}"
|
73
|
+
end
|
74
|
+
inner_playlist_options
|
43
75
|
end
|
44
76
|
|
45
77
|
def blue_pill
|
46
78
|
print "\n"
|
47
79
|
puts "Blue Pill: Main Menu"
|
48
|
-
sleep 1
|
49
80
|
blue_playlist
|
50
81
|
|
51
82
|
user_input = nil
|
52
83
|
while user_input != "menu"
|
53
|
-
user_input = gets.strip
|
84
|
+
user_input = gets.downcase.strip
|
54
85
|
if user_input == "menu"
|
55
86
|
menu
|
87
|
+
elsif user_input == "exit"
|
88
|
+
goodbye
|
56
89
|
elsif (1..50).to_a.include?(user_input.to_i)
|
90
|
+
puts " "
|
57
91
|
puts "Here are details on #{@@pills.blue_songs[user_input.to_i-1].name}"
|
58
92
|
song = @@pills.blue_songs[user_input.to_i-1]
|
59
93
|
puts "Song name: #{song.name}"
|
@@ -62,19 +96,20 @@ class Soundly::CLI
|
|
62
96
|
puts "Duration: #{song.duration_ms}"
|
63
97
|
puts "Popularity: #{song.popularity}"
|
64
98
|
puts "Preview_url: #{song.preview_url}" if song.preview_url != nil
|
65
|
-
|
99
|
+
puts " "
|
100
|
+
puts "Would you like to select another song, Main Menu or Exit?"
|
66
101
|
else
|
67
|
-
puts %(
|
68
|
-
puts
|
69
|
-
|
70
|
-
puts
|
71
|
-
print "\n"
|
102
|
+
puts %(Try again.)
|
103
|
+
puts " "
|
104
|
+
puts %(Select a number from the list, Menu or Exit)
|
105
|
+
puts " "
|
72
106
|
end
|
73
107
|
end
|
74
108
|
end
|
75
109
|
|
76
110
|
def red_pill
|
77
|
-
|
111
|
+
puts " "
|
112
|
+
puts %Q((I like your style human.))
|
78
113
|
puts "Red Pill: Main Menu"
|
79
114
|
red_playlist
|
80
115
|
|
@@ -82,10 +117,13 @@ class Soundly::CLI
|
|
82
117
|
while user_input != "menu"
|
83
118
|
user_input = gets.strip
|
84
119
|
object = @@pills.red_songs.count.to_i
|
85
|
-
|
120
|
+
|
86
121
|
if user_input == "menu"
|
87
122
|
menu
|
123
|
+
elsif user_input == "exit"
|
124
|
+
goodbye
|
88
125
|
elsif (1..object).include?(user_input.to_i)
|
126
|
+
puts " "
|
89
127
|
puts "Here are details on #{@@pills.red_songs[user_input.to_i-1].name}"
|
90
128
|
song = @@pills.red_songs[user_input.to_i-1]
|
91
129
|
puts "Song name: #{song.name}"
|
@@ -95,41 +133,18 @@ class Soundly::CLI
|
|
95
133
|
puts "Popularity: #{song.popularity}"
|
96
134
|
puts "Preview_url: #{song.preview_url}" if song.preview_url != nil
|
97
135
|
print "\n"
|
136
|
+
puts "Would you like to select another song, go back to the Main Menu or Exit?"
|
98
137
|
else
|
99
|
-
puts %(
|
100
|
-
|
101
|
-
|
102
|
-
puts %(Or you can type "Exit" to head back to main menu or course.)
|
138
|
+
puts %(Try again.)
|
139
|
+
print " \n"
|
140
|
+
puts %(Select a number from the list, "Menu" or "Exit")
|
103
141
|
print "\n"
|
104
142
|
end
|
105
143
|
end
|
106
144
|
end
|
107
145
|
|
108
|
-
def menu
|
109
|
-
user_input = nil
|
110
|
-
puts "Main Menu"
|
111
|
-
puts %Q(Type "Blue" for the Blue pill, and "Red" for the Red pill.)
|
112
|
-
puts %Q(Type "Exit" to part ways.)
|
113
|
-
print "\n"
|
114
|
-
puts %Q(Choose wisely, human...)
|
115
|
-
|
116
|
-
while user_input != "exit"
|
117
|
-
user_input = gets.strip.downcase
|
118
|
-
if user_input == "exit"
|
119
|
-
goodbye
|
120
|
-
elsif user_input == "blue"
|
121
|
-
blue_pill
|
122
|
-
elsif user_input == "red"
|
123
|
-
red_pill
|
124
|
-
else
|
125
|
-
puts "Come again?"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
146
|
def goodbye
|
131
|
-
puts %Q(
|
132
|
-
puts %Q(See you soon.)
|
147
|
+
puts %Q(Peace out.)
|
133
148
|
exit
|
134
149
|
end
|
135
|
-
end
|
150
|
+
end
|
data/lib/soundly/tracks.rb
CHANGED
@@ -1,31 +1,35 @@
|
|
1
|
-
require 'rspotify'
|
2
|
-
require 'pry'
|
3
|
-
require_relative 'cli'
|
4
|
-
|
5
1
|
class Soundly::Tracks
|
6
|
-
# attr_accessor :track_name, :artist, :album, :genre, :duration, :popularity, :position, :preview_url
|
7
|
-
|
8
2
|
@@blue_playlist = []
|
9
3
|
@@red_playlist = []
|
10
|
-
|
4
|
+
@@all = []
|
5
|
+
|
6
|
+
def authenticate #LOG IN
|
7
|
+
RSpotify.authenticate(ENV['CLIENT_ID'], ENV['CLIENT_SECRET'])
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.all(playlist)
|
11
|
+
if playlist == "blue"
|
12
|
+
@@blue_playlist
|
13
|
+
else
|
14
|
+
@@red_playlist
|
15
|
+
end
|
16
|
+
end
|
11
17
|
|
12
18
|
def initialize
|
13
19
|
blue_playlist
|
14
20
|
red_playlist
|
15
21
|
end
|
16
22
|
|
17
|
-
def blue_playlist
|
18
|
-
|
23
|
+
def blue_playlist #SPOTIFY TOP 50 IN AMERICA
|
24
|
+
authenticate
|
19
25
|
playlist = RSpotify::Playlist.find('spotifycharts', '37i9dQZEVXbLRQDuF5jeBp')
|
20
26
|
playlist.tracks.each do |song|
|
21
27
|
@@blue_playlist << song
|
22
|
-
|
23
|
-
#Soundly::Tracks.save_song(song)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
def red_playlist
|
28
|
-
|
31
|
+
def red_playlist #MY PERSONAL SPOTIFY PLAYLIST
|
32
|
+
authenticate
|
29
33
|
playlist = RSpotify::Playlist.find('dwyn.hrmn', '7BQJkBkL5muBFOc7ok76XO')
|
30
34
|
playlist.tracks.each do |song|
|
31
35
|
@@red_playlist << song
|
@@ -39,13 +43,4 @@ class Soundly::Tracks
|
|
39
43
|
def red_songs
|
40
44
|
@@red_playlist
|
41
45
|
end
|
42
|
-
|
43
|
-
def self.all(playlist)
|
44
|
-
if playlist == blue
|
45
|
-
@@blue_playlist
|
46
|
-
else
|
47
|
-
@@red_playlist
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
46
|
end
|
data/lib/soundly/version.rb
CHANGED
data/rspotify.md
ADDED
@@ -0,0 +1,255 @@
|
|
1
|
+
# RSpotify
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/rspotify.svg)](http://badge.fury.io/rb/rspotify)
|
4
|
+
[![Build Status](https://travis-ci.org/guilhermesad/rspotify.svg?branch=master)](https://travis-ci.org/guilhermesad/rspotify)
|
5
|
+
|
6
|
+
This is a ruby wrapper for the [Spotify Web API](https://developer.spotify.com/web-api).
|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
* [Full documentation](http://www.rubydoc.info/github/guilhermesad/rspotify/master)
|
11
|
+
* Full API Endpoint coverage
|
12
|
+
* OAuth and other authorization flows
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
gem 'rspotify'
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install rspotify
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
RSpotify was designed with usability as its primary goal, so that you can forget the API and intuitively interact with your playlists, favorite artists, users and so on.
|
31
|
+
|
32
|
+
You can write things like `my_playlist.tracks.sort_by(&:popularity).last.album` without having to think which API calls must be done. RSpotify fills the gaps for you.
|
33
|
+
|
34
|
+
Below are some basic usage examples. Check the [documentation](http://rdoc.info/github/guilhermesad/rspotify/master/frames) for the complete reference.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require 'rspotify'
|
38
|
+
|
39
|
+
artists = RSpotify::Artist.search('Arctic Monkeys')
|
40
|
+
|
41
|
+
arctic_monkeys = artists.first
|
42
|
+
arctic_monkeys.popularity #=> 74
|
43
|
+
arctic_monkeys.genres #=> ["Alternative Pop/Rock", "Indie", ...]
|
44
|
+
arctic_monkeys.top_tracks(:US) #=> (Track array)
|
45
|
+
|
46
|
+
albums = arctic_monkeys.albums
|
47
|
+
albums.first.name #=> "AM"
|
48
|
+
|
49
|
+
am = albums.first
|
50
|
+
am.release_date #=> "2013-09-10"
|
51
|
+
am.images #=> (Image array)
|
52
|
+
am.available_markets #=> ["AR", "BO", "BR", ...]
|
53
|
+
|
54
|
+
tracks = am.tracks
|
55
|
+
tracks.first.name #=> "Do I Wanna Know?"
|
56
|
+
|
57
|
+
do_i_wanna_know = tracks.first
|
58
|
+
do_i_wanna_know.duration_ms #=> 272386
|
59
|
+
do_i_wanna_know.track_number #=> 1
|
60
|
+
do_i_wanna_know.preview_url #=> "https://p.scdn.co/mp3-preview/<id>"
|
61
|
+
|
62
|
+
playlists = RSpotify::Playlist.search('Indie')
|
63
|
+
playlists.first.name #=> "The Indie Mix"
|
64
|
+
|
65
|
+
# You can search within other types too
|
66
|
+
albums = RSpotify::Album.search('The Wall')
|
67
|
+
tracks = RSpotify::Track.search('Thriller')
|
68
|
+
```
|
69
|
+
|
70
|
+
Find by id:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
arctic_monkeys = RSpotify::Artist.find('7Ln80lUS6He07XvHI8qqHH')
|
74
|
+
arctic_monkeys.related_artists #=> (Artist array)
|
75
|
+
|
76
|
+
am = RSpotify::Album.find('41vPD50kQ7JeamkxQW7Vuy')
|
77
|
+
am.album_type #=> "single"
|
78
|
+
|
79
|
+
do_i_wanna_know = RSpotify::Track.find('2UzMpPKPhbcC8RbsmuURAZ')
|
80
|
+
do_i_wanna_know.album #=> (Album object)
|
81
|
+
|
82
|
+
me = RSpotify::User.find('guilhermesad')
|
83
|
+
me.uri #=> "spotify:user:guilhermesad"
|
84
|
+
|
85
|
+
# Or find several objects at once:
|
86
|
+
|
87
|
+
ids = %w(2UzMpPKPhbcC8RbsmuURAZ 7Jzsc04YpkRwB1zeyM39wE)
|
88
|
+
|
89
|
+
my_tracks = RSpotify::Track.find(ids)
|
90
|
+
my_tracks.size #=> 2
|
91
|
+
```
|
92
|
+
|
93
|
+
Some data require authentication to be accessed, such as playlists' details. You can easily get your credentials [here](https://developer.spotify.com/my-applications).
|
94
|
+
|
95
|
+
Then just copy and paste them like so:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
RSpotify.authenticate("<your_client_id>", "<your_client_secret>")
|
99
|
+
|
100
|
+
# Now you can access playlists in detail, browse featured content and more
|
101
|
+
|
102
|
+
me = RSpotify::User.find('guilhermesad')
|
103
|
+
me.playlists #=> (Playlist array)
|
104
|
+
|
105
|
+
# Find by id
|
106
|
+
playlist = RSpotify::Playlist.find('guilhermesad', '1Xi8mgiuHHPLQYOw2Q16xv')
|
107
|
+
playlist.name #=> "d33p"
|
108
|
+
playlist.description #=> "d33p h0uz"
|
109
|
+
playlist.followers['total'] #=> 1
|
110
|
+
playlist.tracks #=> (Track array)
|
111
|
+
|
112
|
+
# Search by category
|
113
|
+
party = RSpotify::Category.find('party')
|
114
|
+
party.playlists #=> (Playlist array)
|
115
|
+
categories = RSpotify::Category.list # See all available categories
|
116
|
+
|
117
|
+
# Access featured content from Spotify's Browse tab
|
118
|
+
featured_playlists = RSpotify::Playlist.browse_featured(country: 'US')
|
119
|
+
new_releases = RSpotify::Album.new_releases(country: 'ES')
|
120
|
+
|
121
|
+
# Access tracks' audio features
|
122
|
+
sorry = RSpotify::Track.search("Sorry").first
|
123
|
+
sorry.audio_features.danceability #=> 0.605
|
124
|
+
sorry.audio_features.energy #=> 0.768
|
125
|
+
sorry.audio_features.tempo #=> 100.209
|
126
|
+
|
127
|
+
# Get recommendations
|
128
|
+
recommendations = RSpotify::Recommendations.generate(seed_genres: ['blues', 'country'])
|
129
|
+
recommendations = RSpotify::Recommendations.generate(seed_tracks: my_fav_tracks.map(&:id))
|
130
|
+
recommendations = RSpotify::Recommendations.generate(seed_artists: my_fav_artists.map(&:id))
|
131
|
+
recommendations.tracks #=> (Track array)
|
132
|
+
```
|
133
|
+
|
134
|
+
## Rails + OAuth
|
135
|
+
|
136
|
+
You might want your application to access a user's Spotify account.
|
137
|
+
|
138
|
+
For instance, suppose you want your app to create playlists for the user based on their taste, or to add a feature that syncs user's playlists with some external app.
|
139
|
+
|
140
|
+
If so, add the following to your application (Remember to [get your credentials](https://developer.spotify.com/my-applications))
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# config/application.rb
|
144
|
+
|
145
|
+
RSpotify::authenticate("<your_client_id>", "<your_client_secret>")
|
146
|
+
```
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
# config/initializers/omniauth.rb
|
150
|
+
|
151
|
+
require 'rspotify/oauth'
|
152
|
+
|
153
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
154
|
+
provider :spotify, "<your_client_id>", "<your_client_secret>", scope: 'user-read-email playlist-modify-public user-library-read user-library-modify'
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
You should replace the scope values for the ones your own app will require from the user. You can see the list of available scopes in [here](https://developer.spotify.com/web-api/using-scopes).
|
159
|
+
|
160
|
+
Next, make a link so the user can log in with his Spotify account:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
<%= link_to 'Sign in with Spotify', '/auth/spotify' %>
|
164
|
+
```
|
165
|
+
|
166
|
+
And create a route to receive the callback:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
# config/routes.rb
|
170
|
+
|
171
|
+
get '/auth/spotify/callback', to: 'users#spotify'
|
172
|
+
```
|
173
|
+
|
174
|
+
Remember you need to tell Spotify this address is white-listed. You can do this by adding it to the Redirect URIs list in your [application page](https://developer.spotify.com/my-applications). An example of Redirect URI would be http://localhost:3000/auth/spotify/callback.
|
175
|
+
|
176
|
+
Finally, create a new RSpotify User with the response received:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class UsersController < ApplicationController
|
180
|
+
def spotify
|
181
|
+
spotify_user = RSpotify::User.new(request.env['omniauth.auth'])
|
182
|
+
# Now you can access user's private data, create playlists and much more
|
183
|
+
|
184
|
+
# Access private data
|
185
|
+
spotify_user.country #=> "US"
|
186
|
+
spotify_user.email #=> "example@email.com"
|
187
|
+
|
188
|
+
# Create playlist in user's Spotify account
|
189
|
+
playlist = spotify_user.create_playlist!('my-awesome-playlist')
|
190
|
+
|
191
|
+
# Add tracks to a playlist in user's Spotify account
|
192
|
+
tracks = RSpotify::Track.search('Know')
|
193
|
+
playlist.add_tracks!(tracks)
|
194
|
+
playlist.tracks.first.name #=> "Somebody That I Used To Know"
|
195
|
+
|
196
|
+
# Access and modify user's music library
|
197
|
+
spotify_user.save_tracks!(tracks)
|
198
|
+
spotify_user.saved_tracks.size #=> 20
|
199
|
+
spotify_user.remove_tracks!(tracks)
|
200
|
+
|
201
|
+
albums = RSpotify::Album.search('launeddas')
|
202
|
+
spotify_user.save_albums!(albums)
|
203
|
+
spotify_user.saved_albums.size #=> 10
|
204
|
+
spotify_user.remove_albums!(albums)
|
205
|
+
|
206
|
+
# Use Spotify Follow features
|
207
|
+
spotify_user.follow(playlist)
|
208
|
+
spotify_user.follows?(artists)
|
209
|
+
spotify_user.unfollow(users)
|
210
|
+
|
211
|
+
# Get user's top played artists and tracks
|
212
|
+
spotify_user.top_artists #=> (Artist array)
|
213
|
+
spotify_user.top_tracks(time_range: 'short_term') #=> (Track array)
|
214
|
+
|
215
|
+
# Check doc for more
|
216
|
+
end
|
217
|
+
end
|
218
|
+
```
|
219
|
+
|
220
|
+
The user's access token is automatically refreshed by RSpotify when needed. This is specially useful if you persist the user data on a database: this way he only needs to log in to Spotify once in his entire use of your application.
|
221
|
+
|
222
|
+
RSpotify provides a way to facilitate persistence:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
hash = spotify_user.to_hash
|
226
|
+
# hash containing all user attributes, including access tokens
|
227
|
+
|
228
|
+
# Use the hash to persist the data the way you prefer...
|
229
|
+
|
230
|
+
# Then recover the Spotify user whenever you like
|
231
|
+
spotify_user = RSpotify::User.new(hash)
|
232
|
+
spotify_user.create_playlist!('my_awesome_playlist') # automatically refreshes token
|
233
|
+
```
|
234
|
+
|
235
|
+
## Getting raw response
|
236
|
+
|
237
|
+
To get the raw response from Spotify API requests, just toggle the `raw_response` variable:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
RSpotify.raw_response = true
|
241
|
+
RSpotify::Artist.search('Cher') #=> (String with raw json response)
|
242
|
+
```
|
243
|
+
|
244
|
+
## Notes
|
245
|
+
|
246
|
+
If you'd like to use OAuth outside rails, have a look [here](https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow) for the requests that need to be made. You should be able to pass the response to RSpotify::User.new just as well, and from there easily create playlists and more for your user.
|
247
|
+
|
248
|
+
## Contributing
|
249
|
+
|
250
|
+
1. Fork it ( https://github.com/guilhermesad/rspotify/fork )
|
251
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
252
|
+
3. Test your changes (`bundle exec rspec`)
|
253
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
254
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
255
|
+
6. Create a new Pull Request
|
data/soundly.gemspec
CHANGED
@@ -25,9 +25,10 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.14"
|
27
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
-
spec.add_development_dependency "rspotify"
|
30
|
-
spec.add_development_dependency "spotify-client"
|
31
|
-
spec.add_development_dependency "omniauth-spotify"
|
32
28
|
spec.add_development_dependency "pry"
|
33
|
-
|
29
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
30
|
+
spec.add_dependency "net-ping"
|
31
|
+
spec.add_dependency "dotenv"
|
32
|
+
spec.add_dependency "rspotify"
|
33
|
+
spec.add_dependency "rainbow"
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soundly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "<dwyn>"
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,28 +38,42 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
61
|
+
version: '3.2'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
68
|
+
version: '3.2'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: net-ping
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
|
-
type: :
|
76
|
+
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
@@ -67,13 +81,13 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: dotenv
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
|
-
type: :
|
90
|
+
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
@@ -81,13 +95,13 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: rspotify
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
|
-
type: :
|
104
|
+
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
@@ -95,13 +109,13 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: rainbow
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0'
|
104
|
-
type: :
|
118
|
+
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
@@ -122,6 +136,7 @@ files:
|
|
122
136
|
- CODE_OF_CONDUCT.md
|
123
137
|
- Gemfile
|
124
138
|
- README.md
|
139
|
+
- Rainbow.md
|
125
140
|
- Rakefile
|
126
141
|
- bin/console
|
127
142
|
- bin/setup
|
@@ -132,6 +147,7 @@ files:
|
|
132
147
|
- lib/soundly/tracks.rb
|
133
148
|
- lib/soundly/version.rb
|
134
149
|
- notes.md
|
150
|
+
- rspotify.md
|
135
151
|
- soundly.gemspec
|
136
152
|
- spec.md
|
137
153
|
homepage: https://github.com/dwyn/soundly
|
@@ -153,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
169
|
version: '0'
|
154
170
|
requirements: []
|
155
171
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.6.
|
172
|
+
rubygems_version: 2.6.14
|
157
173
|
signing_key:
|
158
174
|
specification_version: 4
|
159
175
|
summary: This gem will play songs from a revolving playlist through the Spotify API
|