vk_music 3.1.5 → 4.0.2

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +3 -0
  3. data/.github/workflows/ruby.yml +35 -0
  4. data/.gitignore +6 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +56 -0
  7. data/Gemfile +38 -10
  8. data/Gemfile.lock +71 -20
  9. data/LICENSE.txt +0 -0
  10. data/README.md +113 -94
  11. data/Rakefile +15 -22
  12. data/bin/console +18 -24
  13. data/lib/vk_music.rb +32 -18
  14. data/lib/vk_music/audio.rb +111 -187
  15. data/lib/vk_music/client.rb +181 -647
  16. data/lib/vk_music/playlist.rb +44 -97
  17. data/lib/vk_music/request.rb +13 -0
  18. data/lib/vk_music/request/audios.rb +29 -0
  19. data/lib/vk_music/request/base.rb +75 -0
  20. data/lib/vk_music/request/login.rb +35 -0
  21. data/lib/vk_music/request/my_page.rb +21 -0
  22. data/lib/vk_music/request/playlist.rb +31 -0
  23. data/lib/vk_music/request/playlist_section.rb +35 -0
  24. data/lib/vk_music/request/post.rb +22 -0
  25. data/lib/vk_music/request/profile.rb +24 -0
  26. data/lib/vk_music/request/search.rb +34 -0
  27. data/lib/vk_music/request/wall_section.rb +34 -0
  28. data/lib/vk_music/utility.rb +8 -78
  29. data/lib/vk_music/utility/audio_data_parser.rb +37 -0
  30. data/lib/vk_music/utility/audio_items_parser.rb +18 -0
  31. data/lib/vk_music/utility/audio_node_parser.rb +59 -0
  32. data/lib/vk_music/utility/audios_from_ids_loader.rb +21 -0
  33. data/lib/vk_music/utility/audios_ids_getter.rb +25 -0
  34. data/lib/vk_music/utility/audios_loader.rb +37 -0
  35. data/lib/vk_music/utility/data_type_guesser.rb +43 -0
  36. data/lib/vk_music/utility/duration_parser.rb +17 -0
  37. data/lib/vk_music/utility/last_profile_post_loader.rb +26 -0
  38. data/lib/vk_music/utility/link_decoder.rb +107 -0
  39. data/lib/vk_music/utility/node_text_children_reader.rb +14 -0
  40. data/lib/vk_music/utility/playlist_loader.rb +30 -0
  41. data/lib/vk_music/utility/playlist_node_parser.rb +21 -0
  42. data/lib/vk_music/utility/playlist_section_loader.rb +29 -0
  43. data/lib/vk_music/utility/playlist_url_parser.rb +32 -0
  44. data/lib/vk_music/utility/post_loader.rb +23 -0
  45. data/lib/vk_music/utility/post_url_parser.rb +24 -0
  46. data/lib/vk_music/utility/profile_id_resolver.rb +58 -0
  47. data/lib/vk_music/utility/wall_loader.rb +25 -0
  48. data/lib/vk_music/version.rb +7 -5
  49. data/lib/vk_music/web_parser.rb +9 -0
  50. data/lib/vk_music/web_parser/audios.rb +20 -0
  51. data/lib/vk_music/web_parser/base.rb +27 -0
  52. data/lib/vk_music/web_parser/login.rb +13 -0
  53. data/lib/vk_music/web_parser/my_page.rb +19 -0
  54. data/lib/vk_music/web_parser/playlist.rb +33 -0
  55. data/lib/vk_music/web_parser/playlist_section.rb +53 -0
  56. data/lib/vk_music/web_parser/post.rb +15 -0
  57. data/lib/vk_music/web_parser/profile.rb +33 -0
  58. data/lib/vk_music/web_parser/search.rb +56 -0
  59. data/lib/vk_music/web_parser/wall_section.rb +53 -0
  60. data/vk_music.gemspec +36 -40
  61. metadata +59 -77
  62. data/.travis.yml +0 -7
  63. data/bin/setup +0 -8
  64. data/lib/vk_music/constants.rb +0 -78
  65. data/lib/vk_music/exceptions.rb +0 -21
  66. data/lib/vk_music/link_decoder.rb +0 -102
  67. data/lib/vk_music/utility/log.rb +0 -51
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,78 +0,0 @@
1
- module VkMusic
2
- ##
3
- # Constants.
4
- module Constants
5
- ##
6
- # Default web user agent.
7
- DEFAULT_USER_AGENT = "" # Using empty user agent confuses VK and it returnes MP3
8
-
9
- ##
10
- # Different URLs
11
- module URL
12
- ##
13
- # Hash with URLs to VK pages which are used by library.
14
- VK = {
15
- scheme: "https",
16
- host: "m.vk.com",
17
- home: "https://m.vk.com",
18
- profile: "https://m.vk.com/id0",
19
- feed: "https://m.vk.com/feed",
20
- audios: "https://m.vk.com/audio",
21
- login: "https://m.vk.com/login",
22
- login_action: "https://login.vk.com",
23
- wall: "https://m.vk.com/wall",
24
- audio_unavailable: "https://m.vk.com/mp3/audio_api_unavailable.mp3",
25
- profile_audios: "https://m.vk.com/audios"
26
- }
27
- end
28
-
29
- ##
30
- # Regular expressions
31
- module Regex
32
- ##
33
- # VK user or group ID.
34
- VK_ID_STR = /^-?\d+$/
35
- ##
36
- # VK user or group ID.
37
- VK_ID = /-?\d+/
38
- ##
39
- # VK prefixed user or group ID.
40
- VK_PREFIXED_ID_STR = /^(?:id|club|group|public|event)(\d+)$/
41
- ##
42
- # VK custom ID regular expression.
43
- VK_CUSTOM_ID = /^\w+$/
44
- ##
45
- # VK URL regular expression.
46
- VK_URL = /(?:https?:\/\/)?(?:m\.|www\.)?vk\.com\/([\w\-]+)/
47
- ##
48
- # +href+ attribute with VK ID regular expression.
49
- VK_HREF_ID_CONTAINING = /(?:audios|photo|write|owner_id=|friends\?id=)(-?\d+)/
50
- ##
51
- # VK audios page regular expression.
52
- VK_AUDIOS_URL_POSTFIX = /^audios(-?\d+)$/
53
- ##
54
- # Playlist URL regular expression.
55
- VK_PLAYLIST_URL_POSTFIX = /.*(?:audio_playlist|album\/|playlist\/)(-?\d+)_(\d+)(?:(?:(?:.*(?=&access_hash=)&access_hash=)|\/|%2F|_)([\da-z]+))?/
56
- ##
57
- # Post URL regular expression #1.
58
- VK_POST_URL_POSTFIX = /.*post(-?\d+)_(\d+)/
59
- ##
60
- # Post URL regular expression #2.
61
- VK_WALL_URL_POSTFIX = /.*wall(-?\d+)_(\d+)/
62
- ##
63
- # Audios block ID
64
- VK_BLOCK_URL = /(?:section=recoms_block&type=|act=block&block=)([a-zA-Z\d]+)/
65
- end
66
-
67
- ##
68
- # Names used in VK login form.
69
- VK_LOGIN_FORM_NAMES = {
70
- username: "email",
71
- password: "pass"
72
- }
73
-
74
- ##
75
- # Maximum amount of audios in VK playlist.
76
- MAXIMUM_PLAYLIST_SIZE = 10000
77
- end
78
- end
@@ -1,21 +0,0 @@
1
- module VkMusic
2
- ##
3
- # Exceptions.
4
- module Exceptions
5
- ##
6
- # General class for all the errors.
7
- class VkMusicError < RuntimeError; end
8
- ##
9
- # Failed to login.
10
- class LoginError < VkMusicError; end
11
- ##
12
- # Failed to get request. _Only_ thrown when Mechanize failed to load page
13
- class RequestError < VkMusicError; end
14
- ##
15
- # Parse error. Request is OK, but something went wrong while parsing reply.
16
- # It might be missing playlist/post as well.
17
- class ParseError < VkMusicError; end
18
- end
19
-
20
- include Exceptions
21
- end
@@ -1,102 +0,0 @@
1
- module VkMusic
2
- ##
3
- # Module containing link decoding utilities.
4
- module LinkDecoder
5
- ##
6
- # JS code which creates function to unmask audio URL.
7
- js_code = <<~HEREDOC
8
- function vk_unmask_link(link, vk_id) {
9
-
10
- // Utility functions to unmask
11
-
12
- var audioUnmaskSource = function (encrypted) {
13
- if (encrypted.indexOf('audio_api_unavailable') != -1) {
14
- var parts = encrypted.split('?extra=')[1].split('#');
15
-
16
- var handled_anchor = '' === parts[1] ? '' : handler(parts[1]);
17
-
18
- var handled_part = handler(parts[0]);
19
-
20
- if (typeof handled_anchor != 'string' || !handled_part) {
21
- // if (typeof handled_anchor != 'string') console.warn('Handled_anchor type: ' + typeof handled_anchor);
22
- // if (!handled_part) console.warn('Handled_part: ' + handled_part);
23
- return encrypted;
24
- }
25
-
26
- handled_anchor = handled_anchor ? handled_anchor.split(String.fromCharCode(9)) : [];
27
-
28
- for (var func_key, splited_anchor, l = handled_anchor.length; l--;) {
29
- splited_anchor = handled_anchor[l].split(String.fromCharCode(11));
30
- func_key = splited_anchor.splice(0, 1, handled_part)[0];
31
- if (!utility_object[func_key]) {
32
- // console.warn('Was unable to find key: ' + func_key);
33
- return encrypted;
34
- }
35
- handled_part = utility_object[func_key].apply(null, splited_anchor)
36
- }
37
-
38
- if (handled_part && 'http' === handled_part.substr(0, 4)) return handled_part;
39
- // else console.warn('Failed unmasking: ' + handled_part);
40
- } else {
41
- // console.warn('Bad link: ' + encrypted);
42
- }
43
- return encrypted;
44
- }
45
-
46
- var handler = function (part) {
47
- if (!part || part.length % 4 == 1) return !1;
48
- for (var t, i, o = 0, s = 0, a = ''; i = part.charAt(s++);) {
49
- i = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0PQRSTUVWXYZO123456789+/='.indexOf(i)
50
- ~i && (t = o % 4 ? 64 * t + i : i, o++ % 4) && (a += String.fromCharCode(255 & t >> (-2 * o & 6)));
51
- }
52
- return a;
53
- }
54
-
55
- var utility_object = {
56
- i: function(e, t) {
57
- return utility_object.s(e, t ^ vk_id);
58
- },
59
- s: function(e, t) {
60
- var n = e.length;
61
- if (n) {
62
- var i = r_func(e, t),
63
- o = 0;
64
- for (e = e.split(''); ++o < n;)
65
- e[o] = e.splice(i[n - 1 - o], 1, e[o])[0];
66
- e = e.join('')
67
- }
68
- return e;
69
- }
70
- };
71
-
72
- var r_func = function (e, t) {
73
- var n = e.length,
74
- i = [];
75
- if (n) {
76
- var o = n;
77
- for (t = Math.abs(t); o--;)
78
- t = (n * (o + 1) ^ t + o) % n,
79
- i[o] = t;
80
- }
81
- return i;
82
- }
83
-
84
- return audioUnmaskSource(link);
85
- }
86
- HEREDOC
87
-
88
- ##
89
- # JS context with unmasking link.
90
- @@js_context = ExecJS.compile(js_code)
91
-
92
- ##
93
- # Unmask audio download URL.
94
- # @param link [String] encoded link to audio. Usually looks like "https://m.vk.​com/mp3/audio_api_unavailable.mp3?extra=...".
95
- # @param client_id [Integer] ID of user which got this link. ID is required for decoding.
96
- # @return [String] audio download URL, which can be used only from current IP.
97
- def self.unmask_link(link, client_id)
98
- VkMusic.debug("Unmasking link.")
99
- @@js_context.call("vk_unmask_link", link.to_s, client_id.to_i)
100
- end
101
- end
102
- end
@@ -1,51 +0,0 @@
1
- module VkMusic
2
- ##
3
- # @!group Logger
4
-
5
- ##
6
- # Default logger
7
- @@logger = Logger.new(defined?($LOG_FILE) ? $LOGFILE : STDOUT,
8
- formatter: Proc.new do |severity, datetime, progname, msg|
9
- "[#{datetime}] #{severity}#{progname ? " - #{progname}" : ""}:\t #{msg}\n"
10
- end
11
- )
12
- @@logger.level = $DEBUG ? Logger::DEBUG : Logger::INFO
13
-
14
- ##
15
- # Setup new logger.
16
- # @param new_logger [Logger, nil]
17
- def self.logger=(new_logger)
18
- @@logger = new_logger
19
- end
20
- ##
21
- # Access current logger.
22
- # @return [Logger, nil]
23
- def self.logger
24
- @@logger
25
- end
26
-
27
- ##
28
- # Log message.
29
- def self.log(severity, message = nil, progname = nil)
30
- @@logger.log(severity, message, progname) if @@logger
31
- end
32
-
33
- ##
34
- # Log warn message.
35
- def self.warn(message = nil, progname = nil)
36
- @@logger.log(Logger::WARN, message, progname)
37
- end
38
- ##
39
- # Log info message.
40
- def self.info(message = nil, progname = nil)
41
- @@logger.log(Logger::INFO, message, progname)
42
- end
43
- ##
44
- # Log debug message.
45
- def self.debug(message = nil, progname = nil)
46
- @@logger.log(Logger::DEBUG, message, progname)
47
- end
48
-
49
- ##
50
- # @!endgroup
51
- end