cupertino 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cupertino (0.0.2)
5
+ commander (~> 4.1.2)
6
+ mechanize (~> 2.5.1)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ commander (4.1.2)
12
+ highline (~> 1.6.11)
13
+ domain_name (0.5.3)
14
+ unf (~> 0.0.3)
15
+ highline (1.6.12)
16
+ mechanize (2.5.1)
17
+ domain_name (~> 0.5, >= 0.5.1)
18
+ mime-types (~> 1.17, >= 1.17.2)
19
+ net-http-digest_auth (~> 1.1, >= 1.1.1)
20
+ net-http-persistent (~> 2.5, >= 2.5.2)
21
+ nokogiri (~> 1.4)
22
+ ntlm-http (~> 0.1, >= 0.1.1)
23
+ webrobots (~> 0.0, >= 0.0.9)
24
+ mime-types (1.19)
25
+ net-http-digest_auth (1.2.1)
26
+ net-http-persistent (2.7)
27
+ nokogiri (1.5.5)
28
+ ntlm-http (0.1.1)
29
+ rake (0.9.2.2)
30
+ rspec (0.6.4)
31
+ unf (0.0.5)
32
+ unf_ext
33
+ unf_ext (0.0.5)
34
+ webrobots (0.0.13)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ cupertino!
41
+ rake (~> 0.9.2)
42
+ rspec (~> 0.6.1)
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Cupertino
2
+ **Mechanize the Apple Dev Center**
3
+
4
+ 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!
5
+
6
+ This project is starting with the iOS Provisioning Portal, and may later expand to include iTunes Connect and/or Mac Developer Certificate Utility.
7
+
8
+ ## Usage
9
+
10
+ ```sh
11
+ $ ios devices:list
12
+
13
+ Mattt Thompson's iPad abcdef0123456789...
14
+ Mattt Thompson's iPhone abcdef0123456789...
15
+
16
+ $ ios devices:add "iPad 1"=abc123
17
+ $ ios devices:add "iPad 2"=def456 "iPad 3"=ghi789 ...
18
+
19
+ $ ios devices:remove "iPad 1"
20
+ ```
21
+
22
+ ## Commands
23
+
24
+ - `devices:list`
25
+
26
+ ### To Be Implemented
27
+
28
+ #### Devices
29
+
30
+ - `devices:add`
31
+ - `devices:remove`
32
+
33
+ #### Certificates
34
+
35
+ - `certificates:list [-e development|distribution]`
36
+ - `certificates:add [-e development|distribution]`
37
+ - `certificates:download CERTIFICATE_NAME`
38
+ - `certificates:revoke CERTIFICATE_NAME`
39
+
40
+ #### Application IDs
41
+
42
+ - `app_ids:list`
43
+ - `app_ids:new`
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ gemspec = eval(File.read("cupertino.gemspec"))
5
+
6
+ task :build => "#{gemspec.full_name}.gem"
7
+
8
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["cupertino.gemspec"] do
9
+ system "gem build cupertino.gemspec"
10
+ end
data/bin/ios ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'commander/import'
4
+
5
+ $:.push File.expand_path("../../lib", __FILE__)
6
+
7
+ require 'cupertino'
8
+
9
+ HighLine.track_eof = false # Fix for built-in Ruby
10
+
11
+ program :version, Cupertino::VERSION
12
+ program :description, 'A command-line interface for the iOS Provisioning Portal'
13
+
14
+ program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
15
+ program :help, 'Website', 'https://github.com/mattt'
16
+ program :help_formatter, :compact
17
+
18
+ default_command :help
19
+
20
+ require 'cupertino/provisioning_portal'
data/cupertino.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cupertino"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "cupertino"
7
+ s.authors = ["Mattt Thompson"]
8
+ s.email = "m@mattt.me"
9
+ s.homepage = "http://mattt.me"
10
+ s.version = Cupertino::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "Cupertino"
13
+ s.description = "Mechanize the Apple Developer Center"
14
+
15
+ s.add_development_dependency "rspec", "~> 0.6.1"
16
+ s.add_development_dependency "rake", "~> 0.9.2"
17
+
18
+ s.add_dependency "commander", "~> 4.1.2"
19
+ s.add_dependency "mechanize", "~> 2.5.1"
20
+
21
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,86 @@
1
+ require 'mechanize'
2
+
3
+ module Cupertino
4
+ module ProvisioningPortal
5
+ class Agent < ::Mechanize
6
+ attr_accessor :username, :password, :team
7
+
8
+ def initialize
9
+ super
10
+ self.user_agent_alias = 'Mac Safari'
11
+ end
12
+
13
+ def get(uri, parameters = [], referer = nil, headers = {})
14
+ 3.times do
15
+ super(uri, parameters, referer, headers)
16
+
17
+ case page.title
18
+ when %r{Sign in with your Apple ID}
19
+ login! and redo
20
+ when %r{Select Your Team}
21
+ select_team! and redo
22
+ else
23
+ return page
24
+ end
25
+ end
26
+ end
27
+
28
+ def list_devices
29
+ get("https://developer.apple.com/ios/manage/devices/index.action")
30
+
31
+ devices = []
32
+ page.parser.xpath('//fieldset[@id="fs-0"]/table/tbody/tr').each do |row|
33
+ device = Device.new
34
+ device.name = row.at_xpath('td[@class="name"]/span/text()')
35
+ device.udid = row.at_xpath('td[@class="id"]/text()')
36
+ devices << device
37
+ end
38
+ devices
39
+ end
40
+
41
+ def add_devices(*devices)
42
+ return if devices.empty?
43
+
44
+ get("https://developer.apple.com/ios/manage/devices/upload.action")
45
+
46
+ begin
47
+ file = Tempfile.new(['devices', '.txt'])
48
+ file.write("deviceIdentifier\tdeviceName")
49
+ devices.each do |device|
50
+ file.write("\n#{device.udid}\t#{device.name}")
51
+ end
52
+ file.rewind
53
+
54
+ if form = page.form_with(:name => 'saveupload')
55
+ upload = form.file_uploads.first
56
+ upload.file_name = file.path
57
+ form.submit
58
+ end
59
+ ensure
60
+ file.close!
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def login!
67
+ if form = page.form_with(:name => 'appleConnectForm')
68
+ form.theAccountName = self.username
69
+ form.theAccountPW = self.password
70
+ form.submit
71
+ end
72
+ end
73
+
74
+ def select_team!
75
+ if form = page.form_with(:name => 'saveTeamSelection')
76
+ team_list = form.field_with(:name => 'memberDisplayId')
77
+ team_option = team_list.option_with(:text => self.team)
78
+ team_option.select
79
+
80
+ btn = form.button_with(:name => 'action:saveTeamSelection!save')
81
+ form.click_button(btn)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,39 @@
1
+ command :'devices:list' do |c|
2
+ c.syntax = 'ios devices:list'
3
+ c.summary = 'Lists the Name and ID of Devices in the Provisioning Portal'
4
+ c.description = ''
5
+
6
+ c.action do |args, options|
7
+ devices = agent.list_devices
8
+
9
+ say_ok "Devices:"
10
+ devices.each do |device|
11
+ log device.name, device.udid
12
+ end
13
+ end
14
+ end
15
+
16
+ alias_command :devices, :'devices:list'
17
+
18
+ command :'devices:add' do |c|
19
+ c.syntax = 'ios devices:add DEVICE_NAME=DEVICE_ID [...]'
20
+ c.summary = 'Adds the a device to the Provisioning Portal'
21
+ c.description = ''
22
+
23
+ c.action do |args, options|
24
+ say_error "Missing arguments, expected DEVICE_NAME=DEVICE_ID" and abort if args.nil? or args.empty?
25
+
26
+ devices = []
27
+ args.each do |arg|
28
+ components = arg.strip.gsub(/\"/, '').split(/\=/)
29
+ device = Device.new
30
+ device.name = components.first
31
+ device.udid = components.last
32
+ devices << device
33
+ end
34
+
35
+ agent.add_devices(*devices)
36
+
37
+ say_ok "Added #{devices.length} #{devices.length == 1 ? 'device' : 'devices'}"
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ include Cupertino::ProvisioningPortal
2
+ include Cupertino::ProvisioningPortal::Helpers
3
+
4
+ $:.push File.expand_path('../', __FILE__)
5
+
6
+ require 'commands/devices'
@@ -0,0 +1,33 @@
1
+ # Monkey Patch Commander::UI to alias password to avoid conflicts
2
+ module Commander::UI
3
+ alias :pw :password
4
+ end
5
+
6
+ module Cupertino
7
+ module ProvisioningPortal
8
+ module Helpers
9
+ def agent
10
+ unless @agent
11
+ @agent = Cupertino::ProvisioningPortal::Agent.new
12
+
13
+ @agent.instance_eval do
14
+ def username
15
+ @username ||= ask "Username:"
16
+ end
17
+
18
+ def password
19
+ @password ||= pw "Password:"
20
+ end
21
+
22
+ def team
23
+ teams = page.form_with(:name => 'saveTeamSelection').field_with(:name => 'memberDisplayId').options.collect(&:text)
24
+ @team ||= choose "Select a team:", *teams
25
+ end
26
+ end
27
+ end
28
+
29
+ @agent
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'mechanize'
2
+
3
+ module Cupertino
4
+ module ProvisioningPortal
5
+ class Device < Struct.new(:name, :udid); end
6
+ class Certificate < Struct.new(:name, :provisioning_profiles, :expiration_date, :status); end
7
+ class AppID < Struct.new(:bundle_seed_id, :description, :development_properties, :distribution_properties); end
8
+ class ProvisioningProfile < Struct.new(:name, :app_id, :status); end
9
+ end
10
+ end
11
+
12
+ $:.push File.expand_path('../', __FILE__)
13
+
14
+ require 'provisioning_portal/helpers'
15
+ require 'provisioning_portal/agent'
16
+ require 'provisioning_portal/commands'
data/lib/cupertino.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Cupertino
2
+ VERSION = '0.0.2'
3
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cupertino
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mattt Thompson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-05 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70106699402980 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.1
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70106699402980
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70106699401440 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.2
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70106699401440
36
+ - !ruby/object:Gem::Dependency
37
+ name: commander
38
+ requirement: &70106699399220 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 4.1.2
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70106699399220
47
+ - !ruby/object:Gem::Dependency
48
+ name: mechanize
49
+ requirement: &70106699395800 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.1
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70106699395800
58
+ description: Mechanize the Apple Developer Center
59
+ email: m@mattt.me
60
+ executables:
61
+ - ios
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ./cupertino.gemspec
66
+ - ./Gemfile
67
+ - ./Gemfile.lock
68
+ - ./lib/cupertino/provisioning_portal/agent.rb
69
+ - ./lib/cupertino/provisioning_portal/commands/devices.rb
70
+ - ./lib/cupertino/provisioning_portal/commands.rb
71
+ - ./lib/cupertino/provisioning_portal/helpers.rb
72
+ - ./lib/cupertino/provisioning_portal.rb
73
+ - ./lib/cupertino.rb
74
+ - ./Rakefile
75
+ - ./README.md
76
+ - bin/ios
77
+ homepage: http://mattt.me
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ segments:
90
+ - 0
91
+ hash: 2027864098063448986
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ segments:
99
+ - 0
100
+ hash: 2027864098063448986
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.15
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Cupertino
107
+ test_files: []