opera-mobile-store-sdk 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/opera-mobile-store-sdk.rb +9 -1
- data/lib/opera-mobile-store-sdk/version.rb +1 -1
- data/lib/opera/mobile_store/build.rb +94 -32
- data/lib/opera/mobile_store/compatibility.rb +108 -0
- data/lib/opera/mobile_store/developer.rb +16 -0
- data/lib/opera/mobile_store/device_model.rb +39 -0
- data/lib/opera/mobile_store/device_platform.rb +95 -0
- data/lib/opera/mobile_store/device_platform_family.rb +39 -0
- data/lib/opera/mobile_store/payment_info.rb +21 -3
- data/lib/opera/mobile_store/product.rb +1 -1
- data/lib/opera/mobile_store_sdk/api_object_list.rb +4 -0
- data/lib/opera/mobile_store_sdk/faraday_middleware/response_parser.rb +26 -2
- metadata +6 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ea561cac052e9ae2e85a5b497683918571d0bb38
         | 
| 4 | 
            +
              data.tar.gz: 428415aef7a5e9bdd17fd67678ac0c813bdfa33e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3d1bf6eb12b9869995f71a43ff69f93a0ba1796c9e5345620d7066a97f1add2d804201c51613ac307a8f324109cceeb056640f5c51b0ced775a25b57843be611
         | 
| 7 | 
            +
              data.tar.gz: c490eca79640c9cac48c58141980fe03d2c28b8f82b4fd4445506dfcfc0f06ef1938c61eb1b321cb19eddd4bb33be443eeadaa923c9d0effdae796a036cced14
         | 
| @@ -9,9 +9,17 @@ module Opera | |
| 9 9 | 
             
                autoload :ProductLocalization
         | 
| 10 10 | 
             
                autoload :ProductImage
         | 
| 11 11 | 
             
                autoload :Category
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                autoload :Compatibility
         | 
| 14 | 
            +
             | 
| 12 15 | 
             
                autoload :Build
         | 
| 13 16 | 
             
                autoload :BuildFile
         | 
| 14 17 | 
             
                autoload :Developer
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                autoload :DeviceModel
         | 
| 20 | 
            +
                autoload :DevicePlatformFamily
         | 
| 21 | 
            +
                autoload :DevicePlatform
         | 
| 22 | 
            +
             | 
| 15 23 | 
             
                autoload :PaymentInfo
         | 
| 16 24 |  | 
| 17 25 | 
             
                autoload :InspectableAttributes
         | 
| @@ -44,7 +52,7 @@ module Opera | |
| 44 52 | 
             
                def self.connection
         | 
| 45 53 | 
             
                  @connection ||= Faraday.new(url: Opera::MobileStoreSDK.config.api_host) do |faraday|
         | 
| 46 54 |  | 
| 47 | 
            -
                     | 
| 55 | 
            +
                    faraday.response :logger                  # log requests to STDOUT
         | 
| 48 56 |  | 
| 49 57 | 
             
                    faraday.use MobileStoreSDK::FaradayMiddleware::RequiredResponseFormat
         | 
| 50 58 |  | 
| @@ -8,6 +8,8 @@ module Opera::MobileStore | |
| 8 8 |  | 
| 9 9 | 
             
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 10 |  | 
| 11 | 
            +
                include Opera::MobileStoreSDK::IdentityMapable
         | 
| 12 | 
            +
             | 
| 11 13 | 
             
                # All attributes are Read-Only...
         | 
| 12 14 | 
             
                attr_accessor :id,
         | 
| 13 15 | 
             
                            :name,
         | 
| @@ -20,7 +22,11 @@ module Opera::MobileStore | |
| 20 22 | 
             
                            :build_update_date,
         | 
| 21 23 | 
             
                            :files,
         | 
| 22 24 | 
             
                            :billing,
         | 
| 23 | 
            -
                            :languages
         | 
| 25 | 
            +
                            :languages,
         | 
| 26 | 
            +
                            :uses_sdk,
         | 
| 27 | 
            +
                            :supported_screens,
         | 
| 28 | 
            +
                            :used_permissions,
         | 
| 29 | 
            +
                            :locales
         | 
| 24 30 |  | 
| 25 31 | 
             
                def files
         | 
| 26 32 | 
             
                  @files ||= []
         | 
| @@ -34,11 +40,32 @@ module Opera::MobileStore | |
| 34 40 | 
             
                  @billing ||= false
         | 
