vk_music_loader 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11cfe23b6159ba7d08706798eab0e8a0f28c37f3
4
- data.tar.gz: 683f6784ac82fe6a11833d2a64016a3a4e83a53f
3
+ metadata.gz: 9487bed8735df5dec33b4295a2d70b28cec9d7f1
4
+ data.tar.gz: 3320b8a52fcf60e408c0aa412ab5f9508d87d8f8
5
5
  SHA512:
6
- metadata.gz: 1794e5ae7fa4c128e2975d36231d30d46b69faff7e276359acbbab5188062db6aa0e186898f0f1ebb7b85ac4672a45d72d98b1e25dba5c3f90d5d33a722a0d0f
7
- data.tar.gz: 463449e9f906f3a3bb1700f0c27651f5370b5cd5225c1857909c8d88553b70d765aeb0c6ee09e1465e9efa3723da5e689d51ef24eba1c11ead3b37031ab66687
6
+ metadata.gz: 8da45f9d965ef76e98dc6e088354389d76c9bf47de021e3c740ecd16a4ac8aadc2810ff58d79775dff019c3d2ae87856e34acdef9a0b5107bac21f219b2af160
7
+ data.tar.gz: c852c6fc59de8494da3d92917d3be15f15d1b447e97a4de9d80ceae21ef2e76e5c10611d40dfa53c0a43ec2d0756bf82d5ac58694127520378ac0c94299c23e7
data/README.md CHANGED
@@ -1,22 +1,46 @@
1
- # VkMusicLoader
1
+ # VK Music Loader
2
2
 
