Class: Factorix::API::GameDownloadAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/factorix/api/game_download_api.rb

Overview

API client for downloading Factorio game files

Corresponds to: wiki.factorio.com/Download_API

Constant Summary collapse

BUILDS =

Valid build types

%w[alpha expansion demo headless].freeze
PLATFORMS =

Valid platforms

%w[win64 win64-manual osx linux64].freeze
CHANNELS =

Valid release channels

%w[stable experimental].freeze

Instance Method Summary collapse

Constructor Details

#initializeGameDownloadAPI

Initialize with thread-safe credential loading

Parameters:

  • args (Hash)

    dependency injection arguments



42
43
44
45
# File 'lib/factorix/api/game_download_api.rb', line 42

def initialize(...)
  super
  @service_credential_mutex = Mutex.new
end

Instance Method Details

#download(version:, build:, platform:, output:, handler: nil) ⇒ void

This method returns an undefined value.

Download the game to the specified output path

Parameters:

  • version (String)

    Game version (e.g., “2.0.28”)

  • build (String)

    Build type (alpha, expansion, demo, headless)

  • platform (String)

    Platform (win64, win64-manual, osx, linux64)

  • output (Pathname)

    Output file path

  • handler (Object, nil) (defaults to: nil)

    Event handler for download progress (optional)

Raises:

  • (ArgumentError)

    if build or platform is invalid



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/factorix/api/game_download_api.rb', line 97

def download(version:, build:, platform:, output:, handler: nil)
  validate_build!(build)
  validate_platform!(platform)

  uri = build_download_uri(version, build, platform)
  downloader = Container[:downloader]
  downloader.subscribe(handler) if handler
  begin
    downloader.download(uri, output)
  ensure
    downloader.unsubscribe(handler) if handler
  end
end

#latest_releasesHash{Symbol => Hash}

Fetch latest release information

Examples:

Response format

{
  stable: { alpha: "2.0.28", expansion: "2.0.28", headless: "2.0.28" },
  experimental: { alpha: "2.0.29", expansion: "2.0.29", headless: "2.0.29" }
}

Returns:

  • (Hash{Symbol => Hash})

    Hash containing stable and experimental release info



55
56
57
58
59
60
# File 'lib/factorix/api/game_download_api.rb', line 55

def latest_releases
  logger.debug "Fetching latest releases"
  uri = URI.join(API_BASE_URL, "/api/latest-releases")
  response = client.get(uri)
  JSON.parse((+response.body).force_encoding(Encoding::UTF_8), symbolize_names: true)
end

#latest_version(channel:, build:) ⇒ String?

Get the latest version for a specific channel and build

Parameters:

  • channel (String)

    Release channel (stable, experimental)

  • build (String)

    Build type (alpha, expansion, demo, headless)

Returns:

  • (String, nil)

    Version string or nil if not available



67
68
69
70
# File 'lib/factorix/api/game_download_api.rb', line 67

def latest_version(channel:, build:)
  releases = latest_releases
  releases.dig(channel.to_sym, build.to_sym)
end

#resolve_filename(version:, build:, platform:) ⇒ String

Resolve the download filename by making a HEAD request

Parameters:

  • version (String)

    Game version (e.g., “2.0.28”)

  • build (String)

    Build type (alpha, expansion, demo, headless)

  • platform (String)

    Platform (win64, win64-manual, osx, linux64)

Returns:

  • (String)

    Filename extracted from final redirect URL

Raises:

  • (ArgumentError)

    if build or platform is invalid



79
80
81
82
83
84
85
86
# File 'lib/factorix/api/game_download_api.rb', line 79

def resolve_filename(version:, build:, platform:)
  validate_build!(build)
  validate_platform!(platform)

  uri = build_download_uri(version, build, platform)
  response = client.head(uri)
  File.basename(response.uri.path)
end