omudid 1.0.3 → 1.0.6
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.
- data/Gemfile +2 -2
- data/README.md +93 -2
- data/bin/omudid +1 -1
- data/lib/omudid/local_agent.rb +65 -0
- data/lib/{OneMoreUDID.rb → omudid/portal_agent.rb} +1 -153
- data/lib/omudid/testflight_agent.rb +94 -0
- data/lib/omudid.rb +11 -0
- data/{OneMoreUDID.gemspec → omudid.gemspec} +1 -1
- metadata +8 -5
data/Gemfile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'cupertino'
|
3
|
+
gem 'cupertino'
|
4
4
|
gem 'spinning_cursor'
|
5
5
|
gem 'rainbow'
|
6
6
|
|
7
|
-
# Specify your gem's dependencies in
|
7
|
+
# Specify your gem's dependencies in omudid.gemspec
|
8
8
|
gemspec
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Uploading a new provisioning profile to TestFlight is also supported.
|
|
8
8
|
Installation
|
9
9
|
-
|
10
10
|
```
|
11
|
-
$ gem install
|
11
|
+
$ gem install omudid
|
12
12
|
```
|
13
13
|
|
14
14
|
Usage
|
@@ -16,4 +16,95 @@ Usage
|
|
16
16
|
```
|
17
17
|
$ omudid add
|
18
18
|
$ omudid testflight upload
|
19
|
-
```
|
19
|
+
```
|
20
|
+
|
21
|
+
Example Output
|
22
|
+
-
|
23
|
+
```
|
24
|
+
$ omudid add
|
25
|
+
Apple Username:
|
26
|
+
appleuser@example.com
|
27
|
+
Apple Password:
|
28
|
+
************
|
29
|
+
Profile name (leave blank to select from available profiles):
|
30
|
+
|
31
|
+
Device name:
|
32
|
+
DeviceTen
|
33
|
+
UDID:
|
34
|
+
B123456789012345678901234567890123456789
|
35
|
+
|
36
|
+
Loading page... done
|
37
|
+
Loading page... done
|
38
|
+
|
39
|
+
Note: you can specify the team with a command-line argument
|
40
|
+
|
41
|
+
Please select one of the following teams:
|
42
|
+
1. Y2ZAFJ6Z9R: Team 1 - iOS Developer Program
|
43
|
+
2. LDF73KN5AM: Team 2 - iOS Developer Program
|
44
|
+
? 1
|
45
|
+
|
46
|
+
Loading page... done
|
47
|
+
Device DeviceTen (B123456789012345678901234567890123456789) added
|
48
|
+
|
49
|
+
Loading page... done
|
50
|
+
Loading page... done
|
51
|
+
|
52
|
+
Select a profile:
|
53
|
+
1. profile2
|
54
|
+
2. demo1
|
55
|
+
3. demo3
|
56
|
+
? 2
|
57
|
+
|
58
|
+
Note: you can repeat this process by running:
|
59
|
+
omudid add appleuser@example.com [password] demo1 DeviceTen B123456789012345678901234567890123456789 Y2ZAFJ6Z9R
|
60
|
+
|
61
|
+
Loading page... done
|
62
|
+
Loading page... done
|
63
|
+
Loading page... done
|
64
|
+
Loading page... done
|
65
|
+
Loading page... done
|
66
|
+
Loading page... done
|
67
|
+
Loading page... done
|
68
|
+
Loading page... done
|
69
|
+
Loading page... done
|
70
|
+
Loading page... done
|
71
|
+
Downloaded new profile (./demo1.mobileprovision)
|
72
|
+
Old profile deleted (~/Library/MobileDevice/Provisioning Profiles/demo1.mobileprovision)
|
73
|
+
New profile installed (~/Library/MobileDevice/Provisioning Profiles/demo1.mobileprovision)
|
74
|
+
|
75
|
+
$ omudid testflight upload
|
76
|
+
TestFlight Username:
|
77
|
+
testflightuser@example.com
|
78
|
+
TestFlight Password:
|
79
|
+
********
|
80
|
+
Build ID (leave blank to select from available IDs):
|
81
|
+
|
82
|
+
Profile name (leave blank to select from available local profiles):
|
83
|
+
|
84
|
+
Enter an App ID to list builds (or leave blank to list App IDs):
|
85
|
+
|
86
|
+
|
87
|
+
Loading page... done
|
88
|
+
Loading page... done
|
89
|
+
Select an app ID:
|
90
|
+
1. 151463 (com.example.identifier)
|
91
|
+
? 1
|
92
|
+
|
93
|
+
|
94
|
+
Loading page... done
|
95
|
+
Select a build ID:
|
96
|
+
1. 1857636 (1.0 (1.0))
|
97
|
+
? 1
|
98
|
+
|
99
|
+
Select a profile:
|
100
|
+
1. profile2
|
101
|
+
2. demo1
|
102
|
+
3. demo3
|
103
|
+
? 2
|
104
|
+
|
105
|
+
Note: you can repeat this process by running:
|
106
|
+
omudid testflight list-builds testflightuser@example.com [password] 1857636 demo1
|
107
|
+
|
108
|
+
Loading page... done
|
109
|
+
Submitted ~/Library/MobileDevice/Provisioning Profiles/demo1.mobileprovision
|
110
|
+
```
|
data/bin/omudid
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
module OneMoreUDID
|
2
|
+
class LocalAgent
|
3
|
+
def install_profile(profile_name, filename)
|
4
|
+
|
5
|
+
Dir.glob(File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
6
|
+
|
7
|
+
delete_file = false
|
8
|
+
|
9
|
+
File.open(file, "r") do |_file|
|
10
|
+
|
11
|
+
file_contents = _file.read
|
12
|
+
if String.method_defined?(:encode)
|
13
|
+
#file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
|
14
|
+
|
15
|
+
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
|
16
|
+
file_contents.encode!('UTF-8', 'UTF-16')
|
17
|
+
end
|
18
|
+
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match file_contents
|
19
|
+
|
20
|
+
if matches[1] == profile_name
|
21
|
+
delete_file = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if delete_file
|
26
|
+
say_warning 'Old profile deleted ('+ file +')'
|
27
|
+
File.delete(file)
|
28
|
+
break
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
new_path = File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/' + filename
|
34
|
+
File.rename(Dir.pwd + '/' + filename, new_path)
|
35
|
+
|
36
|
+
say_ok 'New profile installed ('+new_path+')'
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_profiles
|
40
|
+
|
41
|
+
profiles = []
|
42
|
+
|
43
|
+
Dir.glob(File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
44
|
+
|
45
|
+
File.open(file, "r") do |_file|
|
46
|
+
|
47
|
+
file_contents = _file.read
|
48
|
+
if String.method_defined?(:encode)
|
49
|
+
#file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
|
50
|
+
|
51
|
+
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
|
52
|
+
file_contents.encode!('UTF-8', 'UTF-16')
|
53
|
+
end
|
54
|
+
|
55
|
+
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match file_contents
|
56
|
+
profiles << matches[1]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
profiles
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -1,11 +1,4 @@
|
|
1
|
-
require 'mechanize'
|
2
|
-
require 'spinning_cursor'
|
3
|
-
require 'rainbow'
|
4
|
-
require 'iconv' unless String.method_defined?(:encode)
|
5
|
-
|
6
1
|
module OneMoreUDID
|
7
|
-
VERSION = "1.0.3"
|
8
|
-
|
9
2
|
class PortalAgent
|
10
3
|
|
11
4
|
attr_accessor :agent
|
@@ -197,149 +190,4 @@ module OneMoreUDID
|
|
197
190
|
filename
|
198
191
|
end
|
199
192
|
end
|
200
|
-
|
201
|
-
class LocalAgent
|
202
|
-
def install_profile(profile_name, filename)
|
203
|
-
|
204
|
-
Dir.glob(File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
205
|
-
|
206
|
-
delete_file = false
|
207
|
-
|
208
|
-
File.open(file, "r") do |_file|
|
209
|
-
|
210
|
-
file_contents = _file.read
|
211
|
-
if String.method_defined?(:encode)
|
212
|
-
file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
|
213
|
-
end
|
214
|
-
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match file_contents
|
215
|
-
|
216
|
-
if matches[1] == profile_name
|
217
|
-
delete_file = true
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
if delete_file
|
222
|
-
say_warning 'Old profile deleted ('+ file +')'
|
223
|
-
File.delete(file)
|
224
|
-
break
|
225
|
-
end
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
new_path = File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/' + filename
|
230
|
-
File.rename(Dir.pwd + '/' + filename, new_path)
|
231
|
-
|
232
|
-
say_ok 'New profile installed ('+new_path+')'
|
233
|
-
end
|
234
|
-
|
235
|
-
def get_profiles
|
236
|
-
|
237
|
-
profiles = []
|
238
|
-
|
239
|
-
Dir.glob(File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
240
|
-
|
241
|
-
File.open(file, "r") do |_file|
|
242
|
-
|
243
|
-
file_contents = _file.read
|
244
|
-
if String.method_defined?(:encode)
|
245
|
-
file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
|
246
|
-
end
|
247
|
-
|
248
|
-
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match file_contents
|
249
|
-
profiles << matches[1]
|
250
|
-
end
|
251
|
-
|
252
|
-
end
|
253
|
-
|
254
|
-
profiles
|
255
|
-
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
class TestFlightAgent < ::Mechanize
|
260
|
-
|
261
|
-
attr_accessor :username, :password
|
262
|
-
|
263
|
-
def initialize(username, password)
|
264
|
-
super()
|
265
|
-
@username = username
|
266
|
-
@password = password
|
267
|
-
self
|
268
|
-
end
|
269
|
-
|
270
|
-
def get(uri, parameters = [], referer = nil, headers = {})
|
271
|
-
3.times do
|
272
|
-
SpinningCursor.start do
|
273
|
-
banner 'Loading page...'
|
274
|
-
action do
|
275
|
-
super(uri, parameters, referer, headers)
|
276
|
-
end
|
277
|
-
message 'Loading page... '+'done'.color(:green)
|
278
|
-
end
|
279
|
-
|
280
|
-
return page unless page.respond_to?(:body)
|
281
|
-
|
282
|
-
case page.body
|
283
|
-
when /Login to TestFlight and FlightPath/
|
284
|
-
login! and next
|
285
|
-
else
|
286
|
-
return page
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
raise UnsuccessfulAuthenticationError
|
291
|
-
end
|
292
|
-
|
293
|
-
def get_apps
|
294
|
-
get('https://testflightapp.com/dashboard/applications/')
|
295
|
-
|
296
|
-
apps = page.search('tr.goapp')
|
297
|
-
regex = /([0-9]+)/
|
298
|
-
apps.collect { |app| [(app['id'].match regex)[1], app.search('h2 small').text.strip] }
|
299
|
-
end
|
300
|
-
|
301
|
-
def get_builds(app_id)
|
302
|
-
get("https://testflightapp.com/dashboard/applications/#{app_id}/builds/")
|
303
|
-
|
304
|
-
builds = page.search('tr.goversion')
|
305
|
-
regex = /([0-9]+)/
|
306
|
-
builds.collect { |build| [(build['id'].match regex)[1], build.search('td:first')[0].text] }
|
307
|
-
end
|
308
|
-
|
309
|
-
def upload(build_id, profile_name)
|
310
|
-
get("https://testflightapp.com/dashboard/builds/update/#{build_id}/")
|
311
|
-
|
312
|
-
profile_file = get_profile_file(profile_name)
|
313
|
-
|
314
|
-
form = page.form_with(:id => 'provision-form')
|
315
|
-
upload = form.file_uploads.first
|
316
|
-
upload.file_name = profile_file.path
|
317
|
-
form.submit
|
318
|
-
|
319
|
-
say_ok 'Submitted '+profile_file.path
|
320
|
-
end
|
321
|
-
|
322
|
-
def get_profile_file(profile_name)
|
323
|
-
Dir.glob(::File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
324
|
-
|
325
|
-
::File.open(file, "r") do |_file|
|
326
|
-
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match _file.read
|
327
|
-
if matches[1] == profile_name
|
328
|
-
return _file
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
private
|
336
|
-
|
337
|
-
def login!
|
338
|
-
form = page.forms[0]
|
339
|
-
form.username = self.username
|
340
|
-
form.password = self.password
|
341
|
-
form.submit
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
end
|
193
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module OneMoreUDID
|
2
|
+
class TestFlightAgent < ::Mechanize
|
3
|
+
|
4
|
+
attr_accessor :username, :password
|
5
|
+
|
6
|
+
def initialize(username, password)
|
7
|
+
super()
|
8
|
+
@username = username
|
9
|
+
@password = password
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(uri, parameters = [], referer = nil, headers = {})
|
14
|
+
3.times do
|
15
|
+
SpinningCursor.start do
|
16
|
+
banner 'Loading page...'
|
17
|
+
action do
|
18
|
+
super(uri, parameters, referer, headers)
|
19
|
+
end
|
20
|
+
message 'Loading page... '+'done'.color(:green)
|
21
|
+
end
|
22
|
+
|
23
|
+
return page unless page.respond_to?(:body)
|
24
|
+
|
25
|
+
case page.body
|
26
|
+
when /Login to TestFlight and FlightPath/
|
27
|
+
login! and next
|
28
|
+
else
|
29
|
+
return page
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
raise UnsuccessfulAuthenticationError
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_apps
|
37
|
+
get('https://testflightapp.com/dashboard/applications/')
|
38
|
+
|
39
|
+
apps = page.search('tr.goapp')
|
40
|
+
regex = /([0-9]+)/
|
41
|
+
apps.collect { |app| [(app['id'].match regex)[1], app.search('h2 small').text.strip] }
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_builds(app_id)
|
45
|
+
get("https://testflightapp.com/dashboard/applications/#{app_id}/builds/")
|
46
|
+
|
47
|
+
builds = page.search('tr.goversion')
|
48
|
+
regex = /([0-9]+)/
|
49
|
+
builds.collect { |build| [(build['id'].match regex)[1], build.search('td:first')[0].text] }
|
50
|
+
end
|
51
|
+
|
52
|
+
def upload(build_id, profile_name)
|
53
|
+
get("https://testflightapp.com/dashboard/builds/update/#{build_id}/")
|
54
|
+
|
55
|
+
profile_file = get_profile_file(profile_name)
|
56
|
+
|
57
|
+
form = page.form_with(:id => 'provision-form')
|
58
|
+
upload = form.file_uploads.first
|
59
|
+
upload.file_name = profile_file.path
|
60
|
+
form.submit
|
61
|
+
|
62
|
+
say_ok 'Submitted '+profile_file.path+"\n"+'Share link: '+page.link_with(:dom_class => 'bitly').text
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_profile_file(profile_name)
|
66
|
+
Dir.glob(::File.expand_path('~') + '/Library/MobileDevice/Provisioning Profiles/*.mobileprovision') do |file|
|
67
|
+
|
68
|
+
::File.open(file, "r") do |_file|
|
69
|
+
file_contents = _file.read
|
70
|
+
if String.method_defined?(:encode)
|
71
|
+
#file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
|
72
|
+
|
73
|
+
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
|
74
|
+
file_contents.encode!('UTF-8', 'UTF-16')
|
75
|
+
end
|
76
|
+
matches = /<key>Name<\/key>\s+<string>([^<]+)<\/string>/.match file_contents
|
77
|
+
if matches[1] == profile_name
|
78
|
+
return _file
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def login!
|
88
|
+
form = page.forms[0]
|
89
|
+
form.username = self.username
|
90
|
+
form.password = self.password
|
91
|
+
form.submit
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/omudid.rb
ADDED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 6
|
9
|
+
version: 1.0.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Lawson
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2013-
|
17
|
+
date: 2013-06-27 00:00:00 +10:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -105,12 +105,15 @@ files:
|
|
105
105
|
- .gitignore
|
106
106
|
- Gemfile
|
107
107
|
- LICENSE.txt
|
108
|
-
- OneMoreUDID.gemspec
|
109
108
|
- README.md
|
110
109
|
- Rakefile
|
111
110
|
- bin/omudid
|
112
|
-
- lib/OneMoreUDID.rb
|
113
111
|
- lib/cupertino_compatibility.rb
|
112
|
+
- lib/omudid.rb
|
113
|
+
- lib/omudid/local_agent.rb
|
114
|
+
- lib/omudid/portal_agent.rb
|
115
|
+
- lib/omudid/testflight_agent.rb
|
116
|
+
- omudid.gemspec
|
114
117
|
has_rdoc: true
|
115
118
|
homepage: https://github.com/Papercloud/OneMoreUDID
|
116
119
|
licenses:
|