TestFlightExporter 0.0.2 → 0.0.3
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/bin/tfexporter +8 -1
- data/lib/helpers.rb +8 -1
- data/lib/testflight_exporter/version.rb +1 -1
- data/lib/testflight_exporter.rb +23 -19
- metadata +2 -3
- data/tfexplorer.rb +0 -157
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 052bc7e1678d11f15af785d88483aab0094603c5
|
4
|
+
data.tar.gz: ffa7d445b1642cd57567aa408fdb5d8bbadde053
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9833004a1a88899d46dc819ddcc2aff002d69181df48dfa780dc321d00f280cebdf5fe101528fed70148f71b6ffd2bac640695ce7cde44321cc8706af56a3349
|
7
|
+
data.tar.gz: 8556d2d824f1333a84ef7f30de19c35f8bfb04096bd7dc1740265f2658042c9e4aefd4af7fd0c6463df02f90cad1822516e90e73566c7e8662b82b23111e5b51
|
data/bin/tfexporter
CHANGED
@@ -20,6 +20,11 @@ class TestFlightExporterApplication
|
|
20
20
|
program :help, 'Website', 'http://www.touchwonders.com'
|
21
21
|
program :help_formatter, :compact
|
22
22
|
|
23
|
+
global_option '--verbose'
|
24
|
+
global_option '--username STRING', String, 'Your testflight account username'
|
25
|
+
global_option '--password STRING', String, 'Your testflight account password'
|
26
|
+
global_option '--output STRING', String, 'Path to your output folder where your IPA will be downloaded'
|
27
|
+
|
23
28
|
always_trace!
|
24
29
|
|
25
30
|
command :migrate do |c|
|
@@ -27,7 +32,9 @@ class TestFlightExporterApplication
|
|
27
32
|
c.description = 'Helps you setting up all requirements to run a migration.'
|
28
33
|
|
29
34
|
c.action do |args, options|
|
30
|
-
|
35
|
+
ENV['VERBOSE_MODE'] = 'true' if options.verbose
|
36
|
+
|
37
|
+
TestFlightExporter::Setup.new.setup(options.username, options.password, options.output)
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
data/lib/helpers.rb
CHANGED
@@ -14,7 +14,7 @@ module TestFlightExporter
|
|
14
14
|
|
15
15
|
# Logging happens using this method
|
16
16
|
def self.log
|
17
|
-
|
17
|
+
@@log ||= Logger.new(STDOUT)
|
18
18
|
|
19
19
|
@@log.formatter = proc do |severity, datetime, progname, msg|
|
20
20
|
string = "#{severity} [#{datetime.strftime('%Y-%m-%d %H:%M:%S.%2N')}]: "
|
@@ -36,9 +36,16 @@ module TestFlightExporter
|
|
36
36
|
[string, second].join("")
|
37
37
|
end
|
38
38
|
|
39
|
+
@@log.level = Logger::INFO
|
40
|
+
@@log.level = Logger::DEBUG if is_log_verbose?
|
41
|
+
|
39
42
|
@@log
|
40
43
|
end
|
41
44
|
|
45
|
+
def self.is_log_verbose?
|
46
|
+
ENV['VERBOSE_MODE']
|
47
|
+
end
|
48
|
+
|
42
49
|
# EXIT HANDLERS
|
43
50
|
|
44
51
|
# Print error text with error format and exit with in input error_code (default=1)
|
data/lib/testflight_exporter.rb
CHANGED
@@ -15,13 +15,13 @@ module TestFlightExporter
|
|
15
15
|
@team_list = Hash.new
|
16
16
|
end
|
17
17
|
|
18
|
-
def setup
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@username = ask("Enter your TestFlight username: ") { |q| q.echo = true }
|
23
|
-
@password = ask("Enter your TestFlight password: ") { |q| q.echo = "*" }
|
24
|
-
@path = ask("Enter your output folder where all the IPAs will be downloaded: "){ |q| q.echo = true }
|
18
|
+
def setup (username=nil, password=nil, output_folder=nil)
|
19
|
+
@username = username
|
20
|
+
@password = password
|
21
|
+
@path = output_folder
|
22
|
+
@username = ask("Enter your TestFlight username: ") { |q| q.echo = true } if @username.nil?
|
23
|
+
@password = ask("Enter your TestFlight password: ") { |q| q.echo = "*" } if @password.nil?
|
24
|
+
@path = ask("Enter your output folder where all the IPAs will be downloaded: "){ |q| q.echo = true } if @path.nil?
|
25
25
|
|
26
26
|
# Validate ouput folder
|
27
27
|
if File.directory?(@path)
|
@@ -39,7 +39,7 @@ module TestFlightExporter
|
|
39
39
|
def process_login_page page
|
40
40
|
|
41
41
|
# Init login process
|
42
|
-
Helper.log.
|
42
|
+
Helper.log.info 'Login...'.green
|
43
43
|
|
44
44
|
login_form = page.forms.first # by pretty printing the page this is safe catch
|
45
45
|
|
@@ -86,7 +86,6 @@ module TestFlightExporter
|
|
86
86
|
end
|
87
87
|
else
|
88
88
|
# process current team
|
89
|
-
puts ""
|
90
89
|
Helper.log.info "This could take a while... ☕️".green
|
91
90
|
Helper.log.info "Processing team: #{@current_team}".blue
|
92
91
|
|
@@ -100,7 +99,6 @@ module TestFlightExporter
|
|
100
99
|
|
101
100
|
if process_all_teams
|
102
101
|
# process current team
|
103
|
-
puts ""
|
104
102
|
Helper.log.info "This could take a while... ☕️".green
|
105
103
|
Helper.log.info "Processing team: #{@current_team}".blue
|
106
104
|
|
@@ -174,7 +172,6 @@ module TestFlightExporter
|
|
174
172
|
|
175
173
|
number_of_pages = inner_pages.count + 1
|
176
174
|
Helper.log.debug "Page 1 of #{number_of_pages}".magenta
|
177
|
-
puts ""
|
178
175
|
|
179
176
|
# Process current build page
|
180
177
|
process_builds_page builds_page
|
@@ -182,7 +179,6 @@ module TestFlightExporter
|
|
182
179
|
# Cycle over remaning build pages
|
183
180
|
i = 2
|
184
181
|
inner_pages.each do |page|
|
185
|
-
puts ""
|
186
182
|
Helper.log.debug "Page #{i} of #{number_of_pages}".magenta
|
187
183
|
|
188
184
|
process_builds_page @agent.get "https://testflightapp.com#{page}"
|
@@ -210,7 +206,7 @@ module TestFlightExporter
|
|
210
206
|
build_pages.each do |build_id|
|
211
207
|
@agent.get "https://testflightapp.com/dashboard/builds/complete/#{build_id.first}/" do |build_page|
|
212
208
|
# Retrieve current app name
|
213
|
-
@
|
209
|
+
@current_app_name = page.at("h2").text
|
214
210
|
|
215
211
|
process_build_page build_page
|
216
212
|
end
|
@@ -218,16 +214,26 @@ module TestFlightExporter
|
|
218
214
|
end
|
219
215
|
|
220
216
|
def process_build_page page
|
217
|
+
|
218
|
+
# Get build information []i.e. Build 1.0 (1)]
|
219
|
+
build_str = page.search('.vert-nav').search('.anchor').text
|
220
|
+
@current_build_number = build_str.gsub!(/.*?(?=Build)/im, "")
|
221
|
+
|
221
222
|
build_link = page.links_with(:dom_class => 'bitly').first
|
222
223
|
@agent.get("https://www.testflightapp.com#{build_link.href}") { |install_page| process_install_page install_page}
|
223
224
|
end
|
224
225
|
|
225
226
|
def process_install_page page
|
226
227
|
# we need to figure out what kind of build is that
|
227
|
-
release_note = page.search('.clearfix').at("p")
|
228
|
+
release_note = page.search('.clearfix').at("p")
|
229
|
+
if release_note.nil?
|
230
|
+
Helper.log.warn "No release note available for #{@current_app_name} #{@current_build_number}".yellow
|
231
|
+
else
|
232
|
+
release_note = release_note.text
|
233
|
+
Helper.log.debug "RELEASE NOTE".magenta
|
234
|
+
Helper.log.debug release_note.magenta
|
235
|
+
end
|
228
236
|
|
229
|
-
Helper.log.debug "RELEASE NOTE".magenta
|
230
|
-
Helper.log.debug release_note.magenta
|
231
237
|
|
232
238
|
ipa_link = page.link_with(:text => "download the IPA.")
|
233
239
|
ipa_link = page.link_with(:text => "download the IPA") if ipa_link.nil?
|
@@ -237,8 +243,6 @@ module TestFlightExporter
|
|
237
243
|
else
|
238
244
|
download_build(ipa_link, "ipa", release_note)
|
239
245
|
end
|
240
|
-
|
241
|
-
puts ""
|
242
246
|
end
|
243
247
|
|
244
248
|
def download_build link, file_ext, release_note
|
@@ -258,7 +262,7 @@ module TestFlightExporter
|
|
258
262
|
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
259
263
|
|
260
264
|
@agent.get(file_url).save("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{filename}")
|
261
|
-
File.open("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{$1}.txt", 'w') {|f| f.write(release_note) }
|
265
|
+
File.open("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{$1}.txt", 'w') {|f| f.write(release_note) } unless release_note.nil?
|
262
266
|
end
|
263
267
|
end
|
264
268
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: TestFlightExporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fabio Milano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -112,7 +112,6 @@ files:
|
|
112
112
|
- lib/testflight_exporter.rb
|
113
113
|
- lib/testflight_exporter/version.rb
|
114
114
|
- testflight_exporter.gemspec
|
115
|
-
- tfexplorer.rb
|
116
115
|
homepage: ''
|
117
116
|
licenses:
|
118
117
|
- MIT
|
data/tfexplorer.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'mechanize'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
@agent = Mechanize.new
|
7
|
-
|
8
|
-
def process_login_page page
|
9
|
-
|
10
|
-
puts 'Login...'
|
11
|
-
|
12
|
-
login_form = page.forms.first # by pretty printing the page this is safe catch
|
13
|
-
|
14
|
-
login_field = login_form.field_with(:name => 'username')
|
15
|
-
password_field = login_form.field_with(:name => 'password')
|
16
|
-
|
17
|
-
login_field.value = 'fabio@touchwonders.com'
|
18
|
-
password_field.value = 'touchwondersworld'
|
19
|
-
|
20
|
-
login_form.submit
|
21
|
-
|
22
|
-
puts 'Dashboard...'
|
23
|
-
|
24
|
-
team_list = Hash.new
|
25
|
-
@current_team = String.new
|
26
|
-
|
27
|
-
@agent.get("https://testflightapp.com/dashboard/applications/") do |dashboard_page|
|
28
|
-
dashboard_page.links.each do |ll|
|
29
|
-
# Retrieve current team
|
30
|
-
if ll.attributes.attributes['class']
|
31
|
-
@current_team = ll if ll.attributes.attributes['class'].text.eql? "dropdown-toggle team-menu"
|
32
|
-
end
|
33
|
-
|
34
|
-
# Retrieve other team id list
|
35
|
-
team_list.merge!({ll.attributes['data-team-id']=>ll.text}) if ll.attributes['data-team-id']
|
36
|
-
end
|
37
|
-
|
38
|
-
# process current team
|
39
|
-
puts "Processing team: #{@current_team}"
|
40
|
-
|
41
|
-
process_dashboard_page dashboard_page
|
42
|
-
|
43
|
-
# process other teams
|
44
|
-
team_list.each do |team_id, team_name|
|
45
|
-
team_switch = dashboard_page.forms.first
|
46
|
-
team_id_field = team_switch.field_with(:name => 'team')
|
47
|
-
team_id_field.value = team_id
|
48
|
-
team_switch.submit
|
49
|
-
@current_team = team_name
|
50
|
-
|
51
|
-
process_dashboard_page @agent.get("https://testflightapp.com/dashboard/applications/")
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def process_dashboard_page dashboard_page
|
58
|
-
app_link_pattern = /\/dashboard\/applications\/(.*?)\/token\//
|
59
|
-
dashboard_page.links.each do |link|
|
60
|
-
link.href =~ app_link_pattern
|
61
|
-
if $1 != nil
|
62
|
-
puts "Builds page for #{$1}..."
|
63
|
-
@agent.get "https://testflightapp.com/dashboard/applications/#{$1}/builds/" do |builds_page|
|
64
|
-
|
65
|
-
# Collection of all pages for current build
|
66
|
-
inner_pages = Array.new
|
67
|
-
|
68
|
-
builds_page.links.each do |ll|
|
69
|
-
inner_pages.push(ll.href) if ll.href =~ /\?page=*/ unless inner_pages.include?(ll.href)
|
70
|
-
end
|
71
|
-
|
72
|
-
number_of_pages = inner_pages.count + 1
|
73
|
-
puts "Processing page 1 of #{number_of_pages}"
|
74
|
-
puts ""
|
75
|
-
|
76
|
-
# Process current build page
|
77
|
-
process_builds_page builds_page
|
78
|
-
|
79
|
-
# Cycle over remaning build pages
|
80
|
-
i = 2
|
81
|
-
inner_pages.each do |page|
|
82
|
-
puts ""
|
83
|
-
puts "Processing page #{i} of #{number_of_pages}"
|
84
|
-
|
85
|
-
process_builds_page @agent.get "https://testflightapp.com#{page}"
|
86
|
-
|
87
|
-
i = i+1
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def process_builds_page page
|
96
|
-
body = page.body
|
97
|
-
build_pages = body.scan /<tr class="goversion pointer" id="\/dashboard\/builds\/report\/(.*?)\/">/
|
98
|
-
|
99
|
-
build_pages.each do |build_id|
|
100
|
-
@agent.get "https://testflightapp.com/dashboard/builds/complete/#{build_id.first}/" do |build_page|
|
101
|
-
# Retrieve current app name
|
102
|
-
@app_name = page.at("h2").text
|
103
|
-
|
104
|
-
process_build_page build_page
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def process_build_page page
|
110
|
-
build_link = page.links_with(:dom_class => 'bitly').first
|
111
|
-
@agent.get("https://www.testflightapp.com#{build_link.href}") { |install_page| process_install_page install_page}
|
112
|
-
end
|
113
|
-
|
114
|
-
def process_install_page page
|
115
|
-
# we need to figure out what kind of build is that
|
116
|
-
release_note = page.search('.clearfix').at("p").text
|
117
|
-
|
118
|
-
puts "RELEASE NOTE"
|
119
|
-
puts release_note
|
120
|
-
|
121
|
-
ipa_link = page.link_with(:text => "download the IPA.")
|
122
|
-
ipa_link = ipa_link = page.link_with(:text => "download the IPA") if ipa_link.nil?
|
123
|
-
|
124
|
-
if ipa_link.nil?
|
125
|
-
puts "No IPA link found. Do you have permission for current application?"
|
126
|
-
else
|
127
|
-
download_build(ipa_link, "ipa", release_note)
|
128
|
-
end
|
129
|
-
|
130
|
-
puts ""
|
131
|
-
end
|
132
|
-
|
133
|
-
def download_build link, file_ext, release_note
|
134
|
-
|
135
|
-
link.href =~ /\/dashboard\/ipa\/(.*?)\//
|
136
|
-
filename = "#{$1}.#{file_ext}"
|
137
|
-
|
138
|
-
file_url = "https://www.testflightapp.com#{link.href}"
|
139
|
-
puts "Downloading #{file_url}..."
|
140
|
-
|
141
|
-
dirname = File.dirname("out/#{@current_team}")
|
142
|
-
|
143
|
-
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
144
|
-
|
145
|
-
dirname = File.dirname("out/#{@current_team}/#{@app_name}")
|
146
|
-
|
147
|
-
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
148
|
-
|
149
|
-
@agent.get(file_url).save("out/#{@current_team}/#{@app_name}/#{filename}")
|
150
|
-
File.open("out/#{@current_team}/#{@app_name}/#{$1}.txt", 'w') {|f| f.write(release_note) }
|
151
|
-
end
|
152
|
-
|
153
|
-
FileUtils.rm_rf "out"
|
154
|
-
Dir.mkdir "out"
|
155
|
-
|
156
|
-
login_page_url = "https://testflightapp.com/login/"
|
157
|
-
@agent.get(login_page_url) { |page| process_login_page page }
|