class Opera::MobileStore::Product

Constants

FIELDS

Public Class Methods

build_from_nokogiri_node(node) click to toggle source

TODO: Move this implementation to the SDK namespace

# File lib/opera/mobile_store/product.rb, line 128
def self.build_from_nokogiri_node(node)

  # Initialize the category unless it's already in it's Identity Map:
  category_id = if (some_id = node.xpath 'number(category/@id)') && !some_id.nan?
    some_id.to_i
  end

  Category.new(
    id: category_id,
    code: node.xpath("string(category/@code)"),
    name: node.xpath("string(category)")
  ) unless category_id.blank? || Category.identity_mapped?(category_id)

  # Initialize the category unless it's already in it's Identity Map:
  author_id = node.xpath('number(author/@id)').to_i
  
  Developer.new(
    id: author_id,
    name: node.xpath("string(author)"),
    email: node.xpath("string(author_email)")
  ) unless author_id.blank? || Developer.identity_mapped?(author_id)

  data = {
    id:   node.xpath("number(@id)").to_i,
    code: node.xpath("string(@code)"),
    cp_product_id: node.xpath("number(cp_product_id)").to_i,

    category_id: category_id,
    author_id: author_id,

    app_type: node.xpath("string(apptype)"),
    released_at: DateTime.parse(node.xpath "string(release_date)"),
    download_count: node.xpath("number(downloads_count)").to_i,
    support_url: node.xpath("string(support_url)"),
    version: node.xpath("string(version)"),
    # TODO: process requirements node

    # Product localization in English:
    i18n: [
      ProductLocalization.new({
        language_code: "en",
        title: node.xpath("string(product_name)").strip,
        short_description: node.xpath("string(short_description)").strip,
        long_description: node.xpath("string(long_description)").strip
      }.select { |key, val| val.present? })
    ],

    price: node.xpath("number(price)"),
    currency: node.xpath("string(currency)"),
    product_type: node.xpath("string(type)"),
    weight: node.xpath("number(weight)").to_i,
    updated_at: DateTime.parse(node.xpath "string(update_date)"),
    added_at: DateTime.parse(node.xpath "string(add_date)"),

    keywords: node.xpath("keywords/keyword").map do |x|
      value = x.text.strip
      value.present? ? Opera::MobileStoreSDK.html_entities.decode(value) : nil
    end.compact,

    images: node.xpath("images/*").map do |i|
      ProductImage.build_from_nokogiri_node i
    end,

    builds: node.xpath("builds/build").map do |b|
      Build.build_from_nokogiri_node b
    end

  }

  node.xpath("translates/language").each do |language_node|
    data[:i18n] << ProductLocalization.new({
      # We'll ignore the "@code" attribute... only Opera Devs knows WTF with it.
      language_code: language_node.xpath("string(@iso)").strip,
      title: node.xpath("string(title)").strip,
      short_description: node.xpath("string(short_description)").strip,
      long_description: node.xpath("string(description)").strip
    }.select { |key, val| val.present? })
  end

  self.new data
end
deserialize(serializable_hash) click to toggle source
# File lib/opera/mobile_store/product.rb, line 97
def self.deserialize(serializable_hash)
  attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
    field_name, field_value = keyval

    case field_name
    when 'category'
      field_value = Category.deserialize field_value
    when 'author'
      field_value = Developer.deserialize field_value
    when 'i18n'
      field_value = field_value.map do |item_serializable_hash|
        ProductLocalization.deserialize item_serializable_hash
      end
    when 'images'
      field_value = field_value.map do |item_serializable_hash|
        ProductImage.deserialize item_serializable_hash
      end
    when 'builds' # Array of special objects
      field_value = field_value.map do |item_serializable_hash|
        Build.deserialize item_serializable_hash
      end
    end

    hsh[field_name] = field_value
    hsh
  end

  self.new attributes_hash
end

Public Instance Methods

attributes() click to toggle source
# File lib/opera/mobile_store/product.rb, line 66
def attributes
  FIELDS.inject({}) do |hsh, field_name|
    field_value = self.public_send field_name
    hsh[field_name.to_s] = field_value if field_value.present?
    hsh
  end
end
author() click to toggle source
# File lib/opera/mobile_store/product.rb, line 33
def author
  Developer.find author_id if author_id.present?
end
author=(given_author) click to toggle source
# File lib/opera/mobile_store/product.rb, line 37
def author=(given_author)
  @author_id = given_author.id
end
available_language_codes() click to toggle source
# File lib/opera/mobile_store/product.rb, line 62
def available_language_codes
  i18n.map(&:language_code)
end
category() click to toggle source
# File lib/opera/mobile_store/product.rb, line 25
def category
  Category.find category_id if category_id.present?
end
category=(given_category) click to toggle source
# File lib/opera/mobile_store/product.rb, line 29
def category=(given_category)
  @category_id = given_category.id
end
long_description(key = "en") click to toggle source
# File lib/opera/mobile_store/product.rb, line 55
def long_description(key = "en")
  required_data = i18n.detect do |x|
    x.language_code == key.to_s
  end.long_description
  required_data.present? ? required_data : long_description('en')
end
serializable_hash(options = nil) click to toggle source

Override of serializable_hash:

In the case of the category and author of a product, since we can’t query the OMS API for a single entity directly, we’ll replace the entity id field (category_id, author_id) with the serializable hash of the actual object (category, author) as part of the serializable hash:

# File lib/opera/mobile_store/product.rb, line 80
def serializable_hash(options = nil)
  attributes.inject({}) do |shsh, keyval|
    field_name, field_value = keyval

    case field_name
    when 'category_id', 'author_id'
      field_name = field_name[0..-4]
      field_value = self.send(field_name).serializable_hash
    when 'i18n', 'images', 'builds' # Array of special objects
      field_value = field_value.map(&:serializable_hash)
    end

    shsh[field_name] = field_value
    shsh
  end
end
short_description(key = "en") click to toggle source
# File lib/opera/mobile_store/product.rb, line 48
def short_description(key = "en")
  required_data = i18n.detect do |x|
    x.language_code == key.to_s
  end.short_description
  required_data.present? ? required_data : short_description('en')
end
title(key = "en") click to toggle source
# File lib/opera/mobile_store/product.rb, line 41
def title(key = "en")
  required_data = i18n.detect do |x|
    x.language_code == key.to_s
  end.title
  required_data.present? ? required_data : title('en')
end