# frozen_string_literal: true # Service wrapper for downloading weapon images from Granblue servers to S3. # Uses the existing WeaponDownloader but provides a cleaner interface for controllers. # # @example Download images for a weapon # service = WeaponImageDownloadService.new(weapon) # result = service.download # if result.success? # puts result.images # else # puts result.error # end class WeaponImageDownloadService Result = Struct.new(:success?, :images, :error, :total, keyword_init: true) def initialize(weapon, options = {}) @weapon = weapon @force = options[:force] || false @size = options[:size] || 'all' @storage = options[:storage] || :s3 end # Downloads images for the weapon # # @return [Result] Struct with success status, images manifest, and any errors def download downloader = Granblue::Downloaders::WeaponDownloader.new( @weapon.granblue_id, storage: @storage, verbose: Rails.env.development? ) selected_size = @size == 'all' ? nil : @size downloader.download(selected_size) manifest = build_image_manifest Result.new( success?: true, images: manifest, total: count_total_images(manifest) ) rescue StandardError => e Rails.logger.error "[WeaponImageDownload] Failed for #{@weapon.granblue_id}: #{e.message}" Result.new( success?: false, error: e.message ) end private def build_image_manifest sizes = Granblue::Downloaders::WeaponDownloader::SIZES variants = build_variants sizes.each_with_object({}) do |size, manifest| manifest[size] = variants.map do |variant| extension = size == 'base' ? 'png' : 'jpg' "#{variant}.#{extension}" end end end def build_variants # Weapons use the raw granblue_id for base variant variants = [@weapon.granblue_id] if @weapon.transcendence variants << "#{@weapon.granblue_id}_02" variants << "#{@weapon.granblue_id}_03" end # Add element variants for element-changeable weapons (7 variants: 0-6) if Weapon.element_changeable?(@weapon) (0..6).each do |element| variants << "#{@weapon.granblue_id}_#{element}" end end variants end def count_total_images(manifest) manifest.values.sum(&:size) end end