| 35 41 | 
             
                end
         | 
| 36 42 |  | 
| 43 | 
            +
                def compatibility
         | 
| 44 | 
            +
                  @compatibility ||= begin
         | 
| 45 | 
            +
                    compat_query = Opera::MobileStore::Compatibility.where(build_id: id)
         | 
| 46 | 
            +
                    compat = compat_query.first
         | 
| 47 | 
            +
                    if uses_sdk.present?
         | 
| 48 | 
            +
                      compat.min_sdk_version = uses_sdk.min
         | 
| 49 | 
            +
                      compat.max_sdk_version = uses_sdk.max
         | 
| 50 | 
            +
                      compat.target_sdk_version = uses_sdk.target
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                    compat
         | 
| 53 | 
            +
                  end if id.present?
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def min_sdk_version
         | 
| 57 | 
            +
                  @min_sdk_version ||= if uses_sdk.present?
         | 
| 58 | 
            +
                    uses_sdk.min
         | 
| 59 | 
            +
                  else
         | 
| 60 | 
            +
                    compatibility.min_sdk_version
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 37 64 | 
             
                def attributes
         | 
| 38 65 | 
             
                  [
         | 
| 39 66 | 
             
                    :id, :name, :platform, :type, :installer_type, :package_name,
         | 
| 40 67 | 
             
                    :version_name, :version_code, :build_update_date, :files, :billing,
         | 
| 41 | 
            -
                    :languages
         | 
| 68 | 
            +
                    :languages, :uses_sdk, :supported_screens, :used_permissions, :locales
         | 
| 42 69 | 
             
                  ].inject({}) do |hash, field_name|
         | 
| 43 70 | 
             
                    field_value = self.public_send field_name
         | 
| 44 71 | 
             
                    hash[field_name.to_s] = field_value if field_value.present?
         | 
| @@ -53,7 +80,10 @@ module Opera::MobileStore | |
| 53 80 | 
             
                  attributes.inject({}) do |shsh, keyval|
         | 
| 54 81 | 
             
                    field_name, field_value = keyval
         | 
| 55 82 |  | 
| 56 | 
            -
                     | 
| 83 | 
            +
                    case field_name
         | 
| 84 | 
            +
                    when 'uses_sdk'
         | 
| 85 | 
            +
                      field_value = field_value.serializable_hash
         | 
| 86 | 
            +
                    when 'files' # Array of special objects
         | 
| 57 87 | 
             
                      field_value = field_value.map(&:serializable_hash)
         | 
| 58 88 | 
             
                    end
         | 
| 59 89 |  | 
| @@ -62,6 +92,24 @@ module Opera::MobileStore | |
| 62 92 | 
             
                  end
         | 
| 63 93 | 
             
                end
         | 
| 64 94 |  | 
| 95 | 
            +
                def self.deserialize(serializable_hash)
         | 
| 96 | 
            +
                  attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
         | 
| 97 | 
            +
                    field_name, field_value = keyval
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    case field_name
         | 
| 100 | 
            +
                    when 'files'
         | 
| 101 | 
            +
                      field_value = field_value.map do |item_serializable_hash|
         | 
| 102 | 
            +
                        BuildFile.deserialize item_serializable_hash
         | 
| 103 | 
            +
                      end
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    hsh[field_name] = field_value
         | 
| 107 | 
            +
                    hsh
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  self.new attributes_hash
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 65 113 | 
             
                def self.build_from_nokogiri_node(node)
         | 
| 66 114 |  | 
| 67 115 | 
             
                  version_code = node.xpath("string(version_code)")
         | 
| @@ -76,49 +124,63 @@ module Opera::MobileStore | |
| 76 124 | 
             
                    version_name: node.xpath("string(version_name)").strip,
         | 
| 77 125 | 
             
                    version_code: version_code.present? ? version_code.to_i : nil,
         | 
| 78 126 | 
             
                    build_update_date: Time.parse(node.xpath "string(build_update_date)"),
         | 
| 79 | 
            -
                  }.select { |key, val| val.present? }
         | 
| 80 127 |  | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 128 | 
            +
                    files: node.xpath("files/file").map do |f|
         | 
| 129 | 
            +
                      BuildFile.build_from_nokogiri_node f
         | 
| 130 | 
            +
                    end,
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                    languages: node.xpath("languages/language").map do |language|
         | 
