app-info 2.4.3 → 2.5.1

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: 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