app-info 2.4.3 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3a8120207a6e2e38bc41581e3fb1bfa8f181d9262cd5f5f2b2ef7a416bd2dd7
4
- data.tar.gz: 00e5f7124fc1152494ab159baf8a8b737ab4651dab5e8f173c32d3a726a0836f
3
+ metadata.gz: 927106ea47092b85df2f8e1c88321d8949da8d7c9e7bc712d907e89932cd4072
4
+ data.tar.gz: f2d5acb9cd901f7af25307ed385d8d276e19d04e5e02644e3ea15e9698d5363a
5
5
  SHA512:
6
- metadata.gz: 8e118a9412150f37e3b5675027c486b6028b09328554b4d8e3a62d83cabe828b40f25742aa8d4739fc6049a42efd1909f3811613a516a15d2fa0a2edfbea093c
7
- data.tar.gz: 888e45ddaae86097e6eb150aa37c98294d708fa94d519dbeabfb22088f8c1ac94fecdc9aa4806966a3895e283ded8da90c8aa1685d201822129e300d87cd9f5c
6
+ metadata.gz: af27de4ad9737a4d87bad27f910b010f42338586ed02ecfd16414997ff8a07e78a1a3b681ca9ccdba6944d6f306cd47cd9730f3bd73a453ce43fe1d280085030
7
+ data.tar.gz: 8d11fac42b959acc59e9abd71db8c204866ad11e5bd6a3fb746883284f9d1032e959e5636411d6ef4c3e69d020eb42f99c8df04c381c8d295bd063f9bc447f56
data/CHANGELOG.md CHANGED
@@ -9,6 +9,12 @@ 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.5.1] (2021-04-14)
13
+
14
+ ### Add
15
+
16
+ - Restore `dimensions` key from icons method and icon pnguncrush back.
17
+
12
18
  ## [2.4.3] (2021-04-12)
13
19
 
14
20
  ### Fixed
@@ -118,7 +124,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
118
124
 
119
125
  - Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
120
126
 
