nehm 1.5.6.2 → 1.6.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.
@@ -1,38 +1,51 @@
1
+ require 'nehm/playlist'
2
+
1
3
  module Nehm
4
+
5
+ ##
6
+ # Playlist manager works with iTunes playlists
7
+
2
8
  module PlaylistManager
3
- def self.playlist
4
- @temp_playlist || default_user_playlist || music_master_library unless OS.linux?
9
+
10
+ ##
11
+ # Returns default iTunes playlist (contains in ~/.nehmconfig)
12
+
13
+ def self.default_playlist
14
+ default_user_playlist || music_master_library unless OS.linux?
15
+ end
16
+
17
+ ##
18
+ # Checks path for existence and returns it if exists
19
+
20
+ def self.get_playlist(playlist_name)
21
+ if AppleScript.list_of_playlists.include? playlist_name
22
+ Playlist.new(playlist_name)
23
+ else
24
+ UI.term 'Invalid playlist name. Please enter correct name'
25
+ end
5
26
  end
6
27
 
7
28
  def self.set_playlist
8
29
  loop do
9
- playlist = HighLine.new.ask('Enter name of default iTunes playlist to which you want add tracks (press Enter to set it to default iTunes Music library)')
30
+ playlist = HighLine.new.ask('Enter name of default iTunes playlist to that you want add tracks (press Enter to set it to default iTunes Music library):')
10
31
 
11
32
  # If entered nothing, unset iTunes playlist
12
33
  if playlist == ''
13
34
  Cfg[:playlist] = nil
14
- puts Paint['Default iTunes playlist unset', :green]
35
+ UI.success 'Default iTunes playlist unset'
15
36
  break
16
37
  end
17
38
 
18
39
  if AppleScript.list_of_playlists.include? playlist
19
40
  Cfg[:playlist] = playlist
20
- puts Paint["Default iTunes playlist set up to #{playlist}", :green]
41
+ UI.say "#{'Default iTunes playlist set up to'.green} #{playlist.magenta}"
21
42
  break
22
43
  else
23
- puts Paint['Invalid playlist name. Please enter correct name', :red]
44
+ UI.error 'Invalid playlist name. Please enter correct name'
24
45
  end
25
46
  end
26
47
  end
27
48
 
28
- def self.temp_playlist=(playlist)
29
- if AppleScript.list_of_playlists.include? playlist
30
- @temp_playlist = Playlist.new(playlist)
31
- else
32
- puts Paint['Invalid playlist name. Please enter correct name', :red]
33
- exit
34
- end
35
- end
36
49
 
37
50
  module_function
38
51
 
@@ -40,8 +53,12 @@ module Nehm
40
53
  Playlist.new(Cfg[:playlist]) unless Cfg[:playlist].nil?
41
54
  end
42
55
 
56
+ ##
57
+ # Music master library is main iTunes music library
58
+
43
59
  def music_master_library
44
60
  Playlist.new(AppleScript.music_master_library)
45
61
  end
62
+
46
63
  end
47
64
  end
@@ -1,5 +1,11 @@
1
+ require 'nehm/artwork'
2
+
1
3
  module Nehm
4
+
5
+ # Primitive for SoundCloud track
6
+
2
7
  class Track
8
+
3
9
  attr_reader :hash
4
10
 
5
11
  def initialize(hash)
@@ -7,13 +13,7 @@ module Nehm
7
13
  end
8
14
 
9
15
  def artist
10
- title = @hash['title']
11
-
12
- if title.include? ' - '
13
- title.split(' - ')[0]
14
- else
15
- @hash['user']['username']
16
- end
16
+ name[0]
17
17
  end
18
18
 
19
19
  def artwork
@@ -21,34 +21,35 @@ module Nehm
21
21
  end
22
22
 
23
23
  def file_name
24
- "#{name.gsub(/[^0-9A-Za-z -]/, '')}.mp3"
24
+ "#{full_name.tr(',./\\\'$%"', '')}.mp3"
25
25
  end
26
26
 
27
27
  def file_path
28
- File.join(PathManager.dl_path, file_name)
28
+ File.join(ENV['dl_path'], file_name)
29
+ end
30
+
31
+ def full_name
32
+ "#{artist} - #{title}"
29
33
  end
30
34
 
31
35
  def id
32
36
  @hash['id']
33
37
  end
34
38
 
35
- # Used in Get#dl and in Track#file_name
39
+ # Returns artist and title in array
36
40
  def name
37
- artist + ' - ' + title
38
- end
41
+ title = @hash['title']
42
+
43
+ separators = [' - ', ' ~ ']
44
+ separators.each do |sep|
45
+ return title.split(sep) if title.include? sep
46
+ end
39
47
 
40
- def streamable?
41
- @hash['streamable']
48
+ [@hash['user']['username'], title]
42
49
  end
43
50
 
44
51
  def title
45
- title = @hash['title']
46
-
47
- if title.include? ' - '
48
- title.split(' - ')[1]
49
- else
50
- title
51
- end
52
+ name[1]
52
53
  end
53
54
 
54
55
  def url
