nehm 1.5.4 → 1.5.5.1
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/CHANGELOG.md +9 -25
- data/bin/nehm +1 -1
- data/lib/nehm.rb +42 -37
- data/lib/nehm/applescript.rb +18 -15
- data/lib/nehm/artwork.rb +26 -24
- data/lib/nehm/cfg.rb +21 -18
- data/lib/nehm/client.rb +14 -12
- data/lib/nehm/configure.rb +18 -16
- data/lib/nehm/get.rb +82 -83
- data/lib/nehm/help.rb +75 -72
- data/lib/nehm/os.rb +5 -3
- data/lib/nehm/path_manager.rb +52 -50
- data/lib/nehm/playlist.rb +13 -11
- data/lib/nehm/playlist_manager.rb +34 -30
- data/lib/nehm/track.rb +45 -43
- data/lib/nehm/user.rb +58 -55
- data/lib/nehm/user_manager.rb +45 -43
- data/lib/nehm/version.rb +1 -1
- metadata +3 -3
data/lib/nehm/get.rb
CHANGED
@@ -1,101 +1,100 @@
|
|
1
1
|
require 'taglib'
|
2
2
|
|
3
|
-
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module Nehm
|
4
|
+
# Get module responds to 'nehm get/dl ...' commands
|
5
|
+
module Get
|
6
|
+
def self.[](get_or_dl, args)
|
7
|
+
# Processing arguments
|
8
|
+
options = [{ name: 'to', method: PathManager.method(:temp_dl_path=) },
|
9
|
+
{ name: 'from', method: UserManager.method(:temp_user=) },
|
10
|
+
{ name: 'playlist', method: PlaylistManager.method(:temp_playlist=) }]
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
options.each do |option|
|
13
|
+
if args.include? option[:name]
|
14
|
+
index = args.index(option[:name])
|
15
|
+
value = args[index + 1]
|
16
|
+
args.delete_at(index + 1)
|
17
|
+
args.delete_at(index)
|
17
18
|
|
18
|
-
|
19
|
+
option[:method].call(value)
|
20
|
+
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
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
|
-
|
23
|
+
puts 'Getting information about track(s)'
|
24
|
+
user = UserManager.user
|
25
|
+
tracks = []
|
26
|
+
tracks +=
|
27
|
+
case args.last
|
28
|
+
when 'like'
|
29
|
+
user.likes(1)
|
30
|
+
when 'post'
|
31
|
+
user.posts(1)
|
32
|
+
when 'likes'
|
33
|
+
count = args[-2].to_i
|
34
|
+
user.likes(count)
|
35
|
+
when 'posts'
|
36
|
+
count = args[-2].to_i
|
37
|
+
user.posts(count)
|
38
|
+
when %r{https:\/\/soundcloud.com\/}
|
39
|
+
track_from_url(args.last)
|
40
|
+
when nil
|
41
|
+
puts Paint['You must provide option', :red]
|
42
|
+
puts "Input #{Paint['nehm help', :yellow]} for help"
|
43
|
+
exit
|
44
|
+
else
|
45
|
+
puts Paint["Invalid argument(s) '#{args.last}'", :red]
|
46
|
+
puts "Input #{Paint['nehm help', :yellow]} for help"
|
47
|
+
exit
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
puts 'Skip it'
|
50
|
+
tracks.each do |track|
|
51
|
+
if track.streamable?
|
52
|
+
dl(track)
|
53
|
+
dl(track.artwork)
|
54
|
+
tag(track)
|
55
|
+
track.artwork.suicide
|
56
|
+
PlaylistManager.playlist.add_track(track.file_path) if PlaylistManager.playlist && get_or_dl == :get && !OS.linux?
|
57
|
+
else
|
58
|
+
puts "#{Paint['Track', :yellow]} #{Paint[track.name, :cyan]} #{Paint['undownloadable', :yellow]}"
|
59
|
+
end
|
60
60
|
end
|
61
|
-
puts
|
61
|
+
puts Paint['Done!', :green]
|
62
62
|
end
|
63
|
-
puts Paint['Done!', :green]
|
64
|
-
end
|
65
63
|
|
66
|
-
|
64
|
+
module_function
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
def track_from_url(url)
|
67
|
+
hash = Client.get('/resolve', url: url)
|
68
|
+
[*Track.new(hash)]
|
69
|
+
end
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
71
|
+
def dl(arg)
|
72
|
+
puts 'Downloading ' + arg.name
|
73
|
+
path = arg.file_path
|
74
|
+
url = arg.url
|
75
|
+
command = "curl -# -o \"#{path}\" -L #{url}"
|
76
|
+
`#{command}`
|
77
|
+
end
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
79
|
+
def tag(track)
|
80
|
+
path = track.file_path
|
81
|
+
TagLib::MPEG::File.open(path) do |file|
|
82
|
+
puts 'Setting tags'
|
83
|
+
tag = file.id3v2_tag
|
84
|
+
tag.artist = track.artist
|
85
|
+
tag.title = track.title
|
86
|
+
tag.year = track.year
|
89
87
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
# Adding artwork
|
89
|
+
apic = TagLib::ID3v2::AttachedPictureFrame.new
|
90
|
+
apic.mime_type = 'image/jpeg'
|
91
|
+
apic.description = 'Cover'
|
92
|
+
apic.type = TagLib::ID3v2::AttachedPictureFrame::FrontCover
|
93
|
+
apic.picture = File.open(track.artwork.file_path, 'rb') { |f| f.read }
|
94
|
+
tag.add_frame(apic)
|
97
95
|
|
98
|
-
|
96
|
+
file.save
|
97
|
+
end
|
99
98
|
end
|
100
99
|
end
|
101
100
|
end
|
data/lib/nehm/help.rb
CHANGED
@@ -1,90 +1,93 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Nehm
|
2
|
+
# Help module responds to 'nehm help ...' command
|
3
|
+
module Help
|
4
|
+
def self.available_commands
|
5
|
+
puts <<-HELP.gsub(/^ {8}/, '')
|
6
|
+
#{Paint['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
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
#{Paint['Avalaible nehm commands:', :yellow]}
|
9
|
+
#{Paint['get', :green]} Download, set tags and add to your iTunes library last post or like from your profile
|
10
|
+
#{Paint['dl', :green]} Download and set tags last post or like from your profile
|
11
|
+
#{Paint['configure', :green]} Configure application
|
12
|
+
#{Paint['version', :green]} Show version of installed nehm
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
See #{Paint['nehm help [command]', :yellow]} to read about a specific subcommand
|
15
|
+
HELP
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
def self.show(command)
|
19
|
+
case command
|
20
|
+
when 'get', 'dl', 'configure', 'permalink'
|
21
|
+
Help.send(command)
|
22
|
+
when nil
|
23
|
+
Help.available_commands
|
24
|
+
else
|
25
|
+
puts Paint["Command '#{command}' doesn't exist", :red]
|
26
|
+
puts "\n"
|
27
|
+
Help.available_commands
|
28
|
+
end
|
26
29
|
end
|
27
|
-
end
|
28
30
|
|
29
|
-
|
31
|
+
module_function
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
def configure
|
34
|
+
puts <<-CONFIGURE.gsub(/^ {8}/, '')
|
35
|
+
#{Paint['Input:', :yellow]} nehm configure
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
#{Paint['Summary:', :yellow]}
|
38
|
+
Configuring nehm app
|
39
|
+
CONFIGURE
|
40
|
+
end
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
def dl
|
43
|
+
puts <<-DL.gsub(/^ {8}/, '')
|
44
|
+
#{Paint['Input:', :yellow]} nehm dl OPTIONS [from PERMALINK] [to PATH_TO_DIRECTORY] [playlist ITUNES_PLAYLIST]
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
#{Paint['Summary:', :yellow]}
|
47
|
+
Download tracks from SoundCloud and setting tags
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
#{Paint['OPTIONS:', :yellow]}
|
50
|
+
#{Paint['post', :green]} Do same with last post (track or repost) from your profile
|
51
|
+
#{Paint['<number> posts', :green]} Do same with last <number> posts from your profile
|
52
|
+
#{Paint['like', :green]} Do same with your last like
|
53
|
+
#{Paint['<number> likes', :green]} Do same with your last <number> likes
|
54
|
+
#{Paint['url', :magenta]} Do same with track from entered url
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
#{Paint['Extra options:', :yellow]}
|
57
|
+
#{Paint['from PERMALINK', :green]} Do aforecited operations from custom user profile
|
58
|
+
#{Paint['to PATH_TO_DIRECTORY', :green]} Do aforecited operations to custom directory
|
59
|
+
#{Paint['to current', :green]} Do aforecited operations to current working directory
|
60
|
+
#{Paint['playlist ITUNES_PLAYLIST', :green]} Do aforecited operations to custom iTunes playlist
|
61
|
+
DL
|
62
|
+
end
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
def get
|
65
|
+
puts <<-GET.gsub(/^ {8}/, '')
|
66
|
+
#{Paint['Input:', :yellow]} nehm get OPTIONS [from PERMALINK] [to PATH_TO_DIRECTORY] [playlist ITUNES_PLAYLIST]
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
+
#{Paint['Summary:', :yellow]}
|
69
|
+
Download tracks, set tags and add to your iTunes library tracks from Soundcloud
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
#{Paint['OPTIONS:', :yellow]}
|
72
|
+
#{Paint['post', :green]} Do same with last post (track or repost) from your profile
|
73
|
+
#{Paint['<number> posts', :green]} Do same with last <number> posts from your profile
|
74
|
+
#{Paint['like', :green]} Do same with your last like
|
75
|
+
#{Paint['<number> likes', :green]} Do same with your last <number> likes
|
76
|
+
#{Paint['url', :magenta]} Do same with track from entered url
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
#{Paint['Extra options:', :yellow]}
|
79
|
+
#{Paint['from PERMALINK', :green]} Do aforecited operations from profile with PERMALINK
|
80
|
+
#{Paint['to PATH_TO_DIRECTORY', :green]} Do aforecited operations to custom directory
|
81
|
+
#{Paint['to current', :green]} Do aforecited operations to current working directory
|
82
|
+
#{Paint['playlist ITUNES_PLAYLIST', :green]} Do aforecited operations to custom iTunes playlist
|
83
|
+
GET
|
84
|
+
end
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
def permalink
|
87
|
+
puts <<-PERM.gsub(/^ {8}/, '')
|
88
|
+
Permalink is the last word in your profile url
|
89
|
+
Example: for profile url #{Paint['soundcloud.com/qwerty', :magenta]} permalink is #{Paint['qwerty', :magenta]}
|
90
|
+
PERM
|
91
|
+
end
|
89
92
|
end
|
90
93
|
end
|
data/lib/nehm/os.rb
CHANGED
data/lib/nehm/path_manager.rb
CHANGED
@@ -1,69 +1,71 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Nehm
|
2
|
+
module PathManager
|
3
|
+
def self.dl_path
|
4
|
+
@temp_dl_path || default_dl_path
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def self.set_dl_path
|
8
|
+
loop do
|
9
|
+
default_path = File.join(ENV['HOME'], '/Music')
|
10
|
+
ask_sentence = 'Enter path to desirable download directory'
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if Dir.exist?(default_path)
|
13
|
+
ask_sentence << " (press enter to set it to #{Paint[default_path, :magenta]})"
|
14
|
+
else
|
15
|
+
default_path = nil
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
+
path = HighLine.new.ask(ask_sentence + ':')
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
# If user press enter, set path to default
|
21
|
+
path = default_path if path == '' && default_path
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
# If tilde at top of the line of path
|
24
|
+
path = PathManager.tilde_to_home(path) if PathManager.tilde_at_top?(path)
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
if Dir.exist?(path)
|
27
|
+
Cfg[:dl_path] = path
|
28
|
+
puts Paint["Download directory set up to #{Paint[path, :magenta]}", :green]
|
29
|
+
break
|
30
|
+
else
|
31
|
+
puts Paint["This directory doesn't exist. Please enter correct path", :red]
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def self.temp_dl_path=(path)
|
37
|
+
# If 'to ~/../..' entered
|
38
|
+
path = tilde_to_home(path) if tilde_at_top?(path)
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
# If 'to current' entered
|
41
|
+
path = Dir.pwd if path == 'current'
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
if Dir.exist?(path)
|
44
|
+
@temp_dl_path = path
|
45
|
+
else
|
46
|
+
puts Paint['Invalid download path! Please enter correct path', :red]
|
47
|
+
exit
|
48
|
+
end
|
47
49
|
end
|
48
|
-
end
|
49
50
|
|
50
|
-
|
51
|
+
module_function
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
def default_dl_path
|
54
|
+
if Cfg[:dl_path]
|
55
|
+
Cfg[:dl_path]
|
56
|
+
else
|
57
|
+
puts Paint["You don't set up download path!", :red]
|
58
|
+
puts "Set it up from #{Paint['nehm configure', :yellow]} or use #{Paint['[to PATH_TO_DIRECTORY]', :yellow]} option"
|
59
|
+
exit
|
60
|
+
end
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
def tilde_at_top?(path)
|
64
|
+
path[0] == '~'
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
67
|
+
def tilde_to_home(path)
|
68
|
+
File.join(ENV['HOME'], path[1..-1])
|
69
|
+
end
|
68
70
|
end
|
69
71
|
end
|