Class: Factorix::Portal

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

Overview

High-level API wrapper for Factorio MOD Portal

Provides object-oriented interface by converting API responses (Hash) to typed value objects (MODInfo, Release, etc.).

Examples:

List all MODs

portal = Factorix::Portal.new
mods = portal.list_mods(page_size: 10)
mods.each { |mod| puts "#{mod.name}: #{mod.title}" }

Get MOD information

mod = portal.get_mod("space-exploration")
puts mod.summary

Get full MOD details

mod = portal.get_mod_full("space-exploration")
puts mod.detail.description if mod.detail

Download a MOD

mod = portal.get_mod_full("space-exploration")
release = mod.releases.max_by(&:released_at)  # Get latest by release date
portal.download_mod(release, Pathname("downloads/mod.zip")) if release

Instance Method Summary collapse

Instance Method Details

#add_mod_image(mod_name, image_file) ⇒ API::Image

Add an image to a MOD

Parameters:

  • mod_name (String)

    the MOD name

  • image_file (Pathname)

    path to image file

Returns:

Raises:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/factorix/portal.rb', line 157

def add_mod_image(mod_name, image_file)
  logger.info("Adding image to MOD", mod: mod_name, file: image_file.to_s)

  # Initialize upload
  upload_url = mod_management_api.init_image_upload(mod_name)

  # Upload image
  response_data = mod_management_api.finish_image_upload(mod_name, upload_url, image_file)

  # Convert response to API::Image
  image = API::Image[**response_data.transform_keys(&:to_sym)]

  logger.info("Image added successfully", mod: mod_name, image_id: image.id)
  image
end

#download_mod(release, output, handler: nil) ⇒ void

This method returns an undefined value.

Download a MOD release file

Parameters:

  • release (API::Release)

    release object containing download_url and sha1

  • output (Pathname)

    output file path

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

    event handler for download progress (optional)

Raises:



78
79
80
81
82
# File 'lib/factorix/portal.rb', line 78

def download_mod(release, output, handler: nil)
  # Extract path from URI::HTTPS
  download_path = release.download_url.path
  mod_download_api.download(download_path, output, expected_sha1: release.sha1, handler:)
end

#edit_mod(mod_name, **metadata) ⇒ void

This method returns an undefined value.

Edit MOD metadata without uploading new file

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:



142
143
144
145
146
147
148
# File 'lib/factorix/portal.rb', line 142

def edit_mod(mod_name, **)
  raise MODSettingsError, "No metadata provided" if .empty?

  logger.info("Editing MOD metadata", mod: mod_name, fields: .keys)
  mod_management_api.edit_details(mod_name, **)
  logger.info("Metadata updated successfully", mod: mod_name)
end

#edit_mod_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 in desired order

Raises:



180
181
182
183
184
# File 'lib/factorix/portal.rb', line 180

def edit_mod_images(mod_name, image_ids)
  logger.info("Editing MOD images", mod: mod_name, image_count: image_ids.size)
  mod_management_api.edit_images(mod_name, image_ids)
  logger.info("Images updated successfully", mod: mod_name)
end

#get_mod(name) ⇒ API::MODInfo

Get basic information for a specific MOD (Short API)

Parameters:

  • name (String)

    MOD name

Returns:



57
58
59
60
# File 'lib/factorix/portal.rb', line 57

def get_mod(name)
  data = mod_portal_api.get_mod(name)
  API::MODInfo[**data]
end

#get_mod_full(name) ⇒ API::MODInfo

Get full information for a specific MOD (Full API)

Parameters:

  • name (String)

    MOD name

Returns:

  • (API::MODInfo)

    MODInfo object (with Detail if available)



66
67
68
69
# File 'lib/factorix/portal.rb', line 66

def get_mod_full(name)
  data = mod_portal_api.get_mod_full(name)
  API::MODInfo[**data]
end

#list_modsArray<API::MODInfo>

List MODs from the MOD Portal

Parameters:

  • namelist (Array<String>)

    MOD names to filter (positional arguments)

  • hide_deprecated (Boolean, nil)

    hide deprecated MODs

  • page (Integer, nil)

    page number (1-based)

  • page_size (Integer, nil)

    number of results per page

  • sort (String, nil)

    sort field (name, created_at, updated_at)

  • sort_order (String, nil)

    sort order (asc, desc)

  • version (String, nil)

    Factorio version filter

Returns:



48
49
50
51
# File 'lib/factorix/portal.rb', line 48

def list_mods(...)
  response = mod_portal_api.get_mods(...)
  response[:results].map {|mod_data| API::MODInfo[**mod_data] }
end

#upload_mod(mod_name, file_path, **metadata) ⇒ void

This method returns an undefined value.

Upload a MOD file to the portal

Automatically detects if this is a new MOD or update:

  • For new MODs: uses init_publish and includes metadata in finish_upload

  • For existing MODs: uses init_upload, then updates metadata via edit_details

Parameters:

  • mod_name (String)

    the MOD name

  • file_path (Pathname)

    path to MOD zip file

  • metadata (Hash)

    optional metadata

Options Hash (**metadata):

  • :description (String)

    Markdown description

  • :category (String)

    MOD category

  • :license (String)

    License identifier

  • :source_url (String)

    Repository URL

Raises:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/factorix/portal.rb', line 100

def upload_mod(mod_name, file_path, **)
  mod_exists = begin
    get_mod(mod_name)
    logger.info("Uploading new release to existing MOD", mod: mod_name)
    true
  rescue MODNotOnPortalError
    logger.info("Publishing new MOD", mod: mod_name)
    false
  end

  upload_url = mod_exists ? mod_management_api.init_upload(mod_name) : mod_management_api.init_publish(mod_name)

  if mod_exists
    # For existing MODs: upload file, then edit metadata separately
    mod_management_api.finish_upload(mod_name, upload_url, file_path)
    mod_management_api.edit_details(mod_name, **) unless .empty?
  else
    # For new MODs: upload file with metadata
    mod_management_api.finish_upload(mod_name, upload_url, file_path, **)
  end

  logger.info("Upload completed successfully", mod: mod_name)
end