Permalink
Browse files

Initial import

  • Loading branch information...
0 parents commit 1974b527b056342ac2b3ca9549c754c29ad6b59b @mattt mattt committed Jul 5, 2012
3 Gemfile
@@ -0,0 +1,3 @@
+source :rubygems
+
+gemspec
42 Gemfile.lock
@@ -0,0 +1,42 @@
+PATH
+ remote: .
+ specs:
+ cupertino (0.0.1)
+ commander (~> 4.1.2)
+ mechanize (~> 2.5.1)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ commander (4.1.2)
+ highline (~> 1.6.11)
+ domain_name (0.5.3)
+ unf (~> 0.0.3)
+ highline (1.6.12)
+ mechanize (2.5.1)
+ domain_name (~> 0.5, >= 0.5.1)
+ mime-types (~> 1.17, >= 1.17.2)
+ net-http-digest_auth (~> 1.1, >= 1.1.1)
+ net-http-persistent (~> 2.5, >= 2.5.2)
+ nokogiri (~> 1.4)
+ ntlm-http (~> 0.1, >= 0.1.1)
+ webrobots (~> 0.0, >= 0.0.9)
+ mime-types (1.19)
+ net-http-digest_auth (1.2.1)
+ net-http-persistent (2.7)
+ nokogiri (1.5.5)
+ ntlm-http (0.1.1)
+ rake (0.9.2.2)
+ rspec (0.6.4)
+ unf (0.0.5)
+ unf_ext
+ unf_ext (0.0.5)
+ webrobots (0.0.13)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ cupertino!
+ rake (~> 0.9.2)
+ rspec (~> 0.6.1)
43 README.md
@@ -0,0 +1,43 @@
+# Cupertino
+**Mechanize the Apple Dev Center**
+
+Automate administrative tasks that you would normally have to do through the Apple Dev Center websites. Life's too short to manage device identifiers by hand!
+
+This project is starting with the iOS Provisioning Portal, and may later expand to include iTunes Connect and/or Mac Developer Certificate Utility.
+
+## Usage
+
+```sh
+$ ios devices:list
+
+Mattt Thompson's iPad abcdef0123456789...
+Mattt Thompson's iPhone abcdef0123456789...
+
+$ ios devices:add "iPad 1"=abc123
+$ ios devices:add "iPad 2"=def456 "iPad 3"=ghi789 ...
+
+$ ios devices:remove "iPad 1"
+```
+
+## Commands
+
+- `devices:list`
+
+### To Be Implemented
+
+#### Devices
+
+- `devices:add`
+- `devices:remove`
+
+#### Certificates
+
+- `certificates:list [-e development|distribution]`
+- `certificates:add [-e development|distribution]`
+- `certificates:download CERTIFICATE_NAME`
+- `certificates:revoke CERTIFICATE_NAME`
+
+#### Application IDs
+
+- `app_ids:list`
+- `app_ids:new`
10 Rakefile
@@ -0,0 +1,10 @@
+require "bundler"
+Bundler.setup
+
+gemspec = eval(File.read("cupertino.gemspec"))
+
+task :build => "#{gemspec.full_name}.gem"
+
+file "#{gemspec.full_name}.gem" => gemspec.files + ["cupertino.gemspec"] do
+ system "gem build cupertino.gemspec"
+end
20 bin/ios
@@ -0,0 +1,20 @@
+#!/usr/bin/env ruby
+
+require 'commander/import'
+
+$:.push File.expand_path("../../lib", __FILE__)
+
+require 'cupertino'
+
+HighLine.track_eof = false # Fix for built-in Ruby
+
+program :version, Cupertino::VERSION
+program :description, 'A command-line interface for the iOS Provisioning Portal'
+
+program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
+program :help, 'Website', 'https://github.com/mattt'
+program :help_formatter, :compact
+
+default_command :help
+
+require 'cupertino/provisioning_portal'
25 cupertino.gemspec
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "cupertino"
+
+Gem::Specification.new do |s|
+ s.name = "cupertino"
+ s.authors = ["Mattt Thompson"]
+ s.email = "m@mattt.me"
+ s.homepage = "http://mattt.me"
+ s.version = Cupertino::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.summary = "Cupertino"
+ s.description = "Mechanize the Apple Developer Center"
+
+ s.add_development_dependency "rspec", "~> 0.6.1"
+ s.add_development_dependency "rake", "~> 0.9.2"
+
+ s.add_dependency "commander", "~> 4.1.2"
+ s.add_dependency "mechanize", "~> 2.5.1"
+
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
3 lib/cupertino.rb
@@ -0,0 +1,3 @@
+module Cupertino
+ VERSION = '0.0.1'
+end
16 lib/cupertino/provisioning_portal.rb
@@ -0,0 +1,16 @@
+require 'mechanize'
+
+module Cupertino
+ module ProvisioningPortal
+ class Device < Struct.new(:name, :udid); end
+ class Certificate < Struct.new(:name, :provisioning_profiles, :expiration_date, :status); end
+ class AppID < Struct.new(:bundle_seed_id, :description, :development_properties, :distribution_properties); end
+ class ProvisioningProfile < Struct.new(:name, :app_id, :status); end
+ end
+end
+
+$:.push File.expand_path('../', __FILE__)
+
+require 'provisioning_portal/helpers'
+require 'provisioning_portal/agent'
+require 'provisioning_portal/commands'
63 lib/cupertino/provisioning_portal/agent.rb
@@ -0,0 +1,63 @@
+require 'mechanize'
+
+module Cupertino
+ module ProvisioningPortal
+ class Agent < ::Mechanize
+ attr_accessor :username, :password, :team
+
+ def initialize
+ super
+ self.user_agent_alias = 'Mac Safari'
+ end
+
+ def get(uri, parameters = [], referer = nil, headers = {})
+ 3.times do
+ super(uri, parameters, referer, headers)
+
+ case page.title
+ when %r{Sign in with your Apple ID}
+ login! and redo
+ when %r{Select Your Team}
+ select_team! and redo
+ else
+ return page
+ end
+ end
+ end
+
+ def list_devices
+ get("https://developer.apple.com/ios/manage/devices/index.action")
+
+ devices = []
+ page.parser.xpath('//fieldset[@id="fs-0"]/table/tbody/tr').each do |row|
+ device = Device.new
+ device.name = row.at_xpath('td[@class="name"]/span/text()')
+ device.udid = row.at_xpath('td[@class="id"]/text()')
+ devices << device
+ end
+ devices
+ end
+
+ private
+
+ def login!
+ if form = page.form_with(:name => 'appleConnectForm')
+ form.theAccountName = self.username
+ form.theAccountPW = self.password
+ form.submit
+ end
+ end
+
+ def select_team!
+ if form = page.form_with(:name => 'saveTeamSelection')
+ team_list = form.field_with(:name => 'memberDisplayId')
+ team_option = team_list.option_with(:text => self.team)
+ team_option.select
+
+ btn = form.button_with(:name => 'action:saveTeamSelection!save')
+ form.click_button(btn)
+ end
+ end
+ end
+ end
+end
5 lib/cupertino/provisioning_portal/commands.rb
@@ -0,0 +1,5 @@
+include Cupertino::ProvisioningPortal::Helpers
+
+$:.push File.expand_path('../', __FILE__)
+
+require 'commands/devices'
16 lib/cupertino/provisioning_portal/commands/devices.rb
@@ -0,0 +1,16 @@
+command :'devices:list' do |c|
+ c.syntax = 'ios devices:list'
+ c.summary = 'Lists the Name and ID of Devices in the Provisioning Portal'
+ c.description = ''
+
+ c.action do |args, options|
+ devices = agent.list_devices
+
+ say_ok "Devices:"
+ devices.each do |device|
+ log device.name, device.udid
+ end
+ end
+end
+
+alias_command :devices, :'devices:list'
33 lib/cupertino/provisioning_portal/helpers.rb
@@ -0,0 +1,33 @@
+# Monkey Patch Commander::UI to alias password to avoid conflicts
+module Commander::UI
+ alias :pw :password
+end
+
+module Cupertino
+ module ProvisioningPortal
+ module Helpers
+ def agent
+ unless @agent
+ @agent = Cupertino::ProvisioningPortal::Agent.new
+
+ @agent.instance_eval do
+ def username
+ @username ||= ask "Username:"
+ end
+
+ def password
+ @password ||= pw "Password:"
+ end
+
+ def team
+ teams = page.form_with(:name => 'saveTeamSelection').field_with(:name => 'memberDisplayId').options.collect(&:text)
+ @team ||= choose "Select a team:", *teams
+ end
+ end
+ end
+
+ @agent
+ end
+ end
+ end
+end

0 comments on commit 1974b52

Please sign in to comment.