app-info 2.6.4 → 2.7.0.beta5

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
  SHA256:
3
- metadata.gz: f97c42670196b47aacccbaf9fcee52b7bd4a8e3f21cd2f1f8c8ccfb5fdd7f3dc
4
- data.tar.gz: 6f6a3dad1fdf80548e9d65a6ca84df7ac5a2123081e08912546202b8c03ef026
3
+ metadata.gz: 87af7ee3238f0c866c3d4ad7110bba74ae1950e28f1619049ec52470253bf45a
4
+ data.tar.gz: 8eeaaa20c0f5e4036e2c2138f51f42554d0e5b73dc340c9a71ea9ce344d0c55a
5
5
  SHA512:
6
- metadata.gz: f11aea895a604a5cd9452e923a028514dfa36853c4ec7448b7d0dade327a63815c326aff4aa5532514c0b2f90dd966a688feef2f01c709b5d98a182ce81dbadd
7
- data.tar.gz: 54be915b94a47906df35e4149b99136a1bc82da6549890b01a5dd60320208ebd2ccd35fc70b32620a7a2f56f6f6f1566411dca27f9d7aac09d4512051f713d24
6
+ metadata.gz: c61cf34da0123d9cd6e0df63f3f342d61858c3dfc9dfd8e57cfce7a18af9bae5fbc85b8a20e79a9e8b54a630b240105ce036b0f03c49fd96df8945fa472ae148
7
+ data.tar.gz: ae7f4064095ad2c1518095876532c7c6364a785209fefb9e8fbf1fa7c3fe02fe3027df20572db55b5fb72d8cdadd70e59738ec0458a3fd391c264b168f744ff5
data/.rubocop.yml CHANGED
@@ -20,10 +20,12 @@ AllCops:
20
20
  Exclude:
21
21
  - 'bin/*'
22
22
  - 'spec/**/*'
23
- - vendor/bundle/**/*
23
+ - 'vendor/bundle/**/*'
24
24
  - 'Rakefile'
25
25
  - 'app_info.gemspec'
26
26
  - 'lib/app-info.rb'
27
+ - 'lib/app_info/protobuf/models/*_pb.rb'
28
+ - 'main.rb'
27
29
 
28
30
  Metrics/AbcSize:
29
31
  Max: 100
@@ -56,4 +58,19 @@ Lint/AssignmentInCondition:
56
58
  Enabled: false
57
59
 
58
60
  Style/Documentation:
59
- Enabled: false
61
+ Enabled: false
62
+
63
+ Style/PerlBackrefs:
64
+ Exclude:
65
+ - 'lib/app_info/core_ext/string/inflector.rb'
66
+
67
+ Style/DocumentDynamicEvalDefinition:
68
+ Enabled: false
69
+
70
+ Metrics/BlockNesting:
71
+ Exclude:
72
+ - 'lib/app_info/dsym.rb'
73
+
74
+
75
+ Style/SlicingWithRange:
76
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -9,6 +9,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
9
9
 
10
10
  > List all changes before release a new version.
11
11
 
