icloud 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ vendor/bundle
9
+ pkg
10
+ rdoc
11
+ spec/reports
12
+ test/tmp
13
+ test/version_tmp
14
+ tmp
15
+ Gemfile.lock
16
+ doc/
17
+
18
+ # YARD artifacts
19
+ .yardoc
20
+ _yardoc
21
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in icloud.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Maxim
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Icloud
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'icloud'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install icloud
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'icloud/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "icloud"
8
+ gem.version = ICloud::VERSION
9
+ gem.authors = ["Maxim"]
10
+ gem.email = ["parallel588@gmail.com"]
11
+ gem.description = %q{Non official iCloud API}
12
+ gem.summary = %q{Non official iCloud API}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "faraday", "~> 0.8.4"
21
+ gem.add_dependency "uuid", "~> 2.3.6"
22
+ gem.add_dependency "oj", "~> 2.0.0"
23
+
24
+ end
@@ -0,0 +1,241 @@
1
+ require "icloud/version"
2
+
3
+ require 'faraday'
4
+ require 'oj'
5
+ require 'uuid'
6
+
7
+ module ICloud
8
+ URLS = {
9
+ version: "https://www.icloud.com/system/version.json",
10
+ validate: "https://setup.icloud.com",
11
+ # validate: "https://setup.icloud.com/setup/ws/1/validate?clientBuildNumber={0}&clientId={1}",
12
+ authenticate: "https://setup.icloud.com",
13
+ # authenticate: "https://setup.icloud.com/setup/ws/1/login?clientBuildNumber={0}&clientId={1}",
14
+ logout_no_services: "https://setup.icloud.com/setup/ws/1/logout",
15
+ get_contacts_list: "{0}/co/startup?clientBuildNumber={1}&clientId={2}&clientVersion=2.1&dsid={3}&id={4}&locale=en_US&order=last%2Cfirst",
16
+ refresh_web_auth: "{0}/refreshWebAuth?clientBuildNumber={1}&clientId={2}&dsid={3}&id={4}",
17
+ get_notes_list: "{0}/no/startup?clientBuildNumber={1}&clientId={2}&dsid={3}&id={4}",
18
+ get_active_reminders: "{0}/rd/startup?clientVersion=4.0&dsid={1}&id={2}&lang=en-us&usertz=US%2FPacific",
19
+ get_completed_reminders: "{0}/rd/completed?clientVersion=4.0&dsid={1}&id={2}&lang=en-us&usertz=US%2FPacific",
20
+ fmi: nil,
21
+ fmi_init: "{0}/fmipservice/client/web/initClient?dsid={1}&id={2}",
22
+ fmi_refresh: "{0}/fmipservice/client/web/refreshClient?dsid={1}&id={2}",
23
+ get_calendar_events: "{0}/ca/events?clientBuildNumber={1}&clientID={2}&clientVersion=4.0&dsid={3}&endDate={4}&id={5}&lang=en-us&requestID=1&startDate={6}&usertz=US%2FPacific"
24
+ }
25
+
26
+ # Your code goes here...
27
+ class Api
28
+ attr_accessor :login, :password, :instance, :auth
29
+
30
+ def initialize(login, password)
31
+ @login = login
32
+ @password = password
33
+ @auth = nil
34
+ @instance = nil
35
+ end
36
+
37
+ def client_build_number
38
+ version["buildNumber"]
39
+ end
40
+ def client_id
41
+ @uuid ||= UUID.new.generate.upcase
42
+ end
43
+
44
+ def dequote(str)
45
+ ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
46
+ ret.gsub!(/\\(.)/, "\\1")
47
+ ret
48
+ end
49
+
50
+ def webservices
51
+ Oj.load((@auth && @auth.body)||"{}")['webservices']
52
+ end
53
+
54
+ def ds_info
55
+ Oj.load((@auth && @auth.body)||"{}")['dsInfo']
56
+ end
57
+
58
+ def apps
59
+ Oj.load((@auth && @auth.body)||"{}")['apps']
60
+ end
61
+
62
+ def dequote(str)
63
+ ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
64
+ ret.gsub!(/\\(.)/, "\\1")
65
+ ret
66
+ end
67
+
68
+ def cookie=(v)
69
+
70
+ @cookie = v.to_s.split(/,(?=[^;,]*=)|,$/).map { |c|
71
+ cookie_elem = c.split(/;+/)
72
+ first_elem = cookie_elem.shift
73
+ first_elem.strip!
74
+ key, value = first_elem.split(/\=/, 2)
75
+
76
+ cookie = { 'name' =>key, 'value' => value.dup }
77
+
78
+
79
+ cookie_elem.each do |pair|
80
+ pair.strip!
81
+ key, value = pair.split(/=/, 2)
82
+ next unless key
83
+ value = dequote(value.strip) if value
84
+
85
+ case key.downcase
86
+ when 'domain'
87
+ next unless value && !value.empty?
88
+ begin
89
+ cookie['domain'] = value
90
+ cookie['for_domain'] = true
91
+ rescue
92
+ puts ("Couldn't parse domain: #{value}")
93
+ end
94
+ when 'path'
95
+ next unless value && !value.empty?
96
+ cookie['path'] = value
97
+ when 'expires'
98
+ next unless value && !value.empty?
99
+ begin
100
+ cookie['expires'] = Time::parse(value)
101
+ rescue
102
+ puts "Couldn't parse expires: #{value}"
103
+ end
104
+ when 'max-age'
105
+ next unless value && !value.empty?
106
+ begin
107
+ cookie['max_age'] = Integer(value)
108
+ rescue
109
+ puts "Couldn't parse max age '#{value}'"
110
+ end
111
+ when 'comment'
112
+ next unless value
113
+ cookie['comment'] = value
114
+ when 'version'
115
+ next unless value
116
+ begin
117
+ cookie['version'] = Integer(value)
118
+ rescue
119
+ puts "Couldn't parse version '#{value}'"
120
+ cookie['version'] = nil
121
+ end
122
+ when 'secure'
123
+ cookie['secure'] = true
124
+ end
125
+ end
126
+
127
+ cookie['secure'] ||= false
128
+
129
+
130
+ # RFC 6265 4.1.2.2
131
+ cookie['expires'] = Time.now + cookie['max_age'] if cookie['max_age']
132
+ cookie['session'] = !cookie['expires']
133
+
134
+ # Move this in to the cookie jar
135
+ cookie
136
+ }.map{|j| "#{j['name']}=#{j['value']}"}.join(';')
137
+
138
+ end
139
+
140
+ def cookie
141
+ @cookie.to_s
142
+ end
143
+
144
+ def instance=(v)
145
+ @instance = v
146
+ end
147
+
148
+ def instance
149
+ @instance
150
+ end
151
+
152
+
153
+ def version
154
+ @version_resp ||= Faraday.get(URLS[:version])
155
+ Oj.load(@version_resp.body)
156
+ end
157
+
158
+ def validate
159
+ conn = Faraday.new(:url => URLS[:validate])
160
+
161
+ resp = conn.post do |req|
162
+ req.url '/setup/ws/1/validate'
163
+ req.headers["Origin"] = "https://www.icloud.com"
164
+ req.headers["Referer"] = "https://www.icloud.com"
165
+ req.headers["Cookie"] = cookie
166
+ req.params = { "clientBuildNumber" => client_build_number, "clientId" => client_id}
167
+ end
168
+ self.cookie = resp.env[:response_headers]["set-cookie"] if resp.env[:response_headers].has_key?("set-cookie")
169
+ self.instance = Oj.load(resp.body)['instance']
170
+
171
+ resp
172
+
173
+ end
174
+
175
+ def authenticate?
176
+ !!@auth
177
+ end
178
+
179
+ def authenticate(remember_me = false)
180
+ @auth ||
181
+ begin
182
+ validate
183
+ conn = Faraday.new(:url => ICloud::URLS[:authenticate])
184
+ checksum = Digest::SHA1.hexdigest([login, instance].join).upcase
185
+
186
+ auth_params = {
187
+ "apple_id" => login,
188
+ "password" => password,
189
+ "id" => checksum,
190
+ "extended_login" => remember_me
191
+ }
192
+
193
+ @auth = conn.post do |req|
194
+ req.url '/setup/ws/1/login'
195
+ req.headers["Origin"] = "https://www.icloud.com"
196
+ req.headers["Referer"] = "https://www.icloud.com"
197
+ req.headers["Cookie"] = cookie
198
+ req.params = { "clientBuildNumber" => client_build_number, "clientId" => client_id}
199
+ req.body = Oj.dump(auth_params)
200
+ end
201
+
202
+ self.cookie = @auth.env[:response_headers]["set-cookie"]
203
+ self.instance = Oj.load(@auth.body)['instance']
204
+
205
+ end
206
+
207
+ @auth
208
+ end
209
+
210
+ def contacts
211
+ authenticate unless authenticate?
212
+
213
+ @contacts ||
214
+ begin
215
+ conn = Faraday.new(:url => webservices["contacts"]["url"] )
216
+ checksum = Digest::SHA1.hexdigest([login, instance].join).upcase
217
+
218
+ resp = conn.get do |req|
219
+ req.url '/co/startup'
220
+ req.headers["Origin"] = "https://www.icloud.com"
221
+ req.headers["Referer"] = "https://www.icloud.com"
222
+ req.headers["Cookie"] = cookie
223
+ req.params = {
224
+ "clientBuildNumber" => client_build_number,
225
+ "clientId" => client_id,
226
+ "dsid" => ds_info['dsid'],
227
+ "clientVersion" => '2.1',
228
+ "locale" => 'en_US',
229
+ "order" => 'last,first',
230
+ "id" => checksum
231
+ }
232
+ end
233
+
234
+ @contacts = Oj.load(resp.body)
235
+ end
236
+
237
+ @contacts
238
+ end
239
+
240
+ end
241
+ end
@@ -0,0 +1,3 @@
1
+ module ICloud
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: icloud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Maxim
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.4
30
+ - !ruby/object:Gem::Dependency
31
+ name: uuid
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.3.6
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.3.6
46
+ - !ruby/object:Gem::Dependency
47
+ name: oj
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.0.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ description: Non official iCloud API
63
+ email:
64
+ - parallel588@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - icloud.gemspec
75
+ - lib/icloud.rb
76
+ - lib/icloud/version.rb
77
+ homepage: ''
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
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.23
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Non official iCloud API
101
+ test_files: []