vk_music 3.1.4 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
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 +76 -25
  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 +187 -645
  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 +106 -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