vk_music 2.0.0 → 2.1.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 +4 -4
- data/lib/vk_music/client.rb +58 -21
- data/lib/vk_music/constants.rb +3 -2
- data/lib/vk_music/playlist.rb +13 -5
- data/lib/vk_music/utility.rb +2 -2
- data/test/test_find.rb +13 -1
- data/test/test_playlist.rb +6 -0
- data/vk_music.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c25c28560c85999aeffe7b23070762fe875600eb32fde5758c5d02041a9d079b
|
4
|
+
data.tar.gz: 64b80f5fe01c1e8bf19ef95c6660ccbb5043b5fb07257c8590bb93f08af2b7e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bb0b4d69ad1699d760ab30e3e6149b3440318ab7edf2c42e2e17172d18c564f4922fde227089e2dc828658c34689599f93759fa5ea954af350f35747ba32cd2
|
7
|
+
data.tar.gz: 4cb018f20a3cae069616cb1f339703b9f9975f7939a1924225d1840562f30c9f759a21386f00729a499193bd11a3af7339e9b9860ed148cb6f6f3bdae834c0ae
|
data/lib/vk_music/client.rb
CHANGED
@@ -50,28 +50,42 @@ module VkMusic
|
|
50
50
|
#@!group Loading audios
|
51
51
|
|
52
52
|
##
|
53
|
-
#
|
53
|
+
# @!macro [new] find__options
|
54
|
+
# @option options [Symbol] :type (:audio) what to search for (you can find available values for this option above).
|
54
55
|
#
|
55
|
-
#
|
56
|
+
# Search for audio or playlist.
|
57
|
+
#
|
58
|
+
# @note some audios and playlists might be removed from search.
|
56
59
|
#
|
57
60
|
# @todo search in group audios.
|
58
61
|
#
|
59
|
-
#
|
62
|
+
# Possible values of +type+ option:
|
63
|
+
# * +:audio+ - search for audios. Returns up to 50 audios.
|
64
|
+
# * +:playlist+ - search for playlists. Returns up to 6 playlists *without* audios (Loaded with +up_to: 0+ option).
|
65
|
+
# You can get all the audios of selected playlist calling {Client#playlist} method with gained info.
|
66
|
+
#
|
67
|
+
# @overload find(query, options)
|
60
68
|
# @param query [String] string to search for.
|
69
|
+
# @macro options_hash_param
|
70
|
+
# @macro find__options
|
61
71
|
#
|
62
72
|
# @overload find(options)
|
63
73
|
# @macro options_hash_param
|
64
74
|
# @option options [String] :query string to search for.
|
75
|
+
# @macro find__options
|
65
76
|
#
|
66
|
-
# @return [Array<Audio>] array with audios matching given string.
|
67
|
-
# Possibly contains audios without download URL.
|
68
|
-
def find(
|
77
|
+
# @return [Array<Audio>, Array<Playlist>] array with audios or playlists matching given string.
|
78
|
+
# Possibly empty. Possibly contains audios or playlists without download URL.
|
79
|
+
def find(*args)
|
69
80
|
begin
|
70
|
-
case
|
71
|
-
when String
|
72
|
-
|
73
|
-
|
74
|
-
query =
|
81
|
+
case
|
82
|
+
when (args.size == 1 && String === args[0]) ||
|
83
|
+
(args.size == 2 && String === args[0] && Hash === args[1])
|
84
|
+
options = args[1] || {}
|
85
|
+
query = args[0]
|
86
|
+
when args.size == 1 && Hash === args[0]
|
87
|
+
options = args[0]
|
88
|
+
query = options[:query].to_s
|
75
89
|
else
|
76
90
|
raise
|
77
91
|
end
|
@@ -79,10 +93,21 @@ module VkMusic
|
|
79
93
|
raise ArgumentError, "Bad arguments", caller
|
80
94
|
end
|
81
95
|
|
96
|
+
options[:type] ||= :audio
|
97
|
+
|
82
98
|
uri = URI(Constants::URL::VK[:audios])
|
83
|
-
uri.query = Utility.hash_to_params({ "act" => "search", "q" => query.to_s })
|
84
99
|
|
85
|
-
|
100
|
+
case options[:type]
|
101
|
+
when :audio
|
102
|
+
uri.query = Utility.hash_to_params({ "act" => "search", "q" => query })
|
103
|
+
audios__from_page(uri)
|
104
|
+
when :playlist
|
105
|
+
uri.query = Utility.hash_to_params({ "q" => query, "tab" => "global" })
|
106
|
+
urls = playlist_urls__from_page(uri)
|
107
|
+
urls.map { |url| playlist(url, up_to: 0, with_url: false) }
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Bad :type option", caller
|
110
|
+
end
|
86
111
|
end
|
87
112
|
alias search find
|
88
113
|
|
@@ -130,7 +155,7 @@ module VkMusic
|
|
130
155
|
raise ArgumentError, "Bad arguments", caller
|
131
156
|
end
|
132
157
|
|
133
|
-
options[:up_to]
|
158
|
+
options[:up_to] ||= Constants::MAXIMUM_PLAYLIST_SIZE
|
134
159
|
options[:with_url] = true if options[:with_url].nil?
|
135
160
|
|
136
161
|
if options[:with_url]
|
@@ -350,8 +375,8 @@ module VkMusic
|
|
350
375
|
rescue Exception => error
|
351
376
|
raise Exceptions::ParseError, "Unable to get user or group ID. Custom ID: #{str}. Error: #{error.message}", caller
|
352
377
|
end
|
353
|
-
|
354
|
-
|
378
|
+
else
|
379
|
+
raise Exceptions::ParseError, "Unable to convert \"#{str}\" into ID", caller
|
355
380
|
end
|
356
381
|
id
|
357
382
|
end
|
@@ -565,9 +590,9 @@ module VkMusic
|
|
565
590
|
footer_node = first_page.at_css(".audioPlaylist__footer")
|
566
591
|
if footer_node
|
567
592
|
footer_match = footer_node.text.strip.match(/^\d+/)
|
568
|
-
|
593
|
+
real_size = footer_match ? footer_match[0].to_i : 0
|
569
594
|
else
|
570
|
-
|
595
|
+
real_size = 0
|
571
596
|
end
|
572
597
|
rescue Exception => error
|
573
598
|
raise Exceptions::ParseError, error.message, caller
|
@@ -577,7 +602,7 @@ module VkMusic
|
|
577
602
|
first_page_audios = audios__from_page(first_page)
|
578
603
|
|
579
604
|
# Check whether need to make additional requests
|
580
|
-
options[:up_to] =
|
605
|
+
options[:up_to] = real_size if (options[:up_to] < 0 || options[:up_to] > real_size)
|
581
606
|
list = first_page_audios[0, options[:up_to]]
|
582
607
|
while list.length < options[:up_to] do
|
583
608
|
playlist_page = load__page__playlist(owner_id, playlist_id, access_hash, offset: list.length)
|
@@ -590,6 +615,7 @@ module VkMusic
|
|
590
615
|
:access_hash => access_hash,
|
591
616
|
:title => title,
|
592
617
|
:subtitle => subtitle,
|
618
|
+
:real_size => real_size
|
593
619
|
})
|
594
620
|
end
|
595
621
|
|
@@ -608,8 +634,8 @@ module VkMusic
|
|
608
634
|
raise Exceptions::ParseError, error.message, caller
|
609
635
|
end
|
610
636
|
|
611
|
-
|
612
|
-
options[:up_to] =
|
637
|
+
real_size = first_data["totalCount"]
|
638
|
+
options[:up_to] = real_size if (options[:up_to] < 0 || options[:up_to] > real_size)
|
613
639
|
list = first_data_audios[0, options[:up_to]]
|
614
640
|
while list.length < options[:up_to] do
|
615
641
|
json = load__json__playlist_section(owner_id, playlist_id, access_hash,
|
@@ -625,9 +651,20 @@ module VkMusic
|
|
625
651
|
:access_hash => first_data["access_hash"],
|
626
652
|
:title => CGI.unescapeHTML(first_data["title"].to_s),
|
627
653
|
:subtitle => CGI.unescapeHTML(first_data["subtitle"].to_s),
|
654
|
+
:real_size => real_size
|
628
655
|
})
|
629
656
|
end
|
630
657
|
|
658
|
+
# Found playlist on *global* search page
|
659
|
+
def playlist_urls__from_page(obj)
|
660
|
+
page = obj.class == Mechanize::Page ? obj : load__page(obj)
|
661
|
+
begin
|
662
|
+
page.css(".AudioSerp__foundGlobal .AudioPlaylistSlider .al_playlist").map { |elem| elem.attribute("href").to_s }
|
663
|
+
rescue Exception => error
|
664
|
+
raise Exceptions::ParseError, error.message, caller
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
631
668
|
# Load audios from wall using JSON request.
|
632
669
|
def wall__json(owner_id, post_id, options)
|
633
670
|
if options[:up_to] < 0 || options[:up_to] > 91
|
data/lib/vk_music/constants.rb
CHANGED
@@ -24,7 +24,8 @@ module VkMusic
|
|
24
24
|
login: "https://m.vk.com/login",
|
25
25
|
login_action: "https://login.vk.com",
|
26
26
|
wall: "https://m.vk.com/wall",
|
27
|
-
audio_unavailable: "https://m.vk.com/mp3/audio_api_unavailable.mp3"
|
27
|
+
audio_unavailable: "https://m.vk.com/mp3/audio_api_unavailable.mp3",
|
28
|
+
profile_audios: "https://m.vk.com/audios",
|
28
29
|
}
|
29
30
|
|
30
31
|
end
|
@@ -63,7 +64,7 @@ module VkMusic
|
|
63
64
|
|
64
65
|
##
|
65
66
|
# Playlist URL regular expression.
|
66
|
-
VK_PLAYLIST_URL_POSTFIX = /.*audio_playlist(-?\d+)_(\d+)(?:(?:(
|
67
|
+
VK_PLAYLIST_URL_POSTFIX = /.*audio_playlist(-?\d+)_(\d+)(?:(?:(?:.*(?=&access_hash=)&access_hash=)|\/|%2F)([\da-z]+))?/
|
67
68
|
|
68
69
|
##
|
69
70
|
# Post URL regular expression #1.
|
data/lib/vk_music/playlist.rb
CHANGED
@@ -24,11 +24,17 @@ module VkMusic
|
|
24
24
|
##
|
25
25
|
# @return [String, nil] playlist subtitle. May be empty.
|
26
26
|
attr_reader :subtitle
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [Integer, nil] real size of playlist or +nil+ if unknown.
|
30
|
+
attr_reader :real_size
|
27
31
|
|
28
32
|
##
|
29
33
|
# @return [String] playlist description in Russian.
|
30
34
|
def to_s
|
31
|
-
(@subtitle ? "#{@subtitle} - " : "") +
|
35
|
+
(@subtitle && !@subtitle.empty? ? "#{@subtitle} - " : "") +
|
36
|
+
@title +
|
37
|
+
(@real_size ? "(#{self.length} из #{@real_size} аудиозаписей загружено)" : " (#{self.length} аудиозаписей)")
|
32
38
|
end
|
33
39
|
|
34
40
|
##
|
@@ -77,11 +83,12 @@ module VkMusic
|
|
77
83
|
#
|
78
84
|
# @param list [Array] list of audios in playlist.
|
79
85
|
#
|
80
|
-
# @option options [Integer] :id
|
81
|
-
# @option options [Integer] :owner_id
|
82
|
-
# @option options [String] :access_hash
|
86
|
+
# @option options [Integer, nil] :id
|
87
|
+
# @option options [Integer, nil] :owner_id
|
88
|
+
# @option options [String, nil] :access_hash
|
83
89
|
# @option options [String] :title
|
84
|
-
# @option options [String] :subtitle
|
90
|
+
# @option options [String, nil] :subtitle
|
91
|
+
# @option options [Integer, nil] :real_size
|
85
92
|
def initialize(list, options = {})
|
86
93
|
raise ArgumentError, "Bad arguments", caller unless list.class == Array
|
87
94
|
# Saving list
|
@@ -93,6 +100,7 @@ module VkMusic
|
|
93
100
|
@access_hash = Utility.unless_nil_to String, options[:access_hash]
|
94
101
|
@title = options[:title].to_s
|
95
102
|
@subtitle = Utility.unless_nil_to String, options[:subtitle]
|
103
|
+
@real_size = Utility.unless_nil_to Integer, options[:real_size]
|
96
104
|
end
|
97
105
|
|
98
106
|
end
|
data/lib/vk_music/utility.rb
CHANGED
data/test/test_find.rb
CHANGED
@@ -36,8 +36,20 @@ class TestVkMusic < MiniTest::Test
|
|
36
36
|
|
37
37
|
def test_find_bad_arg
|
38
38
|
assert_raises(ArgumentError) do
|
39
|
-
CLIENT.search("Good music",
|
39
|
+
CLIENT.search("Good music", "or not")
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
def test_find_playlist
|
44
|
+
results = CLIENT.find("OST", type: :playlist)
|
45
|
+
refute_empty(results, "There must be lot of playlists")
|
46
|
+
assert_empty(results[0], "Album must be empty")
|
47
|
+
refute_equal(0, results[0].real_size, "Album must actually have some audios")
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_find_unexisting_playlist
|
51
|
+
results = CLIENT.find("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", type: :playlist)
|
52
|
+
assert_empty(results, "There must be no results for such query")
|
53
|
+
end
|
42
54
|
|
43
55
|
end
|
data/test/test_playlist.rb
CHANGED
@@ -18,6 +18,12 @@ class TestVkMusic < MiniTest::Test
|
|
18
18
|
refute_empty(pl[-1].url, "Audio must have download url")
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_big_url
|
22
|
+
pl = CLIENT.playlist("https://m.vk.com/audio?act=audio_playlist256492540_83617715&from=search_owned_playlist&access_hash=b8d408241bcfb60583&back_url=%2Faudios-39786657%3Fq%3Dmashup%26tab%3Downed&back_hash=76ef9186ac6f248a27")
|
23
|
+
refute_empty(pl, "This playlist must not be empty")
|
24
|
+
assert_instance_of(VkMusic::Audio, pl[0], "Playlist members must be of class Audio")
|
25
|
+
end
|
26
|
+
|
21
27
|
def test_playlist_small_with_options
|
22
28
|
pl = CLIENT.playlist(owner_id: -37661843, playlist_id: 1, access_hash: "0e420c32c8b69e6637", with_url: false)
|
23
29
|
refute_empty(pl, "This playlist must not be empty")
|
data/vk_music.gemspec
CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.name = "vk_music"
|
3
3
|
s.summary = "Provides interface to work with VK music via HTTP requests"
|
4
4
|
s.description = "Library to work with audios on popular Russian social network vk.com. VK disabled their public API for audios, so it is now necessary to use parsers instead."
|
5
|
-
s.version = "2.
|
5
|
+
s.version = "2.1.0"
|
6
6
|
s.author = "Kuznetsov Vladislav"
|
7
7
|
s.email = "fizvlad@mail.ru"
|
8
8
|
s.homepage = "https://github.com/fizvlad/vk-music-rb"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vk_music
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kuznetsov Vladislav
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|