nehm 1.6.1 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +52 -35
- data/Rakefile +63 -13
- data/bin/nehm +0 -1
- data/lib/nehm.rb +33 -11
- data/lib/nehm/cfg.rb +19 -6
- data/lib/nehm/client.rb +30 -33
- data/lib/nehm/command.rb +19 -34
- data/lib/nehm/command_manager.rb +8 -18
- data/lib/nehm/commands/configure_command.rb +17 -14
- data/lib/nehm/commands/dl_command.rb +13 -11
- data/lib/nehm/commands/get_command.rb +36 -12
- data/lib/nehm/commands/help_command.rb +5 -5
- data/lib/nehm/commands/search_command.rb +41 -0
- data/lib/nehm/commands/select_command.rb +56 -0
- data/lib/nehm/http_client.rb +66 -0
- data/lib/nehm/menu.rb +96 -0
- data/lib/nehm/option_parser.rb +0 -2
- data/lib/nehm/os.rb +2 -2
- data/lib/nehm/path_manager.rb +5 -24
- data/lib/nehm/playlist.rb +2 -2
- data/lib/nehm/playlist_manager.rb +3 -5
- data/lib/nehm/track.rb +4 -2
- data/lib/nehm/track_manager.rb +135 -0
- data/lib/nehm/tracks_view_command.rb +123 -0
- data/lib/nehm/ui.rb +18 -2
- data/lib/nehm/user_manager.rb +5 -4
- data/lib/nehm/version.rb +1 -1
- data/nehm.gemspec +4 -7
- metadata +13 -64
- data/lib/nehm/tracks.rb +0 -153
data/lib/nehm/command.rb
CHANGED
@@ -5,32 +5,32 @@ module Nehm
|
|
5
5
|
##
|
6
6
|
# Base class for all Nehm commands. When creating a new nehm command, define
|
7
7
|
# #initialize, #execute, #arguments, #program_name, #summary and #usage
|
8
|
-
# (as appropriate)
|
9
|
-
# See the above mentioned methods for details
|
8
|
+
# (as appropriate)
|
9
|
+
# See the above mentioned methods for details
|
10
10
|
|
11
11
|
class Command
|
12
12
|
|
13
13
|
##
|
14
|
-
# Hash with options of the command
|
14
|
+
# Hash with options of the command
|
15
15
|
|
16
16
|
attr_accessor :options
|
17
17
|
|
18
18
|
##
|
19
|
-
# Hash with descriptions of each
|
19
|
+
# Hash with descriptions of each option
|
20
20
|
|
21
21
|
attr_accessor :options_descs
|
22
22
|
|
23
23
|
##
|
24
|
-
# In 'initialize' should be defined all options by method 'add_option'
|
25
|
-
#
|
26
|
-
# See get_command.rb as example.
|
24
|
+
# In 'initialize' should be defined all options by method 'add_option'
|
25
|
+
# See get_command.rb as example
|
27
26
|
|
28
27
|
def initialize
|
29
28
|
@options = {}
|
29
|
+
@options_descs = {}
|
30
30
|
end
|
31
31
|
|
32
32
|
##
|
33
|
-
# Invoke the command with the given list of arguments
|
33
|
+
# Invoke the command with the given list of arguments
|
34
34
|
|
35
35
|
def invoke(args)
|
36
36
|
handle_options(args)
|
@@ -39,7 +39,7 @@ module Nehm
|
|
39
39
|
|
40
40
|
##
|
41
41
|
# Handle the given list of arguments by parsing them and recording the
|
42
|
-
# results
|
42
|
+
# results
|
43
43
|
|
44
44
|
def handle_options(args)
|
45
45
|
parser = OptionParser.new(args, self)
|
@@ -47,16 +47,16 @@ module Nehm
|
|
47
47
|
end
|
48
48
|
|
49
49
|
##
|
50
|
-
# Override to provide command handling
|
50
|
+
# Override to provide command handling
|
51
51
|
#
|
52
52
|
# #options will be filled in with your parsed options, unparsed options will
|
53
|
-
# be left in #options[:args]
|
53
|
+
# be left in #options[:args]
|
54
54
|
|
55
55
|
def execute
|
56
56
|
end
|
57
57
|
|
58
58
|
##
|
59
|
-
# Override to provide details of the arguments a command takes
|
59
|
+
# Override to provide details of the arguments a command takes
|
60
60
|
#
|
61
61
|
# For example:
|
62
62
|
#
|
@@ -73,51 +73,36 @@ module Nehm
|
|
73
73
|
end
|
74
74
|
|
75
75
|
##
|
76
|
-
# The name of the command for command-line invocation
|
76
|
+
# The name of the command for command-line invocation
|
77
77
|
|
78
78
|
def program_name
|
79
79
|
end
|
80
80
|
|
81
81
|
##
|
82
|
-
# Override to display a short description of what this command does
|
82
|
+
# Override to display a short description of what this command does
|
83
83
|
|
84
84
|
def summary
|
85
85
|
end
|
86
86
|
|
87
87
|
##
|
88
|
-
# Override to display the usage for an individual nehm command
|
88
|
+
# Override to display the usage for an individual nehm command
|
89
89
|
#
|
90
|
-
# The text "[options]" is automatically appended to the usage text
|
90
|
+
# The text "[options]" is automatically appended to the usage text
|
91
91
|
|
92
92
|
def usage
|
93
93
|
end
|
94
94
|
|
95
95
|
##
|
96
|
-
# Add a command-line option
|
96
|
+
# Add a command-line option
|
97
97
|
#
|
98
|
-
# Nehm don't use options with dashes to be more user-friendly
|
98
|
+
# Nehm don't use options with dashes to be more user-friendly
|
99
99
|
#
|
100
|
-
# See 'get_command.rb' as example
|
100
|
+
# See 'get_command.rb' as example
|
101
101
|
|
102
102
|
def add_option(option, usage, desc)
|
103
|
-
@options_descs ||= {}
|
104
|
-
|
105
103
|
@options[option] = nil
|
106
104
|
@options_descs[usage] = desc
|
107
105
|
end
|
108
106
|
|
109
|
-
HELP = <<-EOF
|
110
|
-
#{'nehm'.green} is a console tool, which downloads, sets IDv3 tags and adds to your iTunes library your SoundCloud posts or likes in convenient way
|
111
|
-
|
112
|
-
#{'Avalaible nehm commands:'.yellow}
|
113
|
-
#{'get'.green} Download, set tags and add to your iTunes library last post or like from your profile
|
114
|
-
#{'dl'.green} Download and set tags last post or like from your profile
|
115
|
-
#{'configure'.green} Configure application
|
116
|
-
#{'help'.green} Show help for specified command
|
117
|
-
#{'version'.green} Show version of installed nehm
|
118
|
-
|
119
|
-
See #{'nehm help [command]'.yellow} to read about a specific subcommand
|
120
|
-
EOF
|
121
|
-
|
122
107
|
end
|
123
108
|
end
|
data/lib/nehm/command_manager.rb
CHANGED
@@ -3,8 +3,8 @@ require 'nehm/command'
|
|
3
3
|
module Nehm
|
4
4
|
|
5
5
|
##
|
6
|
-
# The command manager contains information about all nehm commands
|
7
|
-
# and run them
|
6
|
+
# The command manager contains information about all nehm commands
|
7
|
+
# It also find and run them
|
8
8
|
|
9
9
|
module CommandManager
|
10
10
|
|
@@ -13,18 +13,15 @@ module Nehm
|
|
13
13
|
:dl,
|
14
14
|
:get,
|
15
15
|
:help,
|
16
|
+
:search,
|
17
|
+
:select,
|
16
18
|
:version
|
17
19
|
]
|
18
20
|
|
19
21
|
##
|
20
|
-
# Run the command specified by 'args'
|
22
|
+
# Run the command specified by 'args'
|
21
23
|
|
22
24
|
def self.run(args)
|
23
|
-
if args.empty?
|
24
|
-
UI.say Nehm::Command::HELP
|
25
|
-
UI.term
|
26
|
-
end
|
27
|
-
|
28
25
|
cmd_name = args.shift.downcase
|
29
26
|
cmd = find_command(cmd_name)
|
30
27
|
cmd.invoke(args)
|
@@ -42,25 +39,18 @@ module Nehm
|
|
42
39
|
command_instance(possibilities.first)
|
43
40
|
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
def find_command_possibilities(cmd_name)
|
42
|
+
def self.find_command_possibilities(cmd_name)
|
48
43
|
len = cmd_name.length
|
49
44
|
COMMANDS.select { |command| command[0, len] == cmd_name }
|
50
45
|
end
|
51
46
|
|
52
|
-
def command_instance(command_name)
|
47
|
+
def self.command_instance(command_name)
|
53
48
|
command_name = command_name.to_s
|
54
49
|
const_name = command_name.capitalize << 'Command'
|
55
50
|
|
56
|
-
|
51
|
+
require "nehm/commands/#{command_name}_command"
|
57
52
|
Nehm.const_get(const_name).new
|
58
53
|
end
|
59
54
|
|
60
|
-
def require_commands
|
61
|
-
project_root = File.dirname(File.absolute_path(__FILE__))
|
62
|
-
Dir.glob(project_root + '/commands/*') { |file| require file }
|
63
|
-
end
|
64
|
-
|
65
55
|
end
|
66
56
|
end
|
@@ -3,15 +3,10 @@ module Nehm
|
|
3
3
|
|
4
4
|
def execute
|
5
5
|
loop do
|
6
|
-
|
7
|
-
UI.say "Permalink: #{Cfg[:permalink].cyan}" if Cfg[:permalink]
|
8
|
-
UI.say "iTunes playlist: #{PlaylistManager.default_playlist.to_s.cyan}" if !OS.linux? && PlaylistManager.default_playlist
|
6
|
+
show_info
|
9
7
|
UI.newline
|
10
|
-
|
11
8
|
show_menu
|
12
|
-
|
13
|
-
sleep(1)
|
14
|
-
UI.newline
|
9
|
+
sleep(UI::SLEEP_PERIOD)
|
15
10
|
end
|
16
11
|
end
|
17
12
|
|
@@ -29,14 +24,22 @@ module Nehm
|
|
29
24
|
|
30
25
|
private
|
31
26
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
27
|
+
def show_info
|
28
|
+
dl_path = PathManager.default_dl_path
|
29
|
+
UI.say "Download path: #{dl_path.magenta}" if dl_path
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
permalink = UserManager.default_permalink
|
32
|
+
UI.say "Permalink: #{permalink.cyan}" if permalink
|
33
|
+
|
34
|
+
playlist = PlaylistManager.default_playlist
|
35
|
+
UI.say "iTunes playlist: #{playlist.to_s.cyan}" if playlist
|
36
|
+
end
|
37
|
+
|
38
|
+
def show_menu
|
39
|
+
UI.menu do |menu|
|
40
|
+
menu.choice(:inc, 'Edit download path'.freeze) { PathManager.set_dl_path }
|
41
|
+
menu.choice(:inc, 'Edit permalink'.freeze) { UserManager.set_uid }
|
42
|
+
menu.choice(:inc, 'Edit iTunes playlist'.freeze) { PlaylistManager.set_playlist } if OS.mac?
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
@@ -1,28 +1,30 @@
|
|
1
|
-
require 'nehm/tracks'
|
2
|
-
|
3
1
|
module Nehm
|
4
2
|
class DlCommand < Command
|
5
3
|
|
6
4
|
def initialize
|
7
5
|
super
|
8
6
|
|
9
|
-
add_option(:from, 'from PERMALINK'
|
7
|
+
add_option(:from, 'from PERMALINK',
|
10
8
|
'Get track(s) from user with PERMALINK')
|
11
9
|
|
12
|
-
add_option(:to, 'to PATH'
|
10
|
+
add_option(:to, 'to PATH',
|
13
11
|
'Download track(s) to PATH')
|
14
12
|
end
|
15
13
|
|
16
14
|
def execute
|
17
|
-
|
15
|
+
@options[:dl] = true
|
16
|
+
|
17
|
+
get_cmd = CommandManager.command_instance('get')
|
18
|
+
get_cmd.options = @options
|
19
|
+
get_cmd.execute
|
18
20
|
end
|
19
21
|
|
20
22
|
def arguments
|
21
|
-
{
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
{ 'post' => 'Download last post (track or repost) from your profile',
|
24
|
+
'NUMBER posts' => 'Download last NUMBER posts from your profile',
|
25
|
+
'like' => 'Download your last like',
|
26
|
+
'NUMBER likes' => 'Download your last NUMBER likes',
|
27
|
+
'URL' => 'Download track from entered URL' }
|
26
28
|
end
|
27
29
|
|
28
30
|
def program_name
|
@@ -30,7 +32,7 @@ module Nehm
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def summary
|
33
|
-
'Download and set tags any track from
|
35
|
+
'Download and set tags any track from SoundCloud'
|
34
36
|
end
|
35
37
|
|
36
38
|
def usage
|
@@ -1,31 +1,55 @@
|
|
1
|
-
require 'nehm/tracks'
|
2
|
-
|
3
1
|
module Nehm
|
4
2
|
class GetCommand < Command
|
5
3
|
|
6
4
|
def initialize
|
7
5
|
super
|
8
6
|
|
9
|
-
add_option(:from, 'from PERMALINK'
|
7
|
+
add_option(:from, 'from PERMALINK',
|
10
8
|
'Get track(s) from user with PERMALINK')
|
11
9
|
|
12
|
-
add_option(:to, 'to PATH'
|
10
|
+
add_option(:to, 'to PATH',
|
13
11
|
'Download track(s) to PATH')
|
14
12
|
|
15
|
-
add_option(:
|
13
|
+
add_option(:pl, 'pl PLAYLIST',
|
16
14
|
'Add track(s) to iTunes playlist with PLAYLIST name')
|
17
15
|
end
|
18
16
|
|
19
17
|
def execute
|
20
|
-
|
18
|
+
track_manager = TrackManager.new(@options)
|
19
|
+
|
20
|
+
UI.say 'Getting information about track(s)'
|
21
|
+
arg = @options[:args].pop
|
22
|
+
tracks =
|
23
|
+
case arg
|
24
|
+
when /^l.*s$/
|
25
|
+
count = @options[:args].pop.to_i
|
26
|
+
track_manager.likes(count, 0)
|
27
|
+
when /^p.*s$/
|
28
|
+
count = @options[:args].pop.to_i
|
29
|
+
track_manager.posts(count, 0)
|
30
|
+
when /^l/
|
31
|
+
track_manager.likes(1, 0)
|
32
|
+
when /^p/
|
33
|
+
track_manager.posts(1, 0)
|
34
|
+
when /https:\/\/soundcloud.com\//
|
35
|
+
track_manager.track_from_url(arg)
|
36
|
+
when nil
|
37
|
+
UI.term 'You must provide an argument'
|
38
|
+
else
|
39
|
+
UI.term "Invalid argument/option '#{arg}'"
|
40
|
+
end
|
41
|
+
|
42
|
+
UI.term 'There are no tracks yet' if tracks.nil?
|
43
|
+
|
44
|
+
track_manager.process_tracks(tracks)
|
21
45
|
end
|
22
46
|
|
23
47
|
def arguments
|
24
|
-
{
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
48
|
+
{ 'post' => 'Get last post (track or repost) from your profile',
|
49
|
+
'NUMBER posts' => 'Get last NUMBER posts from your profile',
|
50
|
+
'like' => 'Get your last like',
|
51
|
+
'NUMBER likes' => 'Get your last NUMBER likes',
|
52
|
+
'URL' => 'Get track from entered URL' }
|
29
53
|
end
|
30
54
|
|
31
55
|
def program_name
|
@@ -33,7 +57,7 @@ module Nehm
|
|
33
57
|
end
|
34
58
|
|
35
59
|
def summary
|
36
|
-
'Download tracks, set tags and add to your iTunes library tracks from
|
60
|
+
'Download tracks, set tags and add to your iTunes library tracks from SoundCloud'
|
37
61
|
end
|
38
62
|
|
39
63
|
def usage
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Nehm
|
2
2
|
class HelpCommand < Command
|
3
3
|
|
4
|
-
|
4
|
+
SPACES_BTWN_NAME_AND_DESC = 3
|
5
5
|
|
6
6
|
def execute
|
7
7
|
command_name = options[:args].pop
|
8
8
|
if command_name.nil?
|
9
|
-
UI.say
|
9
|
+
UI.say HELP
|
10
10
|
UI.term
|
11
11
|
end
|
12
12
|
|
@@ -19,7 +19,7 @@ module Nehm
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def arguments
|
22
|
-
{ 'COMMAND'
|
22
|
+
{ 'COMMAND' => 'name of command to show help' }
|
23
23
|
end
|
24
24
|
|
25
25
|
def program_name
|
@@ -70,14 +70,14 @@ module Nehm
|
|
70
70
|
unless @longest
|
71
71
|
names = []
|
72
72
|
names += @cmd.arguments.keys unless @cmd.arguments.empty?
|
73
|
-
names += @cmd.
|
73
|
+
names += @cmd.options_descs.keys unless @cmd.options_descs.empty?
|
74
74
|
@longest ||= find_longest_name(names).length
|
75
75
|
end
|
76
76
|
|
77
77
|
hash.each do |name, desc|
|
78
78
|
need_spaces = @longest - name.length
|
79
79
|
|
80
|
-
UI.say " #{name}#{' ' * (need_spaces +
|
80
|
+
UI.say " #{name.green}#{' ' * (need_spaces + SPACES_BTWN_NAME_AND_DESC)}#{desc}"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'nehm/tracks_view_command'
|
2
|
+
|
3
|
+
module Nehm
|
4
|
+
|
5
|
+
class SearchCommand < TracksViewCommand
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
@query = @options[:args].join(' ')
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def arguments
|
17
|
+
{ 'QUERY' => 'Search query' }
|
18
|
+
end
|
19
|
+
|
20
|
+
def program_name
|
21
|
+
'nehm search'
|
22
|
+
end
|
23
|
+
|
24
|
+
def summary
|
25
|
+
'Search tracks, print them nicely and download selected tracks'
|
26
|
+
end
|
27
|
+
|
28
|
+
def usage
|
29
|
+
"#{program_name} QUERY [OPTIONS]"
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def get_tracks
|
35
|
+
UI.term 'You must provide an argument' if @query.empty?
|
36
|
+
|
37
|
+
@track_manager.search(@query, @limit, @offset)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'nehm/tracks_view_command'
|
2
|
+
|
3
|
+
module Nehm
|
4
|
+
|
5
|
+
##
|
6
|
+
# This command gets likes/posts from user's account,
|
7
|
+
# Prints as menu, and downloads selected tracks
|
8
|
+
|
9
|
+
class SelectCommand < TracksViewCommand
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super
|
13
|
+
|
14
|
+
add_option(:from, 'from PERMALINK',
|
15
|
+
'Select track(s) from user with PERMALINK')
|
16
|
+
end
|
17
|
+
|
18
|
+
def arguments
|
19
|
+
{ 'likes' => 'Select likes',
|
20
|
+
'posts' => 'Select posts' }
|
21
|
+
end
|
22
|
+
|
23
|
+
def program_name
|
24
|
+
'nehm select'
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute
|
28
|
+
@type = @options[:args].shift
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def summary
|
33
|
+
'Get likes or posts from your account, nicely print them and download selected tracks'
|
34
|
+
end
|
35
|
+
|
36
|
+
def usage
|
37
|
+
"#{program_name} ARGUMENT [OPTIONS]"
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def get_tracks
|
43
|
+
case @type
|
44
|
+
when /l/
|
45
|
+
@track_manager.likes(@limit, @offset)
|
46
|
+
when /p/
|
47
|
+
@track_manager.posts(@limit, @offset)
|
48
|
+
when nil
|
49
|
+
UI.term 'You must provide an argument'
|
50
|
+
else
|
51
|
+
UI.term "Invalid argument/option '#{type}'"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|