| 133 | 
            +
                      language.attributes["code"].to_s.strip
         | 
| 134 | 
            +
                    end,
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                    supported_screens: node.xpath("supports_screens/screen").map do |scr|
         | 
| 137 | 
            +
                      scr.text.strip
         | 
| 138 | 
            +
                    end,
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    used_permissions: node.xpath("uses_permissions/permission").map do |per|
         | 
| 141 | 
            +
                      per.text.strip
         | 
| 142 | 
            +
                    end,
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                    locales: node.xpath("locales/locale").map do |locale_node|
         | 
| 145 | 
            +
                      locale_node.text.strip
         | 
| 146 | 
            +
                    end
         | 
| 147 | 
            +
                  }.select { |key, val| val.present? }
         | 
| 84 148 |  | 
| 85 149 | 
             
                  data[:billing] = node.xpath("string(billing)").to_i > 0
         | 
| 86 150 |  | 
| 87 | 
            -
                   | 
| 88 | 
            -
             | 
| 151 | 
            +
                  uses_sdk_node = node.xpath("uses_sdk").first
         | 
| 152 | 
            +
                  if uses_sdk_node.present?
         | 
| 153 | 
            +
                    uses_sdk_attributes = {
         | 
| 154 | 
            +
                      min:    uses_sdk_node.xpath("string(@min)").strip,
         | 
| 155 | 
            +
                      target: uses_sdk_node.xpath("string(@target)").strip,
         | 
| 156 | 
            +
                      max:    uses_sdk_node.xpath("string(@max)").strip
         | 
| 157 | 
            +
                    }.select { |k,v| v.present? }.inject({}) do |hsh, keyval|
         | 
| 158 | 
            +
                      key, val = keyval
         | 
| 159 | 
            +
                      hsh[key] = val.to_i
         | 
| 160 | 
            +
                      hsh
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                    data[:uses_sdk] = UsesSDK.new uses_sdk_attributes
         | 
| 89 163 | 
             
                  end
         | 
| 90 164 |  | 
| 91 165 | 
             
                  self.new data
         | 
| 92 166 | 
             
                end
         | 
| 93 167 |  | 
| 94 | 
            -
                 | 
| 95 | 
            -
                   | 
| 96 | 
            -
             | 
| 97 | 
            -
                    :version_name, :version_code, :build_update_date, :files, :billing,
         | 
| 98 | 
            -
                    :languages
         | 
| 99 | 
            -
                  ].inject({}) do |hash, field_name|
         | 
| 100 | 
            -
                    field_value = self.public_send field_name
         | 
| 101 | 
            -
                    hash[field_name.to_s] = field_value if field_value.present?
         | 
| 102 | 
            -
                    hash
         | 
| 103 | 
            -
                  end
         | 
| 104 | 
            -
                end
         | 
| 168 | 
            +
                class UsesSDK
         | 
| 169 | 
            +
                  include ActiveModel::Model
         | 
| 170 | 
            +
                  include ActiveModel::Serialization
         | 
| 105 171 |  | 
| 106 | 
            -
             | 
| 107 | 
            -
                  attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
         | 
| 108 | 
            -
                    field_name, field_value = keyval
         | 
| 172 | 
            +
                  include Opera::MobileStore::InspectableAttributes
         | 
| 109 173 |  | 
| 110 | 
            -
             | 
| 111 | 
            -
                    when 'files'
         | 
| 112 | 
            -
                      field_value = field_value.map do |item_serializable_hash|
         | 
| 113 | 
            -
                        BuildFile.deserialize item_serializable_hash
         | 
| 114 | 
            -
                      end
         | 
| 115 | 
            -
                    end
         | 
| 174 | 
            +
                  attr_accessor :min, :target, :max
         | 
| 116 175 |  | 
| 117 | 
            -
             | 
| 118 | 
            -
                     | 
| 176 | 
            +
                  def attributes
         | 
| 177 | 
            +
                    [:min, :target, :max].inject({}) do |hash, field_name|
         | 
| 178 | 
            +
                      field_value = self.public_send field_name
         | 
| 179 | 
            +
                      hash[field_name.to_s] = field_value if field_value.present?
         | 
| 180 | 
            +
                      hash
         | 
| 181 | 
            +
                    end
         | 
| 119 182 | 
             
                  end
         | 