121
- [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.4.3..HEAD
127
+ [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.5.1..HEAD
128
+ [2.5.0]: https://github.com/icyleaf/app-info/compare/v2.4.3...v2.5.1
122
129
  [2.4.3]: https://github.com/icyleaf/app-info/compare/v2.4.2...v2.4.3
123
130
  [2.4.2]: https://github.com/icyleaf/app-info/compare/v2.4.1...v2.4.2
124
131
  [2.4.1]: https://github.com/icyleaf/app-info/compare/v2.3.0...v2.4.1
data/README.md CHANGED
@@ -82,7 +82,7 @@ ipa.bundle_id
82
82
 
83
83
  # get app icons
84
84
  ipa.icons
85
- # => [{:name=>"AppIcon29x29@2x~ipad.png", :file=>"/var/folders/mb/8cm0fz4d499968yss9y1j8bc0000gp/T/d20160728-69669-1xnub30/AppInfo-ios-a5369339399e62046d7d59c52254dac6/Payload/bundle.app/AppIcon29x29@2x~ipad.png"}, ...]
85
+ # => [{:name=>"AppIcon29x29@2x~ipad.png", :file=>"/var/folders/mb/8cm0fz4d499968yss9y1j8bc0000gp/T/d20160728-69669-1xnub30/AppInfo-ios-a5369339399e62046d7d59c52254dac6/Payload/bundle.app/AppIcon29x29@2x~ipad.png"}, :dimensions=>[29, 29], :uncrushed_file=>"..." ...]
86
86
 
87
87
  # get provisioning profile devices
88
88
  ipa.devices
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'image_size'
4
3
  require 'cfpropertylist'
4
+ require 'app_info/png_uncrush'
5
5
  require 'app_info/util'
6
6
 
7
7
  module AppInfo
@@ -43,7 +43,7 @@ module AppInfo
43
43
  info.try(:[], 'MinimumOSVersion')
44
44
  end
45
45
 
46
- def icons
46
+ def icons(uncrush = true)
47
47
  return @icons if @icons
48
48
 
49
49
  @icons = []
@@ -56,12 +56,7 @@ module AppInfo
56
56
 
57
57
  icon_array.each do |items|
58
58
  Dir.glob(File.join(@app_path, "#{items}*")).find_all.each do |file|
59
- dict = {
60
- name: File.basename(file),
61
- file: file
62
- }
63
-
64
- @icons.push(dict)
59
+ @icons << icon_info(file, uncrush)
65
60
  end
66
61
  end
67
62
  end
@@ -121,6 +116,24 @@ module AppInfo
121
116
 
122
117
  private
123
118
 
119
+ def icon_info(file, uncrush = true)
120
+ uncrushed_file = nil
121
+ if uncrush
122
+ path = File.join(File.dirname(file), 'uncrushed')
123
+ Dir.mkdir(path, 0700) unless Dir.exist?(path)
124
+
125
+ uncrushed_file = File.join(path, File.basename(file))
126
+ PngUncrush.decompress(file, uncrushed_file)
127
+ end
128
+
129
+ {
130
+ name: File.basename(file),
131
+ file: file,
132
+ uncrushed_file: uncrushed_file,
133
+ dimensions: PngUncrush.dimensions(file)
134
+ }
135
+ end
136
+
124
137
  def info
125
138
  return unless File.file?(info_path)
126
139
 
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright @ Wenwei Cai on 26 Aug 2012.
4
+ # https://github.com/swcai/iphone-png-normalizer
5
+
6
+ require 'zlib'
7
+ require 'stringio'
8
+
9
+ module AppInfo
10
+ class PngUncrush
11
+ class Error < StandardError; end
12
+ class FormatError < Error; end
13
+
14
+ class PngReader # :nodoc:
15
+ PNG_HEADER = "\x89PNG\r\n\x1a\n".bytes
16
+ CHUNK = 1024
17
+
18
+ attr_reader :data
19
+
20
+ def initialize(raw)
21
+ @io = if raw.is_a?(String)
22
+ StringIO.new(raw)
23
+ elsif raw.respond_to?(:read) && raw.respond_to?(:eof?)
24
+ raw
25
+ else
26
+ raise ArgumentError, "expected data as String or an object responding to read, got #{raw.class}"
27
+ end
28
+
29
+ @data = String.new
30
+ end
31
+
32
+ def size
33
+ @io.size
34
+ end
35
+
36
+ def unpack(a)
37
+ @io.unpack(a)
38
+ end
39
+
40
+ def header
41
+ @header ||= self[0, 8]
42
+ end
43
+
44
+ def png?
45
+ PNG_HEADER == header.bytes
46
+ end
47
+
48
+ def [](offset, length)
49
+ while !@io.eof? && @data.length < offset + length
50
+ data = @io.read(CHUNK)
51
+ break unless data
52
+
53
+ data.force_encoding(@data.encoding) if data.respond_to?(:encoding)
54
+ @data << data
55
+ end
56
+
57
+ @data[offset, length]
58
+ end
59
+ end
60
+
61
+ def self.decompress(input, output)
62
+ new(input).decompress(output)
63
+ end
64
+
65
+ def self.dimensions(input)
66
+ new(input).dimensions
67
+ end
68
+
69
+ def initialize(filename)
70
+ @io = PngReader.new(File.open(filename))
71
+ raise FormatError, 'not a png file' unless @io.png?
72
+ end
73
+
74
+ def dimensions
75
+ _dump_sections(dimensions: true)
76
+ end
77
+
78
+ def decompress(output)
79
+ content = _remap(_dump_sections)
80
+ return false unless content
81
+
82
+ write_file(output, content)
83
+ end
84
+
85
+ private
86
+
87
+ def _dump_sections(dimensions: false)
88
+ pos = @io.header.size
89
+ optimized = false
90
+ [].tap do |sections|
91
+ while pos < @io.size
92
+ type = @io[pos + 4, 4]
93
+ length = @io[pos, 4].unpack('N')[0]
94
+ data = @io[pos + 8, length]
95
+ crc = @io[pos + 8 + length, 4].unpack('N')[0]
96
+ pos += length + 12
97
+
98
+ if type == 'CgBI'
99
+ optimized = true
100
+ next
101
+ end
102
+
103
+ if type == 'IHDR'
104
+ width = data[0, 4].unpack("N")[0]
105
+ height = data[4, 4].unpack("N")[0]
106
+ return [width, height] if dimensions
107
+ end
108
+
109
+ break if type == 'IEND'
110
+
111
+ if type == 'IDAT' && sections.size > 0 && sections.last.first == 'IDAT'
112
+ # Append to the previous IDAT
113
+ sections.last[1] += length
114
+ sections.last[2] += data
115
+ else
116
+ sections << [type, length, data, crc, width, height]
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ def write_file(path, content)
123
+ File.open(path, 'wb') do |file|
124
+ file.puts content
125
+ end
126
+
127
+ true
128
+ end
129
+
130
+ def _remap(sections)
131
+ newPNG = String.new(@io.header)
132
+ sections.map do |(type, length, data, crc, width, height)|
133
+ if type == 'IDAT'
134
+ bufSize = width * height * 4 + height
135
+ data = inflate(data[0, bufSize])
136
+ # duplicate the content of old data at first to avoid creating too many string objects
137
+ newdata = String.new(data)
138
+ pos = 0
139
+
140
+ (0...height).each do |y|
141
+ newdata[pos] = data[pos, 1]
142
+ pos += 1
143
+ (0...width).each do |x|
144
+ newdata[pos+0] = data[pos+2, 1]
145
+ newdata[pos+1] = data[pos+1, 1]
146
+ newdata[pos+2] = data[pos+0, 1]
147
+ newdata[pos+3] = data[pos+3, 1]
148
+ pos += 4
149
+ end
150
+ end
151
+
152
+ data = deflate(newdata)
153
+ length = data.length
154
+ crc = Zlib::crc32(type)
155
+ crc = Zlib::crc32(data, crc)
156
+ crc = (crc + 0x100000000) % 0x100000000
157
+ end
158
+
159
+ newPNG += [length].pack("N") + type + (data if length > 0) + [crc].pack("N")
160
+ end
161
+
162
+ newPNG
163
+ end
164
+
165
+ def inflate(data)
166
+ # make zlib not check the header
167
+ zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
168
+ buf = zstream.inflate(data)
169
+ zstream.finish
170
+ zstream.close
171
+ buf
172
+ end
173
+
174
+ def deflate(data)
175
+ Zlib::Deflate.deflate(data)
176
+ end
177
+ end
178
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppInfo
4
- VERSION = '2.4.3'
4
+ VERSION = '2.5.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app-info
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.3
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - icyleaf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-12 00:00:00.000000000 Z
11
+ date: 2021-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -189,6 +189,7 @@ files:
189
189
  - lib/app_info/ipa/info_plist.rb
190
190
  - lib/app_info/ipa/mobile_provision.rb
191
191
  - lib/app_info/ipa/plugin.rb
192
+ - lib/app_info/png_uncrush.rb
192
193
  - lib/app_info/proguard.rb
193
194
  - lib/app_info/util.rb
194
195
  - lib/app_info/version.rb