@@ -58,5 +59,6 @@ module Nehm
58
59
  def year
59
60
  @hash['created_at'][0..3].to_i
60
61
  end
62
+
61
63
  end
62
64
  end
@@ -0,0 +1,153 @@
1
+ require 'taglib'
2
+
3
+ require 'nehm/applescript'
4
+ require 'nehm/os'
5
+ require 'nehm/track'
6
+
7
+ module Nehm
8
+
9
+ ##
10
+ # Tracks contains logic, that need to 'nehm get/dl ...' commands.
11
+ #
12
+ # It used in 'get_command.rb' and 'dl_command.rb'.
13
+
14
+ module Tracks
15
+
16
+ ##
17
+ # Main method.
18
+
19
+ def self.[](type, options)
20
+ # Setting up user id
21
+ permalink = options[:from]
22
+ uid = permalink ? UserManager.get_uid(permalink) : UserManager.default_uid
23
+ unless uid
24
+ UI.error "You didn't logged in"
25
+ UI.say "Login from #{'nehm configure'.yellow} or use #{'[from PERMALINK]'.yellow} option"
26
+ UI.term
27
+ end
28
+
29
+ # Setting up iTunes playlist
30
+ if type == :get && !OS.linux?
31
+ playlist_name = options[:playlist]
32
+ playlist = playlist_name ? PlaylistManager.get_playlist(playlist_name) : PlaylistManager.default_playlist
33
+ itunes_playlist_ready = true if playlist
34
+ else
35
+ itunes_playlist_ready = false
36
+ end
37
+
38
+ # Setting up download path
39
+ temp_path = options[:to]
40
+ dl_path = temp_path ? PathManager.get_path(temp_path) : PathManager.default_dl_path
41
+ if dl_path
42
+ ENV['dl_path'] = dl_path
43
+ else
44
+ UI.error "You don't set up download path!"
45
+ UI.say "Set it up from #{'nehm configure'.yellow} or use #{'[to PATH_TO_DIRECTORY]'.yellow} option"
46
+ UI.term
47
+ end
48
+
49
+ UI.say 'Getting information about track(s)'
50
+ arg = options[:args].pop
51
+ tracks = []
52
+ tracks +=
53
+ case arg
54
+ when 'like'
55
+ likes(1, uid)
56
+ when 'post'
57
+ posts(1, uid)
58
+ when 'likes'
59
+ count = options[:args].pop.to_i
60
+ likes(count, uid)
61
+ when 'posts'
62
+ count = options[:args].pop.to_i
63
+ posts(count, uid)
64
+ when %r{https:\/\/soundcloud.com\/}
65
+ track(arg)
66
+ when nil
67
+ UI.error 'You must provide argument'
68
+ UI.say "Use #{'nehm help'.yellow} for help"
69
+ UI.term
70
+ else
71
+ UI.error "Invalid argument/option #{arg}"
72
+ UI.say "Use #{'nehm help'.yellow} for help"
73
+ UI.term
74
+ end
75
+
76
+ tracks.each do |track|
77
+ UI.newline
78
+ dl(track)
79
+ tag(track)
80
+ track.artwork.suicide
81
+ playlist.add_track(track.file_path) if itunes_playlist_ready
82
+ UI.newline
83
+ end
84
+ UI.success 'Done!'
85
+ end
86
+
87
+ module_function
88
+
89
+ def dl(track)
90
+ # Downloading track
91
+ UI.say 'Downloading ' + track.full_name
92
+ `curl -# -o \"#{track.file_path}\" -L #{track.url}`
93
+
94
+ # Downloading artwork
95
+ UI.say 'Downloading artwork'
96
+ artwork = track.artwork
97
+ `curl -# -o \"#{artwork.file_path}\" -L #{artwork.url}`
98
+ end
99
+
100
+ def tag(track)
101
+ UI.say 'Setting tags'
102
+ path = track.file_path
103
+ TagLib::MPEG::File.open(path) do |file|
104
+ tag = file.id3v2_tag
105
+ tag.artist = track.artist
106
+ tag.title = track.title
107
+ tag.year = track.year
108
+
109
+ # Adding artwork
110
+ apic = TagLib::ID3v2::AttachedPictureFrame.new
111
+ apic.mime_type = 'image/jpeg'
112
+ apic.description = 'Cover'
113
+ apic.type = TagLib::ID3v2::AttachedPictureFrame::FrontCover
114
+ apic.picture = File.open(track.artwork.file_path, 'rb') { |f| f.read }
115
+ tag.add_frame(apic)
116
+
117
+ file.save
118
+ end
119
+ end
120
+
121
+ def likes(count, uid)
122
+ likes = Client.tracks(count, :likes, uid)
123
+ UI.term 'There are no likes yet' if likes.empty?
124
+
125
+ # Removing playlists and unstreamable tracks
126
+ unstreamable_tracks = likes.reject! { |hash| hash['streamable'] == false }
127
+ UI.warning "Was skipped #{unstreamable_tracks.length} undownloadable track(s)" if unstreamable_tracks
128
+
129
+ likes.map! { |hash| Track.new(hash) }
130
+ end
131
+
132
+ def posts(count, uid)
133
+ posts = Client.tracks(count, :posts, uid)
134
+ UI.term 'There are no posts yet' if posts.empty?
135
+
136
+ # Removing playlists and unstreamable tracks
137
+ first_count = posts.length
138
+ playlists = posts.reject! { |hash| hash['type'] == 'playlist' }
139
+ unstreamable_tracks = posts.reject! { |hash| hash['track']['streamable'] == false }
140
+ if playlists || unstreamable_tracks
141
+ UI.warning "Was skipped #{first_count - posts.length} undownloadable track(s) or playlist(s)"
142
+ end
143
+
144
+ posts.map! { |hash| Track.new(hash['track']) }
145
+ end
146
+
147
+ def track(url)
148
+ hash = Client.track(url)
149
+ [*Track.new(hash)]
150
+ end
151
+
152
+ end
153
+ end
@@ -0,0 +1,35 @@
1
+ module Nehm
2
+ module UI
3
+
4
+ # TODO: add Highline features to UI module
5
+
6
+ def self.error(msg)
7
+ puts "#{msg}\n".red
8
+ end
9
+
10
+ def self.newline
11
+ puts "\n"
12
+ end
13
+
14
+ def self.say(msg)
15
+ puts msg
16
+ end
17
+
18
+ def self.success(msg)
19
+ puts msg.green
20
+ end
21
+
22
+ def self.term(msg = nil)
23
+ if msg
24
+ abort msg.red
25
+ else
26
+ exit
27
+ end
28
+ end
29
+
30
+ def self.warning(msg)
31
+ puts "#{msg}".yellow
32
+ end
33
+
34
+ end
35
+ end
@@ -1,61 +1,38 @@
1
1
  module Nehm
