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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e42dd22de66cd8bb8d2d0b70686102d4d50078677736b036b7c383470ff31f2a
4
- data.tar.gz: c6d3eb20221b599d48a1e4464b837ef294d926b4bc9fbeb81b348e9ae5c63f90
3
+ metadata.gz: c25c28560c85999aeffe7b23070762fe875600eb32fde5758c5d02041a9d079b
4
+ data.tar.gz: 64b80f5fe01c1e8bf19ef95c6660ccbb5043b5fb07257c8590bb93f08af2b7e1
5
5
  SHA512:
6
- metadata.gz: 515fbb7b67a8a53b0e2bc8ed0ef8f34a4cdda560ad94a4880ff8e9b36fb7d3c023386b6c2fca3d0df59eb19487d5a708d21684ddb3bf25bcbda4b2141506dd63
7
- data.tar.gz: 40eac37ca4af3db6eb0d88a7e93277f923565c013207706e0d29e7b14a18354628d9bdb79b8eb71de753571a29a4ed93bbeb0e3adad697a4cdc6cfed3c9598a0
6
+ metadata.gz: 4bb0b4d69ad1699d760ab30e3e6149b3440318ab7edf2c42e2e17172d18c564f4922fde227089e2dc828658c34689599f93759fa5ea954af350f35747ba32cd2
7
+ data.tar.gz: 4cb018f20a3cae069616cb1f339703b9f9975f7939a1924225d1840562f30c9f759a21386f00729a499193bd11a3af7339e9b9860ed148cb6f6f3bdae834c0ae
@@ -50,28 +50,42 @@ module VkMusic
50
50
  #@!group Loading audios
51
51
 
52
52
  ##
53
- # Search for audio.
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
- # @note some audios might be removed from search.
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
- # @overload find(query)
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. Possibly empty.
67
- # Possibly contains audios without download URL.
68
- def find(arg)
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 arg
71
- when String
72
- query = arg
73
- when Hash
74
- query = arg[:query].to_s
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
- audios__from_page(uri)
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] ||= Constants::MAXIMUM_PLAYLIST_SIZE
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
- else
354
- raise Exceptions::ParseError, "Unable to convert \"#{str}\" into ID", caller
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
- playlist_size = footer_match ? footer_match[0].to_i : 0
593
+ real_size = footer_match ? footer_match[0].to_i : 0
569
594
  else
570
- playlist_size = 0
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] = playlist_size if (options[:up_to] < 0 || options[:up_to] > playlist_size)
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
- total_count = first_data["totalCount"]
612
- options[:up_to] = total_count if (options[:up_to] < 0 || options[:up_to] > total_count)
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
@@ -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+)(?:(?:(?:&access_hash=)|\/|%2F)([\da-z]+))?/
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.
@@ -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} - " : "") + "#{@title} (#{self.length} аудиозаписей)"
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
@@ -39,8 +39,8 @@ module VkMusic
39
39
  :post
40
40
  when Constants::Regex::VK_URL
41
41
  :audios
42
- else
43
- :find
42
+ else
43
+ :find
44
44
  end
45
45
  end
46
46
 
@@ -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", query: "or not")
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
@@ -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")
@@ -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.0.0"
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.0.0
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-08 00:00:00.000000000 Z
11
+ date: 2019-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mechanize