bilibili_console 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,28 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021 leejoker
4
- #
5
- # This software is released under the MIT License.
6
- # https://opensource.org/licenses/MIT
7
-
8
- require_relative 'http'
9
-
10
- # response body
11
- module BiliHttp
12
- # response body
13
- class ResponseBody
14
- attr_accessor :code, :message, :ts, :data, :status
15
-
16
- def initialize(json)
17
- @code = json[:code]
18
- @message = json[:message]
19
- @ts = json[:ts]
20
- @status = json[:status]
21
- @data = json[:data]
22
- end
23
-
24
- def to_s
25
- "code: #{@code}, message: #{@message}, ts: #{@ts}, data: #{@data}, status: #{@status}"
26
- end
27
- end
28
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 leejoker
4
+ #
5
+ # This software is released under the MIT License.
6
+ # https://opensource.org/licenses/MIT
7
+
8
+ require_relative 'http'
9
+
10
+ # response body
11
+ module BiliHttp
12
+ # response body
13
+ class ResponseBody
14
+ attr_accessor :code, :message, :ts, :data, :status
15
+
16
+ def initialize(json)
17
+ @code = json[:code]
18
+ @message = json[:message]
19
+ @ts = json[:ts]
20
+ @status = json[:status]
21
+ @data = json[:data]
22
+ end
23
+
24
+ def to_s
25
+ "code: #{@code}, message: #{@message}, ts: #{@ts}, data: #{@data}, status: #{@status}"
26
+ end
27
+ end
28
+ end
@@ -1,102 +1,103 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021 leejoker
4
- #
5
- # This software is released under the MIT License.
6
- # https://opensource.org/licenses/MIT
7
-
8
- require_relative 'http/http'
9
- require_relative 'base'
10
- require 'rqrcode'
11
- require 'json'
12
-
13
- # login module
14
- module Bilibili
15
- include BiliHttp
16
- # bilibili user info
17
- class UserInfo
18
- attr_accessor :face, :level_info, :uid, :money, :moral, :uname, :vip_type
19
-
20
- def initialize(json)
21
- return if json.nil?
22
-
23
- @face = json[:face]
24
- @level_info = json[:level_info]
25
- @uid = json[:mid]
26
- @money = json[:money]
27
- @moral = json[:moral]
28
- @uname = json[:moral]
29
- @vip_type = json[:vipType]
30
- end
31
-
32
- def to_json(*opt)
33
- {
34
- face: @face,
35
- level_info: @level_info,
36
- uid: @uid,
37
- money: @money,
38
- moral: @moral,
39
- uname: @uname,
40
- vip_type: @vip_type
41
- }.to_json(*opt)
42
- end
43
- end
44
-
45
- # login class
46
- class Login < BilibiliBase
47
- attr_accessor :url, :oauth_key
48
-
49
- def login_url
50
- data = get_jsonl('https://passport.bilibili.com/qrcode/getLoginUrl')
51
- @url = data[:url]
52
- @oauth_key = data[:oauthKey]
53
- end
54
-
55
- def show_qrcode
56
- qr = RQRCode::QRCode.new(@url)
57
- pic = qr.as_ansi(
58
- light: "\033[47m", dark: "\033[40m",
59
- fill_character: ' ',
60
- quiet_zone_size: 1
61
- )
62
- puts pic
63
- end
64
-
65
- def login_user_info
66
- set_http_cookie
67
- data = get_jsona('https://api.bilibili.com/nav')
68
- if data.code != '-101'
69
- Bilibili::UserInfo.new(data)
70
- else
71
- puts 'Cookie已失效'
72
- clean_cookie
73
- login_user_info
74
- end
75
- end
76
-
77
- def login
78
- login_url
79
- show_qrcode
80
- print '已完成扫码?[y/n]'
81
- over = $stdin.gets.chomp
82
- return nil unless over == 'y'
83
-
84
- post_form_jsonl('https://passport.bilibili.com/qrcode/getLoginInfo', { oauthKey: @oauth_key })
85
- puts 'Login Success !!!'
86
- save_cookie
87
- 'success'
88
- end
89
-
90
- private
91
-
92
- def set_http_cookie
93
- cookies = @http_client.login_http.cookies
94
- if cookies.nil? || cookies.empty?
95
- login
96
- @http_client.api_http.cookies = @http_client.login_http.cookies
97
- else
98
- @http_client.api_http.cookies = cookies
99
- end
100
- end
101
- end
102
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 leejoker
4
+ #
5
+ # This software is released under the MIT License.
6
+ # https://opensource.org/licenses/MIT
7
+
8
+ require_relative 'http/http'
9
+ require_relative 'base'
10
+ require_relative 'api'
11
+ require 'rqrcode'
12
+ require 'json'
13
+
14
+ # login module
15
+ module Bilibili
16
+ include BiliHttp
17
+ # bilibili user info
18
+ class UserInfo
19
+ attr_accessor :face, :level_info, :uid, :money, :moral, :uname, :vip_type
20
+
21
+ def initialize(json)
22
+ return if json.nil?
23
+
24
+ @face = json[:face]
25
+ @level_info = json[:level_info]
26
+ @uid = json[:mid]
27
+ @money = json[:money]
28
+ @moral = json[:moral]
29
+ @uname = json[:moral]
30
+ @vip_type = json[:vipType]
31
+ end
32
+
33
+ def to_json(*opt)
34
+ {
35
+ face: @face,
36
+ level_info: @level_info,
37
+ uid: @uid,
38
+ money: @money,
39
+ moral: @moral,
40
+ uname: @uname,
41
+ vip_type: @vip_type
42
+ }.to_json(*opt)
43
+ end
44
+ end
45
+
46
+ # login class
47
+ class Login < BilibiliBase
48
+ attr_accessor :url, :oauth_key
49
+
50
+ def login_url
51
+ data = get_jsonl(Api::Login::QRCODE)
52
+ @url = data[:url]
53
+ @oauth_key = data[:oauthKey]
54
+ end
55
+
56
+ def show_qrcode
57
+ qr = RQRCode::QRCode.new(@url)
58
+ pic = qr.as_ansi(
59
+ light: "\033[47m", dark: "\033[40m",
60
+ fill_character: ' ',
61
+ quiet_zone_size: 1
62
+ )
63
+ puts pic
64
+ end
65
+
66
+ def login_user_info
67
+ set_http_cookie
68
+ data = get_jsona(Api::Login::USERINFO)
69
+ if data.code != '-101'
70
+ Bilibili::UserInfo.new(data)
71
+ else
72
+ puts 'Cookie已失效'
73
+ clean_cookie
74
+ login_user_info
75
+ end
76
+ end
77
+
78
+ def login
79
+ login_url
80
+ show_qrcode
81
+ print '已完成扫码?[y/n]'
82
+ over = $stdin.gets.chomp
83
+ return nil unless over == 'y'
84
+
85
+ post_form_jsonl(Api::Login::INFO, { oauthKey: @oauth_key })
86
+ puts 'Login Success !!!'
87
+ save_cookie
88
+ 'success'
89
+ end
90
+
91
+ private
92
+
93
+ def set_http_cookie
94
+ cookies = @http_client.login_http.cookies
95
+ if cookies.nil? || cookies.empty?
96
+ login
97
+ @http_client.api_http.cookies = @http_client.login_http.cookies
98
+ else
99
+ @http_client.api_http.cookies = cookies
100
+ end
101
+ end
102
+ end
103
+ end
@@ -1,24 +1,24 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021 leejoker
4
- #
5
- # This software is released under the MIT License.
6
- # https://opensource.org/licenses/MIT
7
-
8
- require_relative 'http/http'
9
-
10
- # video module
11
- module Bilibili
12
- include BiliHttp
13
-
14
- # bilibili video interfaces
15
- class Manga < BilibiliBase
16
- def check_in
17
- cur_header = {
18
- 'User-Agent': 'Mozilla/5.0 BiliDroid/6.4.0 (bbcallen@gmail.com) os/android model/M1903F11I mobi_app/android build/6040500 channel/bili innerVer/6040500 osVer/9.0.0 network/2'
19
- }
20
- post_jsonm('https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn?platform=android',
21
- cur_header, { 'platform' => 'android' })
22
- end
23
- end
24
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 leejoker
4
+ #
5
+ # This software is released under the MIT License.
6
+ # https://opensource.org/licenses/MIT
7
+
8
+ require_relative 'http/http'
9
+ require_relative 'api'
10
+
11
+ # video module
12
+ module Bilibili
13
+ include BiliHttp
14
+
15
+ # bilibili video interfaces
16
+ class Manga < BilibiliBase
17
+ def check_in
18
+ cur_header = {
19
+ 'User-Agent': 'Mozilla/5.0 BiliDroid/6.4.0 (bbcallen@gmail.com) os/android model/M1903F11I mobi_app/android build/6040500 channel/bili innerVer/6040500 osVer/9.0.0 network/2'
20
+ }
21
+ post_jsonm(Api::Manga::CHECK_IN, cur_header, { 'platform' => 'android' })
22
+ end
23
+ end
24
+ end
@@ -1,10 +1,10 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021 10344742
4
- #
5
- # This software is released under the MIT License.
6
- # https://opensource.org/licenses/MIT
7
-
8
- module Bilibili
9
- VERSION = '0.0.1'
10
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 10344742
4
+ #
5
+ # This software is released under the MIT License.
6
+ # https://opensource.org/licenses/MIT
7
+
8
+ module Bilibili
9
+ VERSION = '0.0.3'
10
+ end
@@ -1,123 +1,193 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021 leejoker
4
- #
5
- # This software is released under the MIT License.
6
- # https://opensource.org/licenses/MIT
7
-
8
- require_relative 'http/http'
9
- require 'down'
10
- require 'fileutils'
11
- require 'ruby-progressbar'
12
-
13
- # video module
14
- module Bilibili
15
- include BiliHttp
16
- # video page list
17
- class PageInfo
18
- attr_accessor :cid, :page, :from, :part, :duration, :vid, :weblink
19
-
20
- def initialize(json)
21
- return if json.nil?
22
-
23
- @cid = json[:cid]
24
- @page = json[:page]
25
- @from = json[:from]
26
- @part = json[:part]
27
- @duration = json[:duration]
28
- @vid = json[:vid]
29
- @weblink = json[:weblink]
30
- end
31
-
32
- def to_json(*opt)
33
- {
34
- cid: @cid,
35
- page: @page,
36
- from: @from,
37
- part: @part,
38
- duration: @duration,
39
- vid: @vid,
40
- weblink: @weblink
41
- }.to_json(*opt)
42
- end
43
- end
44
-
45
- # bilibili video interfaces
46
- class Video < BilibiliBase
47
- def video_page_list(bv_id)
48
- return nil if bv_id.nil?
49
-
50
- url = "https://api.bilibili.com/x/player/pagelist?bvid=#{bv_id}"
51
- datas = get_jsona(url)
52
- return nil if datas.nil?
53
-
54
- datas.map do |d|
55
- Bilibili::PageInfo.new(d)
56
- end
57
- end
58
-
59
- def get_video_url(bv_id, cid, video_qn = '720')
60
- qn = BilibiliBase.video_qn[video_qn]
61
- url = "https://api.bilibili.com/x/player/playurl?bvid=#{bv_id}&cid=#{cid}&qn=#{qn}&fnval=0&fnver=0&fourk=1"
62
- data = get_jsona(url)
63
- data[:durl]
64
- end
65
-
66
- def video_url_list(bv_id, video_qn = '720')
67
- result = []
68
- page_list = video_page_list(bv_id)
69
- return nil if page_list.nil?
70
-
71
- page_list.each do |page|
72
- get_video_url(bv_id, page.cid, video_qn).each do |durl|
73
- order = durl[:order] < 10 ? "0#{durl[:order]}" : durl[:order]
74
- result << { 'name': "#{page.part}_#{order}.flv", 'url': durl[:url].to_s }
75
- end
76
- end
77
- result
78
- end
79
-
80
- def download_video_by_bv(bv_id, video_qn = '720')
81
- urls = video_url_list(bv_id, video_qn)
82
- return nil if urls.empty?
83
-
84
- download_path = "#{File.expand_path(@options['download_path'].to_s, __dir__)}/#{bv_id}/"
85
- urls.each do |durl|
86
- download_file(durl[:url], download_path, durl[:name])
87
- end
88
- end
89
-
90
- private
91
-
92
- def download_file(url, dir, filename)
93
- progressbar = ProgressBar.create
94
- total_size = 0
95
- headers = generate_headers
96
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
97
- puts "开始下载文件: #{filename}"
98
- Down::NetHttp.download(url,
99
- destination: "#{dir}#{filename}",
100
- headers: headers,
101
- content_length_proc: proc { |size| total_size = size },
102
- progress_proc: proc { |cursize| progressbar.progress = cursize.to_f / total_size * 100.0 })
103
- end
104
-
105
- def create_cookie_str(cookies)
106
- cookies = cookies['/']
107
- cookies_to_set_str = ''
108
- cookies.each do |key, value|
109
- cookies_to_set_str += "#{key}=#{value}; "
110
- end
111
- cookies_to_set_str
112
- end
113
-
114
- def generate_headers
115
- headers = BiliHttp.headers
116
- {
117
- 'User-Agent' => headers[:"User-Agent"],
118
- 'Referer' => headers[:Referer],
119
- 'Cookie' => create_cookie_str(load_cookie)
120
- }
121
- end
122
- end
123
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 leejoker
4
+ #
5
+ # This software is released under the MIT License.
6
+ # https://opensource.org/licenses/MIT
7
+
8
+ require_relative 'http/http'
9
+ require_relative 'api'
10
+ require 'fileutils'
11
+
12
+ # video module
13
+ module Bilibili
14
+ include BiliHttp
15
+ # video page list
16
+ class PageInfo
17
+ attr_accessor :cid, :page, :from, :part, :duration, :vid, :weblink
18
+
19
+ def initialize(json)
20
+ return if json.nil?
21
+
22
+ @cid = json[:cid]
23
+ @page = json[:page]
24
+ @from = json[:from]
25
+ @part = json[:part]
26
+ @duration = json[:duration]
27
+ @vid = json[:vid]
28
+ @weblink = json[:weblink]
29
+ end
30
+
31
+ def to_json(*opt)
32
+ {
33
+ cid: @cid,
34
+ page: @page,
35
+ from: @from,
36
+ part: @part,
37
+ duration: @duration,
38
+ vid: @vid,
39
+ weblink: @weblink
40
+ }.to_json(*opt)
41
+ end
42
+ end
43
+
44
+ # bilibili video interfaces
45
+ class Video < BilibiliBase
46
+ def video_page_list(bv_id)
47
+ return nil if bv_id.nil?
48
+
49
+ url = "#{Api::Video::PAGE_LIST}?bvid=#{bv_id}"
50
+ datas = get_jsona(url)
51
+ return nil if datas.nil?
52
+
53
+ datas.map do |d|
54
+ Bilibili::PageInfo.new(d)
55
+ end
56
+ end
57
+
58
+ def get_video_url(bv_id, cid, video_qn = '720')
59
+ qn = BilibiliBase.video_qn[video_qn]
60
+ url = "#{Api::Video::PLAY_URL}?bvid=#{bv_id}&cid=#{cid}&qn=#{qn}&fnval=0&fnver=0&fourk=1"
61
+ data = get_jsona(url)
62
+ data[:durl]
63
+ end
64
+
65
+ def video_url_list(bv_id, video_qn = '720')
66
+ result = []
67
+ page_list = video_page_list(bv_id)
68
+ return nil if page_list.nil?
69
+
70
+ page_list.each do |page|
71
+ get_video_url(bv_id, page.cid, video_qn).each do |down_url|
72
+ order = down_url[:order] < 10 ? "0#{down_url[:order]}" : down_url[:order]
73
+ result << { 'name': "#{page.part}_#{order}.flv", 'url': down_url[:url].to_s, 'prefix': page.part,
74
+ 'order': "#{page.page}#{order}", 'bv': bv_id.to_s }
75
+ end
76
+ end
77
+ result
78
+ end
79
+
80
+ def download_video_by_bv(bv_id, options)
81
+ urls = video_url_list(bv_id, options[:qn])
82
+ return nil if urls.empty?
83
+
84
+ urls = page_slice(urls, options[:start], options[:end], options[:page])
85
+ download_path = "#{File.expand_path(@options['download_path'].to_s, __dir__)}/#{bv_id}/"
86
+ url_array = []
87
+ urls.map { |url| download_file(url, download_path) }.each_with_index do |u, i|
88
+ same_part = same_part?(u, i)
89
+ url_array << u[:file_path]
90
+ combine_media(url_array, "#{download_path}#{u[:prefix]}.flv") unless same_part
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def page_slice(urls, start_page, end_page, page)
97
+ if page.nil?
98
+ start_page = start_page.to_i - 1
99
+ if end_page.nil?
100
+ urls.slice(start_page, urls.size - start_page)
101
+ elsif start_page < end_page.to_i
102
+ urls.slice(start_page, end_page.to_i)
103
+ else
104
+ raise 'start should not less than or equals to end'
105
+ end
106
+ else
107
+ [] << urls[page.to_i - 1]
108
+ end
109
+ end
110
+
111
+ def next?(array, index)
112
+ !array[index + 1].nil?
113
+ end
114
+
115
+ def same_part?(array, idx)
116
+ next?(array, idx) && array[idx][:prefix] == array[idx + 1][:prefix]
117
+ end
118
+
119
+ def download_file(url, dir)
120
+ file_path = check_path(dir, url[:name])
121
+ url[:file_path] = file_path
122
+ puts "开始下载文件到: #{file_path}, 视频地址:#{url[:url]}"
123
+ headers = generate_headers
124
+ wget_download(url[:url], headers['User-Agent'], headers['Referer'], headers['Cookie'], file_path)
125
+ dest_file_exist?(file_path)
126
+ url
127
+ end
128
+
129
+ def check_path(dir, filename)
130
+ FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
131
+ "#{dir}#{filename}"
132
+ end
133
+
134
+ def create_cookie_str(cookies)
135
+ cookie_array = cookies['/'].map do |key, value|
136
+ "#{key}=#{value}; "
137
+ end
138
+ cookie_array.join
139
+ end
140
+
141
+ def generate_headers
142
+ headers = BiliHttp.headers
143
+ {
144
+ 'User-Agent' => headers[:"User-Agent"],
145
+ 'Referer' => headers[:Referer],
146
+ 'Cookie' => create_cookie_str(load_cookie)
147
+ }
148
+ end
149
+
150
+ def combine_media(files, dest)
151
+ return if files.size.zero?
152
+
153
+ if files.size == 1
154
+ FileUtils.mv(files[0], dest)
155
+ files.clear
156
+ return
157
+ end
158
+
159
+ return if files.select! { |file| File.exist?(file) }.size.zero?
160
+
161
+ `ffmpeg -i concat:"#{files.join('|')}" -c copy #{dest}`
162
+ files.clear
163
+ end
164
+
165
+ def dest_file_exist?(dest)
166
+ if File.exist?(dest)
167
+ local = File.new(dest).size
168
+ raise 'file size is zero' if local.zero?
169
+
170
+ true
171
+ else
172
+ false
173
+ end
174
+ end
175
+
176
+ def wget_file_size(command)
177
+ result = `#{command} -o -`
178
+ hash = {}
179
+ result.split("\n").filter { |n| n.include?(':') }.each do |line|
180
+ a = line.split(':')
181
+ hash[a[0].strip] = a[1].strip
182
+ end
183
+ hash['Content-Length'].to_i
184
+ end
185
+
186
+ def wget_download(url, user_agent, referer, cookie, dest)
187
+ config_path = File.expand_path((@options['config_path']).to_s, __dir__)
188
+ File.write("#{config_path}/cookie", cookie) unless File.exist?("#{config_path}/cookie")
189
+ command = "wget '#{url}' --referer '#{referer}' --user-agent '#{user_agent}' --load-cookie='#{config_path}/cookie' "
190
+ `#{command} -c -O "#{dest}"`
191
+ end
192
+ end
193
+ end