3
+ <a href="https://vk.com"><img src="https://cdn2.iconfinder.com/data/icons/vkontakte-3/154/api-vk-vkontakte-programming-128.png" align="left" hspace="10" vspace="6" width="50" height="50"></a>
4
+
5
+ **VK Music Loader** is a simple CLI Ruby gem to download music from VK (ВКонта́кте) using easy and convenient way of authorization - [Implicit Flow](https://new.vk.com/dev/implicit_flow_user)
6
+ This gem aimed at Ruby 2.0 or later.
3
7
 
4
8
  ## Installation
5
9
 
6
- ```
7
- gem install vk_music_loader
10
+ ```sh
11
+ $ gem install vk_music_loader
8
12
  ```
9
13
 
10
14
  ## Usage
11
15
 
12
- ```
13
- vk_music_loader -id user_or_group_id [-app your_standalone_app_id] [-folder folder_path_to_download_music]
16
+ To login you will need [create Standalone Application](https://new.vk.com/editapp?act=create) or use the author's application (default APP ID: `5377636`)
17
+
18
+ ```sh
19
+ $ vk_music_loader -id USER_OR_GROUP_ID
20
+ $ vk_music_loader -q QUERY_SEARCH
21
+ [ -app (or -app, --app, -application, --application) your_standalone_app_id (default: 5377636) ]
22
+ [ -count (or count, -count, --count, c, -c, --c) count_of_songs ]
23
+ [ -folder (or -folder, --folder, path, -path, --path, -p) folder_path_to_download_music (default: 'music') ]
24
+ [ -random (or --random, shuffle, -shuffle, --shuffle, -r) shuffle_download_flag (default: false) ]
14
25
  ```
15
26
 
27
+ If the song is already in the folder, it will not be downloaded.
28
+ ## Usage examples
29
+ ```sh
30
+ # Download all music from VK Public:
31
+ $ vk_music_loader -id -45172096
32
+
33
+ # Download 20 first songs from user in specified folder:
34
+ $ vk_music_loader -id 243556640 -с 20 -p '/Volumes/FLASHKA/music_in_da_bass_car'
35
+
36
+ # Download 4 random Eminem Song:
37
+ $ vk_music_loader -q 'Eminem' -c 4 -r
38
+ ```
39
+ ![](https://github.com/m1neral/vk_music_loader/blob/gh-wiki/wiki_src/record.gif)
16
40
 
17
41
  ## Contributing
18
42
 
19
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/vk_music_loader.
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/m1neral/vk_music_loader.
20
44
 
21
45
 
22
46
  ## License
data/bin/vk_music_loader CHANGED
@@ -2,10 +2,4 @@
2
2
 
3
3
  require 'vk_music_loader'
4
4
 
5
- opts = Slop.parse do |o|
6
- o.integer 'app', '-app', '--app', '-application', '-application', default: 5377636 # author's application (you can use it)
7
- o.integer 'id', '-id', '--id', '-user-id', '--user-id', '-group-id', '--group-id'
8
- o.string 'folder', '-folder', '--folder', 'path', '-path', '--path', default: 'audio'
9
- end
10
-
11
- VkMusicLoader.call(opts)
5
+ VkMusicLoader.call
@@ -14,8 +14,25 @@ require 'vk_music_loader/authorizer'
14
14
  require 'vk_music_loader/songs_downloader'
15
15
 
16
16
  module VkMusicLoader
17
- def self.call(opts)
18
- auth_token = Authorizer.new(opts[:app]).perform
19
- SongsDownloader.new(auth_token, opts[:id], opts[:folder]).perform
17
+ def self.call
18
+ begin
19
+ opts = Slop.parse uppress_errors: true do |o|
20
+ o.integer 'app', '-app', '--app', '-application', '-application', default: 5377636 # author's application (you can use it)
21
+ o.integer 'id', '-id', '--id', '-user-id', '--user-id', '-group-id', '--group-id'
22
+ o.string 'query', '-query', '--query', '-q', 'search', '-search', '--search'
23
+ o.integer 'count', '-count', '--count', 'c', '-c', '--c'
24
+ o.string 'folder', '-folder', '--folder', 'path', '-path', '--path', '-p', default: 'audio'
25
+ o.bool 'random', '-random', '--random', 'shuffle', '-shuffle', '--shuffle', '-r'
26
+ end
27
+
28
+ if opts[:id] || opts[:query]
29
+ auth_token = VkMusicLoader::Authorizer.new(opts[:app]).perform
30
+ VkMusicLoader::SongsDownloader.new(auth_token, opts).perform
31
+ else
32
+ puts 'No user id or group id or query'
33
+ end
34
+ rescue Slop::Error => e
35
+ puts e.message
36
+ end
20
37
  end
21
38
  end
@@ -1,6 +1,14 @@
1
1
  module VkMusicLoader
2
2
  class Authorizer
3
- AUTH_FILE_PATH = File.expand_path('~') + '/.vk_auth_data'
3
+ AUTH_FILE_PATH = File.expand_path('~') + '/.vk_music_loader/auth_data'
4
+
5
+ AUTHORIZE_API_PATH = 'https://oauth.vk.com/authorize'
6
+ QUERY_PARAMS = {
7
+ scope: 'audio',
8
+ redirect_uri: 'http://oauth.vk.com/blank.html',
9
+ display: 'page',
10
+ response_type: 'token'
11
+ }
4
12
 
5
13
  def initialize(app_id)
6
14
  @app_id = app_id
@@ -14,15 +22,30 @@ module VkMusicLoader
14
22
 
15
23
  attr_reader :app_id
16
24
 
17
- def get_auth_params_from_browser_bar
18
- Launchy.open("https://oauth.vk.com/authorize?client_id=#{app_id}&scope=audio&redirect_uri=http://oauth.vk.com/blank.html&display=page&response_type=token")
25
+ def query_params
26
+ QUERY_PARAMS.merge(client_id: app_id)
27
+ end
28
+
29
+ def build_uri
30
+ uri = URI(AUTHORIZE_API_PATH)
31
+ uri.query = URI.encode_www_form(query_params)
32
+ uri
33
+ end
34
+
35
+ def get_auth_params_from_browser_bar(uri)
19
36
  ARGV.clear
37
+
38
+ Launchy.open(uri)
20
39
  puts 'Paste full URL from browser bar and press ENTER: '
21
40
  CGI.parse(URI(gets.chomp.strip).fragment)
22
41
  end
23
42
 
24
43
  def save_auth_params_to_file
25
- auth_params = get_auth_params_from_browser_bar
44
+ auth_params = get_auth_params_from_browser_bar(build_uri)
45
+
46
+ dir_path = File.dirname(AUTH_FILE_PATH)
47
+ Dir.mkdir(dir_path) unless File.exists?(dir_path)
48
+
26
49
  auth_file = File.open(AUTH_FILE_PATH, 'w')
27
50
  auth_file.puts(Time.new + auth_params['expires_in'].first.to_i)
28
51
  auth_file.puts(auth_params['access_token'].first)
@@ -1,49 +1,103 @@
1
1
  module VkMusicLoader
2
2
  class SongsDownloader
3
- def initialize(auth_token, user_id, audio_folder_path)
3
+ API_AUDIO_METHOD_PATHS = {
4
+ get: 'https://api.vk.com/method/audio.get',
5
+ search: 'https://api.vk.com/method/audio.search'
6
+ }
7
+
8
+ QUERY_PARAMS = {
9
+ v: '5.53'
10
+ }
11
+
12
+ def initialize(auth_token, opts)
4
13
  @auth_token = auth_token
5
- @user_id = user_id
6
- @audio_folder_path = audio_folder_path
14
+ @opts = opts
7
15
  end
8
16
 
9
17
  def perform
10
- download_songs(get_playlist(auth_token))
18
+ raw_playlist = get_raw_playlist
19
+
20
+ if raw_playlist['error']
21
+ puts raw_playlist['error']['error_msg']
22
+ else
23
+ download_songs(get_milled_playlist(raw_playlist))
24
+ end
11
25
  end
12
26
 
13
27
  private
14
28
 
15
- attr_reader :auth_token, :user_id, :audio_folder_path
29
+ attr_reader :auth_token, :opts
30
+
31
+ def query_params
32
+ merged_query_params = QUERY_PARAMS.merge(access_token: auth_token)
33
+ merged_query_params[:owner_id] = opts[:id] unless opts[:query]
34
+ merged_query_params[:q] = opts[:query] unless opts[:id]
35
+ merged_query_params[:count] = 300 if opts[:query]
36
+ # In other cases, do not set the number of audios, because bug: https://new.vk.com/bugs?act=show&id=5502832_1
16
37
 
17
- def get_playlist(auth_token)
18
- http = Net::HTTP.new('api.vk.com', 443)
38
+ merged_query_params
39
+ end
40
+
41
+ def audio_method_path
42
+ if opts[:id]
43
+ API_AUDIO_METHOD_PATHS[:get]
44
+ elsif opts[:query]
45
+ API_AUDIO_METHOD_PATHS[:search]
46
+ end
47
+ end
48
+
49
+ def build_uri
50
+ uri = URI(audio_method_path)
51
+ uri.query = URI.encode_www_form(query_params)
52
+ uri
53
+ end
54
+
55
+ def build_http(uri)
56
+ http = Net::HTTP.new(uri.host, uri.port)
19
57
  http.use_ssl = true
20
58
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
59
+ http
60
+ end
21
61
 
22
- req = Net::HTTP::Get.new("https://api.vk.com/method/audio.get?owner_id=#{user_id}&v=5.50&access_token=#{auth_token}")
23
- res = http.request(req)
62
+ def get_raw_playlist
63
+ uri = build_uri
64
+ req = Net::HTTP::Get.new(uri)
65
+ res = build_http(uri).request(req)
24
66
 
25
67
  JSON.parse(res.body)
26
68
  end
27
69
 
70
+ def get_milled_playlist(raw_playlist)
71
+ songs = raw_playlist['response']['items']
72
+ songs_count = opts[:count] || songs.count
73
+
74
+ opts[:random] ? songs.sample(songs_count) : songs.take(songs_count)
75
+ end
76
+
28
77
  def download_songs(playlist)
29
- Dir.mkdir(audio_folder_path) unless File.exists?(audio_folder_path)
78
+ Dir.mkdir(opts[:folder]) unless File.exists?(opts[:folder])
30
79
 
31
- songs = playlist['response']['items']
80
+ downloads_count = 0
32
81
 
33
- songs.each do |song|
82
+ playlist.each do |song|
34
83
  song_url = URI.parse(song['url'])
35
- file_name = "#{song['artist']} - #{song['title']}.mp3"
36
- file_path = "#{audio_folder_path}/#{file_name}"
84
+ file_name = "#{song['artist']} - #{song['title']}".slice(0, 100).gsub(/[\x00\/\\:\*\?\"<>\|]/, '_') + '.mp3'
85
+ file_path = "#{opts[:folder]}/#{file_name}"
37
86
 
38
87
  unless File.file?(file_path)
39
88
  File.open(file_path, 'w') do |f|
40
89
  f.write Net::HTTP.get(song_url)
41
90
  f.close
42
91
 
92
+ downloads_count += 1
43
93
  puts "Downloaded: #{file_name}"
44
94
  end
45
95
  end
46
96
  end
97
+
98
+ puts "-----> Downloaded #{downloads_count} songs in #{opts[:folder]}"
99
+ puts "-----> The other #{playlist.count - downloads_count} songs have been already downloaded" if
100
+ playlist.count - downloads_count > 0
47
101
  end
48
102
  end
49
103
  end
@@ -1,4 +1,3 @@
1
-
2
1
  require 'rubygems'
3
2
  require 'time'
4
3
  require 'cgi'
@@ -12,11 +11,22 @@ require 'launchy'
12
11
  require '../vk_music_loader/authorizer'
13
12
  require '../vk_music_loader/songs_downloader'
14
13
 
15
- opts = Slop.parse do |o|
16
- o.integer 'app', '-app', '--app', '-application', '-application', default: 5377636 # author's application (you can use it)
17
- o.integer 'id', '-id', '--id', '-user-id', '--user-id', '-group-id', '--group-id'
18
- o.string 'folder', '-folder', '--folder', 'path', '-path', '--path', default: 'audio'
19
- end
14
+ begin
15
+ opts = Slop.parse uppress_errors: true do |o|
16
+ o.integer 'app', '-app', '--app', '-application', '-application', default: 5377636 # author's application (you can use it)
17
+ o.integer 'id', '-id', '--id', '-user-id', '--user-id', '-group-id', '--group-id'
18
+ o.string 'query', '-query', '--query', '-q', 'search', '-search', '--search'
19
+ o.integer 'count', '-count', '--count', 'c', '-c', '--c'
20
+ o.string 'folder', '-folder', '--folder', 'path', '-path', '--path', '-p', default: 'audio'
21
+ o.bool 'random', '-random', '--random', 'shuffle', '-shuffle', '--shuffle', '-r'
22
+ end
20
23
 
21
- auth_token = VkMusicLoader::Authorizer.new(opts[:app]).perform
22
- VkMusicLoader::SongsDownloader.new(auth_token, opts[:id], opts[:folder]).perform
24
+ if opts[:id] || opts[:query]
25
+ auth_token = VkMusicLoader::Authorizer.new(opts[:app]).perform
26
+ VkMusicLoader::SongsDownloader.new(auth_token, opts).perform
27
+ else
28
+ puts 'No user id or group id or query'
29
+ end
30
+ rescue Slop::Error => e
31
+ puts e.message
32
+ end
@@ -1,3 +1,3 @@
1
1
  module VkMusicLoader
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vk_music_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anatoly Ryabov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-09 00:00:00.000000000 Z
11
+ date: 2016-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: launchy
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: '4.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: '4.4'
41
41
  description: Download your VK playlist in one command
42
42
  email:
43
43
  - a.ryabov1993@gmail.com