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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7580c98f69eaa74be9332b97b6c508f6189b5e0e
4
- data.tar.gz: 0aa75ee6c1c38dcf970acd47116ec627bec85549
3
+ metadata.gz: ea561cac052e9ae2e85a5b497683918571d0bb38
4
+ data.tar.gz: 428415aef7a5e9bdd17fd67678ac0c813bdfa33e
5
5
  SHA512:
6
- metadata.gz: 9565ba3b577af06ec4a9532d1982ebb90c42152dd7f8f6ef66a977934b5d593a183534dd0420900c27cfb42409aceaca2d174fae3a0d62f021a6ee281f87f3e2
7
- data.tar.gz: bfed336b46f33cf1aabf435807b77fafdcd54229c2d078c3465fb81a55438a4e486ccb86e5d98a537a4e6f6f0ff3a8cddaedb5c1d3baf722cc5fdaa4260f84e3
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
- # faraday.response :logger # log requests to STDOUT
55
+ faraday.response :logger # log requests to STDOUT
48
56
 
49
57
  faraday.use MobileStoreSDK::FaradayMiddleware::RequiredResponseFormat
50
58
 
@@ -1,5 +1,5 @@
1
1
  module Opera
2
2
  module MobileStoreSDK
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
@@ -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
- if field_name == 'files' # Array of special objects
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
- data[:files] = node.xpath("files/file").map do |f|
82
- BuildFile.build_from_nokogiri_node f
83
- end
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
- data[:languages] = node.xpath("languages/language").map do |language|
88
- language.attributes["code"].to_s.strip
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
- def attributes
95
- [
96
- :id, :name, :platform, :type, :installer_type, :package_name,
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
- def self.deserialize(serializable_hash)
107
- attributes_hash = serializable_hash.inject({}) do |hsh, keyval|
108
- field_name, field_value = keyval
172
+ include Opera::MobileStore::InspectableAttributes
109
173
 
110
- case field_name
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
- hsh[field_name] = field_value
118
- hsh
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 = Author.deserialize 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 = "Opera::MobileStore::#{real_root_name.classify}".safe_constantize
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}/#{real_root_name.singularize}"
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.2
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-23 00:00:00.000000000 Z
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