email_vision 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Rakefile +55 -0
- data/Readme.md +28 -0
- data/VERSION +1 -0
- data/email_vision.gemspec +46 -0
- data/lib/email_vision.rb +109 -0
- data/spec/account.yml.example +9 -0
- data/spec/email_vision_spec.rb +157 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
task :default => :spec
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color --backtrace']}
|
4
|
+
|
5
|
+
def account
|
6
|
+
YAML.load(File.read('spec/account.yml')) rescue {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def email_vision
|
10
|
+
@email_vision ||= begin
|
11
|
+
$LOAD_PATH << 'lib'
|
12
|
+
require 'email_vision'
|
13
|
+
require 'yaml'
|
14
|
+
EmailVision.new(account)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'possible actions'
|
19
|
+
task :actions do
|
20
|
+
unnecessary_actions = [:open_api_connection, :close_api_connection]
|
21
|
+
actions = email_vision.send(:connection).wsdl.soap_actions
|
22
|
+
puts (actions - unnecessary_actions).map{|x|" - #{x}"}.sort.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'test update here, since it takes forever to be processed'
|
26
|
+
task :test_update do
|
27
|
+
user = account[:changeable_user]
|
28
|
+
value = rand(1111111)
|
29
|
+
email_vision.update(user[:email], :firstname => value)
|
30
|
+
start = Time.now
|
31
|
+
loop do
|
32
|
+
sleep 5
|
33
|
+
puts (Time.now - start).to_i
|
34
|
+
data = email_vision.find(user[:email])
|
35
|
+
break if data[:firstname] == value.to_s
|
36
|
+
end
|
37
|
+
puts "SUCCESS!!!!!! #{(Time.now - start).to_i}"
|
38
|
+
end
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'jeweler'
|
42
|
+
project_name = 'email_vision'
|
43
|
+
Jeweler::Tasks.new do |gem|
|
44
|
+
gem.name = project_name
|
45
|
+
gem.summary = "Ruby SOAP Api Client for EmailVision / CampaignCommander"
|
46
|
+
gem.email = "grosser.michael@gmail.com"
|
47
|
+
gem.homepage = "http://github.com/grosser/#{project_name}"
|
48
|
+
gem.authors = ["Michael Grosser"]
|
49
|
+
gem.add_dependency 'savon'
|
50
|
+
end
|
51
|
+
|
52
|
+
Jeweler::GemcutterTasks.new
|
53
|
+
rescue LoadError
|
54
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
55
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
EmailVision SOAP Api Client
|
2
|
+
|
3
|
+
gem install email_vision
|
4
|
+
|
5
|
+
Usage
|
6
|
+
=====
|
7
|
+
|
8
|
+
emv = EmailVision.new(:password => 'foo', :login => 'bar', :key => 'token')
|
9
|
+
emv.find 'me@host.com'
|
10
|
+
emv.create_or_update :email => 'me@host.com', :foo => 1
|
11
|
+
|
12
|
+
emv.create :email => 'me@host.com', :foo => 1
|
13
|
+
emv.update :email => 'me@host.com', :foo => 1
|
14
|
+
emv.change_email 'me@host.com', 'you@host.com'
|
15
|
+
|
16
|
+
emv.columns
|
17
|
+
|
18
|
+
emv.unjoin 'me@host.com'
|
19
|
+
emv.rejoin 'me@host.com'
|
20
|
+
|
21
|
+
# create, create_or_update, update, change_email return a job-id
|
22
|
+
emv.job_status job_id
|
23
|
+
|
24
|
+
Author
|
25
|
+
======
|
26
|
+
[Michael Grosser](http://pragmatig.wordpress.com)
|
27
|
+
grosser.michael@gmail.com
|
28
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{email_vision}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Grosser"]
|
12
|
+
s.date = %q{2010-07-31}
|
13
|
+
s.email = %q{grosser.michael@gmail.com}
|
14
|
+
s.files = [
|
15
|
+
".gitignore",
|
16
|
+
"Rakefile",
|
17
|
+
"Readme.md",
|
18
|
+
"VERSION",
|
19
|
+
"email_vision.gemspec",
|
20
|
+
"lib/email_vision.rb",
|
21
|
+
"spec/account.yml.example",
|
22
|
+
"spec/email_vision_spec.rb"
|
23
|
+
]
|
24
|
+
s.homepage = %q{http://github.com/grosser/email_vision}
|
25
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
s.rubygems_version = %q{1.3.6}
|
28
|
+
s.summary = %q{Ruby SOAP Api Client for EmailVision / CampaignCommander}
|
29
|
+
s.test_files = [
|
30
|
+
"spec/email_vision_spec.rb"
|
31
|
+
]
|
32
|
+
|
33
|
+
if s.respond_to? :specification_version then
|
34
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
35
|
+
s.specification_version = 3
|
36
|
+
|
37
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
38
|
+
s.add_runtime_dependency(%q<savon>, [">= 0"])
|
39
|
+
else
|
40
|
+
s.add_dependency(%q<savon>, [">= 0"])
|
41
|
+
end
|
42
|
+
else
|
43
|
+
s.add_dependency(%q<savon>, [">= 0"])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/lib/email_vision.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'savon'
|
2
|
+
|
3
|
+
class EmailVision
|
4
|
+
WSDL = "http://emvapi.emv3.com/apimember/services/MemberService?wsdl"
|
5
|
+
SESSION_TIMEOUT = 10*60
|
6
|
+
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
7
|
+
attr_accessor :options
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
self.options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def find(email_or_id)
|
14
|
+
result = execute_by_email_or_id(:get_member, email_or_id)
|
15
|
+
return unless result.is_a?(Hash)
|
16
|
+
result = convert_to_hash(result[:attributes][:entry], :key, :value)
|
17
|
+
result.reject{|k,v| v.nil? }
|
18
|
+
end
|
19
|
+
|
20
|
+
def unjoin(email_or_id)
|
21
|
+
execute_by_email_or_id(:unjoin_member, email_or_id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def rejoin(email_or_id)
|
25
|
+
execute_by_email_or_id(:rejoin_member, email_or_id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update(attributes)
|
29
|
+
execute_by_obj(:update_member_by_obj, attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_email(old, new)
|
33
|
+
execute(:update_member, :email => old, :field => :email, :value => new)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create(attributes)
|
37
|
+
execute_by_obj(:insert_member_by_obj, attributes)
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_or_update(attributes)
|
41
|
+
execute_by_obj(:insert_or_update_member_by_obj, attributes)
|
42
|
+
end
|
43
|
+
|
44
|
+
# should be one of: Insert, Processing, Processed, Error, Job_Done_Or_Does_Not_Exist
|
45
|
+
def job_status(job_id)
|
46
|
+
execute(:get_member_job_status, :synchro_id => job_id)[:status]
|
47
|
+
end
|
48
|
+
|
49
|
+
def columns
|
50
|
+
result = execute(:desc_member_table)
|
51
|
+
result = convert_to_hash(result[:fields], :name, :type)
|
52
|
+
result.each{|k,v| result[k] = to_ruby_style(v)}
|
53
|
+
result
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def connection
|
59
|
+
unless connected?
|
60
|
+
response = client.open_api_connection{|r|
|
61
|
+
r.body = {
|
62
|
+
:login => options[:login],
|
63
|
+
:pwd => options[:password],
|
64
|
+
:key => options[:key]
|
65
|
+
}
|
66
|
+
}
|
67
|
+
@token = response.to_hash[:open_api_connection_response][:return]
|
68
|
+
@token_requested = Time.now.to_i
|
69
|
+
end
|
70
|
+
client
|
71
|
+
end
|
72
|
+
|
73
|
+
def client
|
74
|
+
@client ||= Savon::Client.new WSDL
|
75
|
+
end
|
76
|
+
|
77
|
+
def connected?
|
78
|
+
@token and @token_requested > (Time.now.to_i - SESSION_TIMEOUT)
|
79
|
+
end
|
80
|
+
|
81
|
+
def execute_by_email_or_id(method, email_or_id)
|
82
|
+
if email_or_id.to_s.include?('@')
|
83
|
+
execute("#{method}_by_email", :email => email_or_id)
|
84
|
+
else
|
85
|
+
execute("#{method}_by_id", :id => email_or_id)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_ruby_style(name)
|
90
|
+
name.downcase.to_sym
|
91
|
+
end
|
92
|
+
|
93
|
+
def execute_by_obj(method, attributes)
|
94
|
+
entries = attributes.map{|k,v| {:entry => {:key => k, :value => v}}}
|
95
|
+
execute(method, :member => {:email => attributes[:email], :dynContent => entries})
|
96
|
+
end
|
97
|
+
|
98
|
+
def execute(method, options={})
|
99
|
+
response = connection.send(method){|r| r.body = options.merge(:token => @token) }
|
100
|
+
response.to_hash["#{method}_response".to_sym][:return]
|
101
|
+
end
|
102
|
+
|
103
|
+
def convert_to_hash(entries, key, value)
|
104
|
+
entries.inject({}) do |hash, part|
|
105
|
+
hash[to_ruby_style(part[key])] = part[value]
|
106
|
+
hash
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
:login: api_your_host
|
2
|
+
:password: your_password
|
3
|
+
:key: your_api_key
|
4
|
+
:test_user: # this must be the complete data of a user currently in email vision
|
5
|
+
:gender: "0"
|
6
|
+
:email: test@test.de
|
7
|
+
:datejoin: 2009-12-07T13:36:15+01:00
|
8
|
+
:firstname: Test
|
9
|
+
:member_id: "1014086935042"
|
@@ -0,0 +1,157 @@
|
|
1
|
+
$LOAD_PATH << 'lib'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'email_vision'
|
4
|
+
|
5
|
+
describe "EmailVision" do
|
6
|
+
let(:email){"#{rand(1111111)}.foo@justatest.com"}
|
7
|
+
let(:random_value){rand(11111111111).to_s}
|
8
|
+
let(:expired_token){'Duy-M5FktALawBJ7dZN94s6hLEgLGKXC_j7cCqlDUMXRGw2shqHYbR9Zud_19EBtFkSCbJ0ZmrZ_d0ieBqgR'}
|
9
|
+
|
10
|
+
# updates need some time to finish on the server...
|
11
|
+
def wait_for_job_to_finish
|
12
|
+
job_id = yield
|
13
|
+
20.times do
|
14
|
+
sleep 5
|
15
|
+
puts status = client.job_status(job_id)
|
16
|
+
return if status == 'Job_Done_Or_Does_Not_Exist'
|
17
|
+
end
|
18
|
+
raise "Job not finished in time!"
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset_email
|
22
|
+
email = client.find(changeable_user[:member_id])[:email]
|
23
|
+
wait_for_job_to_finish do
|
24
|
+
client.update_email(email, changeable_user[:email])
|
25
|
+
end
|
26
|
+
email = client.find(changeable_user[:member_id])[:email]
|
27
|
+
email.should == changeable_user[:email]
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:config){YAML.load(File.read('spec/account.yml'))}
|
31
|
+
let(:client){EmailVision.new(config)}
|
32
|
+
let(:findable_user) do
|
33
|
+
data = config[:findable_user]
|
34
|
+
data[:datejoin] = DateTime.parse(data[:datejoin].to_s)
|
35
|
+
data
|
36
|
+
end
|
37
|
+
let(:changeable_user){config[:changeable_user]}
|
38
|
+
|
39
|
+
it "has a VERSION" do
|
40
|
+
EmailVision::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can call more than one method" do
|
44
|
+
first = client.find(findable_user[:email])
|
45
|
+
first.should == client.find(findable_user[:email])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can reconnect when token is expired" do
|
49
|
+
client.instance_variable_set('@token', expired_token)
|
50
|
+
client.instance_variable_set('@token_requested', Time.now.to_i - EmailVision::SESSION_TIMEOUT - 10)
|
51
|
+
client.find(findable_user[:email])[:email].should == findable_user[:email]
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :find do
|
55
|
+
it "can find by email" do
|
56
|
+
response = client.find(findable_user[:email])
|
57
|
+
response.should == findable_user
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can find by id" do
|
61
|
+
response = client.find(findable_user[:member_id])
|
62
|
+
response.should == findable_user
|
63
|
+
end
|
64
|
+
|
65
|
+
it "is nil when nothing was found" do
|
66
|
+
client.find('foo@bar.baz').should == nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :update do
|
71
|
+
it "can update a attribute" do
|
72
|
+
wait_for_job_to_finish do
|
73
|
+
client.update(:email => changeable_user[:email], :firstname => random_value)
|
74
|
+
end
|
75
|
+
puts data = client.find(changeable_user[:email])
|
76
|
+
data[:firstname].should == random_value
|
77
|
+
|
78
|
+
# it does not overwrite other attributes
|
79
|
+
data[:lastname].should == changeable_user[:lastname]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns a job id" do
|
83
|
+
job_id = client.update(:email => changeable_user[:email], :firstname => random_value)
|
84
|
+
client.job_status(job_id).should == 'Insert'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe :update_email do
|
89
|
+
after do
|
90
|
+
reset_email
|
91
|
+
end
|
92
|
+
|
93
|
+
it "updates the email" do
|
94
|
+
wait_for_job_to_finish do
|
95
|
+
client.update_email(changeable_user[:email], email)
|
96
|
+
end
|
97
|
+
client.find(email)[:email].should == email
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe :create_or_update do
|
102
|
+
it "can create a record" do
|
103
|
+
wait_for_job_to_finish do
|
104
|
+
client.create_or_update(:email => email, :firstname => 'first-name')
|
105
|
+
end
|
106
|
+
data = client.find(email)
|
107
|
+
data[:firstname].should == 'first-name'
|
108
|
+
end
|
109
|
+
|
110
|
+
it "can update a record" do
|
111
|
+
wait_for_job_to_finish do
|
112
|
+
client.create_or_update(:email => changeable_user[:email], :firstname => random_value)
|
113
|
+
end
|
114
|
+
data = client.find(changeable_user[:email])
|
115
|
+
data[:firstname].should == random_value
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe :create do
|
120
|
+
it "can create a record" do
|
121
|
+
wait_for_job_to_finish do
|
122
|
+
client.create(:email => email, :firstname => 'first-name')
|
123
|
+
end
|
124
|
+
data = client.find(email)
|
125
|
+
data[:firstname].should == 'first-name'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe :columns do
|
130
|
+
it "can read them" do
|
131
|
+
data = client.columns
|
132
|
+
data[:dateunjoin].should == :date
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe :unjoin do
|
137
|
+
it "can unjoin a member" do
|
138
|
+
wait_for_job_to_finish do
|
139
|
+
client.unjoin(changeable_user[:email])
|
140
|
+
end
|
141
|
+
date = client.find(changeable_user[:email])[:dateunjoin]
|
142
|
+
date.is_a?(DateTime).should == true
|
143
|
+
Time.parse(date.to_s).should be_close(Time.now, 40)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe :rejoin do
|
148
|
+
it "can rejoin a member" do
|
149
|
+
wait_for_job_to_finish do
|
150
|
+
client.rejoin(changeable_user[:email])
|
151
|
+
end
|
152
|
+
date = client.find(changeable_user[:email])[:datejoin]
|
153
|
+
date.is_a?(DateTime).should == true
|
154
|
+
Time.parse(date.to_s).should be_close(Time.now, 40)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: email_vision
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Michael Grosser
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-31 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: savon
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description:
|
33
|
+
email: grosser.michael@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files: []
|
39
|
+
|
40
|
+
files:
|
41
|
+
- .gitignore
|
42
|
+
- Rakefile
|
43
|
+
- Readme.md
|
44
|
+
- VERSION
|
45
|
+
- email_vision.gemspec
|
46
|
+
- lib/email_vision.rb
|
47
|
+
- spec/account.yml.example
|
48
|
+
- spec/email_vision_spec.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/grosser/email_vision
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.6
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Ruby SOAP Api Client for EmailVision / CampaignCommander
|
79
|
+
test_files:
|
80
|
+
- spec/email_vision_spec.rb
|