| 120 183 |  | 
| 121 | 
            -
                  self.new attributes_hash
         | 
| 122 184 | 
             
                end
         | 
| 123 185 |  | 
| 124 186 | 
             
              end
         | 
| @@ -0,0 +1,108 @@ | |
| 1 | 
            +
            require "active_model"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Opera::MobileStore
         | 
| 4 | 
            +
              class Compatibility
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                include ActiveModel::Model
         | 
| 7 | 
            +
                include ActiveModel::Serialization
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                include Opera::MobileStoreSDK::APIAccessible
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # All attributes are Read-Only...
         | 
| 14 | 
            +
                attr_accessor :model_ids, :platform_ids, :platform_family_ids, :product_id,
         | 
| 15 | 
            +
                              :build_id,
         | 
| 16 | 
            +
                              :min_sdk_version, :target_sdk_version, :max_sdk_version
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def attributes
         | 
| 19 | 
            +
                  [
         | 
| 20 | 
            +
                    :model_ids, :platform_ids, :platform_family_ids, :product_id, :build_id,
         | 
| 21 | 
            +
                    :min_sdk_version, :target_sdk_version, :max_sdk_version
         | 
| 22 | 
            +
                  ].inject({}) do |hash, field_name|
         | 
| 23 | 
            +
                    field_value = self.public_send field_name
         | 
| 24 | 
            +
                    hash[field_name.to_s] = field_value unless field_value.nil?
         | 
| 25 | 
            +
                    hash
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def min_sdk_version
         | 
| 30 | 
            +
                  @min_sdk_version ||= platforms.map(&:android_sdk_level).compact.min
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def models
         | 
| 34 | 
            +
                  model_ids.map { |model_id| DeviceModel.find model_id }
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def platforms
         | 
| 38 | 
            +
                  platform_ids.map { |platform_id| DevicePlatform.find platform_id }
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def platform_families
         | 
| 42 | 
            +
                  platform_family_ids.map do |platform_family_id|
         | 
| 43 | 
            +
                    DevicePlatform.find platform_family_id
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def build
         | 
| 48 | 
            +
                  Build.find build_id if build_id.present?
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                self.singleton_class.send :alias_method, :deserialize, :new
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                # TODO: Move this implementation to the SDK namespace
         | 
| 54 | 
            +
                def self.build_from_nokogiri_node(node)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  t_node = node.xpath("build").first || node.xpath("product").first
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  ref_key = case t_node.node_name
         | 
| 59 | 
            +
                  when 'build' then :build_id
         | 
| 60 | 
            +
                  when 'product' then :product_id
         | 
| 61 | 
            +
                  else raise "No recognizable compatibility parent"
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  # parse the rest of the data:
         | 
| 65 | 
            +
                  data = {
         | 
| 66 | 
            +
                    ref_key => t_node.xpath("number(@id)").to_i,
         | 
| 67 | 
            +
                    model_ids: t_node.xpath("models/model").map do |model_node|
         | 
| 68 | 
            +
                      device_model_id = model_node.xpath("number(@id)").to_i
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                      DeviceModel.new(
         | 
| 71 | 
            +
                        id:   device_model_id,
         | 
| 72 | 
            +
                        code: model_node.xpath("string(@code)").strip,
         | 
| 73 | 
            +
                        name: model_node.text.strip
         | 
| 74 | 
            +
                      ) unless DeviceModel.identity_mapped? device_model_id
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      device_model_id
         | 
| 77 | 
            +
                    end,
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    platform_ids: t_node.xpath("platforms/platform").map do |platform_node|
         | 
| 80 | 
            +
                      device_platform_id = platform_node.xpath("number(@id)").to_i
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                      DevicePlatform.new(
         | 
| 83 | 
            +
                        id:   device_platform_id,
         | 
| 84 | 
            +
                        code: platform_node.xpath("string(@code)").strip,
         | 
| 85 | 
            +
                        name: platform_node.text.strip
         | 
| 86 | 
            +
                      ) unless DevicePlatform.identity_mapped? device_platform_id
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      device_platform_id
         | 
| 89 | 
            +
                    end,
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    platform_family_ids: t_node.xpath("platform_families/platform_family").map do |platform_family_node|
         | 
| 92 | 
            +
                      platform_family_id = platform_family_node.xpath("number(@id)").to_i
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                      DevicePlatformFamily.new(
         | 
| 95 | 
            +
                        id:   platform_family_id,
         | 
| 96 | 
            +
                        code: platform_family_node.xpath("string(@code)").strip,
         | 
| 97 | 
            +
                        name: platform_family_node.text.strip
         | 
| 98 | 
            +
                      ) unless DevicePlatformFamily.identity_mapped? platform_family_id
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                      platform_family_id
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
                  }
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  self.new data
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              end
         | 
