audio_addict 0.1.9 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -2
- data/bin/radio +1 -0
- data/lib/audio_addict.rb +8 -8
- data/lib/audio_addict/api.rb +13 -13
- data/lib/audio_addict/auto_properties.rb +1 -1
- data/lib/audio_addict/cache.rb +2 -4
- data/lib/audio_addict/channel.rb +13 -13
- data/lib/audio_addict/cli.rb +10 -12
- data/lib/audio_addict/commands/api.rb +8 -9
- data/lib/audio_addict/commands/base.rb +4 -6
- data/lib/audio_addict/commands/channels.rb +5 -6
- data/lib/audio_addict/commands/config.rb +47 -8
- data/lib/audio_addict/commands/history.rb +4 -4
- data/lib/audio_addict/commands/log.rb +10 -11
- data/lib/audio_addict/commands/login.rb +4 -5
- data/lib/audio_addict/commands/now.rb +6 -7
- data/lib/audio_addict/commands/playlist.rb +9 -13
- data/lib/audio_addict/commands/set.rb +7 -13
- data/lib/audio_addict/commands/vote.rb +9 -10
- data/lib/audio_addict/config.rb +3 -4
- data/lib/audio_addict/exceptions.rb +6 -6
- data/lib/audio_addict/extensions/file.rb +2 -2
- data/lib/audio_addict/inspectable.rb +1 -1
- data/lib/audio_addict/log.rb +2 -3
- data/lib/audio_addict/radio.rb +13 -6
- data/lib/audio_addict/track.rb +3 -3
- data/lib/audio_addict/version.rb +2 -2
- metadata +5 -7
- data/lib/audio_addict/commands/status.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3530b3f712aaf7023144c17e182aca9aa659cde5c10426207a7f74a7c5ed94e2
|
4
|
+
data.tar.gz: 84935800acaa568734b0b7d326420f414d03287dab47f23049d5ab1b99c8f5e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 831a5050b49f28803e23a1e65565558eea4a10dca028b9320de05994f7028ab3e3721aab474dc5a09e0655fd6b3479b8db0bd11530266f650ab5a128ad0d6725
|
7
|
+
data.tar.gz: 2a8a65335a02e86725780441d78515c9667c83f34b2674269da749e25476bbca1bd56dedcb67e0fca8f68c98b27a88e5eaaf6632a279c2386bb12e6ae4b887a8
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@ AudioAddict Command Line
|
|
2
2
|
==================================================
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/audio_addict.svg)](https://badge.fury.io/rb/audio_addict)
|
5
|
-
[![Build Status](https://
|
5
|
+
[![Build Status](https://github.com/DannyBen/audio_addict/workflows/Test/badge.svg)](https://github.com/DannyBen/audio_addict/actions?query=workflow%3ATest)
|
6
6
|
[![Maintainability](https://api.codeclimate.com/v1/badges/91e1a8251b771881bf6b/maintainability)](https://codeclimate.com/github/DannyBen/audio_addict/maintainability)
|
7
7
|
|
8
8
|
---
|
@@ -60,7 +60,6 @@ AudioAddict Radio Utilities
|
|
60
60
|
|
61
61
|
Commands:
|
62
62
|
login Save login credentials
|
63
|
-
status Show configuration status
|
64
63
|
set Set the radio network and channel
|
65
64
|
channels Show list of channels
|
66
65
|
now Show network, channel and playing track
|
data/bin/radio
CHANGED
data/lib/audio_addict.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "requires"
|
2
|
+
require "byebug" if ENV["BYEBUG"]
|
3
3
|
requires \
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
"audio_addict/exceptions",
|
5
|
+
"audio_addict/cache",
|
6
|
+
"audio_addict/inspectable",
|
7
|
+
"audio_addict/auto_properties",
|
8
|
+
"audio_addict/commands/base",
|
9
|
+
"audio_addict"
|
data/lib/audio_addict/api.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
1
|
+
require "httparty"
|
2
2
|
|
3
3
|
module AudioAddict
|
4
4
|
class API
|
5
5
|
include HTTParty
|
6
6
|
include Cache
|
7
7
|
|
8
|
-
base_uri
|
8
|
+
base_uri "https://api.audioaddict.com/v1"
|
9
|
+
debug_output $stderr if ENV['AUDIO_ADDICT_DEBUG']
|
9
10
|
|
10
11
|
attr_accessor :network
|
11
12
|
|
@@ -15,22 +16,22 @@ module AudioAddict
|
|
15
16
|
|
16
17
|
def login(username, password)
|
17
18
|
session = session(username, password)
|
18
|
-
Config.session_key = session[
|
19
|
-
Config.listen_key = session[
|
20
|
-
Config.email = session[
|
21
|
-
Config.premium = session[
|
19
|
+
Config.session_key = session["key"]
|
20
|
+
Config.listen_key = session["member"]["listen_key"]
|
21
|
+
Config.email = session["member"]["email"]
|
22
|
+
Config.premium = session["member"]["user_type"] == "premium"
|
22
23
|
Config.save
|
23
24
|
end
|
24
25
|
|
25
|
-
def get(path, args={})
|
26
|
+
def get(path, args = {})
|
26
27
|
response http.get "/#{network}/#{path}", headers: headers, body: args
|
27
28
|
end
|
28
29
|
|
29
|
-
def post(path, args={})
|
30
|
+
def post(path, args = {})
|
30
31
|
response http.post "/#{network}/#{path}", headers: headers, body: args
|
31
32
|
end
|
32
33
|
|
33
|
-
def delete(path, args={})
|
34
|
+
def delete(path, args = {})
|
34
35
|
response http.delete "/#{network}/#{path}", headers: headers, body: args
|
35
36
|
end
|
36
37
|
|
@@ -39,13 +40,13 @@ module AudioAddict
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def basic_auth
|
42
|
-
http.basic_auth
|
43
|
+
http.basic_auth "streams", "diradio"
|
43
44
|
end
|
44
45
|
|
45
46
|
def session(username, password)
|
46
47
|
params = { member_session: { username: username, password: password } }
|
47
48
|
basic_auth
|
48
|
-
response http.post "/#{network}/member_sessions", body: params
|
49
|
+
response http.post "/#{network || "di"}/member_sessions", body: params
|
49
50
|
end
|
50
51
|
|
51
52
|
def session_key
|
@@ -56,7 +57,7 @@ module AudioAddict
|
|
56
57
|
Config.listen_key
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
+
private
|
60
61
|
|
61
62
|
def response(httparty_response)
|
62
63
|
raise APIError.new httparty_response unless httparty_response.success?
|
@@ -70,6 +71,5 @@ module AudioAddict
|
|
70
71
|
def headers
|
71
72
|
{ "X-Session-Key" => session_key }
|
72
73
|
end
|
73
|
-
|
74
74
|
end
|
75
75
|
end
|
data/lib/audio_addict/cache.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "lightly"
|
2
2
|
|
3
3
|
module AudioAddict
|
4
4
|
module Cache
|
5
|
-
|
6
5
|
def cache
|
7
6
|
@cache ||= Lightly.new life: cache_life, dir: cache_dir
|
8
7
|
end
|
@@ -12,7 +11,7 @@ module AudioAddict
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def cache_life!
|
15
|
-
Config.cache_life ||
|
14
|
+
Config.cache_life || "6h"
|
16
15
|
end
|
17
16
|
|
18
17
|
def cache_dir
|
@@ -22,6 +21,5 @@ module AudioAddict
|
|
22
21
|
def cache_dir!
|
23
22
|
Config.cache_dir || "#{Dir.home}/.audio_addict/cache"
|
24
23
|
end
|
25
|
-
|
26
24
|
end
|
27
25
|
end
|
data/lib/audio_addict/channel.rb
CHANGED
@@ -3,11 +3,11 @@ module AudioAddict
|
|
3
3
|
include Cache
|
4
4
|
include AutoProperties
|
5
5
|
include Inspectable
|
6
|
-
|
6
|
+
|
7
7
|
attr_reader :radio
|
8
8
|
|
9
9
|
def initialize(radio, properties)
|
10
|
-
@radio, @properties
|
10
|
+
@radio, @properties = radio, properties
|
11
11
|
end
|
12
12
|
|
13
13
|
def inspectable
|
@@ -17,8 +17,8 @@ module AudioAddict
|
|
17
17
|
def active?
|
18
18
|
# Seems like each network has a different way of marking inactive channels.
|
19
19
|
# This is where we normalize it
|
20
|
-
return false if !properties[
|
21
|
-
return false if name[0] ==
|
20
|
+
return false if !properties["asset_id"]
|
21
|
+
return false if name[0] == "X" and key[0] != "x"
|
22
22
|
return true
|
23
23
|
end
|
24
24
|
|
@@ -36,15 +36,15 @@ module AudioAddict
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def similar_channels
|
39
|
-
similar = properties[
|
39
|
+
similar = properties["similar_channels"]
|
40
40
|
return [] unless similar
|
41
|
-
ids = similar.map { |s| s[
|
41
|
+
ids = similar.map { |s| s["similar_channel_id"] }
|
42
42
|
radio.search_by_id ids
|
43
43
|
end
|
44
44
|
|
45
45
|
def vote(direction = :up, track: nil)
|
46
|
-
track ||= current_track
|
47
|
-
endpoint = "tracks/#{track}/vote/#{id}"
|
46
|
+
track ||= current_track
|
47
|
+
endpoint = "tracks/#{track.id}/vote/#{id}"
|
48
48
|
|
49
49
|
if direction == :delete
|
50
50
|
radio.api.delete endpoint
|
@@ -52,16 +52,16 @@ module AudioAddict
|
|
52
52
|
radio.api.post "#{endpoint}/#{direction}"
|
53
53
|
end
|
54
54
|
|
55
|
-
log_like if direction == :up and Config.like_log
|
55
|
+
log_like track if direction == :up and Config.like_log
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
private
|
59
59
|
|
60
|
-
def log_like
|
61
|
-
|
60
|
+
def log_like(track = nil)
|
61
|
+
track ||= current_track
|
62
|
+
message = "#{radio.name} :: #{name} :: #{track.artist} :: #{track.title}"
|
62
63
|
file = Config.like_log
|
63
64
|
File.append file, message unless File.contains? file, message
|
64
65
|
end
|
65
|
-
|
66
66
|
end
|
67
67
|
end
|
data/lib/audio_addict/cli.rb
CHANGED
@@ -4,20 +4,18 @@ module AudioAddict
|
|
4
4
|
router = MisterBin::Runner.new version: VERSION,
|
5
5
|
header: "AudioAddict Radio Utilities"
|
6
6
|
|
7
|
-
router.route
|
8
|
-
router.route
|
9
|
-
router.route
|
10
|
-
router.route
|
11
|
-
router.route
|
12
|
-
router.route
|
13
|
-
router.route
|
14
|
-
router.route
|
15
|
-
router.route
|
16
|
-
router.route
|
17
|
-
router.route 'api', to: Commands::APICmd
|
7
|
+
router.route "login", to: Commands::LoginCmd
|
8
|
+
router.route "set", to: Commands::SetCmd
|
9
|
+
router.route "channels", to: Commands::ChannelsCmd
|
10
|
+
router.route "now", to: Commands::NowCmd
|
11
|
+
router.route "history", to: Commands::HistoryCmd
|
12
|
+
router.route "vote", to: Commands::VoteCmd
|
13
|
+
router.route "playlist", to: Commands::PlaylistCmd
|
14
|
+
router.route "config", to: Commands::ConfigCmd
|
15
|
+
router.route "log", to: Commands::LogCmd
|
16
|
+
router.route "api", to: Commands::APICmd
|
18
17
|
|
19
18
|
router
|
20
19
|
end
|
21
20
|
end
|
22
|
-
|
23
21
|
end
|
@@ -10,9 +10,9 @@ module AudioAddict
|
|
10
10
|
|
11
11
|
param "ENDPOINT", "API endpoint path"
|
12
12
|
|
13
|
-
example "radio channels"
|
14
|
-
example "radio get track_history/channel/1"
|
15
|
-
example "radio post tracks/1/vote/2/up"
|
13
|
+
example "radio api channels"
|
14
|
+
example "radio api get track_history/channel/1"
|
15
|
+
example "radio api post tracks/1/vote/2/up"
|
16
16
|
|
17
17
|
def run
|
18
18
|
needs :network
|
@@ -20,22 +20,21 @@ module AudioAddict
|
|
20
20
|
puts response.to_yaml
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
private
|
24
24
|
|
25
25
|
def api_method
|
26
|
-
return :post if args[
|
27
|
-
return :delete if args[
|
26
|
+
return :post if args["post"]
|
27
|
+
return :delete if args["delete"]
|
28
28
|
return :get
|
29
29
|
end
|
30
30
|
|
31
31
|
def endpoint
|
32
|
-
args[
|
32
|
+
args["ENDPOINT"]
|
33
33
|
end
|
34
34
|
|
35
35
|
def api
|
36
36
|
@api ||= API.new current_network
|
37
37
|
end
|
38
|
-
|
39
38
|
end
|
40
39
|
end
|
41
|
-
end
|
40
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "mister_bin"
|
2
|
+
require "colsole"
|
3
|
+
require "tty/prompt"
|
4
4
|
|
5
5
|
module AudioAddict
|
6
6
|
module Commands
|
7
7
|
class Base < MisterBin::Command
|
8
|
-
|
9
8
|
def needs(*config_keys)
|
10
9
|
missing = []
|
11
10
|
config_keys.each do |key|
|
@@ -34,7 +33,6 @@ module AudioAddict
|
|
34
33
|
def prompt
|
35
34
|
@prompt ||= TTY::Prompt.new
|
36
35
|
end
|
37
|
-
|
38
36
|
end
|
39
37
|
end
|
40
|
-
end
|
38
|
+
end
|
@@ -22,19 +22,19 @@ module AudioAddict
|
|
22
22
|
|
23
23
|
say "!undgrn!#{radio.name}\n"
|
24
24
|
|
25
|
-
search = args[
|
25
|
+
search = args["SEARCH"]
|
26
26
|
|
27
27
|
channels = search ? radio.search(search) : radio.channels
|
28
|
-
|
28
|
+
|
29
29
|
channels = channels.values
|
30
|
-
if args[
|
30
|
+
if args["--info"]
|
31
31
|
show_verbose channels
|
32
32
|
else
|
33
33
|
show_compact channels
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
private
|
38
38
|
|
39
39
|
def show_verbose(channels)
|
40
40
|
channels.each do |channel|
|
@@ -61,7 +61,6 @@ module AudioAddict
|
|
61
61
|
say "!txtblu!#{channel.key.rjust 25} !txtgrn!#{channel.name.strip}"
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
65
64
|
end
|
66
65
|
end
|
67
|
-
end
|
66
|
+
end
|
@@ -10,6 +10,7 @@ module AudioAddict
|
|
10
10
|
usage "radio config del KEY"
|
11
11
|
usage "radio config show"
|
12
12
|
usage "radio config edit"
|
13
|
+
usage "radio config check"
|
13
14
|
usage "radio config guide"
|
14
15
|
usage "radio config --help"
|
15
16
|
|
@@ -25,6 +26,7 @@ module AudioAddict
|
|
25
26
|
command "show", "Show the entire config file contents"
|
26
27
|
command "edit", "Open the config file for editing"
|
27
28
|
command "guide", "Show a list of supported config keys and their purpose"
|
29
|
+
command "check", "Verify and report problems with the config file"
|
28
30
|
|
29
31
|
example "radio config edit"
|
30
32
|
example "radio config set like_log ~/like.log"
|
@@ -32,21 +34,21 @@ module AudioAddict
|
|
32
34
|
example "radio config get listen_key"
|
33
35
|
|
34
36
|
def get_command
|
35
|
-
key = args[
|
37
|
+
key = args["KEY"].to_sym
|
36
38
|
value = Config.properties[key]
|
37
39
|
say value ? "!txtgrn!#{value}" : "!txtred!<Unset>"
|
38
40
|
end
|
39
41
|
|
40
42
|
def set_command
|
41
|
-
key = args[
|
42
|
-
value = args[
|
43
|
+
key = args["KEY"].to_sym
|
44
|
+
value = args["VALUE"]
|
43
45
|
Config.properties[key] = value
|
44
46
|
Config.save
|
45
47
|
say "!txtgrn!#{key}=#{value}"
|
46
48
|
end
|
47
49
|
|
48
50
|
def del_command
|
49
|
-
key = args[
|
51
|
+
key = args["KEY"].to_sym
|
50
52
|
Config.delete key
|
51
53
|
Config.save
|
52
54
|
say "!txtgrn!Deleted"
|
@@ -62,7 +64,7 @@ module AudioAddict
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def edit_command
|
65
|
-
editor = ENV[
|
67
|
+
editor = ENV["EDITOR"] || "vi"
|
66
68
|
system "#{editor} #{Config.path}"
|
67
69
|
end
|
68
70
|
|
@@ -74,7 +76,29 @@ module AudioAddict
|
|
74
76
|
end
|
75
77
|
end
|
76
78
|
|
77
|
-
|
79
|
+
def check_command
|
80
|
+
errors = verify_and_show_keys required_keys, critical: true
|
81
|
+
warnings = verify_and_show_keys optional_keys
|
82
|
+
|
83
|
+
say "Done. #{errors} errors, #{warnings} warnings."
|
84
|
+
errors > 0 ? 1 : 0
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def verify_and_show_keys(keys, critical: false)
|
90
|
+
problems = 0
|
91
|
+
prefix = critical ? "!txtred!Error !txtrst!" : "!txtylw!Warning!txtrst!"
|
92
|
+
|
93
|
+
keys.each do |key, command|
|
94
|
+
if !Config.has_key? key
|
95
|
+
problems += 1
|
96
|
+
say "#{prefix} : Key !txtgrn!#{key}!txtrst! is not set. Fix with !txtpur!radio #{command}!txtrst!."
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
problems
|
101
|
+
end
|
78
102
|
|
79
103
|
def key_guide
|
80
104
|
{
|
@@ -88,7 +112,22 @@ module AudioAddict
|
|
88
112
|
cache_life: "Specify the cache life period.\nDefault: 6h.",
|
89
113
|
}
|
90
114
|
end
|
91
|
-
|
115
|
+
|
116
|
+
def required_keys
|
117
|
+
{
|
118
|
+
email: "login",
|
119
|
+
session_key: "login",
|
120
|
+
listen_key: "login",
|
121
|
+
network: "set",
|
122
|
+
channel: "set",
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
def optional_keys
|
127
|
+
{
|
128
|
+
like_log: "config set like_log PATH",
|
129
|
+
}
|
130
|
+
end
|
92
131
|
end
|
93
132
|
end
|
94
|
-
end
|
133
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AudioAddict
|
2
2
|
module Commands
|
3
3
|
class HistoryCmd < Base
|
4
|
-
summary "Show track history for the current channel"
|
4
|
+
summary "Show track history for the current channel"
|
5
5
|
|
6
6
|
help "This command shows the last few tracks that were playing on the currently active channel in reverse order (top track is the most recent)."
|
7
7
|
|
@@ -11,13 +11,13 @@ module AudioAddict
|
|
11
11
|
def run
|
12
12
|
needs :network, :channel
|
13
13
|
say "!undgrn!#{radio.name} > #{current_channel.name}"
|
14
|
-
say
|
14
|
+
say ""
|
15
15
|
tracks.each do |track|
|
16
16
|
say "!txtgrn! #{track.artist.rjust max_artist_len}!txtrst! : !txtblu!#{track.title}"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
private
|
21
21
|
|
22
22
|
def tracks
|
23
23
|
@tracks ||= current_channel.track_history
|
@@ -28,4 +28,4 @@ module AudioAddict
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
@@ -32,13 +32,13 @@ module AudioAddict
|
|
32
32
|
|
33
33
|
def show_command
|
34
34
|
needs :like_log
|
35
|
-
query = args[
|
35
|
+
query = args["SEARCH"]
|
36
36
|
puts query ? log.search(query) : log.data
|
37
37
|
end
|
38
38
|
|
39
39
|
def tail_command
|
40
40
|
needs :like_log
|
41
|
-
lines = args[
|
41
|
+
lines = args["--lines"].to_i
|
42
42
|
puts log.data[-lines..-1]
|
43
43
|
end
|
44
44
|
|
@@ -52,10 +52,10 @@ module AudioAddict
|
|
52
52
|
tree = log.tree
|
53
53
|
|
54
54
|
say ""
|
55
|
-
network = prompt.select "Network:", tree.keys, marker:
|
56
|
-
channel = prompt.select "Channel:", tree[network].keys, marker:
|
57
|
-
artist
|
58
|
-
|
55
|
+
network = prompt.select "Network:", tree.keys, symbols: { marker: ">" }, filter: true, per_page: 10
|
56
|
+
channel = prompt.select "Channel:", tree[network].keys, symbols: { marker: ">" }, filter: true, per_page: page_size
|
57
|
+
artist = prompt.select "Artist:", tree[network][channel].keys, symbols: { marker: ">" }, filter: true, per_page: page_size
|
58
|
+
|
59
59
|
say "Songs:"
|
60
60
|
tree[network][channel][artist].each { |song| say "- !txtgrn!#{song}" }
|
61
61
|
say ""
|
@@ -65,8 +65,8 @@ module AudioAddict
|
|
65
65
|
|
66
66
|
def tree_command
|
67
67
|
yaml = log.tree.to_yaml
|
68
|
-
filename = args[
|
69
|
-
|
68
|
+
filename = args["--save"]
|
69
|
+
|
70
70
|
if filename
|
71
71
|
File.write filename, yaml
|
72
72
|
say "!txtgrn!Saved #{filename}"
|
@@ -75,7 +75,7 @@ module AudioAddict
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
private
|
79
79
|
|
80
80
|
def log
|
81
81
|
@log ||= Log.new
|
@@ -84,7 +84,6 @@ module AudioAddict
|
|
84
84
|
def page_size
|
85
85
|
@page_size ||= detect_terminal_size[1] - 4
|
86
86
|
end
|
87
|
-
|
88
87
|
end
|
89
88
|
end
|
90
|
-
end
|
89
|
+
end
|
@@ -15,16 +15,16 @@ module AudioAddict
|
|
15
15
|
say "!txtylw!You are already logged in as !undylw!#{Config.email}"
|
16
16
|
proceed = prompt.yes? "Login again?"
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
login_prompt if proceed
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
private
|
23
23
|
|
24
24
|
def login_prompt
|
25
25
|
user = prompt.ask "Username :", default: Config.email
|
26
26
|
pass = prompt.mask "Password :"
|
27
|
-
|
27
|
+
|
28
28
|
if user and pass
|
29
29
|
say "Logging in... "
|
30
30
|
radio.api.login user, pass
|
@@ -33,7 +33,6 @@ module AudioAddict
|
|
33
33
|
say "!txtred!Cancelled"
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
38
37
|
end
|
39
|
-
end
|
38
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AudioAddict
|
2
2
|
module Commands
|
3
3
|
class NowCmd < Base
|
4
|
-
summary "Show network, channel and playing track"
|
4
|
+
summary "Show network, channel and playing track"
|
5
5
|
|
6
6
|
help "This command displays the active network and channel, as well as the currently playing track."
|
7
7
|
|
@@ -11,15 +11,14 @@ module AudioAddict
|
|
11
11
|
def run
|
12
12
|
needs :network, :channel
|
13
13
|
|
14
|
-
say
|
15
|
-
say
|
16
|
-
say
|
14
|
+
say "!txtblu! Network !txtrst!: !txtgrn!#{radio.name}!txtrst! # #{radio.network}"
|
15
|
+
say "!txtblu! Channel !txtrst!: !txtgrn!#{current_channel.name}!txtrst! # #{current_channel.key}"
|
16
|
+
say "!txtblu! Track !txtrst!: ... "
|
17
17
|
|
18
18
|
track = current_channel.current_track
|
19
19
|
resay "!txtblu! Track !txtrst!: !txtgrn!#{track.title.strip}"
|
20
|
-
say
|
20
|
+
say "!txtblu! By !txtrst!: !txtgrn!#{track.artist.strip}"
|
21
21
|
end
|
22
|
-
|
23
22
|
end
|
24
23
|
end
|
25
|
-
end
|
24
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AudioAddict
|
2
2
|
module Commands
|
3
3
|
class PlaylistCmd < Base
|
4
|
-
summary "Generate playlists"
|
4
|
+
summary "Generate playlists"
|
5
5
|
|
6
6
|
help "This command lets you generate playlists for the active network. In order to allow configuration, the process is done in two stages: 'init' and 'generate'."
|
7
7
|
|
@@ -22,7 +22,7 @@ module AudioAddict
|
|
22
22
|
|
23
23
|
require_premium_account
|
24
24
|
|
25
|
-
name = args[
|
25
|
+
name = args["NAME"]
|
26
26
|
outfile = "#{name}.yml"
|
27
27
|
|
28
28
|
say "!txtred!Warning!txtrst!: !txtgrn!#{outfile}!txtrst! already exists!" if File.exist? outfile
|
@@ -34,12 +34,12 @@ module AudioAddict
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def generate_command(name=nil)
|
37
|
+
def generate_command(name = nil)
|
38
38
|
needs :network, :channel, :listen_key
|
39
39
|
|
40
40
|
require_premium_account
|
41
41
|
|
42
|
-
name ||= args[
|
42
|
+
name ||= args["NAME"]
|
43
43
|
|
44
44
|
infile = "#{name}.yml"
|
45
45
|
outfile = "#{name}.pls"
|
@@ -53,15 +53,12 @@ module AudioAddict
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
private
|
57
57
|
|
58
58
|
def generate_config(outfile)
|
59
|
-
data = {
|
60
|
-
template: "http://prem2.#{radio.domain}:80/%{channel_key}?%{listen_key}"
|
61
|
-
}
|
62
|
-
|
59
|
+
data = { template: radio.url_template }
|
63
60
|
channels = {}
|
64
|
-
|
61
|
+
|
65
62
|
radio.channels.each do |key, channel|
|
66
63
|
key = fix_key key.to_sym
|
67
64
|
channels[key] = channel.name
|
@@ -107,10 +104,9 @@ module AudioAddict
|
|
107
104
|
|
108
105
|
# This is a patch to circumvent some anomalies in the AudioAddict API
|
109
106
|
def fix_key(key)
|
110
|
-
key = :electrohouse if current_network ==
|
107
|
+
key = :electrohouse if current_network == "di" and key == :electro
|
111
108
|
key
|
112
109
|
end
|
113
|
-
|
114
110
|
end
|
115
111
|
end
|
116
|
-
end
|
112
|
+
end
|
@@ -19,8 +19,8 @@ module AudioAddict
|
|
19
19
|
example "radio set - rockradio"
|
20
20
|
|
21
21
|
def run
|
22
|
-
channel = args[
|
23
|
-
network = args[
|
22
|
+
channel = args["CHANNEL"]
|
23
|
+
network = args["NETWORK"]
|
24
24
|
|
25
25
|
full_set = (channel and network) || !(channel or network)
|
26
26
|
|
@@ -31,7 +31,7 @@ module AudioAddict
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
private
|
35
35
|
|
36
36
|
def set_both(channel, network)
|
37
37
|
needs :session_key
|
@@ -50,19 +50,14 @@ module AudioAddict
|
|
50
50
|
|
51
51
|
if !channel
|
52
52
|
channel_menu
|
53
|
-
|
54
|
-
elsif channel == '-'
|
53
|
+
elsif channel == "-"
|
55
54
|
save_channel radio.channels.keys.first
|
56
|
-
|
57
55
|
elsif radio.valid_channel? channel
|
58
56
|
save_channel channel
|
59
|
-
|
60
57
|
elsif radio.search(channel).any?
|
61
58
|
channel_menu channel
|
62
|
-
|
63
59
|
else
|
64
60
|
say "!txtred!Invalid channel: #{radio.name} > #{channel}"
|
65
|
-
|
66
61
|
end
|
67
62
|
end
|
68
63
|
|
@@ -91,13 +86,13 @@ module AudioAddict
|
|
91
86
|
def channel_prompt(channels)
|
92
87
|
options = channels.map { |channel| ["#{channel.name.ljust 20} # #{channel.key}", channel.key] }.to_h
|
93
88
|
options = { "Cancel" => :cancel }.merge options
|
94
|
-
prompt.select "Channel :", options, marker:
|
89
|
+
prompt.select "Channel :", options, symbols: { marker: ">" }, filter: true
|
95
90
|
end
|
96
91
|
|
97
92
|
def network_prompt(networks)
|
98
93
|
options = networks.invert
|
99
94
|
options["Skip"] = :cancel
|
100
|
-
prompt.select "Network :", options, marker:
|
95
|
+
prompt.select "Network :", options, symbols: { marker: ">" }, filter: true, per_page: 10
|
101
96
|
end
|
102
97
|
|
103
98
|
def save_channel(channel, echo: true)
|
@@ -111,7 +106,6 @@ module AudioAddict
|
|
111
106
|
Config.save
|
112
107
|
say "Network : !txtgrn!#{radio.name}!txtrst! # #{network}" if echo
|
113
108
|
end
|
114
|
-
|
115
109
|
end
|
116
110
|
end
|
117
|
-
end
|
111
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AudioAddict
|
2
2
|
module Commands
|
3
3
|
class VoteCmd < Base
|
4
|
-
summary "Vote on a recently played track"
|
4
|
+
summary "Vote on a recently played track"
|
5
5
|
|
6
6
|
help "This command starts an interactive voting prompt for the currently playing track or for previously played tracks."
|
7
7
|
|
@@ -22,7 +22,7 @@ module AudioAddict
|
|
22
22
|
vote_mode == :now ? vote_now : vote_past
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
private
|
26
26
|
|
27
27
|
def vote_past
|
28
28
|
track = get_user_track
|
@@ -54,9 +54,9 @@ module AudioAddict
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def get_user_track
|
57
|
-
options = tracks.map { |t| ["#{t.artist.ljust max_artist_len} > #{t.title}", t
|
57
|
+
options = tracks.map { |t| ["#{t.artist.ljust max_artist_len} > #{t.title}", t] }.to_h
|
58
58
|
options = { "Cancel" => :cancel }.merge options
|
59
|
-
prompt.select "Track:", options, marker:
|
59
|
+
prompt.select "Track:", options, symbols: { marker: ">" }
|
60
60
|
end
|
61
61
|
|
62
62
|
def get_user_vote
|
@@ -64,9 +64,9 @@ module AudioAddict
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def menu_prompt
|
67
|
-
options = { "Like" => :up, "Dislike" => :down,
|
68
|
-
|
69
|
-
prompt.select "Vote:", options, marker:
|
67
|
+
options = { "Like" => :up, "Dislike" => :down,
|
68
|
+
"Unvote" => :delete, "Cancel" => :cancel }
|
69
|
+
prompt.select "Vote:", options, symbols: { marker: ">" }
|
70
70
|
end
|
71
71
|
|
72
72
|
def simple_prompt
|
@@ -75,13 +75,12 @@ module AudioAddict
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def vote_style
|
78
|
-
args[
|
78
|
+
args["--all"] ? :menu : :simple
|
79
79
|
end
|
80
80
|
|
81
81
|
def vote_mode
|
82
|
-
args[
|
82
|
+
args["--past"] ? :past : :now
|
83
83
|
end
|
84
|
-
|
85
84
|
end
|
86
85
|
end
|
87
86
|
end
|
data/lib/audio_addict/config.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "yaml"
|
2
2
|
|
3
3
|
module AudioAddict
|
4
4
|
class Config
|
@@ -6,7 +6,7 @@ module AudioAddict
|
|
6
6
|
attr_writer :path
|
7
7
|
|
8
8
|
def method_missing(name, *args, &_blk)
|
9
|
-
if name.to_s.end_with?
|
9
|
+
if name.to_s.end_with? "="
|
10
10
|
name = name[0..-2].to_sym
|
11
11
|
properties[name] = args.first
|
12
12
|
else
|
@@ -39,13 +39,12 @@ module AudioAddict
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def path
|
42
|
-
@path ||= ENV.fetch(
|
42
|
+
@path ||= ENV.fetch("AUDIO_ADDICT_CONFIG_PATH", default_path)
|
43
43
|
end
|
44
44
|
|
45
45
|
def default_path
|
46
46
|
"#{Dir.home}/.audio_addict/config"
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module AudioAddict
|
2
2
|
class Error < StandardError; end
|
3
|
-
|
3
|
+
|
4
4
|
class Interrupt < Error; end
|
5
5
|
|
6
6
|
class ArgumentError < Error; end
|
@@ -10,16 +10,16 @@ module AudioAddict
|
|
10
10
|
|
11
11
|
def initialize(missing_keys)
|
12
12
|
@missing_keys = missing_keys
|
13
|
-
super "Some parameters required by this operation are missing"
|
13
|
+
super "Some parameters required by this operation are missing"
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
class PremiumAccount < Error
|
18
|
-
def initialize(message="This operation requires a premium account")
|
18
|
+
def initialize(message = "This operation requires a premium account")
|
19
19
|
super
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
class APIError < Error
|
24
24
|
attr_reader :response
|
25
25
|
|
@@ -28,4 +28,4 @@ module AudioAddict
|
|
28
28
|
super "#{response.code} #{response.message}:\n#{response.body}"
|
29
29
|
end
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils"
|
2
2
|
|
3
3
|
class File
|
4
4
|
def self.contains?(file, content)
|
@@ -10,7 +10,7 @@ class File
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.append(file, content)
|
13
|
-
open(file,
|
13
|
+
open(file, "a") { |f| f.puts content }
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.deep_write(file, content)
|
data/lib/audio_addict/log.rb
CHANGED
@@ -31,9 +31,9 @@ module AudioAddict
|
|
31
31
|
|
32
32
|
def tree!
|
33
33
|
result = {}
|
34
|
-
|
34
|
+
|
35
35
|
data.each do |line|
|
36
|
-
network, channel, artist, song = line.split(
|
36
|
+
network, channel, artist, song = line.split(" :: ")
|
37
37
|
result[network] ||= {}
|
38
38
|
result[network][channel] ||= {}
|
39
39
|
result[network][channel][artist] ||= []
|
@@ -42,6 +42,5 @@ module AudioAddict
|
|
42
42
|
|
43
43
|
result
|
44
44
|
end
|
45
|
-
|
46
45
|
end
|
47
46
|
end
|
data/lib/audio_addict/radio.rb
CHANGED
@@ -10,7 +10,8 @@ module AudioAddict
|
|
10
10
|
rockradio: "Rock Radio",
|
11
11
|
radiotunes: "Radio Tunes",
|
12
12
|
jazzradio: "Jazz Radio",
|
13
|
-
classicalradio: "Classical Radio"
|
13
|
+
classicalradio: "Classical Radio",
|
14
|
+
zenradio: "Zen Radio",
|
14
15
|
}
|
15
16
|
|
16
17
|
DOMAINS = {
|
@@ -18,7 +19,8 @@ module AudioAddict
|
|
18
19
|
rockradio: "rockradio.com",
|
19
20
|
radiotunes: "radiotunes.com",
|
20
21
|
jazzradio: "jazzradio.com",
|
21
|
-
classicalradio: "classicalradio.com"
|
22
|
+
classicalradio: "classicalradio.com",
|
23
|
+
zenradio: "zenradio.com",
|
22
24
|
}
|
23
25
|
|
24
26
|
def self.networks(search = nil)
|
@@ -50,6 +52,11 @@ module AudioAddict
|
|
50
52
|
DOMAINS[network.to_sym]
|
51
53
|
end
|
52
54
|
|
55
|
+
def url_template
|
56
|
+
channel_path = network == "zenradio" ? "zr%{channel_key}_aac" : "%{channel_key}"
|
57
|
+
"http://prem2.#{domain}:80/#{channel_path}?%{listen_key}"
|
58
|
+
end
|
59
|
+
|
53
60
|
def channels
|
54
61
|
@channels ||= channels!
|
55
62
|
end
|
@@ -57,7 +64,7 @@ module AudioAddict
|
|
57
64
|
def search(query)
|
58
65
|
channels.select do |key, channel|
|
59
66
|
"#{key} #{channel.name.downcase}".include? query.downcase
|
60
|
-
end
|
67
|
+
end
|
61
68
|
end
|
62
69
|
|
63
70
|
def search_by_id(ids)
|
@@ -77,16 +84,16 @@ module AudioAddict
|
|
77
84
|
@api ||= API.new network
|
78
85
|
end
|
79
86
|
|
80
|
-
|
87
|
+
private
|
81
88
|
|
82
89
|
def channels!
|
83
90
|
response = cache.get "#{network}/channels" do
|
84
|
-
api.get
|
91
|
+
api.get "channels"
|
85
92
|
end
|
86
93
|
|
87
94
|
result = {}
|
88
95
|
response.map do |channel|
|
89
|
-
key = channel[
|
96
|
+
key = channel["key"]
|
90
97
|
candidate = Channel.new self, channel
|
91
98
|
result[key] = candidate if candidate.active?
|
92
99
|
end
|
data/lib/audio_addict/track.rb
CHANGED
@@ -6,7 +6,7 @@ module AudioAddict
|
|
6
6
|
attr_reader :channel
|
7
7
|
|
8
8
|
def initialize(channel, properties)
|
9
|
-
@channel, @properties
|
9
|
+
@channel, @properties = channel, properties
|
10
10
|
end
|
11
11
|
|
12
12
|
def inspectable
|
@@ -14,11 +14,11 @@ module AudioAddict
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def id
|
17
|
-
properties[
|
17
|
+
properties["track_id"]
|
18
18
|
end
|
19
19
|
|
20
20
|
def title
|
21
|
-
properties[
|
21
|
+
properties["title"].strip
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/audio_addict/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module AudioAddict
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.3.0"
|
3
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: audio_addict
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.19'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.19'
|
97
97
|
description: Command line for playlist management and voting for AudioAddict radio
|
98
98
|
networks
|
99
99
|
email: db@dannyben.com
|
@@ -120,7 +120,6 @@ files:
|
|
120
120
|
- lib/audio_addict/commands/now.rb
|
121
121
|
- lib/audio_addict/commands/playlist.rb
|
122
122
|
- lib/audio_addict/commands/set.rb
|
123
|
-
- lib/audio_addict/commands/status.rb
|
124
123
|
- lib/audio_addict/commands/vote.rb
|
125
124
|
- lib/audio_addict/config.rb
|
126
125
|
- lib/audio_addict/exceptions.rb
|
@@ -149,8 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
148
|
- !ruby/object:Gem::Version
|
150
149
|
version: '0'
|
151
150
|
requirements: []
|
152
|
-
|
153
|
-
rubygems_version: 2.7.6
|
151
|
+
rubygems_version: 3.2.3
|
154
152
|
signing_key:
|
155
153
|
specification_version: 4
|
156
154
|
summary: AudioAddict Command Line
|
@@ -1,61 +0,0 @@
|
|
1
|
-
module AudioAddict
|
2
|
-
module Commands
|
3
|
-
class StatusCmd < Base
|
4
|
-
summary "Show configuration status"
|
5
|
-
|
6
|
-
help "This command shows high level status based on your configuration file."
|
7
|
-
|
8
|
-
usage "radio status [--unsafe]"
|
9
|
-
usage "radio status --help"
|
10
|
-
|
11
|
-
option "-u --unsafe", "Show the full session and listen keys"
|
12
|
-
|
13
|
-
def keys
|
14
|
-
{
|
15
|
-
path: {
|
16
|
-
name: "Config Path", value: Config.path },
|
17
|
-
|
18
|
-
email: {
|
19
|
-
name: "Email", command: 'login' },
|
20
|
-
|
21
|
-
session_key: {
|
22
|
-
name: "Session Key", command: 'login', secret: true },
|
23
|
-
|
24
|
-
listen_key: {
|
25
|
-
name: "Listen Key", command: 'login', secret: true },
|
26
|
-
|
27
|
-
network: {
|
28
|
-
name: "Network", command: 'set' },
|
29
|
-
|
30
|
-
channel: {
|
31
|
-
name: "Channel", command: 'set' },
|
32
|
-
|
33
|
-
like_log: {
|
34
|
-
name: "Like Log", command: 'config like_log PATH' },
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def run
|
39
|
-
keys.each do |key, info|
|
40
|
-
value = info[:value] || Config.properties[key]
|
41
|
-
|
42
|
-
if value and !args['--unsafe'] and info[:secret]
|
43
|
-
value = "***#{value[-4, 4]}"
|
44
|
-
end
|
45
|
-
|
46
|
-
if value
|
47
|
-
display_value = "!txtgrn!#{value}!txtrst!"
|
48
|
-
else
|
49
|
-
display_value = "!txtred!<Unset>!txtrst!"
|
50
|
-
if info[:command]
|
51
|
-
display_value = "#{display_value} - set with !txtpur!radio #{info[:command]}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
say "!txtblu!#{info[:name].rjust 14}!txtrst! : #{display_value}"
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|