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 +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +1 -1
- data/lib/app_info/ipa/info_plist.rb +21 -8
- data/lib/app_info/png_uncrush.rb +178 -0
- data/lib/app_info/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 927106ea47092b85df2f8e1c88321d8949da8d7c9e7bc712d907e89932cd4072
|
4
|
+
data.tar.gz: f2d5acb9cd901f7af25307ed385d8d276e19d04e5e02644e3ea15e9698d5363a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
|
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
|
data/lib/app_info/version.rb
CHANGED
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
|
+
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-
|
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
|