| 108 | 
            +
            end
         | 
| @@ -68,5 +68,21 @@ module Opera::MobileStore | |
| 68 68 | 
             
                  self.new data
         | 
| 69 69 | 
             
                end
         | 
| 70 70 |  | 
| 71 | 
            +
                def self.deserialize(serializable_hash)
         | 
| 72 | 
            +
                  attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
         | 
| 73 | 
            +
                    field_name, field_value = keyval
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    case field_name
         | 
| 76 | 
            +
                    when 'payment_info'
         | 
| 77 | 
            +
                      field_value = PaymentInfo.deserialize field_value
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    hsh[field_name] = field_value
         | 
| 81 | 
            +
                    hsh
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  self.new attributes_hash
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 71 87 | 
             
              end
         | 
| 72 88 | 
             
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require "active_model"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Opera::MobileStore
         | 
| 4 | 
            +
              class DeviceModel
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                include ActiveModel::Model
         | 
| 7 | 
            +
                include ActiveModel::Serialization
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                include Opera::MobileStoreSDK::IdentityMapable
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                include Opera::MobileStoreSDK::APIAccessible
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # All attributes are Read-Only...
         | 
| 16 | 
            +
                attr_accessor :id, :code, :name
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def attributes
         | 
| 19 | 
            +
                  [:id, :code, :name].inject({}) do |hash, field_name|
         | 
| 20 | 
            +
                    field_value = self.public_send field_name
         | 
| 21 | 
            +
                    hash[field_name.to_s] = field_value unless field_value.nil?
         | 
| 22 | 
            +
                    hash
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                self.singleton_class.send :alias_method, :deserialize, :new
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def self.build_from_nokogiri_node(node)
         | 
| 29 | 
            +
                  data = {
         | 
| 30 | 
            +
                    id:   node.xpath("number(@id)").to_i,
         | 
| 31 | 
            +
                    code: node.xpath("string(@code)").strip,
         | 
| 32 | 
            +
                    name: node.text.strip
         | 
| 33 | 
            +
                  }.select { |key, val| val.present? }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  self.new data
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            require "active_model"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Opera::MobileStore
         | 
| 4 | 
            +
              class DevicePlatform
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                include ActiveModel::Model
         | 
