Files
w3dhub_linux_launcher/lib/worker/w3dhub_api.rb

167 lines
5.2 KiB
Ruby

module W3DHubLauncher
class W3DHubApi
API_TIMEOUT = 30 # seconds
API_CONNECT_TIMEOUT = 10 # seconds
PRIMARY_W3DHUB_API_ENDPOINT = "https://secure.w3dhub.com".freeze
ALTERNATIVE_W3DHUB_API_ENDPOINT = "https://backend.w3d.cyberarm.dev".freeze
attr_reader :applications
def initialize
@access_token = nil
@applications = []
@http_clients = {}
end
def headers(form_encoded: false, range: nil)
array = [
["user-agent", W3DHubLauncher::USER_AGENT],
["accept", "application/json"],
]
array << ["content-type", "application/x-www-form-urlencoded"] if form_encoded
array << ["authorization", "Bearer #{@access_token}"] if @access_token
array << ["range", "bytes=#{range}-"] if range
# pp array
array
end
# return raw response to requester
def fetch(url, method: :get, body: nil, headers: headers())
result = CyberarmEngine::Result.new
Sync do |task|
task.with_timeout(API_TIMEOUT) do
Async::HTTP::Internet.send(method, url, headers, body) do |response|
pp [method, url, headers, body, response]
if response.success?
result.data = response.read
else
result.error = true
end
end
rescue StandardError => e
result.error = e
rescue Async::TimeoutError => e
result.error = e
end
result
end
result
end
# write response to file, periodically reporting progress to requester
def download(url, path:, method: :get, body: nil, headers: headers(), &block)
result = CyberarmEngine::Result.new
Sync do |task|
Async::HTTP::Internet.send(method, url, headers, body) do |response|
if response.success?
content_length = response.headers["content-length"] || 0
total_downloaded_bytes = 0
range = Integer(headers.find { |key, value| key == "range" }&.last&.split("=")&.last&.split("-")&.first || 0)
File.open(path, range.positive? ? "r+b" : "wb") do |file|
file.pos = range if range.positive?
response.each do |chunk|
file.write(chunk)
downloaded_bytes = chunk.length
total_downloaded_bytes += downloaded_bytes
block&.call(downloaded_bytes, total_downloaded_bytes, content_length)
end
end
result.data = true
end
rescue StandardError => e
result.error = e
rescue Async::TimeoutError
result.error = e
end
end
result
end
def user_login()
result = CyberarmEngine::Result.new
end
def refresh_user_login()
result = CyberarmEngine::Result.new
end
def fetch_user_details()
result = CyberarmEngine::Result.new
end
def fetch_applications
result = CyberarmEngine::Result.new
# If we're not signed in, then the primary backend will try to redirect us to the alternate backend. So skip it if we're not signed in.
primary_result = @access_token ? fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/launcher/1/get-applications") : CyberarmEngine::Result.new(error: true)
alternate_result = fetch("#{ALTERNATIVE_W3DHUB_API_ENDPOINT}/apis/launcher/1/get-applications")
single_source = false
# We've failed to retrieve data
if primary_result.error? && alternate_result.error?
return result
# We've only gotten data back from the primary backend
elsif primary_result.okay? && alternate_result.error?
result.data = primary_result.data
single_source = true
# We've only gotten data back from the alternate backend
elsif primary_result.error? && alternate_result.okay?
result.data = alternate_result.data
single_source = true
end
unless single_source
puts "FIXME: merge applications source"
# We've gotten data back from both backends, merge them.
# pp [primary_result, alternate_result]
# FIXME: Merge primary and alternate results
end
@applications = JSON.parse(result.data)["applications"]&.map { |app| W3DHubLauncher::Worker::Api::Application.new(app) } || []
result
end
def fetch_news(category)
fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-news", method: :post, body: "data={\"category\":\"#{category}\"}", headers: headers(form_encoded: true))
end
def fetch_events(category)
fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-server-events", method: :post, body: "data={\"serverPath\":\"#{category}\"}", headers: headers(form_encoded: true))
end
def fetch_test_events(category)
fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-testing-times")
end
def fetch_manifest()
result = CyberarmEngine::Result.new
end
def fetch_package_details(packages)
body = URI.encode_www_form("data": JSON.dump({ packages: packages }))
fetch("#{@access_token ? PRIMARY_W3DHUB_API_ENDPOINT : ALTERNATIVE_W3DHUB_API_ENDPOINT}/apis/launcher/1/get-package-details", method: :post, body: body, headers: headers(form_encoded: true))
end
def download_package()
download()
end
end
end