Permalink
Fetching contributors…
Cannot retrieve contributors at this time
216 lines (179 sloc) 5.66 KB
# Simple admiral stats exporter from kancolle-arcade.net
require 'faraday'
require 'faraday-cookie_jar'
require 'yaml'
require 'json'
# Read configurations
config = YAML.load_file('config.yaml')
# Base URL
BASE_URL = 'https://kancolle-arcade.net'
# Top page
TOP_URL = '/ac/'
# POST
LOGIN_URL = '/ac/api/Auth/login'
# Common part of API URLs
API_BASE_URL = '/ac/api/'
# Common HTTP headers
HTTP_HEADER_HOST = 'kancolle-arcade.net'
HTTP_HEADER_REFERER = 'https://kancolle-arcade.net/ac'
HTTP_HEADER_UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0'
# API URLs
API_URLS = [
'Personal/basicInfo',
'Area/captureInfo',
'TcBook/info',
'EquipBook/info',
'Campaign/history',
'Campaign/info',
'Campaign/present',
# From REVISION 2 (2016-06-30)
'CharacterList/info',
'EquipList/info',
# From 2016-07-26
'Quest/info',
# From 2016-10-27
'Event/info',
# イベントの開始・終了日とイベントアイコンの表示制御フラグのみを返す
# 'Event/hold',
# From 2017-02-14
'RoomItemList/info',
# From REVISION 5 (2017-04-26)
'BlueprintList/info',
# From VERSION A (2017-09-21)
'Exercise/info',
# From VERSION B (2018-07-24)
'Cop/info'
# 期間限定作戦の開始日とholdStatusのみを返す
# 'Cop/hold',
]
# Prefix for memo file name
MEMO_FILE_PREFIX = 'memo'
# Admiral Stats Import URL
AS_IMPORT_URL = 'https://www.admiral-stats.com/api/v1/import'
# User Agent for logging on www.admiral-stats.com
AS_HTTP_HEADER_UA = 'AdmiralStatsExporter-Ruby/1.15.0'
# Check whether to upload JSON files or not
do_upload = ARGV.include?('--upload')
if do_upload and config['upload']['token'].to_s.empty?
puts 'ERROR: For upload, authorization token is required in config.yaml'
exit 1
end
# Check whether to output a memo file or not
memo = nil
if ARGV.include?('--memo')
print 'Memo: '
memo = STDIN.gets
end
# Create new directory for latest JSON files
timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
json_dir = config['output']['dir'] + "/" + timestamp
FileUtils.mkdir_p(json_dir)
# Disable SSL verification for Windows support
conn = Faraday.new(url: BASE_URL, ssl: { verify: false }) do |faraday|
faraday.request :url_encoded
# faraday.response :logger
faraday.use :cookie_jar
faraday.adapter Faraday.default_adapter
end
# Access to retrieve my session ID (JSESSIONID)
res = conn.get do |req|
req.url TOP_URL
end
unless res.status == 200
puts "ERROR: Failed to access #{BASE_URL}#{TOP_URL} (status code = #{res.status})"
exit 1
end
# Login (POST)
res = conn.post do |req|
req.url LOGIN_URL
req.headers['Content-Type'] = 'application/json'
req.headers['Host'] = HTTP_HEADER_HOST
req.headers['Referer'] = HTTP_HEADER_REFERER
req.headers['User-Agent'] = HTTP_HEADER_UA
req.headers['X-Requested-With'] = 'XMLHttpRequest'
req.body = "{\"id\":\"#{config['login']['id']}\",\"password\":\"#{config['login']['password']}\"}"
end
unless res.status == 200
puts "ERROR: Failed to login (status code = #{res.status})"
exit 1
end
# Access to APIs
API_URLS.each do |api_url|
res = conn.get do |req|
req.url API_BASE_URL + api_url
req.headers['Host'] = HTTP_HEADER_HOST
req.headers['Referer'] = HTTP_HEADER_REFERER
req.headers['User-Agent'] = HTTP_HEADER_UA
req.headers['X-Requested-With'] = 'XMLHttpRequest'
end
# Create filename from URL automatically
filename = api_url.gsub('/', '_') + "_#{timestamp}.json"
if res.status == 200
File.write(json_dir + '/' + filename, res.body)
puts "Succeeded to download #{filename}"
elsif res.status > 200 && res.status < 300
puts "No content. Stopped to download #{filename} (status code = #{res.status})"
else
puts "ERROR: Failed to download #{filename} (status code = #{res.status})"
end
end
# Create memo file
if memo
memo_filename = "#{MEMO_FILE_PREFIX}_#{timestamp}.txt"
File.write(json_dir + '/' + memo_filename, memo)
puts "Succeeded to create #{memo_filename}"
end
# Upload exported files to Admiral Stats
if do_upload
# New connection for Admiral Stats API
as_conn = Faraday.new do |faraday|
faraday.request :url_encoded
# faraday.response :logger
faraday.adapter Faraday.default_adapter
end
# Set Authorization header
as_conn.authorization :Bearer, config['upload']['token']
# Get currently importable file types
res = as_conn.get do |req|
req.url "#{AS_IMPORT_URL}/file_types"
req.headers['User-Agent'] = AS_HTTP_HEADER_UA
end
case res.status
when 200
importable_file_types = JSON.parse(res.body)
puts "Importable file types: #{importable_file_types.join(', ')}"
when 401
json = JSON.parse(res.body)
json['errors'].each do |error|
puts "ERROR: #{error['message']}"
end
exit 1
end
Dir::foreach(json_dir) do |f|
if f =~ /^(.+)_(\d{8}_\d{6})\.json$/
file_type, timestamp = $1, $2
next unless importable_file_types.include?(file_type)
# Open, read and close file
json = open(File.join(json_dir, f), &:read)
res = as_conn.post do |req|
req.url "#{AS_IMPORT_URL}/#{file_type}/#{timestamp}"
req.headers['Content-Type'] = 'application/json'
req.headers['User-Agent'] = AS_HTTP_HEADER_UA
req.body = json
end
case res.status
when 200, 201
json = JSON.parse(res.body)
puts "#{json['data']['message']}(ファイル名:#{f}"
when 400, 401
json = JSON.parse(res.body)
json['errors'].each do |error|
puts "ERROR: #{error['message']}(ファイル名:#{f}"
end
else
# Unexpected error
puts "ERROR: #{res.body}"
end
end
end
end