| 7 | 
            +
                include ActiveModel::Serialization
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                include Opera::MobileStoreSDK::IdentityMapable
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                include Opera::MobileStoreSDK::APIAccessible
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                OPERA_PLATFORM_TO_ANDROID_SDK_MAPPINGS = {
         | 
| 16 | 
            +
                  'platform-android-1-0' => 1,
         | 
| 17 | 
            +
                  'platform-android-1-1' => 2,
         | 
| 18 | 
            +
                  'platform-android-1-5' => 3,
         | 
| 19 | 
            +
                  'platform-android-1-6' => 4,
         | 
| 20 | 
            +
                  'platform-android-2-0' => 5,
         | 
| 21 | 
            +
                  'platform-android-2-0-1' => 6,
         | 
| 22 | 
            +
                  'platform-android-2-1' => 7,
         | 
| 23 | 
            +
                  'platform-android-2-2' => 8,
         | 
| 24 | 
            +
                  'platform-android-2-3' => 9,
         | 
| 25 | 
            +
                  'platform-android-2-3-3-plus' => 10,
         | 
| 26 | 
            +
                  'platform-android-3-0' => 11,
         | 
| 27 | 
            +
                  'platform-android-3-1' => 12,
         | 
| 28 | 
            +
                  'platform-android-3-2' => 13,
         | 
| 29 | 
            +
                  'platform-android-4-0' => 14,
         | 
| 30 | 
            +
                  'platform-android-4-0-3-plus' => 15,
         | 
| 31 | 
            +
                  'platform-android-4-1-plus' => 16,
         | 
| 32 | 
            +
                  'platform-android-4-2-plus' => 17,
         | 
| 33 | 
            +
                  'platform-android-4-3' => 18,
         | 
| 34 | 
            +
                  'platform-android-4-4' => 19,
         | 
| 35 | 
            +
                  'platform-android-4-4-plus' => 20
         | 
| 36 | 
            +
                }.freeze
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                ANDROID_SDK_LEVEL_VERSION_CODES = {
         | 
| 39 | 
            +
                  22 => 'LOLLIPOP_MR1',
         | 
| 40 | 
            +
                  21 => 'LOLLIPOP',
         | 
| 41 | 
            +
                  20 => 'KITKAT_WATCH',
         | 
| 42 | 
            +
                  19 => 'KITKAT',
         | 
| 43 | 
            +
                  18 => 'JELLY_BEAN_MR2',
         | 
| 44 | 
            +
                  17 => 'JELLY_BEAN_MR1',
         | 
| 45 | 
            +
                  16 => 'JELLY_BEAN',
         | 
| 46 | 
            +
                  15 => 'ICE_CREAM_SANDWICH_MR1',
         | 
| 47 | 
            +
                  14 => 'ICE_CREAM_SANDWICH',
         | 
| 48 | 
            +
                  13 => 'HONEYCOMB_MR2',
         | 
| 49 | 
            +
                  12 => 'HONEYCOMB_MR1',
         | 
| 50 | 
            +
                  11 => 'HONEYCOMB',
         | 
| 51 | 
            +
                  10 => 'GINGERBREAD_MR1',
         | 
| 52 | 
            +
                   9 => 'GINGERBREAD',
         | 
| 53 | 
            +
                   8 => 'FROYO',
         | 
| 54 | 
            +
                   7 => 'ECLAIR',
         | 
| 55 | 
            +
                   6 => 'ECLAIR_0_1',
         | 
| 56 | 
            +
                   5 => 'ECLAIR',
         | 
| 57 | 
            +
                   4 => 'DONUT',
         | 
| 58 | 
            +
                   3 => 'CUPCAKE',
         | 
| 59 | 
            +
                   2 => 'BASE_1_1',
         | 
| 60 | 
            +
                   1 => 'BASE'
         | 
| 61 | 
            +
                }.freeze
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # All attributes are Read-Only...
         | 
| 64 | 
            +
                attr_accessor :id, :code, :name
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def attributes
         | 
| 67 | 
            +
                  [:id, :code, :name].inject({}) do |hash, field_name|
         | 
| 68 | 
            +
                    field_value = self.public_send field_name
         | 
| 69 | 
            +
                    hash[field_name.to_s] = field_value unless field_value.nil?
         | 
| 70 | 
            +
                    hash
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def android_sdk_level
         | 
| 75 | 
            +
                  OPERA_PLATFORM_TO_ANDROID_SDK_MAPPINGS[code] if code['platform-android'].present?
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def android_version_code
         | 
| 79 | 
            +
                  ANDROID_SDK_LEVEL_VERSION_CODES[android_sdk_level]
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                self.singleton_class.send :alias_method, :deserialize, :new
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                def self.build_from_nokogiri_node(node)
         | 
| 85 | 
            +
                  data = {
         | 
| 86 | 
            +
                    id:   node.xpath("number(@id)").to_i,
         | 
| 87 | 
            +
                    code: node.xpath("string(@code)").strip,
         | 
| 88 | 
            +
                    name: node.text.strip
         | 
| 89 | 
            +
                  }.select { |key, val| val.present? }
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  self.new data
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require "active_model"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Opera::MobileStore
         | 
| 4 | 
            +
              class DevicePlatformFamily
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                include ActiveModel::Model
         | 
| 7 | 
            +
                include ActiveModel::Serialization
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                include Opera::MobileStoreSDK::IdentityMapable
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                include Opera::MobileStoreSDK::APIAccessible
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # All attributes are Read-Only...
         | 
| 16 | 
            +
                attr_accessor :id, :code, :name
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def attributes
         | 
| 19 | 
            +
                  [:id, :code, :name].inject({}) do |hash, field_name|
         | 
| 20 | 
            +
                    field_value = self.public_send field_name
         | 
| 21 | 
            +
                    hash[field_name.to_s] = field_value unless field_value.nil?
         | 
| 22 | 
            +
                    hash
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                self.singleton_class.send :alias_method, :deserialize, :new
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def self.build_from_nokogiri_node(node)
         | 
