class Reading::Csv::Parse::ParseLine::ParseVariants

using Util::Blank

Public Instance Methods

auto_name_from_url(url) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 140
def auto_name_from_url(url)
  return nil if url.nil?
  config.fetch(:item).fetch(:sources).fetch(:names_from_urls)
        .each do |url_part, auto_name|
          if url.include?(url_part)
            return auto_name
          end
        end
  config.fetch(:item).fetch(:sources).fetch(:default_name_for_url)
end
call(name, columns) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 13
def call(name, columns)
  format_in_name = format(name)
  length_in_length = length(columns[:length])
  extra_info_in_name = extra_info(name).presence
  sources_str = columns[:sources]&.presence || " "
  separator = if sources_str.match(config.fetch(:csv).fetch(:regex).fetch(:formats))
                config.fetch(:csv).fetch(:regex).fetch(:formats_split)
              else
                config.fetch(:csv).fetch(:long_separator)
              end
  sources_str.split(separator).map do |variant_with_extra_info|
    variant_str = variant_with_extra_info.split(config.fetch(:csv).fetch(:long_separator)).first
    variant =
      { format: format(variant_str) || format_in_name || template[:format],
        sources: sources(variant_str)                 || [],
        isbn: isbn(variant_str)                       || template[:isbn],
        length: length(variant_str,
                in_variant: true) || length_in_length || template[:length],
        extra_info: extra_info(variant_with_extra_info).presence ||
                                  extra_info_in_name || template[:extra_info] }
    if variant != template_with_empty_sources
      variant
    else
      nil
    end
  end.compact.presence || []
end
extra_info(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 76
def extra_info(str)
  separated = str.split(config.fetch(:csv).fetch(:long_separator))
  separated.delete_at(0) # everything before the extra info.
  separated.reject do |str|
    str.start_with?("#{config.fetch(:csv).fetch(:series_prefix)} ") ||
      str.match(config.fetch(:csv).fetch(:regex).fetch(:series_volume))
  end
end
format(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 49
def format(str)
  emoji = str.match(/^#{config.fetch(:csv).fetch(:regex).fetch(:formats)}/).to_s
  config.fetch(:item).fetch(:formats).key(emoji)
end
isbn(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 54
def isbn(str)
  isbns = str.scan(config.fetch(:csv).fetch(:regex).fetch(:isbn))
  if isbns.count > 1
    raise InvalidItemError, "Only one ISBN/ASIN is allowed per item variant"
  end
  isbns[0]&.to_s
end
length(str, in_variant: false) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 62
def length(str, in_variant: false)
  return nil if str.nil?
  len = str.strip
  time_length = len.match(config.fetch(:csv).fetch(:regex).fetch(:time_length))&.captures&.first
  return time_length unless time_length.nil?
  pages_length_regex =
    if in_variant
      config.fetch(:csv).fetch(:regex).fetch(:pages_length_in_variant)
    else
      config.fetch(:csv).fetch(:regex).fetch(:pages_length)
    end
  len.match(pages_length_regex)&.captures&.first&.to_i
end
source_array_to_hash(array) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 118
def source_array_to_hash(array)
  return nil if array.nil? || array.empty?
  array = [array[0].strip, array[1]&.strip]
  if valid_url?(array[0])
    if valid_url?(array[1])
      raise InvalidItemError, "Each Source must have only one one URL."
    end
    array = array.reverse
  elsif !valid_url?(array[1]) && !array[1].nil?
    raise InvalidItemError, "Invalid URL, or each Source must have only one one name."
  end
  url = array[1]
  url.chop! if url&.chars&.last == "/"
  name = array[0] || auto_name_from_url(url)
  { name: name || template.fetch(:sources).first[:name],
    url: url   || template.fetch(:sources).first[:url] }
end
sources(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 85
def sources(str)
  (sources_urls(str) + sources_names(str).map { |name| [name]})
    .map { |source_array| source_array_to_hash(source_array) }
    .compact.presence
end
sources_names(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 100
def sources_names(str)
  sources_with_commas_around_length(str)
    .gsub(config.fetch(:csv).fetch(:regex).fetch(:sources), config.fetch(:csv).fetch(:separator))
    .split(config.fetch(:csv).fetch(:separator))
    .reject do |name|
      name.match?(config.fetch(:csv).fetch(:regex).fetch(:time_length)) ||
        name.match?(config.fetch(:csv).fetch(:regex).fetch(:pages_length_in_variant))
    end
    .map { |name| name.sub(/\A\s*#{config.fetch(:csv).fetch(:regex).fetch(:formats)}\s*/, "") }
    .map(&:strip)
    .reject(&:empty?)
end
sources_urls(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 91
def sources_urls(str)
  str
    .scan(config.fetch(:csv).fetch(:regex).fetch(:sources))
    .map(&:compact)
    .reject do |source|
      source.first.match?(config.fetch(:csv).fetch(:regex).fetch(:isbn))
    end
end
sources_with_commas_around_length(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 113
def sources_with_commas_around_length(str)
  str.sub(config.fetch(:csv).fetch(:regex).fetch(:time_length), ", \\1, ")
     .sub(config.fetch(:csv).fetch(:regex).fetch(:pages_length_in_variant), ", \\1, ")
end
template() click to toggle source
# File lib/reading/csv/parse_variants.rb, line 41
def template
  @template ||= config.fetch(:item).fetch(:template).fetch(:variants).first
end
template_with_empty_sources() click to toggle source
# File lib/reading/csv/parse_variants.rb, line 45
def template_with_empty_sources
  @template_with_empty_sources ||= template.merge(sources: [])
end
valid_url?(str) click to toggle source
# File lib/reading/csv/parse_variants.rb, line 136
def valid_url?(str)
  str&.match?(/http[^\s,]+/)
end