class TestFlightExporter::Setup
Public Class Methods
new()
click to toggle source
# File lib/testflight_exporter.rb, line 13 def initialize @agent = Mechanize.new @team_list = Hash.new @downloaded_binaries = 0 end
Public Instance Methods
download_build(link, file_ext, release_note)
click to toggle source
# File lib/testflight_exporter.rb, line 264 def download_build link, file_ext, release_note link.href =~ /\/dashboard\/ipa\/(.*?)\// filename = "#{$1}.#{file_ext}" file_url = "https://www.testflightapp.com#{link.href}" Helper.log.debug "Downloading #{file_url}...".magenta dirname = File.dirname("#{@path}/#{@current_team}") FileUtils.mkdir_p(dirname) unless File.directory?(dirname) dirname = File.dirname("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds") FileUtils.mkdir_p(dirname) unless File.directory?(dirname) @agent.get(file_url).save("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{filename}") if File.file?("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{filename}") @downloaded_binaries = @downloaded_binaries + 1 @build_downloaded_binaries = @build_downloaded_binaries + 1 File.open("#{@path}/#{@current_team}/#{@current_bundle_identifier} builds/#{$1}.txt", 'w') {|f| f.write(release_note) } unless release_note.nil? end end
exit_by_print_success_builds_no()
click to toggle source
# File lib/testflight_exporter.rb, line 289 def exit_by_print_success_builds_no Helper.log.info "#{@downloaded_binaries} binaries have been successfully downloaded! ".green unless @downloaded_binaries==0 Helper.log.info "Thanks for using our tool. Hoped you liked it. Please don't forget to share it ;)".cyan exit end
process_app_information(app_information_page)
click to toggle source
# File lib/testflight_exporter.rb, line 207 def process_app_information app_information_page @agent.get "https://testflightapp.com#{app_information_page}" do |app_information| # Looking up the bundle identifier @current_bundle_identifier = app_information.at("strong:contains('BundleID')").parent.parent.at("td").next.text end end
process_build_page(page)
click to toggle source
# File lib/testflight_exporter.rb, line 232 def process_build_page page # Get build information []i.e. Build 1.0 (1)] build_str = page.search('.vert-nav').search('.anchor').text @current_build_number = build_str.gsub!(/.*?(?=Build)/im, "") build_link = page.links_with(:dom_class => 'bitly').first @agent.get("https://www.testflightapp.com#{build_link.href}") { |install_page| process_install_page install_page} end
process_builds_page(page)
click to toggle source
# File lib/testflight_exporter.rb, line 214 def process_builds_page page body = page.body build_pages = body.scan /<tr class="goversion pointer" id="\/dashboard\/builds\/report\/(.*?)\/">/ build_pages.each do |build_id| unless @max.nil? break if @build_downloaded_binaries == @max end @agent.get "https://testflightapp.com/dashboard/builds/complete/#{build_id.first}/" do |build_page| # Retrieve current app name @current_app_name = page.at("h2").text process_build_page build_page end end end
process_dashboard_page(dashboard_page)
click to toggle source
# File lib/testflight_exporter.rb, line 162 def process_dashboard_page dashboard_page app_link_pattern = /\/dashboard\/applications\/(.*?)\/token\// dashboard_page.links.each do |link| link.href =~ app_link_pattern if $1 != nil Helper.log.debug "Builds page for #{$1}...".magenta @build_downloaded_binaries = 0 @agent.get "https://testflightapp.com/dashboard/applications/#{$1}/builds/" do |builds_page| # Processing app information to retrieve additional information on current application app_information_link = builds_page.link_with(:text => "App Information") process_app_information app_information_link.href # Collection of all pages for current build inner_pages = Array.new builds_page.links.each do |ll| inner_pages.push(ll.href) if ll.href =~ /\?page=*/ unless inner_pages.include?(ll.href) end number_of_pages = inner_pages.count + 1 Helper.log.debug "Page 1 of #{number_of_pages}".magenta # Process current build page process_builds_page builds_page # Cycle over remaning build pages i = 2 inner_pages.each do |page| break if (!@max.nil? && @build_downloaded_binaries == @max) Helper.log.debug "Page #{i} of #{number_of_pages}".magenta process_builds_page @agent.get "https://testflightapp.com#{page}" i = i+1 end end end end end
process_install_page(page)
click to toggle source
# File lib/testflight_exporter.rb, line 242 def process_install_page page # we need to figure out what kind of build is that release_note = page.search('.clearfix').at("p") if release_note.nil? Helper.log.warn "No release note available for #{@current_app_name} #{@current_build_number}".yellow else release_note = release_note.text Helper.log.debug "RELEASE NOTE".magenta Helper.log.debug release_note.magenta end ipa_link = page.link_with(:text => "download the IPA.") ipa_link = page.link_with(:text => "download the IPA") if ipa_link.nil? if ipa_link.nil? Helper.log.warn "No IPA link found. Do you have permission for current application?".yellow else download_build(ipa_link, "ipa", release_note) end end
process_login_page(page)
click to toggle source
# File lib/testflight_exporter.rb, line 41 def process_login_page page # Init login process Helper.log.info 'Login...'.green login_form = page.forms.first # by pretty printing the page this is safe catch login_field = login_form.field_with(:name => 'username') password_field = login_form.field_with(:name => 'password') login_field.value = @username password_field.value = @password login_form.submit @agent.get("https://testflightapp.com/dashboard/applications/") do |dashboard_page| @dashboard_page = dashboard_page @dashboard_page.links.each do |ll| # Retrieve current team if ll.attributes.attributes['class'] @current_team = ll if ll.attributes.attributes['class'].text.eql? "dropdown-toggle team-menu" end # Retrieve other team id list @team_list.merge!({ll.text=>ll.attributes['data-team-id']}) if ll.attributes['data-team-id'] end # If we don't have any current team something went wrong with the authentication process if (@current_team.nil? || @current_team.text.empty?) Helper.exit_with_error "Something went wrong during authentication process." end unless @team.nil? process_teams false, @team exit_by_print_success_builds_no end if (@team_list.count > 1) # We have multiple teams for current account hence we present a nice menu selection to the user choose do |menu| menu.prompt = "Please choose your team? " menu.choice(@current_team.to_s) do |choice| process_teams false, choice end @team_list.each do |team_name, team_id| menu.choice(team_name) do |choice| process_teams false, choice end end menu.choice("All teams") { process_teams true } end else # process current team Helper.log.info "This could take a while... ☕️".green Helper.log.info "Processing team: #{@current_team}".blue process_dashboard_page dashboard_page end end end
process_teams(process_all_teams, team_name=nil)
click to toggle source
# File lib/testflight_exporter.rb, line 109 def process_teams process_all_teams, team_name=nil if process_all_teams # process current team Helper.log.info "This could take a while... ☕️".green Helper.log.info "Processing team: #{@current_team}".blue process_dashboard_page @dashboard_page # process other teams @team_list.each do |team_name, team_id| switch_to_team_id team_id, team_name process_dashboard_page @agent.get("https://testflightapp.com/dashboard/applications/") end else if @current_team.to_s == team_name # process current team Helper.log.info "Processing team: #{@current_team}".blue process_dashboard_page @dashboard_page exit_by_print_success_builds_no else if @team_list["#{team_name}"].nil? Helper.exit_with_error "Sorry, I can\'t find #{team_name} in your teams.".red end switch_to_team_id @team_list["#{team_name}"], team_name # process current team process_dashboard_page @agent.get("https://testflightapp.com/dashboard/applications/") exit_by_print_success_builds_no end end end
setup(options)
click to toggle source
# File lib/testflight_exporter.rb, line 19 def setup (options) @username = options.username @password = options.password @team = options.team @path = options.output @max = options.max @username = ask("Enter your TestFlight username: ") { |q| q.echo = true } if @username.nil? @password = ask("Enter your TestFlight password: ") { |q| q.echo = "*" } if @password.nil? @path = ask("Enter your output folder where all the IPAs will be downloaded: "){ |q| q.echo = true } if @path.nil? # Validate ouput folder if File.directory?(@path) # The in input path already exist we prefer to fail instead of using overriding policies Helper.exit_with_error "\"#{@path}\" is an existing directory. Please specify another output folder".red end # Initialize Test Flight login page login_page_url = "https://testflightapp.com/login/" @agent.get(login_page_url) { |page| process_login_page page } end
switch_to_team_id(team_id, team_name)
click to toggle source
# File lib/testflight_exporter.rb, line 146 def switch_to_team_id team_id, team_name team_switch = @dashboard_page.forms.first team_id_field = team_switch.field_with(:name => 'team') team_id_field.value = team_id begin team_switch.submit @current_team = team_name Helper.log.info "Processing team: #{@current_team}".blue rescue Exception => e Helper.exit_with_error e end end