cupertino 0.0.2

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 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: []