2
+
3
+ ##
4
+ # User manager works with SoundCloud users' id
5
+
2
6
  module UserManager
3
- def self.user
4
- @temp_user || default_user
7
+
8
+ ##
9
+ # Returns default user id (contains in ~/.nehmconfig)
10
+
11
+ def self.default_uid
12
+ Cfg[:default_id]
5
13
  end
6
14
 
7
- def self.logged_in?
8
- Cfg.key?(:default_id)
15
+ def self.get_uid(permalink)
16
+ user = Client.user(permalink)
17
+ UI.term 'Invalid permalink. Please enter correct permalink' if user.nil?
18
+
19
+ user['id']
9
20
  end
10
21
 
11
- def self.log_in
22
+ def self.set_uid
12
23
  loop do
13
24
  permalink = HighLine.new.ask('Please enter your permalink (last word in your profile url): ')
14
- user = get_user(permalink)
25
+ user = Client.user(permalink)
15
26
  if user
16
27
  Cfg[:default_id] = user.id
17
28
  Cfg[:permalink] = permalink
18
- puts Paint['Successfully logged in!', :green]
29
+ UI.success 'Successfully logged in!'
19
30
  break
20
31
  else
21
- puts Paint['Invalid permalink. Please enter correct permalink', :red]
32
+ UI.error 'Invalid permalink. Please enter correct permalink'
22
33
  end
23
34
  end
24
35
  end
25
36
 
26
- def self.temp_user=(permalink)
27
- user = get_user(permalink)
28
- if user
29
- @temp_user = User.new(user.id)
30
- else
31
- puts Paint['Invalid permalink. Please enter correct permalink', :red]
32
- exit
33
- end
34
- end
35
-
36
- module_function
37
-
38
- def default_user
39
- if UserManager.logged_in?
40
- User.new(Cfg[:default_id])
41
- else
42
- puts Paint["You didn't logged in", :red]
43
- puts "Login from #{Paint['nehm configure', :yellow]} or use #{Paint['[from PERMALINK]', :yellow]} option"
44
- exit
45
- end
46
- end
47
-
48
- def get_user(permalink)
49
- begin
50
- user = Client.get('/resolve', url: "https://soundcloud.com/#{permalink}")
51
- rescue SoundCloud::ResponseError => e
52
- if e.message =~ /404/
53
- user = nil
54
- else
55
- raise e
56
- end
57
- end
58
- user
59
- end
60
37
  end
61
38
  end
@@ -1,3 +1,3 @@
1
1
  module Nehm
2
- VERSION = '1.5.6.2'.freeze
2
+ VERSION = '1.6.1'.freeze
3
3
  end
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
  spec.required_ruby_version = '>= 1.9.3'
22
22
 
23
- spec.add_dependency 'bogy', '>= 1.1'
23
+ spec.add_dependency 'bogy'
24
24
  spec.add_dependency 'certifi'
25
+ spec.add_dependency 'colored'
25
26
  spec.add_dependency 'faraday', '>= 0.9.1'
26
27
  spec.add_dependency 'highline', '>= 1.7.2'
27
- spec.add_dependency 'paint'
28
28
  spec.add_dependency 'soundcloud', '>= 0.3.2'
29
29
  spec.add_dependency 'taglib-ruby', '>= 0.7.0'
30
30
  end