Commit 9b40d56c authored by 神楽坂玲奈's avatar 神楽坂玲奈

iduel-images-downloader

parent ec791ff3
mkexy --encoding=utf-8 main.rb mkexy main.rb
exerb -c gui -k utf8 main.exy exerb -c gui -k utf8 main.exy
upx main.exe upx main.exe
unicode.data:
file: E:/Ruby200/lib/ruby/gems/2.0.0/gems/addressable-2.3.5/data/unicode.data
resource: resource:
icon: icon:
- width: 256 - width: 256
......
{"port":9998,"ygopro":{"path":"e:/zh99998/Documents/GitHub/mycard-lite","textfont":"c:/windows/fonts/simsun.ttc","numfont":"c:/windows/fonts/arialbd.ttf"},"url":"http://my-card.in/rooms"}
\ No newline at end of file
#encoding: UTF-8
if !File.file? 'data/allcards.dll'
puts "请放到iDuel目录下运行"
exit
end
cards = IO.readlines('data/allcards.dll').size / 2
puts "卡片总计 #{cards} 张"
if File.file? 'data/config.ini'
require 'inifile'
config = IniFile.new IO.read('data/config.ini', mode: 'rb:BOM|UTF-16LE:UTF-8')
path = config['Config'] && config['Config']['CardImagePath']
end
if !path or !File.directory? path
require 'win32/registry'
path = Win32::Registry::HKEY_CURRENT_USER.open('Software\OCGSOFT\Cards') { |reg| reg['Path'] } rescue ''
path.force_encoding(Encoding::GBK).encode!(Encoding::UTF_8)
end
if !path or !File.directory? path
Dir.mkdir 'data' unless File.directory? 'data'
path = 'data/image'
end
puts "本地卡图路径 #{path}"
Dir.mkdir path unless File.directory? path
def batch_download(main_url, files, content_type=nil)
connections = {}
count = {total: files.size, error: 0}
[10*100, files.size].min.times { do_download(main_url, files, content_type, count, connections) }
end
def do_download(main_url, files, content_type, count, connections)
if connections.size < 10
connection = EventMachine::HttpRequest.new(main_url)
connections[connection] = 0
else
connection = connections.min_by { |key, value| value }
if connection[1] >= 100
return
else
connection = connection[0]
end
end
remote_path, local_path = files.shift
connections[connection] += 1
connection.get(path: remote_path, keepalive: connections[connection] != 100).callback { |http|
puts File.basename local_path
count[:error] = 0
count[:total] -= 1
if http.response_header['CONNECTION'] != 'keep-alive'
connection.close
connections.delete(connection)
do_download(main_url, files, content_type, count, connections) while !files.empty? and (connections.size < 10 or connections.values.min < 100)
end
if http.response_header.status == 200 and (!content_type or http.response_header['CONTENT_TYPE'] == content_type)
IO.binwrite local_path, http.response
else
puts http.response_header.http_status
end
if count[:total].zero?
connections.each_key { |connection| connection.close }
connections.clear
puts 'all done'
EM.stop
end
}.errback { |http|
puts http.error
connection.close
connections.delete(connection)
files[remote_path] = local_path
count[:error] += 1
if count[:error] <= 10*100
do_download(main_url, files, content_type, count, connections) while !files.empty? and (connections.size < 10 or connections.values.min < 100)
else
connections.each_key { |connection| connection.close }
connections.clear
puts 'network error'
EM.stop
end
}
end
cards_to_download = (1..cards).to_a - Dir.glob(File.expand_path '*.jpg', path).collect { |file| File.basename(file, '.jpg').to_i }
puts "需要下载 #{cards_to_download.size} 张"
exit if cards_to_download.empty?
#monkey patch for exerb & addressable
if defined? ExerbRuntime
require 'stringio'
module Addressable
module IDNA
module File
class <<self
def join(*args)
end
def expand_path(*args)
end
def dirname(*args)
end
def open(*args)
result = ExerbRuntime.open('unicode.data')
if block_given?
begin
yield result
ensure
result.close
end
end
end
end
end
end
end
end
require 'em-http-request'
EventMachine.run do
http = EventMachine::HttpRequest.new('http://p.ocgsoft.cn/:osid.jpg').get redirects: 10
http.callback { |http|
main_url = http.last_effective_url
puts "获取卡图下载地址: #{main_url}"
files = {}
cards_to_download.each { |card_id| files[main_url.path.gsub(':osid', card_id.to_s)] = File.join(path, card_id.to_s + '.jpg') }
batch_download(main_url.to_s, files, 'image/jpeg')
}
end
\ No newline at end of file
...@@ -6,16 +6,23 @@ if defined?(Ocra) or defined?(Exerb) ...@@ -6,16 +6,23 @@ if defined?(Ocra) or defined?(Exerb)
require 'fileutils' require 'fileutils'
require 'uri' require 'uri'
require 'open-uri' require 'open-uri'
require 'net/http'
require 'win32api' require 'win32api'
require 'win32ole' require 'win32ole'
require 'win32/registry' require 'win32/registry'
require 'websocket-eventmachine-server' require 'websocket-eventmachine-server'
require 'em-http'
require 'rb-notifu'
require 'sqlite3'
require 'socket'
require 'net/http'
exit exit
end end
# = Runtime # = Runtime
begin begin
# == initialize # == initialize
Version = "0.1.0" Version = "0.1.0"
Platform = (RUBY_PLATFORM['mswin'] || RUBY_PLATFORM['mingw']) ? :win32 : :linux Platform = (RUBY_PLATFORM['mswin'] || RUBY_PLATFORM['mingw']) ? :win32 : :linux
System_Encoding = Encoding.find("locale") rescue Encoding.find(Encoding.locale_charmap) System_Encoding = Encoding.find("locale") rescue Encoding.find(Encoding.locale_charmap)
...@@ -154,9 +161,10 @@ begin ...@@ -154,9 +161,10 @@ begin
def service def service
require 'socket'
TCPServer.new('0.0.0.0', Config['port']).close rescue return #check port in use, seems eventmachine enabled IP_REUSEADDR.
require 'websocket-eventmachine-server' require 'websocket-eventmachine-server'
EventMachine.run do EventMachine.run do
WebSocket::EventMachine::Server.start(:host => "0.0.0.0", :port => Config['port']) do |ws| WebSocket::EventMachine::Server.start(:host => "0.0.0.0", :port => Config['port']) do |ws|
ws.onopen do ws.onopen do
ws.send({'version' => Version}.to_json) ws.send({'version' => Version}.to_json)
...@@ -170,7 +178,86 @@ begin ...@@ -170,7 +178,86 @@ begin
puts "Client disconnected" puts "Client disconnected"
end end
end end
if File.file? File.join(File.dirname(Config['ygopro']['path']), 'cards.cdb')
require 'sqlite3'
db = SQLite3::Database.new File.join(File.dirname(Config['ygopro']['path']), 'cards.cdb')
cards = db.execute('select id from datas').flatten
images_to_download = cards - Dir.glob(File.join(File.dirname(Config['ygopro']['path']), 'pics', '*.jpg')).collect { |file| File.basename(file, '.jpg').to_i }
thumbnails_to_download = cards - Dir.glob(File.join(File.dirname(Config['ygopro']['path']), 'pics', 'thumbnail', '*.jpg')).collect { |file| File.basename(file, '.jpg').to_i }
end
unless images_to_download.empty? and thumbnails_to_download.empty?
require 'em-http'
require 'uri'
http = EM::HttpRequest.new('https://my-card.in/cards/image.json').get
http.callback {
response = JSON.parse http.response
p response
image_url = URI(response['url'])
thumbnail_url = URI(response['thumbnail_url'])
Dir.mkdir File.join(File.dirname(Config['ygopro']['path']), 'pics') unless File.directory? File.join(File.dirname(Config['ygopro']['path']), 'pics')
Dir.mkdir File.join(File.dirname(Config['ygopro']['path']), 'pics', 'thumbnail') unless File.directory? File.join(File.dirname(Config['ygopro']['path']), 'pics', 'thumbnail')
files = {}
thumbnails_to_download.each { |card_id| files[thumbnail_url.path.gsub(':id', card_id.to_s)] = File.join(File.dirname(Config['ygopro']['path']), 'pics', 'thumbnail', card_id.to_s + '.jpg') }
images_to_download.each { |card_id| files[image_url.path.gsub(':id', card_id.to_s)] = File.join(File.dirname(Config['ygopro']['path']), 'pics', card_id.to_s + '.jpg') }
batch_download(image_url.to_s, files, 'image/jpeg')
}
require 'rb-notifu'
Notifu::show :message => "缩略: #{thumbnails_to_download.size}, 完整: #{images_to_download.size}".encode(System_Encoding), :baloon => false, :type => :info, :title => "正在下载卡图".encode(System_Encoding) do |status|
if status == 3
System.web 'http://my-card.in/rooms/'
end
end
end
end
end
def batch_download(main_url, files, content_type=nil)
connections = {}
retried = [0] #pass by reference
[1*100, files.size].min.times { do_download(main_url, files, content_type, retried, connections) }
end
def do_download(main_url, files, content_type, retried, connections)
if connections.size < 1
connection = EventMachine::HttpRequest.new(main_url)
connections[connection] = 0
else
connection = connections.min_by { |key, value| value }
if connection[1] >= 100
return
else
connection = connection[0]
end
end end
remote_path, local_path = files.shift
connections[connection] += 1
connection.get(path: remote_path, keepalive: connections[connection] != 100).callback { |http|
puts local_path
retried[0] = 0
if http.response_header['CONNECTION'] != 'keep-alive'
connection.close
connections.delete(connection)
do_download(main_url, files, content_type, retried, connections) while !files.empty? and (connections.size < 1 or connections.values.min < 100)
elsif files.empty?
connection.close
connections.delete(connection)
end
if http.response_header.status == 200 and (!content_type or http.response_header['CONTENT_TYPE'] == content_type)
IO.binwrite local_path, http.response
else
puts http.response_header.http_status
end
}.errback { |http|
puts http.error
connection.close
connections.delete(connection)
files[remote_path] = local_path
retried[0] += 1
if retried[0] <= 10*100
do_download(main_url, files, content_type, retried, connections) while !files.empty? and (connections.size < 1 or connections.values.min < 100)
end
}
end end
def load_system_conf def load_system_conf
...@@ -276,7 +363,7 @@ begin ...@@ -276,7 +363,7 @@ begin
when 'registed' when 'registed'
registed? registed?
when 'mycard:///' when 'mycard:///'
#service service
when /mycard:\/\/(.*)/ when /mycard:\/\/(.*)/
parse_uri(command) parse_uri(command)
when /.*\.(?:ydk|yrp)$/ when /.*\.(?:ydk|yrp)$/
...@@ -349,7 +436,36 @@ begin ...@@ -349,7 +436,36 @@ begin
end end
end end
#monkey patch for exerb & addressable
if defined? ExerbRuntime
module Addressable
module IDNA
module File
class <<self
def join(*args)
end
def expand_path(*args)
end
def dirname(*args)
end
def open(*args)
result = ExerbRuntime.open('unicode.data')
if block_given?
begin
yield result
ensure
result.close
end
end
end
end
end
end
end
end
save_config save_config
if ARGV.first if ARGV.first
parse ARGV.first.dup.force_encoding(System_Encoding).encode!(Encoding::UTF_8) parse ARGV.first.dup.force_encoding(System_Encoding).encode!(Encoding::UTF_8)
else else
...@@ -359,7 +475,7 @@ begin ...@@ -359,7 +475,7 @@ begin
else else
System.web(Config['url']) System.web(Config['url'])
end end
#service service
end end
rescue => exception rescue => exception
error = "程序出现了错误,请把你的操作及以下信息发送至zh99998@gmail.com来帮助我们完善程序 error = "程序出现了错误,请把你的操作及以下信息发送至zh99998@gmail.com来帮助我们完善程序
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment