nehm 1.5.6.2 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +8 -0
- data/README.md +6 -7
- data/bin/nehm +6 -1
- data/lib/nehm.rb +31 -48
- data/lib/nehm/applescript.rb +7 -2
- data/lib/nehm/artwork.rb +6 -6
- data/lib/nehm/cfg.rb +5 -1
- data/lib/nehm/client.rb +78 -6
- data/lib/nehm/command.rb +123 -0
- data/lib/nehm/command_manager.rb +66 -0
- data/lib/nehm/commands/configure_command.rb +44 -0
- data/lib/nehm/commands/dl_command.rb +41 -0
- data/lib/nehm/commands/get_command.rb +44 -0
- data/lib/nehm/commands/help_command.rb +85 -0
- data/lib/nehm/commands/version_command.rb +23 -0
- data/lib/nehm/option_parser.rb +31 -0
- data/lib/nehm/os.rb +5 -0
- data/lib/nehm/path_manager.rb +28 -31
- data/lib/nehm/playlist.rb +7 -1
- data/lib/nehm/playlist_manager.rb +31 -14
- data/lib/nehm/track.rb +23 -21
- data/lib/nehm/tracks.rb +153 -0
- data/lib/nehm/ui.rb +35 -0
- data/lib/nehm/user_manager.rb +19 -42
- data/lib/nehm/version.rb +1 -1
- data/nehm.gemspec +2 -2
- metadata +24 -18
- data/lib/nehm/configure.rb +0 -24
- data/lib/nehm/get.rb +0 -100
- data/lib/nehm/help.rb +0 -93
- data/lib/nehm/user.rb +0 -81
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nehm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Nigmatzianov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogy
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: certifi
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,47 +39,47 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: colored
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0
|
47
|
+
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: faraday
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.9.1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.9.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: highline
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.7.2
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.7.2
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: soundcloud
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,15 +133,21 @@ files:
|
|
133
133
|
- lib/nehm/artwork.rb
|
134
134
|
- lib/nehm/cfg.rb
|
135
135
|
- lib/nehm/client.rb
|
136
|
-
- lib/nehm/
|
137
|
-
- lib/nehm/
|
138
|
-
- lib/nehm/
|
136
|
+
- lib/nehm/command.rb
|
137
|
+
- lib/nehm/command_manager.rb
|
138
|
+
- lib/nehm/commands/configure_command.rb
|
139
|
+
- lib/nehm/commands/dl_command.rb
|
140
|
+
- lib/nehm/commands/get_command.rb
|
141
|
+
- lib/nehm/commands/help_command.rb
|
142
|
+
- lib/nehm/commands/version_command.rb
|
143
|
+
- lib/nehm/option_parser.rb
|
139
144
|
- lib/nehm/os.rb
|
140
145
|
- lib/nehm/path_manager.rb
|
141
146
|
- lib/nehm/playlist.rb
|
142
147
|
- lib/nehm/playlist_manager.rb
|
143
148
|
- lib/nehm/track.rb
|
144
|
-
- lib/nehm/
|
149
|
+
- lib/nehm/tracks.rb
|
150
|
+
- lib/nehm/ui.rb
|
145
151
|
- lib/nehm/user_manager.rb
|
146
152
|
- lib/nehm/version.rb
|
147
153
|
- nehm.gemspec
|
@@ -165,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
171
|
version: '0'
|
166
172
|
requirements: []
|
167
173
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.4.
|
174
|
+
rubygems_version: 2.4.8
|
169
175
|
signing_key:
|
170
176
|
specification_version: 4
|
171
177
|
summary: Convenient way to download tracks from SoundCloud via terminal
|
data/lib/nehm/configure.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Nehm
|
2
|
-
# Configure module responds to 'nehm configure' command
|
3
|
-
module Configure
|
4
|
-
def self.menu
|
5
|
-
loop do
|
6
|
-
puts "Download path: #{Paint[Cfg[:dl_path], :magenta]}" if Cfg[:dl_path]
|
7
|
-
puts "Permalink: #{Paint[Cfg[:permalink], :cyan]}" if Cfg[:permalink]
|
8
|
-
puts "iTunes playlist: #{Paint[PlaylistManager.playlist, :cyan]}" if !OS.linux? && PlaylistManager.playlist
|
9
|
-
puts "\n"
|
10
|
-
|
11
|
-
HighLine.new.choose do |menu|
|
12
|
-
menu.prompt = Paint['Choose setting', :yellow]
|
13
|
-
|
14
|
-
menu.choice('Edit download path'.freeze) { PathManager.set_dl_path }
|
15
|
-
menu.choice('Edit permalink'.freeze) { UserManager.log_in }
|
16
|
-
menu.choice('Edit iTunes playlist'.freeze) { PlaylistManager.set_playlist } unless OS.linux?
|
17
|
-
menu.choice('Exit'.freeze) { puts 'Goodbye!'; exit }
|
18
|
-
end
|
19
|
-
sleep(1)
|
20
|
-
puts "\n"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/nehm/get.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'taglib'
|
2
|
-
|
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=) }]
|
11
|
-
|
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)
|
18
|
-
|
19
|
-
option[:method].call(value)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
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
|
49
|
-
|
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
|
-
end
|
61
|
-
puts Paint['Done!', :green]
|
62
|
-
end
|
63
|
-
|
64
|
-
module_function
|
65
|
-
|
66
|
-
def track_from_url(url)
|
67
|
-
hash = Client.get('/resolve', url: url)
|
68
|
-
[*Track.new(hash)]
|
69
|
-
end
|
70
|
-
|
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
|
78
|
-
|
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
|
87
|
-
|
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)
|
95
|
-
|
96
|
-
file.save
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/lib/nehm/help.rb
DELETED
@@ -1,93 +0,0 @@
|
|
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
|
7
|
-
|
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
|
13
|
-
|
14
|
-
See #{Paint['nehm help [command]', :yellow]} to read about a specific subcommand
|
15
|
-
HELP
|
16
|
-
end
|
17
|
-
|
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
|
29
|
-
end
|
30
|
-
|
31
|
-
module_function
|
32
|
-
|
33
|
-
def configure
|
34
|
-
puts <<-CONFIGURE.gsub(/^ {8}/, '')
|
35
|
-
#{Paint['Input:', :yellow]} nehm configure
|
36
|
-
|
37
|
-
#{Paint['Summary:', :yellow]}
|
38
|
-
Configuring nehm app
|
39
|
-
CONFIGURE
|
40
|
-
end
|
41
|
-
|
42
|
-
def dl
|
43
|
-
puts <<-DL.gsub(/^ {8}/, '')
|
44
|
-
#{Paint['Input:', :yellow]} nehm dl OPTIONS [from PERMALINK] [to PATH_TO_DIRECTORY] [playlist ITUNES_PLAYLIST]
|
45
|
-
|
46
|
-
#{Paint['Summary:', :yellow]}
|
47
|
-
Download tracks from SoundCloud and setting tags
|
48
|
-
|
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
|
55
|
-
|
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
|
63
|
-
|
64
|
-
def get
|
65
|
-
puts <<-GET.gsub(/^ {8}/, '')
|
66
|
-
#{Paint['Input:', :yellow]} nehm get OPTIONS [from PERMALINK] [to PATH_TO_DIRECTORY] [playlist ITUNES_PLAYLIST]
|
67
|
-
|
68
|
-
#{Paint['Summary:', :yellow]}
|
69
|
-
Download tracks, set tags and add to your iTunes library tracks from Soundcloud
|
70
|
-
|
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
|
77
|
-
|
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
|
85
|
-
|
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
|
92
|
-
end
|
93
|
-
end
|
data/lib/nehm/user.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'faraday'
|
3
|
-
|
4
|
-
module Nehm
|
5
|
-
class User
|
6
|
-
# Max limit of tracks for correct SoundCloud requests
|
7
|
-
SOUNDCLOUD_MAX_LIMIT = 180
|
8
|
-
|
9
|
-
def initialize(id)
|
10
|
-
@id = id
|
11
|
-
end
|
12
|
-
|
13
|
-
def likes(count)
|
14
|
-
# Method to_i return 0, if there aren't any numbers in string
|
15
|
-
if count == 0
|
16
|
-
puts Paint['Invalid number of likes!', :red]
|
17
|
-
exit
|
18
|
-
end
|
19
|
-
|
20
|
-
d = count / SOUNDCLOUD_MAX_LIMIT
|
21
|
-
m = count % SOUNDCLOUD_MAX_LIMIT
|
22
|
-
d = m == 0 ? d : d + 1
|
23
|
-
|
24
|
-
likes = []
|
25
|
-
d.times do |i|
|
26
|
-
limit = count > SOUNDCLOUD_MAX_LIMIT ? SOUNDCLOUD_MAX_LIMIT : count
|
27
|
-
count -= SOUNDCLOUD_MAX_LIMIT
|
28
|
-
|
29
|
-
likes += Client.get("/users/#{@id}/favorites?limit=#{limit}&offset=#{(i)*SOUNDCLOUD_MAX_LIMIT}")
|
30
|
-
end
|
31
|
-
|
32
|
-
if likes.empty?
|
33
|
-
puts Paint['There are no likes yet :(', :red]
|
34
|
-
exit
|
35
|
-
end
|
36
|
-
|
37
|
-
likes.map! { |hash| Track.new(hash) }
|
38
|
-
end
|
39
|
-
|
40
|
-
# Post is last track/repost in profile
|
41
|
-
def posts(count)
|
42
|
-
# Method to_i return 0, if there aren't any numbers in string
|
43
|
-
if count == 0
|
44
|
-
puts Paint['Invalid number of posts!', :red]
|
45
|
-
exit
|
46
|
-
end
|
47
|
-
|
48
|
-
d = count / SOUNDCLOUD_MAX_LIMIT
|
49
|
-
m = count % SOUNDCLOUD_MAX_LIMIT
|
50
|
-
d = m == 0 ? d : d + 1
|
51
|
-
|
52
|
-
# Official SC API wrapper doesn't support posts
|
53
|
-
# So I should get posts by HTTP requests
|
54
|
-
conn = Faraday.new(url: 'https://api-v2.soundcloud.com/')
|
55
|
-
|
56
|
-
posts = []
|
57
|
-
d.times do |i|
|
58
|
-
limit = count > SOUNDCLOUD_MAX_LIMIT ? SOUNDCLOUD_MAX_LIMIT : count
|
59
|
-
count -= SOUNDCLOUD_MAX_LIMIT
|
60
|
-
|
61
|
-
response = conn.get("/profile/soundcloud:users:#{@id}?limit=#{limit}&offset=#{i*SOUNDCLOUD_MAX_LIMIT}")
|
62
|
-
parsed = JSON.parse(response.body)
|
63
|
-
collection = parsed['collection']
|
64
|
-
|
65
|
-
break if collection.nil?
|
66
|
-
|
67
|
-
posts += collection
|
68
|
-
end
|
69
|
-
|
70
|
-
if posts.empty?
|
71
|
-
puts Paint['There are no posts yet :(', :red]
|
72
|
-
exit
|
73
|
-
end
|
74
|
-
|
75
|
-
rejected = posts.reject! { |hash| hash['type'] == 'playlist' }
|
76
|
-
puts Paint["Was skipped #{rejected.length} playlist(s) (nehm doesn't download playlists)", :yellow] if rejected
|
77
|
-
|
78
|
-
posts.map! { |hash| Track.new(hash['track']) }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|