smugglys/translatomatic

View on GitHub
lib/translatomatic/resource_file/subtitle.rb

Summary

Maintainability
A
0 mins
Test Coverage
module Translatomatic
  module ResourceFile
    # Subtitle resource file.
    # requires 'titlekit' gem
    class Subtitle < Base
      # (see Base.extensions)
      def self.extensions
        %w[srt ass ssa]
      end

      # (see Base.enabled?)
      def self.enabled?
        @enabled ||= begin
          require 'titlekit'
          true
        rescue LoadError
          false
        end
      end

      # (see Base#set)
      def set(key, value)
        super(key, value)

        if @subtitle_map.include?(key)
          @subtitle_map[key][:lines] = value.to_s
        else
          add_subtitle(lines: value) unless value.blank?
        end
      end

      # (see Base#save)
      def save(target = path, options = {})
        add_created_by unless options[:no_created_by] || created_by?
        export(target)
      end

      private

      def init
        @subtitle_map = {}
        @subtitles = []
        @keynum = 1
      end

      def load
        @metadata.reset
        subtitles = import(@path)
        subtitles.each { |i| add_subtitle(i) }
        init_properties
      end

      def process_metadata(key, subtitle)
        lines = subtitle[:lines] || ''
        context = @metadata.parse_comment(lines)
        @metadata.assign_key(key) unless context.present?
      end

      def add_created_by
        # TODO
      end

      def add_subtitle(subtitle = {})
        key = "key#{@keynum}"
        subtitle[:id] ||= @keynum
        subtitle[:start] ||= @keynum * 10
        subtitle[:end] ||= @keynum * 10 + 5
        process_metadata(key, subtitle)
        @keynum += 1
        @subtitle_map[key] = subtitle
        @subtitles << subtitle
      end

      # Find the first gap in subtitles with a minimum length in seconds.
      # @return [Array] [start, end] Start and end times of the gap
      def find_gap(min_length)
        last = 0
        @subtitles.each do |subtitle|
          return [last, subtitle.start] if subtitle.start - last >= min_length
          last = subtitle.end
        end
        [last, -1]
      end

      def init_properties
        @properties = @subtitle_map.transform_values { |i| i[:lines] }
      end

      def import(path)
        contents = read_contents(path)
        return [] if contents.blank?
        import_export_class(path).import(contents)
      end

      def export(target, _options = {})
        content = import_export_class(target).export(@subtitles) || ''
        content = content.gsub(/[\r\n]+\Z/, '') + "\n"
        target.write(content)
      end

      def import_export_class(path)
        class_name = path.extname.sub(/^\./, '').upcase
        Titlekit.const_get(class_name)
      end
    end
  end
end