sudara/alonetone

View on GitHub
app/models/upload/metadata.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

class Upload
  # Helper class to extract metadata from an MP3 file.
  class Metadata
    ATTRIBUTE_TO_ID3_TAG_NAME = {
      album: 'album',
      artist: 'artist',
      bitrate: 'bitrate',
      length: 'length',
      samplerate: 'samplerate',
      title: 'title',
      id3_track_num: 'tracknum',
      genre: 'genre_s'
    }.freeze

    attr_reader :file

    def initialize(file)
      @file = file
    end

    def attributes
      @attributes ||= extract_attributes
    end

    def self.sanitize_encoding(value)
      if value.respond_to?(:encode)
        value.encode(
          'UTF-8', invalid: :replace, undef: :replace, replace: "\ufffd"
        ).unicode_normalize(:nfkc)
      else
        value
      end
    end

    private

    def mp3info_attributes
      Mp3Info.open(file.path) do |info|
        ATTRIBUTE_TO_ID3_TAG_NAME.each_with_object({}) do |(name, tag_name), attributes|
          value = info.respond_to?(tag_name) ? info.public_send(tag_name) : info.tag[tag_name]
          attributes[name] = self.class.sanitize_encoding(value)
        end
      end
    rescue Mp3InfoError
      {}
    end

    def extract_attributes
      mp3info_attributes.reject { |_, value| value.blank? }
    end
  end
end