12
+ ## [2.7.0.beta5] (2021-10-14)
13
+
14
+ ### Fixed
15
+
16
+ - Renamed methods of inflector (Conflicts with similar external methods, such like ActiveSupport Core Extensions)
17
+ - Keep same behavior methods between apk and aab
18
+
19
+ ## [2.7.0.beta2] (2021-09-29)
20
+
21
+ ### Fixed
22
+
23
+ - Fix allocator undefined data class [#38](https://github.com/icyleaf/app_info/pull/38)
24
+
25
+ ## [2.7.0.beta1] (2021-09-27)
26
+
27
+ ### Added
28
+
29
+ - Android App Bundle a.k.a `aab` file parts support [#36](https://github.com/icyleaf/app_info/pull/36)
30
+
31
+ ## [2.6.5] (2021-09-17)
32
+
33
+ ### Added
34
+
35
+ - Add ability to retrieve manifest metadata (depend on playtestcloud/ruby_apk forked one)
36
+
12
37
  ## [2.6.4] (2021-09-10)
13
38
 
14
39
  ### Fixed
@@ -179,7 +204,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
179
204
 
180
205
  - Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
181
206
 
182
- [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.6.4..HEAD
207
+ [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.7.0.beta5..HEAD
208
+ [2.7.0.beta5]: https://github.com/icyleaf/app-info/compare/v2.7.0.beta2...v2.7.0.beta5
209
+ [2.7.0.beta2]: https://github.com/icyleaf/app-info/compare/v2.7.0.beta1...v2.7.0.beta2
210
+ [2.7.0.beta1]: https://github.com/icyleaf/app-info/compare/v2.6.5...v2.7.0.beta1
211
+ [2.6.5]: https://github.com/icyleaf/app-info/compare/v2.6.4...v2.6.5
183
212
  [2.6.4]: https://github.com/icyleaf/app-info/compare/v2.6.3...v2.6.4
184
213
  [2.6.3]: https://github.com/icyleaf/app-info/compare/v2.6.1...v2.6.3
185
214
  [2.6.1]: https://github.com/icyleaf/app-info/compare/v2.6.0...v2.6.1
data/README.md CHANGED
@@ -5,16 +5,18 @@
5
5
  [![Gem version](https://img.shields.io/gem/v/app-info.svg?style=flat)](https://rubygems.org/gems/app_info)
6
6
  [![License](https://img.shields.io/badge/license-MIT-red.svg?style=flat)](LICENSE)
7
7
 
8
- Teardown tool for mobile(ipa/apk) app, macOS app and dSYM.zip file, analysis metedata like version, name, icon etc.
8
+ Teardown tool for mobile app (ipa, apk and aab file), macOS app and dSYM.zip file, analysis metedata like version, name, icon etc.
9
9
 
10
10
  ## Support
11
11
 
12
- - Android apk file
12
+ - Android file
13
+ - `.apk`
14
+ - `.aab` (Androld App Bundle)
13
15
  - iOS ipa file
14
- - Info.plist file
15
- - .mobileprovision/.provisionprofile file
16
- - macOS App(.zip) file
17
- - dSYM(.zip) file
16
+ - `Info.plist` file
17
+ - `.mobileprovision`/`.provisionprofile` file
18
+ - Zipped macOS App file
19
+ - Zipped dSYMs file
18
20
 
19
21
  ## Installation
20
22
 
@@ -54,6 +56,7 @@ parser = AppInfo.parse('App.dSYm.zip')
54
56
  # If detect file type failed, you can parse in other way
55
57
  parser = AppInfo::IPA.new('iphone.ipa')
56
58
  parser = AppInfo::APK.new('android.apk')
59
+ parser = AppInfo::AAB.new('android.aab')
57
60
  parser = AppInfo::InfoPlist.new('Info.plist')
58
61
  parser = AppInfo::MobileProvision.new('uuid.mobileprovision')
59
62
  parser = AppInfo::Macos.new('App.dSYm.zip')
data/app_info.gemspec CHANGED
@@ -23,10 +23,11 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'CFPropertyList', '< 3.1.0', '>= 2.3.4'
24
24
  spec.add_dependency 'image_size', '>= 1.5', '< 2.2'
25
25
  spec.add_dependency 'ruby-macho', '< 3', '>= 1.4'
26
- spec.add_dependency 'ruby_android', '~> 0.7.7'
26
+ spec.add_dependency 'android_parser', '~> 2.4.1'
27
27
  spec.add_dependency 'rubyzip', '>= 1.2', '< 3.0'
28
28
  spec.add_dependency 'uuidtools', '>= 2.1.5', '< 2.3.0'
29
29
  spec.add_dependency 'icns', '~> 0.2.0'
30
+ spec.add_dependency 'google-protobuf', '~> 3.18.0'
30
31
 
31
32
  spec.add_development_dependency 'bundler', '>= 1.12'
32
33
  spec.add_development_dependency 'rake', '>= 10.0'
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'app_info/protobuf/manifest'
4
+ require 'image_size'
5
+ require 'forwardable'
6
+
7
+ module AppInfo
8
+ # Parse APK file
9
+ class AAB
10
+ include Helper::HumanFileSize
11
+ extend Forwardable
12
+
13
+ attr_reader :file
14
+
15
+ # APK Devices
16
+ module Device
17
+ PHONE = 'Phone'
18
+ TABLET = 'Tablet'
19
+ WATCH = 'Watch'
20
+ TV = 'Television'
21
+ end
22
+
23
+ BASE_PATH = 'base'
24
+ BASE_MANIFEST = "#{BASE_PATH}/manifest/AndroidManifest.xml"
25
+ BASE_RESOURCES = "#{BASE_PATH}/resources.pb"
26
+
27
+ def initialize(file)
28
+ @file = file
29
+ end
30
+
31
+ def size(human_size: false)
32
+ file_to_human_size(@file, human_size: human_size)
33
+ end
34
+
35
+ def os
36
+ Platform::ANDROID
37
+ end
38
+ alias file_type os
39
+
40
+ def_delegators :manifest, :version_name
41
+
42
+ alias release_version version_name
43
+
44
+ def package_name
45
+ manifest.package
46
+ end
47
+ alias identifier package_name
48
+ alias bundle_id package_name
49
+
50
+ def version_code
51
+ manifest.version_code.to_s
52
+ end
53
+ alias build_version version_code
54
+
55
+ def name
56
+ manifest.label
57
+ end
58
+
59
+ def device_type
60
+ if wear?
61
+ Device::WATCH
62
+ elsif tv?
63
+ Device::TV
64
+ else
65
+ Device::PHONE
66
+ end
67
+ end
68
+
69
+ # TODO: find a way to detect
70
+ # Found answer but not works: https://stackoverflow.com/questions/9279111/determine-if-the-device-is-a-smartphone-or-tablet
71
+ # def tablet?
72
+ # resource.first_package
73
+ # .entries('bool')
74
+ # .select{|e| e.name == 'isTablet' }
75
+ # .size >= 1
76
+ # end
77
+
78
+ def wear?
79
+ use_features.include?('android.hardware.type.watch')
80
+ end
81
+
82
+ def tv?
83
+ use_features.include?('android.software.leanback')
84
+ end
85
+
86
+ def min_sdk_version
87
+ manifest.uses_sdk.min_sdk_version
88
+ end
89
+ alias min_os_version min_sdk_version
90
+
91
+ def target_sdk_version
92
+ manifest.uses_sdk.target_sdk_version
93
+ end
94
+
95
+ def use_features
96
+ @use_features ||= manifest&.uses_feature&.map(&:name)
97
+ end
98
+
99
+ def use_permissions
100
+ @use_permissions ||= manifest&.uses_permission&.map(&:name)
101
+ end
102
+
103
+ def activities
104
+ @activities ||= manifest.activities
105
+ end
106
+
107
+ def services
108
+ @services ||= manifest.services
109
+ end
110
+
111
+ def components
112
+ @components ||= manifest.components.transform_values
113
+ end
114
+
115
+ def signs
116
+ return @signs if @signs
117
+
118
+ @signs = []
119
+ each_file do |path, data|
120
+ # find META-INF/xxx.{RSA|DSA}
121
+ next unless path =~ %r{^META-INF/} && data.unpack('CC') == [0x30, 0x82]
122
+
123
+ @signs << APK::Sign.new(path, OpenSSL::PKCS7.new(data))
124
+ end
125
+
126
+ @signs
127
+ end
128
+
129
+ def certificates
130
+ @certificates ||= signs.each_with_object([]) do |sign, obj|
131
+ obj << APK::Certificate.new(sign.path, sign.sign.certificates[0])
132
+ end
133
+ end
134
+
135
+ def each_file
136
+ zip.each do |entry|
137
+ next unless entry.file?
138
+
139
+ yield entry.name, @zip.read(entry)
140
+ end
141
+ end
142
+
143
+ def read_file(name, base_path: BASE_PATH)
144
+ content = @zip.read(entry(name, base_path: base_path))
145
+ return parse_binary_xml(content) if xml_file?(name)
146
+
147
+ content
148
+ end
149
+
150
+ def entry(name, base_path: BASE_PATH)
151
+ entry = @zip.find_entry(File.join(base_path, name))
152
+ raise NotFoundError, "'#{name}'" if entry.nil?
153
+
154
+ entry
155
+ end
156
+
157
+ def manifest
158
+ io = zip.read(zip.find_entry(BASE_MANIFEST))
159
+ @manifest ||= Protobuf::Manifest.parse(io, resource)
160
+ end
161
+
162
+ def resource
163
+ io = zip.read(zip.find_entry(BASE_RESOURCES))
164
+ @resource ||= Protobuf::Resources.parse(io)
165
+ end
166
+
167
+ def zip
168
+ @zip ||= Zip::File.open(@file)
169
+ end
170
+
171
+ def icons
172
+ @icons ||= manifest.icons.each_with_object([]) do |res, obj|
173
+ path = res.value
174
+ filename = File.basename(path)
175
+ filepath = File.join(contents, File.dirname(path))
176
+ file = File.join(filepath, filename)
177
+ FileUtils.mkdir_p filepath
178
+
179
+ binary_data = read_file(path)
180
+ File.write(file, binary_data, encoding: Encoding::BINARY)
181
+
182
+ obj << {
183
+ name: filename,
184
+ file: file,
185
+ dimensions: ImageSize.path(file).size
186
+ }
187
+ end
188
+ end
189
+
190
+ def clear!
191
+ return unless @contents
192
+
193
+ FileUtils.rm_rf(@contents)
194
+
195
+ @aab = nil
196
+ @contents = nil
197
+ @icons = nil
198
+ @app_path = nil
199
+ @info = nil
200
+ end
201
+
202
+ def contents
203
+ @contents ||= File.join(Dir.mktmpdir, "AppInfo-android-#{SecureRandom.hex}")
204
+ end
205
+
206
+ private
207
+
208
+ def xml_file?(file)
209
+ File.extname(file) == '.xml'
210
+ end
211
+
212
+ # TODO: how to convert xml content after decode protoubufed content
213
+ def parse_binary_xml(io)
214
+ io
215
+ # Aapt::Pb::XmlNode.decode(io)
216
+ end
217
+ end
218
+ end
data/lib/app_info/apk.rb CHANGED
@@ -7,6 +7,7 @@ require 'forwardable'
7
7
  module AppInfo
8
8
  # Parse APK file
9
9
  class APK
10
+ include Helper::HumanFileSize
10
11
  extend Forwardable
11
12
 
12
13
  attr_reader :file
@@ -24,11 +25,11 @@ module AppInfo
24
25
  end
25
26
 
26
27
  def size(human_size: false)
27
- AppInfo::Util.file_size(@file, human_size)
28
+ file_to_human_size(@file, human_size: human_size)
28
29
  end
29
30
 
30
31
  def os
31
- AppInfo::Platform::ANDROID
32
+ Platform::ANDROID
32
33
  end
33
34
  alias file_type os
34
35
 
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppInfo
4
+ module Inflector
5
+ def ai_snakecase
6
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
7
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
8
+ .tr('-', '_')
9
+ .gsub(/\s/, '_')
10
+ .gsub(/__+/, '_')
11
+ .downcase
12
+ end
13
+
14
+ def ai_camelcase(first_letter: :upper, separators: ['-', '_', '\s'])
15
+ str = dup
16
+
17
+ separators.each do |s|
18
+ str = str.gsub(/(?:#{s}+)([a-z])/) { $1.upcase }
19
+ end
20
+
21
+ case first_letter
22
+ when :upper, true
23
+ str = str.gsub(/(\A|\s)([a-z])/) { $1 + $2.upcase }
24
+ when :lower, false
25
+ str = str.gsub(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
26
+ end
27
+
28
+ str
29
+ end
30
+ end
31
+ end
32
+
33
+ class String
34
+ include AppInfo::Inflector
35
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'app_info/core_ext/object/try'
4
+ require 'app_info/core_ext/string/inflector'
data/lib/app_info/dsym.rb CHANGED
@@ -5,6 +5,8 @@ require 'macho'
5
5
  module AppInfo
6
6
  # DSYM parser
7
7
  class DSYM
8
+ include Helper::Archive
9
+
8
10
  attr_reader :file
9
11
 
10
12
  def initialize(file)
@@ -12,7 +14,7 @@ module AppInfo
12
14
  end
13
15
 
14
16
  def file_type
15
- AppInfo::Platform::DSYM
17
+ Platform::DSYM
16
18
  end
17
19
 
18
20
  def object
@@ -91,7 +93,7 @@ module AppInfo
91
93
  @contents = @file
92
94
  else
93
95
  dsym_dir = nil
94
- @contents = Util.unarchive(@file, path: 'dsym') do |path, zip_file|
96
+ @contents = unarchive(@file, path: 'dsym') do |path, zip_file|
95
97
  zip_file.each do |f|
96
98
  unless dsym_dir
97
99
  dsym_dir = f.name
@@ -114,6 +116,8 @@ module AppInfo
114
116
 
115
117
  # DSYM Mach-O
116
118
  class MachO
119
+ include Helper::HumanFileSize
120
+
117
121
  def initialize(file, size = 0)
118
122
  @file = file
119
123
  @size = size
@@ -132,7 +136,7 @@ module AppInfo
132
136
  end
133
137
 
134
138
  def size(human_size: false)
135
- return Util.size_to_human_size(@size) if human_size
139
+ return number_to_human_size(@size) if human_size
136
140
 
137
141
  @size
138
142
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zip'
4
+ require 'fileutils'
5
+ require 'securerandom'
6
+
7
+ module AppInfo
8
+ class Error < StandardError; end
9
+
10
+ class NotFoundError < Error; end
11
+
12
+ class UnkownFileTypeError < Error; end
13
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppInfo
4
+ # App Platform
5
+ module Platform
6
+ MACOS = 'macOS'
7
+ IOS = 'iOS'
8
+ ANDROID = 'Android'
9
+ DSYM = 'dSYM'
10
+ PROGUARD = 'Proguard'
11
+ end
12
+
13
+ # Device Type
14
+ module Device
15
+ MACOS = 'macOS'
16
+ IPHONE = 'iPhone'
17
+ IPAD = 'iPad'
18
+ UNIVERSAL = 'Universal'
19
+ end
20
+
21
+ module AndroidDevice
22
+ PHONE = 'Phone'
23
+ TABLET = 'Tablet'
24
+ WATCH = 'Watch'
25
+ TV = 'Television'
26
+ end
27
+
28
+ # Icon Key
29
+ ICON_KEYS = {
30
+ Device::IPHONE => ['CFBundleIcons'],
31
+ Device::IPAD => ['CFBundleIcons~ipad'],
32
+ Device::UNIVERSAL => ['CFBundleIcons', 'CFBundleIcons~ipad'],
33
+ Device::MACOS => %w[CFBundleIconFile CFBundleIconName]
34
+ }.freeze
35
+
36
+ module Helper
37
+ module HumanFileSize
38
+ def file_to_human_size(file, human_size:)
39
+ number = File.size(file)
40
+ human_size ? number_to_human_size(number) : number
41
+ end
42
+
43
+ FILE_SIZE_UNITS = %w[B KB MB GB TB].freeze
44
+
45
+ def number_to_human_size(number)
46
+ if number.to_i < 1024
47
+ exponent = 0
48
+ else
49
+ max_exp = FILE_SIZE_UNITS.size - 1
50
+ exponent = (Math.log(number) / Math.log(1024)).to_i
51
+ exponent = max_exp if exponent > max_exp
52
+ number = format('%<number>.2f', number: (number / (1024**exponent.to_f)))
53
+ end
54
+
55
+ "#{number} #{FILE_SIZE_UNITS[exponent]}"
56
+ end
57
+ end
58
+
59
+ module Archive
60
+ require 'zip'
61
+ require 'fileutils'
62
+ require 'securerandom'
63
+
64
+ # Unarchive zip file
65
+ #
66
+ # source: https://github.com/soffes/lagunitas/blob/master/lib/lagunitas/ipa.rb
67
+ def unarchive(file, path: nil)
68
+ path = path ? "#{path}-" : ''
69
+ root_path = "#{Dir.mktmpdir}/AppInfo-#{path}#{SecureRandom.hex}"
70
+ Zip::File.open(file) do |zip_file|
71
+ if block_given?
72
+ yield root_path, zip_file
73
+ else
74
+ zip_file.each do |f|
75
+ f_path = File.join(root_path, f.name)
76
+ FileUtils.mkdir_p(File.dirname(f_path))
77
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
78
+ end
79
+ end
80
+ end
81
+
82
+ root_path
83
+ end
84
+
85
+ def tempdir(file, prefix:)
86
+ dest_path ||= File.join(File.dirname(file), prefix)
87
+ dest_file = File.join(dest_path, File.basename(file))
88
+
89
+ Dir.mkdir(dest_path, 0_700) unless Dir.exist?(dest_path)
90
+
91
+ dest_file
92
+ end
93
+ end
94
+
95
+ module Defines
96
+ def create_class(klass_name, parent_class, namespace:)
97
+ klass = Class.new(parent_class) do
98
+ yield if block_given?
99
+ end
100
+
101
+ name = namespace.to_s.empty? ? klass_name : "#{namespace}::#{klass_name}"
102
+ if Object.const_get(namespace).const_defined?(klass_name)
103
+ Object.const_get(namespace).const_get(klass_name)
104
+ elsif Object.const_defined?(name)
105
+ Object.const_get(name)
106
+ else
107
+ Object.const_get(namespace).const_set(klass_name, klass)
108
+ end
109
+ end
110
+
111
+ def define_instance_method(key, value)
112
+ instance_variable_set("@#{key}", value)
113
+ self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
114
+ def #{key}
115
+ @#{key}
116
+ end
117
+ RUBY
118
+ end
119
+ end
120
+
121
+ module ReferenceParser
122
+ def reference_segments(value)
123
+ new_value = value.is_a?(Aapt::Pb::Reference) ? value.name : value
124
+ return new_value.split('/', 2) if new_value.include?('/')
125
+
126
+ [nil, new_value]
127
+ end
128
+ end
129
+ end
130
+ end
@@ -67,13 +67,13 @@ module AppInfo
67
67
  def device_type
68
68
  device_family = info.try(:[], 'UIDeviceFamily')
69
69
  if device_family == [1]
70
- AppInfo::Device::IPHONE
70
+ Device::IPHONE
71
71
  elsif device_family == [2]
72
- AppInfo::Device::IPAD
72
+ Device::IPAD
73
73
  elsif device_family == [1, 2]
74
- AppInfo::Device::UNIVERSAL
74
+ Device::UNIVERSAL
75
75
  elsif !info.try(:[], 'DTSDKName').nil? || !info.try(:[], 'DTPlatformName').nil?
76
- AppInfo::Device::MACOS
76
+ Device::MACOS
77
77
  end
78
78
  end
79
79
 
@@ -112,13 +112,13 @@ module AppInfo
112
112
  def_delegators :info, :to_h
113
113
 
114
114
  def method_missing(method_name, *args, &block)
115
- info.try(:[], Util.format_key(method_name)) ||
115
+ info.try(:[], method_name.to_s.ai_camelcase) ||
116
116
  info.send(method_name) ||
117
117
  super
118
118
  end
119
119
 
120
120
  def respond_to_missing?(method_name, *args)
121
- info.key?(Util.format_key(method_name)) ||
121
+ info.key?(method_name.to_s.ai_camelcase) ||
122
122
  info.respond_to?(method_name) ||
123
123
  super
124
124
  end
data/lib/app_info/ipa.rb CHANGED
@@ -8,6 +8,8 @@ require 'cfpropertylist'
8
8
  module AppInfo
9
9
  # IPA parser
10
10
  class IPA
11
+ include Helper::HumanFileSize
12
+ include Helper::Archive
11
13
  extend Forwardable
12
14
 
13
15
  attr_reader :file
@@ -28,11 +30,11 @@ module AppInfo
28
30
  end
29
31
 
30
32
  def size(human_size: false)
31
- AppInfo::Util.file_size(@file, human_size)
33
+ file_to_human_size(@file, human_size: human_size)
32
34
  end
33
35
 
34
36
  def os
35
- AppInfo::Platform::IOS
37
+ Platform::IOS
36
38
  end
37
39
  alias file_type os
38
40
 
@@ -195,7 +197,7 @@ module AppInfo
195
197
  end
196
198
 
197
199
  def contents
198
- @contents ||= Util.unarchive(@file, path: 'ios')
200
+ @contents ||= unarchive(@file, path: 'ios')
199
201
  end
200
202
 
201
203
  private
@@ -213,7 +215,7 @@ module AppInfo
213
215
 
214
216
  # Uncrush png to normal png file (iOS)
215
217
  def uncrush_png(src_file)
216
- dest_file = Util.tempdir(src_file, prefix: 'uncrushed')
218
+ dest_file = tempdir(src_file, prefix: 'uncrushed')
217
219
  PngUncrush.decompress(src_file, dest_file)
218
220
  File.exist?(dest_file) ? dest_file : nil
219
221
  end