longbow-fdv 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,389 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+ # require 'mini_magick'
3
+ require 'RMagick'
4
+ include Magick
5
+ require 'colors'
6
+ require 'xcodeproj'
7
+ require 'open-uri'
8
+ require 'utilities'
9
+
10
+ module Longbow
11
+
12
+ # Images
13
+ def self.create_images directory, t, obj
14
+ # Bad Params
15
+ if !directory || !t || !obj
16
+ return false
17
+ end
18
+
19
+ # Get Device Information
20
+ iPhone = obj['devices'].include? 'iPhone'
21
+ iPad = obj['devices'].include? 'iPad'
22
+
23
+ # Resize Icons
24
+ resize_icons directory, t, iPhone, iPad
25
+
26
+ # Resize Launch Images
27
+ resize_launch_images directory, t
28
+
29
+ # Write JSON for Icon Assets
30
+ write_json_for_icons directory, t, iPhone, iPad
31
+
32
+ # Write JSON for Launch Assets
33
+ write_json_for_launch_images directory, t
34
+
35
+ end
36
+
37
+
38
+ # Create & Resize Icons
39
+ def self.resize_icons directory, t, iPhone, iPad
40
+ # Set Up
41
+ target = t['name']
42
+
43
+ # Get Image Information
44
+ img_path = ''
45
+ if t['icon_url']
46
+ img_path = self.path_for_downloaded_image_from_url directory, target, t['icon_url'], 'icons'
47
+ elsif t['icon_path']
48
+ img_path = directory + '/' + t['icon_path']
49
+ end
50
+
51
+ # Make directory
52
+ img_dir = make_asset_directory directory, target, '.appiconset/'
53
+
54
+ # Resize
55
+ image_sizes = []
56
+ image_sizes += ['180x180', '120x120', '114x114', '87x87', '80x80', '58x58', '57x57', '29x29'] if iPhone
57
+ image_sizes += ['167x167', '152x152', '144x144', '100x100', '80x80', '76x76', '72x72', '58x58', '50x50', '40x40', '29x29'] if iPad
58
+ image_sizes.uniq.each do |size|
59
+ image = Image.read(img_path).first
60
+ next unless image
61
+ resize_image_to_directory img_dir, image, size, 'icon'
62
+ end
63
+
64
+ Longbow::green (' - Created Icon images for ' + target) unless $nolog
65
+ return true
66
+ end
67
+
68
+
69
+ # Create & Resize Launch Images
70
+ def self.resize_launch_images directory, t
71
+ # Set Up
72
+ target = t['name']
73
+
74
+ ['launch_phone_p', 'launch_phone_l', 'launch_tablet_p', 'launch_tablet_l'].each do |key|
75
+ if t[key + '_url']
76
+ img_path = self.path_for_downloaded_image_from_url directory, key + '_' + target, t[key + '_url'], 'launch'
77
+ elsif t[key + '_path']
78
+ img_path = directory + '/' + t[key + '_path']
79
+ else
80
+ next
81
+ end
82
+
83
+ # Make directory
84
+ img_dir = make_asset_directory directory, target, '.launchimage/'
85
+
86
+ # Make resize sizes
87
+ sizes = []
88
+ if key == 'launch_phone_p'
89
+ sizes = ['640x1136','640x960','320x480']
90
+ elsif key == 'launch_phone_l'
91
+ sizes = ['1136x640','960x640','480x320']
92
+ elsif key == 'launch_tablet_p'
93
+ sizes = ['1536x2048','768x1024','1536x2008','768x1004']
94
+ elsif key == 'launch_tablet_l'
95
+ sizes = ['2048x1536','1024x768','2048x1496','1024x748']
96
+ end
97
+
98
+ # Resize Images
99
+ sizes.each do |size|
100
+ image = Image.read(img_path).first
101
+ return false unless image
102
+ resize_image_to_directory img_dir, image, size, key + '_'
103
+ end
104
+ end
105
+
106
+ Longbow::green (' - Created Launch images for ' + target) unless $nolog
107
+ return true
108
+ end
109
+
110
+
111
+ # Resize Image to Directory
112
+ def self.resize_image_to_directory directory, image, size, tag
113
+ sizes = size.split('x')
114
+ new_w = Integer(sizes[0])
115
+ new_h = Integer(sizes[1])
116
+ image.resize_to_fill! new_w, new_h
117
+ image.write directory + '/' + tag + size + '.png'
118
+ end
119
+
120
+
121
+ # Create JSON
122
+ def self.write_json_for_icons directory, t, iPhone, iPad
123
+ # Set Up
124
+ target = t['name']
125
+
126
+ # Make directory
127
+ img_dir = make_asset_directory directory, target, '.appiconset/'
128
+
129
+ # Write the JSON file
130
+ File.open(img_dir + '/Contents.json', 'w') do |f|
131
+ f.write('{ "images" : [ ')
132
+
133
+ if iPhone
134
+ f.write( '{ "size" : "29x29", "idiom" : "iphone", "filename" : "icon58x58.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon87x87.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon80x80.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon120x120.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon120x120.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon29x29.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon57x57.png", "scale" : "1x" }, { "size" : "57x57", "idiom" : "iphone", "filename" : "icon114x114.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon180x180.png", "scale" : "3x" }' + (iPad ? ',' : ''))
135
+ end
136
+
137
+ if iPad
138
+ f.write( '{ "idiom" : "ipad", "size" : "29x29", "scale" : "1x", "filename" : "icon29x29.png" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x", "filename" : "icon58x58.png" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x", "filename" : "icon40x40.png" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x", "filename" : "icon80x80.png" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x", "filename" : "icon76x76.png" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x", "filename" : "icon152x152.png" }, { "idiom" : "ipad", "size" : "50x50", "scale" : "1x", "filename" : "icon50x50.png" }, { "idiom" : "ipad", "size" : "50x50", "scale" : "2x", "filename" : "icon100x100.png" }, { "idiom" : "ipad", "size" : "72x72", "scale" : "1x", "filename" : "icon72x72.png" }, { "idiom" : "ipad", "size" : "72x72", "scale" : "2x", "filename" : "icon144x144.png" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x", "filename" : "icon167x167.png" }')
139
+ end
140
+
141
+ f.write(' ], "info" : { "version" : 1, "author" : "xcode" }, "properties" : { "pre-rendered" : true } }')
142
+ end
143
+
144
+ # Return true
145
+ Longbow::green (' - Created Images.xcassets icon set for ' + target) unless $nolog
146
+ return true
147
+ end
148
+
149
+
150
+ # JSON for Launch Images
151
+ def self.write_json_for_launch_images directory, t
152
+ # Set Up
153
+ target = t['name']
154
+ phone_portrait = t['launch_phone_p_url'] || t['launch_phone_p_path']
155
+ phone_landscape = t['launch_phone_l_url'] || t['launch_phone_l_path']
156
+ tablet_portrait = t['launch_tablet_p_url'] || t['launch_tablet_p_path']
157
+ tablet_landscape = t['launch_tablet_l_url'] || t['launch_tablet_l_path']
158
+ return false unless phone_portrait || phone_landscape || tablet_landscape || tablet_portrait
159
+
160
+ # Make Directory
161
+ img_dir = make_asset_directory directory, target, '.launchimage/'
162
+
163
+ File.open(img_dir + '/Contents.json', 'w') do |f|
164
+ f.write('{"images" : [')
165
+
166
+ if phone_portrait
167
+ f.write('{
168
+ "orientation" : "portrait",
169
+ "idiom" : "iphone",
170
+ "extent" : "full-screen",
171
+ "minimum-system-version" : "7.0",
172
+ "filename" : "launch_phone_p_640x960.png",
173
+ "scale" : "2x"
174
+ },
175
+ {
176
+ "extent" : "full-screen",
177
+ "idiom" : "iphone",
178
+ "subtype" : "retina4",
179
+ "filename" : "launch_phone_p_640x1136.png",
180
+ "minimum-system-version" : "7.0",
181
+ "orientation" : "portrait",
182
+ "scale" : "2x"
183
+ },
184
+ {
185
+ "orientation" : "portrait",
186
+ "idiom" : "iphone",
187
+ "extent" : "full-screen",
188
+ "filename" : "launch_phone_p_320x480.png",
189
+ "scale" : "1x"
190
+ },
191
+ {
192
+ "orientation" : "portrait",
193
+ "idiom" : "iphone",
194
+ "extent" : "full-screen",
195
+ "filename" : "launch_phone_p_640x960.png",
196
+ "scale" : "2x"
197
+ },
198
+ {
199
+ "orientation" : "portrait",
200
+ "idiom" : "iphone",
201
+ "extent" : "full-screen",
202
+ "subtype" : "retina4",
203
+ "filename" : "launch_phone_p_640x1136.png",
204
+ "scale" : "2x"
205
+ }')
206
+ f.write ',' if phone_landscape || tablet_portrait || tablet_landscape
207
+ end
208
+
209
+ if phone_landscape
210
+ f.write('{
211
+ "orientation" : "landscape",
212
+ "idiom" : "iphone",
213
+ "extent" : "full-screen",
214
+ "minimum-system-version" : "7.0",
215
+ "filename" : "launch_phone_l_960x640.png",
216
+ "scale" : "2x"
217
+ },
218
+ {
219
+ "extent" : "full-screen",
220
+ "idiom" : "iphone",
221
+ "subtype" : "retina4",
222
+ "filename" : "launch_phone_l_1136x640.png",
223
+ "minimum-system-version" : "7.0",
224
+ "orientation" : "landscape",
225
+ "scale" : "2x"
226
+ },
227
+ {
228
+ "orientation" : "landscape",
229
+ "idiom" : "iphone",
230
+ "extent" : "full-screen",
231
+ "filename" : "launch_phone_l_480x320.png",
232
+ "scale" : "1x"
233
+ },
234
+ {
235
+ "orientation" : "landscape",
236
+ "idiom" : "iphone",
237
+ "extent" : "full-screen",
238
+ "filename" : "launch_phone_l_960x640.png",
239
+ "scale" : "2x"
240
+ },
241
+ {
242
+ "orientation" : "landscape",
243
+ "idiom" : "iphone",
244
+ "extent" : "full-screen",
245
+ "subtype" : "retina4",
246
+ "filename" : "launch_phone_l_1136x640.png",
247
+ "scale" : "2x"
248
+ }')
249
+ f.write ',' if tablet_portrait || tablet_landscape
250
+ end
251
+
252
+ if tablet_portrait
253
+ f.write('{
254
+ "orientation" : "portrait",
255
+ "idiom" : "ipad",
256
+ "extent" : "full-screen",
257
+ "filename" : "launch_tablet_p_768x1024.png",
258
+ "minimum-system-version" : "7.0",
259
+ "scale" : "1x"
260
+ },
261
+ {
262
+ "orientation" : "portrait",
263
+ "idiom" : "ipad",
264
+ "extent" : "full-screen",
265
+ "filename" : "launch_tablet_p_1536x2048.png",
266
+ "minimum-system-version" : "7.0",
267
+ "scale" : "2x"
268
+ },
269
+ {
270
+ "orientation" : "portrait",
271
+ "idiom" : "ipad",
272
+ "extent" : "to-status-bar",
273
+ "scale" : "1x",
274
+ "filename" : "launch_tablet_p_768x1004.png"
275
+ },
276
+ {
277
+ "orientation" : "portrait",
278
+ "idiom" : "ipad",
279
+ "extent" : "full-screen",
280
+ "scale" : "1x",
281
+ "filename" : "launch_tablet_p_768x1024.png"
282
+ },
283
+ {
284
+ "orientation" : "portrait",
285
+ "idiom" : "ipad",
286
+ "extent" : "to-status-bar",
287
+ "scale" : "2x",
288
+ "filename" : "launch_tablet_p_1536x2008.png"
289
+ },
290
+ {
291
+ "orientation" : "portrait",
292
+ "idiom" : "ipad",
293
+ "extent" : "full-screen",
294
+ "scale" : "2x",
295
+ "filename" : "launch_tablet_p_1536x2048.png"
296
+ }')
297
+ f.write ',' if tablet_landscape
298
+ end
299
+
300
+ if tablet_landscape
301
+ f.write('{
302
+ "orientation" : "landscape",
303
+ "idiom" : "ipad",
304
+ "extent" : "full-screen",
305
+ "filename" : "launch_tablet_l_1024x768.png",
306
+ "minimum-system-version" : "7.0",
307
+ "scale" : "1x"
308
+ },
309
+ {
310
+ "orientation" : "landscape",
311
+ "idiom" : "ipad",
312
+ "extent" : "full-screen",
313
+ "filename" : "launch_tablet_l_2048x1536.png",
314
+ "minimum-system-version" : "7.0",
315
+ "scale" : "2x"
316
+ },
317
+ {
318
+ "orientation" : "landscape",
319
+ "idiom" : "ipad",
320
+ "extent" : "to-status-bar",
321
+ "scale" : "1x",
322
+ "filename" : "launch_tablet_l_1024x748.png"
323
+ },
324
+ {
325
+ "orientation" : "landscape",
326
+ "idiom" : "ipad",
327
+ "extent" : "full-screen",
328
+ "scale" : "1x",
329
+ "filename" : "launch_tablet_l_1024x768.png"
330
+ },
331
+ {
332
+ "orientation" : "landscape",
333
+ "idiom" : "ipad",
334
+ "extent" : "to-status-bar",
335
+ "scale" : "2x",
336
+ "filename" : "launch_tablet_l_2048x1496.png"
337
+ },
338
+ {
339
+ "orientation" : "landscape",
340
+ "idiom" : "ipad",
341
+ "extent" : "full-screen",
342
+ "scale" : "2x",
343
+ "filename" : "launch_tablet_l_2048x1536.png"
344
+ }')
345
+ end
346
+
347
+ f.write('],"info" : {"version" : 1,"author" : "xcode"}}')
348
+ end
349
+
350
+ # Return true
351
+ Longbow::green (' - Created Images.xcassets launch image set for ' + target) unless $nolog
352
+ return true
353
+ end
354
+
355
+
356
+ # Asset Directory Methods
357
+ def self.make_asset_directory directory, target, path_extension
358
+ asset_path = assets_file_path directory
359
+ full_path = asset_path + '/' + Longbow::stripped_text(target) + path_extension
360
+ FileUtils::mkdir_p full_path
361
+ return full_path
362
+ end
363
+
364
+ def self.assets_file_path directory
365
+ asset_path = ''
366
+ Dir.glob(directory + '/**/*/').each do |d|
367
+ searching = 'Images.xcassets/'
368
+ asset_path = d if d.slice(d.length - searching.length, searching.length) == searching
369
+ break if asset_path.length > 0
370
+ end
371
+
372
+ return asset_path
373
+ end
374
+
375
+
376
+ # Download Image from URL
377
+ def self.path_for_downloaded_image_from_url directory, filename, url, folder
378
+ img_path = directory + '/resources/'+ folder + '/'
379
+ img_file_name = filename + '.png'
380
+ FileUtils::mkdir_p img_path
381
+ puts img_path
382
+ File.open(img_path + img_file_name, 'wb') do |f|
383
+ f.write open(url).read
384
+ end
385
+
386
+ return img_path + img_file_name
387
+ end
388
+
389
+ end
@@ -0,0 +1,50 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+ require 'colors'
3
+ require 'open-uri'
4
+ require 'json'
5
+
6
+ module Longbow
7
+
8
+ def self.json_object_from_directory directory
9
+ return nil unless directory
10
+
11
+ # Check for longbow.json
12
+ @json_path = directory + '/longbow.json'
13
+ unless File.exists?(@json_path)
14
+ Longbow::red "\n Couldn't find longbow.json at #{@json_path}\n"
15
+ puts " Run this command to install the correct files:\n longbow install\n"
16
+ return nil
17
+ end
18
+
19
+ # Create hash from longbow.json
20
+ json_contents = File.open(@json_path).read
21
+ return json_object_from_string json_contents
22
+ end
23
+
24
+
25
+ def self.json_object_from_url url
26
+ return nil unless url
27
+ contents = ''
28
+ open(url) {|io| contents = io.read}
29
+ return json_object_from_string contents
30
+ end
31
+
32
+
33
+ def self.json_object_from_string contents
34
+ begin
35
+ !!JSON.parse(contents)
36
+ rescue
37
+ return nil
38
+ end
39
+
40
+ return JSON.parse(contents)
41
+ end
42
+
43
+
44
+ def self.lint_json_object obj
45
+ return false unless obj
46
+ return false unless obj['targets']
47
+ return true
48
+ end
49
+
50
+ end
@@ -0,0 +1,64 @@
1
+ module Longbow
2
+
3
+ # Create Plist from Original Plist Content
4
+ def self.create_plist_from_old_plist old_plist, info_hash, global_hash
5
+ return '' unless old_plist
6
+ return old_plist unless (info_hash || global_hash)
7
+ plist_text = old_plist
8
+ [global_hash,info_hash].each do |hash|
9
+ next unless hash
10
+ hash.each_key do |k|
11
+ value = hash[k]
12
+ matches = plist_text.match /<key>#{k}<\/key>\s*<(.*?)>.*<\/(.*?)>/
13
+ if matches
14
+ plist_text = plist_text.sub(matches[0], "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "\n")
15
+ else
16
+ plist_text = plist_text.sub(/<\/dict>\s*<\/plist>/, "<key>" + k + "</key>\n" + recursive_plist_value_for_value(value) + "\n</dict></plist>")
17
+ end
18
+ end
19
+ end
20
+
21
+ return plist_text
22
+ end
23
+
24
+ # Recursively create Plist Values for a given object
25
+ def self.recursive_plist_value_for_value value
26
+ return '' unless value != nil
27
+
28
+ # Check Number
29
+ if value.kind_of?(Numeric)
30
+ return '<real>' + value.to_s + '</real>'
31
+ end
32
+
33
+ # Check Boolean
34
+ if !!value == value
35
+ if value == true
36
+ return '<true />'
37
+ else
38
+ return '<false />'
39
+ end
40
+ end
41
+
42
+ # Check Array
43
+ if value.kind_of?(Array)
44
+ total_values = '<array>'
45
+ value.each do |v|
46
+ total_values += recursive_plist_value_for_value(v)
47
+ end
48
+ return total_values + '</array>'
49
+ end
50
+
51
+ # Check Hash
52
+ if value.kind_of?(Hash)
53
+ total_values = '<dict>'
54
+ value.each_key do |key|
55
+ total_values += '<key>' + key + '</key>'
56
+ total_values += recursive_plist_value_for_value value[key]
57
+ end
58
+ return total_values + '</dict>'
59
+ end
60
+
61
+ return '<string>' + value.to_s + '</string>'
62
+ end
63
+
64
+ end