| 29 | 
            +
                  data = {
         | 
| 30 | 
            +
                    id:   node.xpath("number(@id)").to_i,
         | 
| 31 | 
            +
                    code: node.xpath("string(@code)").strip,
         | 
| 32 | 
            +
                    name: node.text.strip
         | 
| 33 | 
            +
                  }.select { |key, val| val.present? }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  self.new data
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -9,7 +9,8 @@ module Opera::MobileStore | |
| 9 9 | 
             
                include Opera::MobileStore::InspectableAttributes
         | 
| 10 10 |  | 
| 11 11 | 
             
                def type
         | 
| 12 | 
            -
                  self.class.name.demodulize.downcase
         | 
| 12 | 
            +
                  ref_type = self.class.name.demodulize.downcase
         | 
| 13 | 
            +
                  ref_type == 'pay_pal' ? 'paypal' : ref_type
         | 
| 13 14 | 
             
                end
         | 
| 14 15 |  | 
| 15 16 | 
             
                def self.build_from_nokogiri_node(node)
         | 
| @@ -26,6 +27,22 @@ module Opera::MobileStore | |
| 26 27 | 
             
                  end
         | 
| 27 28 | 
             
                end
         | 
| 28 29 |  | 
| 30 | 
            +
                def self.deserialize(serializable_hash)
         | 
| 31 | 
            +
                  attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
         | 
| 32 | 
            +
                    field_name, field_value = keyval
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    case field_name
         | 
| 35 | 
            +
                    when 'payment_info'
         | 
| 36 | 
            +
                      field_value = PaymentInfo.deserialize field_value
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    hsh[field_name] = field_value
         | 
| 40 | 
            +
                    hsh
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  self.new attributes_hash
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 29 46 | 
             
                class Check < PaymentInfo
         | 
| 30 47 | 
             
                  attr_accessor :name, :address
         | 
| 31 48 |  | 
| @@ -37,7 +54,7 @@ module Opera::MobileStore | |
| 37 54 | 
             
                  end
         | 
| 38 55 |  | 
| 39 56 | 
             
                  def attributes
         | 
| 40 | 
            -
                    [:name, :address].inject({}) do |hash, method|
         | 
| 57 | 
            +
                    [:type, :name, :address].inject({}) do |hash, method|
         | 
| 41 58 | 
             
                      value = self.public_send method
         | 
| 42 59 | 
             
                      hash[method] = value unless value.nil?
         | 
| 43 60 | 
             
                      hash
         | 
| @@ -73,6 +90,7 @@ module Opera::MobileStore | |
| 73 90 |  | 
| 74 91 | 
             
                  def attributes
         | 
