cloudsponge 0.9.13 → 0.10.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e56bc323a8bf54a660af8749c900d462789a4ef
4
- data.tar.gz: 0b22bcc9fd676d2f5210875529bf905a38910b28
3
+ metadata.gz: e1a01d2d8ae64b616b8a026823eeef87953b9410
4
+ data.tar.gz: 4a8f24f37f4ad76c015304895e4a83a7e82480fe
5
5
  SHA512:
6
- metadata.gz: 56cccbb44346a4f8d5397c8590d9a7c6cee13a1451f8c7a32bce262e87bd70261bb68d264a74eea0e68251f6f8d83ca5520cba5adf29aedfc58888752d3d7bae
7
- data.tar.gz: cdbb9f9fe62f0fc33f98b27f24c25c49191d16d2d249f4304470a9813c3f8d536feb41b0cbcf8ff3455640c2bcd0d16ac6747d4a545fa7aea7aad08edfea2ba6
6
+ metadata.gz: f5023ae6e43ae5eea5d4fde43b01da0f665e72350d94f38c372535ef3e0bfa06971f04e007704308fd1b8c0c2a594148f3332d5cba3026c2a8f4bb7f855eea2f
7
+ data.tar.gz: 6b271864e6c3498ae21f51d64c3d3a65b5ff41ab4d03df03e123bb97d77a4ac967d00aaa225cabeb5cedc51c0f7a3ae1d6794d2eb66e68dca38a44402a084e41
@@ -1,16 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cloudsponge (0.9.13)
4
+ cloudsponge (0.10.0)
5
5
  json (>= 1.6.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- json (1.8.1)
10
+ addressable (2.4.0)
11
+ crack (0.4.2)
12
+ safe_yaml (~> 1.0.0)
13
+ hashdiff (0.2.3)
14
+ json (1.8.3)
15
+ rake (10.5.0)
16
+ safe_yaml (1.0.4)
17
+ vcr (3.0.0)
18
+ webmock (1.22.3)
19
+ addressable (>= 2.3.6)
20
+ crack (>= 0.3.2)
21
+ hashdiff
11
22
 
12
23
  PLATFORMS
13
24
  ruby
14
25
 
15
26
  DEPENDENCIES
16
27
  cloudsponge!
28
+ rake
29
+ vcr
30
+ webmock
31
+
32
+ BUNDLED WITH
33
+ 1.11.2
data/README.md CHANGED
@@ -32,6 +32,8 @@ Usage:
32
32
  contacts = importer.get_contacts
33
33
  break
34
34
  end
35
+ # be nice and take a short break
36
+ sleep 1
35
37
  end
36
38
  ```
37
39
 
@@ -47,15 +49,24 @@ Install
47
49
  -------
48
50
 
49
51
  ```bash
50
- sudo gem install cloudsponge
52
+ gem install cloudsponge
51
53
  ```
52
54
 
55
+ OR using bunder, add
56
+
57
+ ```ruby
58
+ # cloudsponge integration library
59
+ gem 'cloudsponge', github: 'cloudsponge/cloudsponge-lib-ruby'
60
+ ```
61
+
62
+ to your Gemfile
63
+
53
64
  License
54
65
  =======
55
66
 
56
67
  (The MIT License)
57
68
 
58
- Copyright (c) 2013 Cloud Copy, Inc.
69
+ Copyright (c) Cloud Copy, Inc.
59
70
 
60
71
  Permission is hereby granted, free of charge, to any person obtaining
61
72
  a copy of this software and associated documentation files (the
@@ -4,7 +4,6 @@ require File.expand_path("../lib/cloudsponge/version", __FILE__)
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "cloudsponge"
6
6
  s.version = Cloudsponge::VERSION
7
- s.licenses = ['MIT']
8
7
  s.platform = Gem::Platform::RUBY
9
8
  s.authors = ["Graeme Rouse"]
10
9
  s.email = ["graeme@cloudsponge.com"]
@@ -13,7 +12,10 @@ Gem::Specification.new do |s|
13
12
  s.description = "CloudSponge is the tool that you need to go viral. Create an account at http://www.cloudsponge.com and integrate with this library. In a few lines of code you'll have access to your users' contact lists."
14
13
 
15
14
  s.required_rubygems_version = ">= 1.3.6"
16
- s.add_runtime_dependency 'json', '~> 1.6', '>= 1.6.1'
15
+ s.add_dependency "json", ">=1.6.1"
16
+ s.add_development_dependency "rake"
17
+ s.add_development_dependency "vcr"
18
+ s.add_development_dependency "webmock"
17
19
 
18
20
  s.files = `git ls-files`.split("\n")
19
21
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
@@ -1,5 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/version')
2
2
  require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/contact_importer')
3
+ require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/contact_base')
3
4
  require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/contact')
4
5
  require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/event')
5
6
  require File.expand_path(File.dirname(__FILE__) + '/cloudsponge/cs_exception')
@@ -1,69 +1,49 @@
1
1
  module Cloudsponge
2
-
3
- class Contact
4
- attr_accessor :first_name, :last_name, :emails, :phones, :addresses
5
-
6
- def self.from_array(list)
7
- list.map { |contact_data| Contact.new(contact_data) }.compact
8
- end
9
-
2
+ class Contact < ContactBase
3
+ attribute :first_name
4
+ attribute :last_name
5
+ attribute :phones
6
+ attribute :emails
7
+ attribute :addresses
8
+ attribute :groups
9
+ attribute :dob
10
+ attribute :birthday
11
+ attribute :title
12
+ attribute :companies
13
+ attribute :job_title
14
+ attribute :photos
15
+ attribute :locations
16
+
10
17
  def initialize(contact_data)
11
18
  super()
12
- # get the basic data
13
- self.first_name = contact_data['first_name']
14
- self.last_name = contact_data['last_name']
15
-
16
- # get the phone numbers
17
- self.phones = []
18
- contact_data['phone'] && contact_data['phone'].each do |phone|
19
- self.add_array_value(self.phones, phone['number'], phone['type'])
20
- end
21
-
22
- self.emails = []
23
- contact_data['email'] && contact_data['email'].each do |email|
24
- self.add_array_value(self.emails, email['address'], email['type'])
25
- end
26
-
27
- @addresses = contact_data['address'] && contact_data['address'].inject([]) do |memo, address|
28
- memo << {
29
- :type => address['type'],
30
- :street => address["street"],
31
- :city => address["city"],
32
- :region => address["region"],
33
- :country => address["country"],
34
- :postal_code => address["postal_code"],
35
- :formatted => address["formatted"]}
36
- end || []
37
-
19
+ @contact_data = contact_data
38
20
  self
39
21
  end
22
+
23
+ def self.from_array(list)
24
+ list.map { |contact_data| Contact.new(contact_data) }.compact
25
+ end
40
26
 
41
27
  def name
42
28
  "#{self.first_name} #{self.last_name}"
43
29
  end
44
-
30
+
45
31
  def email
46
- Contact.get_first_value(self.emails)
47
- end
48
-
49
- def phone
50
- Contact.get_first_value(self.phones)
32
+ first_from(:emails)
51
33
  end
52
34
 
53
- def address
54
- self.addresses && self.addresses.first && "#{self.addresses.first[:street]} #{self.addresses.first[:city]} #{self.addresses.first[:region]}".strip
35
+ def phone
36
+ first_from(:phones)
55
37
  end
56
38
 
57
- def add_array_value(collection, value, type = nil)
58
- collection << {:value => value, :type => type}
39
+ def address
40
+ first_from(:addresses)
59
41
  end
60
42
 
61
- private
62
-
63
- def self.get_first_value(from_array)
64
- from_array && from_array.first && from_array.first[:value]
43
+ def first_from(field)
44
+ from_array = self.send(field)
45
+ return from_array && from_array.first && from_array.first[:value] unless field.to_sym == :addresses
46
+ self.addresses && self.addresses.first && "#{self.addresses.first[:street]} #{self.addresses.first[:city]} #{self.addresses.first[:region]}".strip
65
47
  end
66
-
67
48
  end
68
-
69
- end
49
+ end
@@ -0,0 +1,49 @@
1
+ module Cloudsponge
2
+ class ContactBase
3
+ def self.attribute(name)
4
+ plural = {emails: "email", phones: "phone", addresses: "address"}
5
+
6
+ if plural.keys.include? name
7
+ define_method(name) do
8
+ send("process_#{plural[name]}", @contact_data[plural[name]])
9
+ end
10
+ else
11
+ define_method(name) do
12
+ @contact_data[name.to_s]
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def process_email(content)
20
+ @emails = content && content.inject([]) do |memo, email|
21
+ email = email.inject({}){|i,(k,v)| i[k.to_sym] = v; i}
22
+ memo << {:value => email[:address], :type => email[:type]}
23
+ end || []
24
+ @emails
25
+ end
26
+
27
+ def process_phone(content)
28
+ @phones = content && content.inject([]) do |memo, phone|
29
+ phone = phone.inject({}){|i,(k,v)| i[k.to_sym] = v; i}
30
+ memo << {:value => phone[:number], :type => phone[:type]}
31
+ end || []
32
+ @phones
33
+ end
34
+
35
+ def process_address(content)
36
+ @addresses = content && content.inject([]) do |memo, address|
37
+ memo << {
38
+ :type => address['type'],
39
+ :street => address["street"],
40
+ :city => address["city"],
41
+ :region => address["region"],
42
+ :country => address["country"],
43
+ :postal_code => address["postal_code"],
44
+ :formatted => address["formatted"]}
45
+ end || []
46
+ @addresses
47
+ end
48
+ end
49
+ end
@@ -64,7 +64,7 @@ module Cloudsponge
64
64
  full_url = generate_poll_url(EVENTS_PATH, import_id)
65
65
 
66
66
  # get the response from the server and decode it
67
- resp = Utility.get_and_decode_response(full_url)
67
+ resp = Utility.get_and_decode_response(full_url, auth)
68
68
  # interpret the result
69
69
  Event.from_array(resp['events'])
70
70
  end
@@ -91,7 +91,7 @@ module Cloudsponge
91
91
 
92
92
  # get the response from the server and decode it
93
93
  begin
94
- resp = Utility.get_and_decode_response(generate_poll_url(CONTACTS_PATH, import_id))
94
+ resp = Utility.get_and_decode_response(generate_poll_url(CONTACTS_PATH, import_id), auth)
95
95
  rescue CsException => e
96
96
  raise e unless e.code == 404
97
97
  end
@@ -110,7 +110,7 @@ module Cloudsponge
110
110
 
111
111
  # get and decode the response into an associated array
112
112
  # Throws an exception if there was a problem at the server
113
- Utility.post_and_decode_response(full_url(CONSENT_PATH), authenticated_params(params))
113
+ Utility.post_and_decode_response(full_url(CONSENT_PATH), params, auth)
114
114
  end
115
115
 
116
116
  # invokes the begin import action for the desktop applet import process.
@@ -122,7 +122,7 @@ module Cloudsponge
122
122
 
123
123
  # get and decode the response into an associated array
124
124
  # Throws an exception if there was a problem at the server
125
- Utility.post_and_decode_response(full_url(APPLET_PATH), authenticated_params(params))
125
+ Utility.post_and_decode_response(full_url(APPLET_PATH), params, auth)
126
126
  end
127
127
 
128
128
  # invokes the begin import action for the desktop applet import process.
@@ -134,7 +134,7 @@ module Cloudsponge
134
134
 
135
135
  # get and decode the response into an associated array
136
136
  # Throws an exception if there was a problem at the server
137
- Utility.post_and_decode_response(full_url(IMPORT_PATH), authenticated_params(params))
137
+ Utility.post_and_decode_response(full_url(IMPORT_PATH), params, auth)
138
138
  end
139
139
 
140
140
  def full_url(path)
@@ -146,9 +146,13 @@ module Cloudsponge
146
146
  params.merge({:domain_key => self.key, :domain_password => self.password})
147
147
  end
148
148
 
149
+ def auth
150
+ {:domain_key => self.key, :domain_password => self.password}
151
+ end
152
+
149
153
  def authenticated_query(params = {})
150
154
  # append domain_key, domain_password to params and serialze into a query string
151
- Utility.object_to_query(authenticated_params(params))
155
+ Utility.object_to_query(params)
152
156
  end
153
157
 
154
158
  def create_applet_tag(id, url)
@@ -13,18 +13,18 @@ module Cloudsponge
13
13
 
14
14
  def self.object_to_query(object)
15
15
  return object unless object.is_a? Hash
16
- object.map{ |k,v| "#{URI.encode(k.to_s)}=#{URI.encode(v.to_s)}" }.join('&')
16
+ object.map{ |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join('&')
17
17
  end
18
18
 
19
- def self.post_and_decode_response(url, params)
19
+ def self.post_and_decode_response(url, params, auth)
20
20
  # post the response
21
- response = post_url(url, params)
21
+ response = post_url(url, params, auth)
22
22
  decode_response(response)
23
23
  end
24
24
 
25
- def self.get_and_decode_response(full_url)
25
+ def self.get_and_decode_response(full_url, auth)
26
26
  # get the response
27
- response = get_url(full_url)
27
+ response = get_url(full_url, auth)
28
28
  decode_response(response)
29
29
  end
30
30
 
@@ -54,24 +54,29 @@ module Cloudsponge
54
54
  object
55
55
  end
56
56
 
57
- def self.get_url(url)
57
+ def self.get_url(url, auth)
58
58
  url = URI.parse(url)
59
- open_http(url).get("#{url.path}?#{url.query}")
59
+ open_http(url, url.query, auth, :get)
60
60
  end
61
61
 
62
- def self.post_url(url, params)
62
+ def self.post_url(url, params, auth)
63
63
  url = URI.parse(url)
64
- open_http(url).post("#{url.path}","#{object_to_query(params)}")
64
+ open_http(url, params, auth, :post)
65
65
  end
66
66
 
67
- def self.open_http(url)
67
+ def self.open_http(url, params, auth, method)
68
68
  http = Net::HTTP.new(url.host, url.port)
69
- # @csimport_http.read_timeout = @timeout || 30
70
69
  if url.port == 443
71
70
  http.use_ssl = true
71
+ end
72
+ request = if method == :post
73
+ Net::HTTP::Post.new(url.request_uri)
74
+ else
75
+ Net::HTTP::Get.new(url.request_uri)
72
76
  end
73
- http.start unless http.started?
74
- http
77
+ request.set_form_data(params) if method == :post
78
+ request.basic_auth(auth[:domain_key], auth[:domain_password])
79
+ http.request(request)
75
80
  end
76
81
  end
77
82
  end
@@ -1,3 +1,3 @@
1
1
  module Cloudsponge
2
- VERSION = "0.9.13"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+
5
+ bundler_args:
6
+ --path $SHIPPABLE_BUILD_DIR/_vendor
7
+
8
+ build:
9
+ ci:
10
+ # install bundle into the cached _vendor path
11
+ - bundle install --gemfile=$SHIPPABLE_GEMFILE $SHIPPABLE_BUNDLER_ARGS
12
+
13
+ # run specs
14
+ - bundle exec rake test
15
+
16
+ cache: true
@@ -17,6 +17,73 @@ class TestContact < Test::Unit::TestCase
17
17
  assert_equal data['last_name'], contact.last_name
18
18
  assert_equal "#{data['first_name']} #{data['last_name']}", contact.name
19
19
  assert_equal 'joe@example.com', contact.email
20
- assert_equal '555-1234', contact.phone
20
+ assert_equal '555-1234' , contact.phone
21
+ end
22
+
23
+ def test_from_all_possible_attributes
24
+ data = { "first_name" =>"Abigale Kirlin",
25
+ "last_name" =>"Kautzer",
26
+ "phone"=>
27
+ [{"number" => "1-274-714-0088", "type" => "Business fax"},
28
+ {"number" => "(719) 110-7733 x682", "type" => "Home"},
29
+ {"number" => "(425) 385-9484 x8245", "type" => "Other"},
30
+ {"number" => "906.146.3215", "type" => "Mobile"},
31
+ {"number" => "935.208.5960", "type" => "Primary"},
32
+ {"number" => "528.604.8156 x570", "type" => "Home fax"},
33
+ {"number" => "119.297.9772 x184", "type" => "Business"},
34
+ {"number" => "(712) 636-9651 x6347", "type" => "Other fax"}],
35
+ "email"=>
36
+ [{"address"=>"cesar@kub.info", "type"=>"E-mail 1"},
37
+ {"address"=>"germaine.gorczany@stroman.org", "type"=>"E-mail 2"},
38
+ {"address"=>"onie_pfannerstill@herzog.co", "type"=>"E-mail 3"}],
39
+ "address"=>
40
+ [{"type"=>"Home",
41
+ "street"=>"4535 Bednar Trace ",
42
+ "city"=>"Turnermouth",
43
+ "region"=>"Wisconsin",
44
+ "postal_code"=>"45589-5220",
45
+ "country"=>"Ghana"},
46
+ {"type"=>"Business",
47
+ "street"=>"3000 White Mill ",
48
+ "city"=>"Dachburgh",
49
+ "region"=>"South Dakota",
50
+ "postal_code"=>"38529-1507",
51
+ "country"=>"Sweden"},
52
+ {"type"=>"Other",
53
+ "street"=>"5997 Wolf Underpass ",
54
+ "city"=>"Port Tyrese",
55
+ "region"=>"Colorado",
56
+ "postal_code"=>"32992-0271",
57
+ "country"=>"Tanzania"}],
58
+ "groups"=>[],
59
+ "dob"=>"1994-08-27",
60
+ "birthday"=>"08-27",
61
+ "companies"=>["O'Conner Inc"],
62
+ "title"=> "Mr.",
63
+ "job_title"=>"District Integration Administrator",
64
+ "photos"=>[],
65
+ "locations"=>[]}
66
+
67
+ assert contact = Cloudsponge::Contact.new(data)
68
+ assert_equal data['first_name'], contact.first_name
69
+ assert_equal data['last_name'], contact.last_name
70
+ assert_equal "#{data['first_name']} #{data['last_name']}", contact.name
71
+
72
+ assert_equal 'cesar@kub.info', contact.email
73
+ assert_equal '1-274-714-0088', contact.phone
74
+ assert_equal '4535 Bednar Trace Turnermouth Wisconsin', contact.address
75
+
76
+ assert_equal Array, contact.emails.class
77
+ assert_equal Array, contact.phones.class
78
+ assert_equal Array, contact.addresses.class
79
+
80
+ assert_equal data["groups"] , contact.groups
81
+ assert_equal data["dob"] , contact.dob
82
+ assert_equal data["birthday"] , contact.birthday
83
+ assert_equal data["companies"], contact.companies
84
+ assert_equal data["title"] , contact.title
85
+ assert_equal data["job_title"], contact.job_title
86
+ assert_equal data["photos"] , contact.photos
87
+ assert_equal data["locations"], contact.locations
21
88
  end
22
89
  end