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.
- checksums.yaml +4 -4
- data/.env.example +3 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.rubocop.yml +56 -0
- data/Gemfile +38 -10
- data/Gemfile.lock +71 -20
- data/LICENSE.txt +0 -0
- data/README.md +113 -94
- data/Rakefile +15 -22
- data/bin/console +18 -24
- data/lib/vk_music.rb +32 -18
- data/lib/vk_music/audio.rb +111 -187
- data/lib/vk_music/client.rb +181 -647
- data/lib/vk_music/playlist.rb +44 -97
- data/lib/vk_music/request.rb +13 -0
- data/lib/vk_music/request/audios.rb +29 -0
- data/lib/vk_music/request/base.rb +75 -0
- data/lib/vk_music/request/login.rb +35 -0
- data/lib/vk_music/request/my_page.rb +21 -0
- data/lib/vk_music/request/playlist.rb +31 -0
- data/lib/vk_music/request/playlist_section.rb +35 -0
- data/lib/vk_music/request/post.rb +22 -0
- data/lib/vk_music/request/profile.rb +24 -0
- data/lib/vk_music/request/search.rb +34 -0
- data/lib/vk_music/request/wall_section.rb +34 -0
- data/lib/vk_music/utility.rb +8 -78
- data/lib/vk_music/utility/audio_data_parser.rb +37 -0
- data/lib/vk_music/utility/audio_items_parser.rb +18 -0
- data/lib/vk_music/utility/audio_node_parser.rb +59 -0
- data/lib/vk_music/utility/audios_from_ids_loader.rb +21 -0
- data/lib/vk_music/utility/audios_ids_getter.rb +25 -0
- data/lib/vk_music/utility/audios_loader.rb +37 -0
- data/lib/vk_music/utility/data_type_guesser.rb +43 -0
- data/lib/vk_music/utility/duration_parser.rb +17 -0
- data/lib/vk_music/utility/last_profile_post_loader.rb +26 -0
- data/lib/vk_music/utility/link_decoder.rb +107 -0
- data/lib/vk_music/utility/node_text_children_reader.rb +14 -0
- data/lib/vk_music/utility/playlist_loader.rb +30 -0
- data/lib/vk_music/utility/playlist_node_parser.rb +21 -0
- data/lib/vk_music/utility/playlist_section_loader.rb +29 -0
- data/lib/vk_music/utility/playlist_url_parser.rb +32 -0
- data/lib/vk_music/utility/post_loader.rb +23 -0
- data/lib/vk_music/utility/post_url_parser.rb +24 -0
- data/lib/vk_music/utility/profile_id_resolver.rb +58 -0
- data/lib/vk_music/utility/wall_loader.rb +25 -0
- data/lib/vk_music/version.rb +7 -5
- data/lib/vk_music/web_parser.rb +9 -0
- data/lib/vk_music/web_parser/audios.rb +20 -0
- data/lib/vk_music/web_parser/base.rb +27 -0
- data/lib/vk_music/web_parser/login.rb +13 -0
- data/lib/vk_music/web_parser/my_page.rb +19 -0
- data/lib/vk_music/web_parser/playlist.rb +33 -0
- data/lib/vk_music/web_parser/playlist_section.rb +53 -0
- data/lib/vk_music/web_parser/post.rb +15 -0
- data/lib/vk_music/web_parser/profile.rb +33 -0
- data/lib/vk_music/web_parser/search.rb +56 -0
- data/lib/vk_music/web_parser/wall_section.rb +53 -0
- data/vk_music.gemspec +36 -40
- metadata +59 -77
- data/.travis.yml +0 -7
- data/bin/setup +0 -8
- data/lib/vk_music/constants.rb +0 -78
- data/lib/vk_music/exceptions.rb +0 -21
- data/lib/vk_music/link_decoder.rb +0 -102
- data/lib/vk_music/utility/log.rb +0 -51
data/bin/setup
DELETED
data/lib/vk_music/constants.rb
DELETED
@@ -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
|
data/lib/vk_music/exceptions.rb
DELETED
@@ -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
|
data/lib/vk_music/utility/log.rb
DELETED
@@ -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
|