| 75 92 | 
             
                    [
         | 
| 93 | 
            +
                      :type,
         | 
| 76 94 | 
             
                      :bank_account, :bank_name, :bank_address, :bank_swiftbic, :bank_iban,
         | 
| 77 95 | 
             
                      :bank_routing_number, :intermediary_bank_name, :intermediary_bank_address,
         | 
| 78 96 | 
             
                      :intermediary_bank_swiftbic, :intermediary_bank_iban
         | 
| @@ -91,7 +109,7 @@ module Opera::MobileStore | |
| 91 109 | 
             
                  end
         | 
| 92 110 |  | 
| 93 111 | 
             
                  def attributes
         | 
| 94 | 
            -
                    { account: account }
         | 
| 112 | 
            +
                    { type: 'paypal', account: account }
         | 
| 95 113 | 
             
                  end
         | 
| 96 114 | 
             
                end
         | 
| 97 115 |  | 
| @@ -102,7 +102,7 @@ module Opera::MobileStore | |
| 102 102 | 
             
                    when 'category'
         | 
| 103 103 | 
             
                      field_value = Category.deserialize field_value
         | 
| 104 104 | 
             
                    when 'author'
         | 
| 105 | 
            -
                      field_value =  | 
| 105 | 
            +
                      field_value = Developer.deserialize field_value
         | 
| 106 106 | 
             
                    when 'i18n'
         | 
| 107 107 | 
             
                      field_value = field_value.map do |item_serializable_hash|
         | 
| 108 108 | 
             
                        ProductLocalization.deserialize item_serializable_hash
         | 
| @@ -165,6 +165,10 @@ module Opera | |
| 165 165 | 
             
                    def action_param
         | 
| 166 166 | 
             
                      @_action_param ||= case @klass
         | 
| 167 167 | 
             
                        when "Opera::MobileStore::Developer" then "full_developers"
         | 
| 168 | 
            +
                        when "Opera::MobileStore::Compatibility" then "compatibility"
         | 
| 169 | 
            +
                        when "Opera::MobileStore::DeviceModel" then "models"
         | 
| 170 | 
            +
                        when "Opera::MobileStore::DevicePlatform" then "platforms"
         | 
| 171 | 
            +
                        when "Opera::MobileStore::DevicePlatformFamily" then "platform_families"
         | 
| 168 172 | 
             
                        else @klass.demodulize.underscore.pluralize
         | 
| 169 173 | 
             
                      end
         | 
| 170 174 | 
             
                    end
         | 
| @@ -22,10 +22,34 @@ module Opera | |
| 22 22 |  | 
| 23 23 | 
             
                          real_root_name = xml_data.xpath("name(/xml/*)")
         | 
| 24 24 |  | 
| 25 | 
            -
                          parser_class =  | 
| 25 | 
            +
                          parser_class = case real_root_name
         | 
| 26 | 
            +
                          when "platforms"
         | 
| 27 | 
            +
                            Opera::MobileStore::DevicePlatform
         | 
| 28 | 
            +
                          when "platform_families"
         | 
| 29 | 
            +
                            Opera::MobileStore::DevicePlatformFamily
         | 
| 30 | 
            +
                          else
         | 
| 31 | 
            +
                            "Opera::MobileStore::#{real_root_name.classify}".safe_constantize
         | 
| 32 | 
            +
                          end
         | 
| 26 33 |  | 
| 27 34 | 
             
                          # Parse each node:
         | 
| 28 | 
            -
                          collection_path = "/xml/#{real_root_name} | 
| 35 | 
            +
                          collection_path = "/xml/#{real_root_name}"
         | 
| 36 | 
            +
                          collection_path += case real_root_name
         | 
| 37 | 
            +
                          when "compatibility"
         | 
| 38 | 
            +
                            # Add the product id to the compatibility child nodes if
         | 
| 39 | 
            +
                            # a product compatibility was queried instead of a build compat:
         | 
| 40 | 
            +
                            product_param = request_env.url.query[/product_id=(\d+)/i]
         | 
| 41 | 
            +
                            if product_param.present?
         | 
| 42 | 
            +
                              product_id = product_param.split('=').last.to_i
         | 
| 43 | 
            +
                              xml_data.xpath("#{collection_path}/product").each do |product_compat_node|
         | 
| 44 | 
            +
                                product_compat_node.set_attribute('id', product_id)
         | 
| 45 | 
            +
                              end
         | 
| 46 | 
            +
                            end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                            # Return an empty string...
         | 
| 49 | 
            +
                            ""
         | 
| 50 | 
            +
                          else
         | 
| 51 | 
            +
                            "/#{real_root_name.singularize}"
         | 
| 52 | 
            +
                          end
         | 
| 29 53 |  | 
| 30 54 | 
             
                          parsed_data = xml_data.xpath(collection_path).map do |item_node|
         | 
| 31 55 | 
             
                            parser_class.build_from_nokogiri_node item_node
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: opera-mobile-store-sdk
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Roberto Quintanilla
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-04- | 
| 11 | 
            +
            date: 2015-04-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -130,7 +130,11 @@ files: | |
| 130 130 | 
             
            - lib/opera/mobile_store/build.rb
         | 
| 131 131 | 
             
            - lib/opera/mobile_store/build_file.rb
         | 
| 132 132 | 
             
            - lib/opera/mobile_store/category.rb
         | 
| 133 | 
            +
            - lib/opera/mobile_store/compatibility.rb
         | 
| 133 134 | 
             
            - lib/opera/mobile_store/developer.rb
         | 
| 135 | 
            +
            - lib/opera/mobile_store/device_model.rb
         | 
| 136 | 
            +
            - lib/opera/mobile_store/device_platform.rb
         | 
| 137 | 
            +
            - lib/opera/mobile_store/device_platform_family.rb
         | 
| 134 138 | 
             
            - lib/opera/mobile_store/inspectable_attributes.rb
         | 
| 135 139 | 
             
            - lib/opera/mobile_store/payment_info.rb
         | 
| 136 140 | 
             
            - lib/opera/mobile_store/product.rb
         |