longbow-fdv 0.1.0

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.
@@ -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