Class: Factorix::API::MODManagementAPI

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

Overview

API client for MOD management operations (upload, publish, edit)

Requires API key authentication via APICredential. Uses api_credential lazy loading to avoid early environment variable evaluation.

Instance Method Summary collapse

Constructor Details

#initializeMODManagementAPI

Initialize with thread-safe credential loading

Parameters:

  • args (Hash)

    dependency injection arguments



43
44
45
46
# File 'lib/factorix/api/mod_management_api.rb', line 43

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

Instance Method Details

#edit_details(mod_name, **metadata) ⇒ void

This method returns an undefined value.

Edit MOD details (for post-upload metadata changes)

Parameters:

  • mod_name (String)

    the MOD name

  • metadata (Hash)

    metadata to update

Options Hash (**metadata):

  • :description (String)

    Markdown description

  • :summary (String)

    Brief description

  • :title (String)

    MOD title

  • :category (String)

    MOD category

  • :tags (Array<String>)

    Array of tags

  • :license (String)

    License identifier

  • :homepage (String)

    Homepage URL

  • :source_url (String)

    Repository URL

  • :faq (String)

    FAQ text

  • :deprecated (Boolean)

    Deprecation flag

Raises:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/factorix/api/mod_management_api.rb', line 126

def edit_details(mod_name, **)
  validate_metadata!(, ALLOWED_EDIT_METADATA, "edit_details")

  uri = URI.join(BASE_URL, "/api/v2/mods/edit_details")

  # URI.encode_www_form handles arrays as multiple params (tags=a&tags=b)
  form_data = {mod: mod_name, **}.transform_keys(&:to_s)
  body = URI.encode_www_form(form_data)

  logger.info("Editing MOD details", mod: mod_name, fields: .keys)
  client.post(uri, body:, headers: build_auth_header, content_type: "application/x-www-form-urlencoded")
  logger.info("Edit completed successfully", mod: mod_name)
  publish("mod.changed", mod: mod_name)
rescue HTTPNotFoundError
  raise MODNotOnPortalError, "MOD '#{mod_name}' not found on portal"
end

#edit_images(mod_name, image_ids) ⇒ void

This method returns an undefined value.

Edit MOD’s image list

Parameters:

  • mod_name (String)

    the MOD name

  • image_ids (Array<String>)

    array of image IDs (SHA1 hashes)

Raises:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/factorix/api/mod_management_api.rb', line 191

def edit_images(mod_name, image_ids)
  raise ArgumentError, "image_ids must be an array" unless image_ids.is_a?(Array)

  uri = URI.join(BASE_URL, "/api/v2/mods/images/edit")

  form_data = {mod: mod_name, images: image_ids.join(",")}
  body = URI.encode_www_form(form_data)

  logger.info("Editing MOD images", mod: mod_name, image_count: image_ids.size)
  client.post(uri, body:, headers: build_auth_header, content_type: "application/x-www-form-urlencoded")
  logger.info("Images updated successfully", mod: mod_name)
  publish("mod.changed", mod: mod_name)
rescue HTTPNotFoundError
  raise MODNotOnPortalError, "MOD '#{mod_name}' not found on portal"
end

#finish_image_upload(mod_name, upload_url, image_file) ⇒ Hash

Complete image upload

Parameters:

  • mod_name (String)

    the MOD name

  • upload_url (URI::HTTPS)

    the upload URL from init_image_upload

  • image_file (Pathname)

    path to image file

Returns:

  • (Hash)

    parsed response with image info (id, url, thumbnail)

Raises:



170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/factorix/api/mod_management_api.rb', line 170

def finish_image_upload(mod_name, upload_url, image_file)
  logger.info("Uploading image file", mod: mod_name, file: image_file.to_s)

  response = uploader.upload(upload_url, image_file, field_name: "image")
  data = JSON.parse(response.body)

  logger.info("Image upload completed successfully", mod: mod_name, image_id: data["id"])
  publish("mod.changed", mod: mod_name)
  data
rescue JSON::ParserError => e
  raise HTTPError, "Invalid JSON response: #{e.message}"
end

#finish_upload(mod_name, upload_url, file_path, **metadata) ⇒ void

This method returns an undefined value.

Complete upload (works for both publish and update scenarios)

Parameters:

  • mod_name (String)

    the MOD name

  • upload_url (URI::HTTPS)

    the upload URL from init_publish or init_upload

  • file_path (Pathname)

    path to MOD zip file

  • metadata (Hash)

    optional metadata (only used for init_publish)

Options Hash (**metadata):

  • :description (String)

    Markdown description

  • :category (String)

    MOD category

  • :license (String)

    License identifier

  • :source_url (String)

    Repository URL

Raises:



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/factorix/api/mod_management_api.rb', line 96

def finish_upload(mod_name, upload_url, file_path, **)
  validate_metadata!(, ALLOWED_UPLOAD_METADATA, "finish_upload")

  logger.info("Uploading MOD file", mod: mod_name, file: file_path.to_s, metadata_count: .size)

  fields = .transform_keys(&:to_s)

  uploader.upload(upload_url, file_path, fields:)
  logger.info("Upload completed successfully", mod: mod_name)
  publish("mod.changed", mod: mod_name)
end

#init_image_upload(mod_name) ⇒ URI::HTTPS

Initialize image upload for a MOD

Parameters:

  • mod_name (String)

    the MOD name

Returns:

  • (URI::HTTPS)

    upload URL

Raises:



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/factorix/api/mod_management_api.rb', line 150

def init_image_upload(mod_name)
  uri = URI.join(BASE_URL, "/api/v2/mods/images/add")
  body = URI.encode_www_form({mod: mod_name})

  logger.info("Initializing image upload", mod: mod_name)
  response = client.post(uri, body:, headers: build_auth_header, content_type: "application/x-www-form-urlencoded")

  parse_upload_url(response)
rescue HTTPNotFoundError
  raise MODNotOnPortalError, "MOD '#{mod_name}' not found on portal"
end

#init_publish(mod_name) ⇒ URI::HTTPS

Initialize new MOD publication

Parameters:

  • mod_name (String)

    the MOD name

Returns:

  • (URI::HTTPS)

    upload URL

Raises:



54
55
56
57
58
59
60
61
62
# File 'lib/factorix/api/mod_management_api.rb', line 54

def init_publish(mod_name)
  uri = URI.join(BASE_URL, "/api/v2/mods/init_publish")
  body = URI.encode_www_form({mod: mod_name})

  logger.info("Initializing MOD publication", mod: mod_name)
  response = client.post(uri, body:, headers: build_auth_header, content_type: "application/x-www-form-urlencoded")

  parse_upload_url(response)
end

#init_upload(mod_name) ⇒ URI::HTTPS

Initialize update to existing MOD

Parameters:

  • mod_name (String)

    the MOD name

Returns:

  • (URI::HTTPS)

    upload URL

Raises:



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/factorix/api/mod_management_api.rb', line 71

def init_upload(mod_name)
  uri = URI.join(BASE_URL, "/api/v2/mods/releases/init_upload")
  body = URI.encode_www_form({mod: mod_name})

  logger.info("Initializing MOD upload", mod: mod_name)
  response = client.post(uri, body:, headers: build_auth_header, content_type: "application/x-www-form-urlencoded")

  parse_upload_url(response)
rescue HTTPNotFoundError
  raise MODNotOnPortalError, "MOD '#{mod_name}' not found on portal"
end