sugarcrm 0.6.2 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +13 -8
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/sugarcrm.rb +7 -139
- data/lib/sugarcrm/association_methods.rb +45 -0
- data/lib/sugarcrm/attribute_methods.rb +65 -0
- data/lib/sugarcrm/base.rb +85 -0
- data/lib/sugarcrm/connection.rb +126 -103
- data/lib/sugarcrm/{api → connection/api}/get_available_modules.rb +6 -1
- data/lib/sugarcrm/{api → connection/api}/get_document_revision.rb +2 -1
- data/lib/sugarcrm/{api → connection/api}/get_entries.rb +5 -6
- data/lib/sugarcrm/{api → connection/api}/get_entries_count.rb +3 -5
- data/lib/sugarcrm/{api → connection/api}/get_entry.rb +6 -6
- data/lib/sugarcrm/{api → connection/api}/get_entry_list.rb +6 -6
- data/lib/sugarcrm/{api → connection/api}/get_module_fields.rb +2 -1
- data/lib/sugarcrm/{api → connection/api}/get_note_attachment.rb +1 -1
- data/lib/sugarcrm/connection/api/get_relationships.rb +34 -0
- data/lib/sugarcrm/{api → connection/api}/get_report_entries.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/get_server_info.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/get_user_id.rb +2 -2
- data/lib/sugarcrm/{api → connection/api}/get_user_team_id.rb +2 -2
- data/lib/sugarcrm/{api → connection/api}/login.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/logout.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/seamless_login.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/search_by_module.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_campaign_merge.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_document_revision.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_entries.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_entry.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_note_attachment.rb +0 -0
- data/lib/sugarcrm/{api → connection/api}/set_relationship.rb +1 -1
- data/lib/sugarcrm/{api → connection/api}/set_relationships.rb +1 -1
- data/lib/sugarcrm/connection/helper.rb +10 -0
- data/lib/sugarcrm/exceptions.rb +6 -0
- data/lib/sugarcrm/module.rb +105 -6
- data/lib/sugarcrm/module_methods.rb +18 -0
- data/lib/sugarcrm/request.rb +13 -3
- data/lib/sugarcrm/response.rb +75 -25
- data/test/connection/test_get_available_modules.rb +12 -0
- data/test/connection/test_get_entries.rb +21 -0
- data/test/connection/test_get_entry.rb +20 -0
- data/test/connection/test_get_entry_list.rb +28 -0
- data/test/connection/test_get_module_fields.rb +14 -0
- data/test/connection/test_get_relationships.rb +15 -0
- data/test/connection/test_get_server_info.rb +12 -0
- data/test/connection/test_get_user_id.rb +12 -0
- data/test/connection/test_get_user_team_id.rb +12 -0
- data/test/connection/test_login.rb +12 -0
- data/test/connection/test_logout.rb +12 -0
- data/test/helper.rb +4 -1
- data/test/test_connection.rb +12 -48
- data/test/test_module.rb +14 -0
- data/test/test_response.rb +5 -14
- data/test/test_sugarcrm.rb +16 -14
- metadata +60 -34
- data/lib/sugarcrm/api/get_relationship.rb +0 -25
- data/lib/sugarcrm/core_ext/attribute.rb +0 -67
- data/lib/sugarcrm/core_ext/remove_method.rb +0 -6
- data/lib/sugarcrm/core_ext/singleton_class.rb +0 -13
data/README.rdoc
CHANGED
@@ -11,8 +11,8 @@ RubyGem for interacting with SugarCRM via REST.
|
|
11
11
|
== Description:
|
12
12
|
|
13
13
|
I've implemented all of the basic API calls that SugarCRM supports, and am actively building an abstraction layer
|
14
|
-
on top of the basic API methods. The end result will be
|
15
|
-
|
14
|
+
on top of the basic API methods. The end result will be ActiveRecord style finders and first class objects. Some
|
15
|
+
of this functionality is included today.
|
16
16
|
|
17
17
|
== FEATURES/PROBLEMS:
|
18
18
|
|
@@ -23,20 +23,25 @@ objects. Some of this functionality is included today.
|
|
23
23
|
|
24
24
|
require 'sugarcrm'
|
25
25
|
# Establish a connection
|
26
|
-
|
26
|
+
SugarCRM::Base.establish_connection("http://localhost/sugarcrm", 'user', 'password', {:debug => false})
|
27
27
|
|
28
28
|
# Retrieve a user by ID, using the SugarCRM::User Proxy object
|
29
29
|
SugarCRM::User.find(id)
|
30
30
|
|
31
31
|
# Show a list of available modules
|
32
|
-
|
32
|
+
SugarCRM.modules
|
33
|
+
|
34
|
+
# Use the HTTP for direct API calls
|
35
|
+
SugarCRM.connection.get_entry(1)
|
33
36
|
|
34
37
|
# Lookup a user by name. Find any associated accounts
|
35
|
-
|
38
|
+
SugarCRM::User.find_by_username('sarah').accounts
|
39
|
+
|
40
|
+
# Same operation, but using the direct API calls
|
41
|
+
SugarCRM.connection.get_entry_list(
|
36
42
|
"Users",
|
37
|
-
"users.user_name = \'
|
43
|
+
"users.user_name = \'sarah\'",
|
38
44
|
{
|
39
|
-
:fields => ["first_name", "last_name"],
|
40
45
|
:link_fields => [
|
41
46
|
{
|
42
47
|
"name" => "accounts",
|
@@ -48,7 +53,7 @@ objects. Some of this functionality is included today.
|
|
48
53
|
|
49
54
|
== REQUIREMENTS:
|
50
55
|
|
51
|
-
* activesupport gem
|
56
|
+
* >= activesupport 3.0.0 gem
|
52
57
|
* json gem
|
53
58
|
|
54
59
|
== INSTALL:
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ begin
|
|
14
14
|
gem.authors = ["Carl Hicks"]
|
15
15
|
gem.add_development_dependency "shoulda", ">= 0"
|
16
16
|
gem.add_dependency "json", ">= 0"
|
17
|
-
gem.add_dependency "activesupport", ">=
|
17
|
+
gem.add_dependency "activesupport", ">= 3.0"
|
18
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
19
|
end
|
20
20
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.2
|
data/lib/sugarcrm.rb
CHANGED
@@ -1,143 +1,11 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
module SugarCRM
|
4
|
-
|
5
|
-
Dir["#{File.dirname(__FILE__)}/sugarcrm/**/*.rb"].each { |f| load(f) }
|
6
|
-
|
7
1
|
require 'pp'
|
8
|
-
require 'uri'
|
9
|
-
require 'net/https'
|
10
|
-
require 'digest/md5'
|
11
|
-
|
12
2
|
require 'rubygems'
|
13
3
|
require 'active_support/core_ext'
|
14
|
-
require 'json'
|
15
|
-
|
16
|
-
class Base
|
17
|
-
# Unset all of the instance methods we don't need.
|
18
|
-
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^define_method$|^class$|^instance_of.$)/ }
|
19
|
-
|
20
|
-
# This holds our connection
|
21
|
-
cattr_accessor :connection, :instance_writer => false
|
22
|
-
|
23
|
-
# Contains the name of the module in SugarCRM
|
24
|
-
class_attribute :module_name
|
25
|
-
self.module_name = self.name.split(/::/)[-1]
|
26
|
-
|
27
|
-
# Contains the fields found on the current module
|
28
|
-
class_attribute :module_fields
|
29
|
-
self.module_fields = {}
|
30
|
-
|
31
|
-
# Tracks if we have extended our class with attribute methods yet.
|
32
|
-
class_attribute :attribute_methods_generated
|
33
|
-
self.attribute_methods_generated = false
|
34
|
-
|
35
|
-
# Contains a list of attributes
|
36
|
-
attr :attributes, true
|
37
|
-
attr :debug, true
|
38
|
-
|
39
|
-
def self.establish_connection(url, user, pass, opts={})
|
40
|
-
options = {
|
41
|
-
:debug => false,
|
42
|
-
}.merge(opts)
|
43
|
-
@debug = options[:debug]
|
44
|
-
@@connection = SugarCRM::Connection.new(url, user, pass, @debug)
|
45
|
-
end
|
46
|
-
|
47
|
-
# Registers the module fields on the class
|
48
|
-
def self.register_module_fields
|
49
|
-
self.module_fields = connection.get_fields(self.module_name)["module_fields"] if self.module_fields.length == 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def initialize(attributes={})
|
53
|
-
@attributes = attributes_from_module_fields.merge(attributes)
|
54
|
-
define_attribute_methods
|
55
|
-
end
|
56
|
-
|
57
|
-
def inspect
|
58
|
-
self
|
59
|
-
end
|
60
|
-
|
61
|
-
def to_s
|
62
|
-
attrs = []
|
63
|
-
@attributes.each_key do |k|
|
64
|
-
attrs << "#{k}: #{attribute_for_inspect(k)}"
|
65
|
-
end
|
66
|
-
"#<#{self.class} #{attrs.join(", ")}>"
|
67
|
-
end
|
68
|
-
|
69
|
-
# Returns an <tt>#inspect</tt>-like string for the value of the
|
70
|
-
# attribute +attr_name+. String attributes are elided after 50
|
71
|
-
# characters, and Date and Time attributes are returned in the
|
72
|
-
# <tt>:db</tt> format. Other attributes return the value of
|
73
|
-
# <tt>#inspect</tt> without modification.
|
74
|
-
#
|
75
|
-
# person = Person.create!(:name => "David Heinemeier Hansson " * 3)
|
76
|
-
#
|
77
|
-
# person.attribute_for_inspect(:name)
|
78
|
-
# # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
|
79
|
-
#
|
80
|
-
# person.attribute_for_inspect(:created_at)
|
81
|
-
# # => '"2009-01-12 04:48:57"'
|
82
|
-
def attribute_for_inspect(attr_name)
|
83
|
-
value = read_attribute(attr_name)
|
84
|
-
|
85
|
-
if value.is_a?(String) && value.length > 50
|
86
|
-
"#{value[0..50]}...".inspect
|
87
|
-
elsif value.is_a?(Date) || value.is_a?(Time)
|
88
|
-
%("#{value.to_s(:db)}")
|
89
|
-
else
|
90
|
-
value.inspect
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
protected
|
95
|
-
|
96
|
-
# Generates get/set methods for keys in the attributes hash
|
97
|
-
def define_attribute_methods
|
98
|
-
return if attribute_methods_generated?
|
99
|
-
@attributes.each_pair do |k,v|
|
100
|
-
self.class.module_eval %Q?
|
101
|
-
def #{k}
|
102
|
-
read_attribute :#{k}
|
103
|
-
end
|
104
|
-
def #{k}=(value)
|
105
|
-
write_attribute :#{k},value
|
106
|
-
end
|
107
|
-
?
|
108
|
-
end
|
109
|
-
self.class.attribute_methods_generated = true
|
110
|
-
end
|
111
|
-
|
112
|
-
# Wrapper around class attribute
|
113
|
-
def attribute_methods_generated?
|
114
|
-
self.class.attribute_methods_generated
|
115
|
-
end
|
116
|
-
|
117
|
-
def module_fields_registered?
|
118
|
-
self.class.module_fields.length > 0
|
119
|
-
end
|
120
|
-
|
121
|
-
# Returns a hash of the module fields from the
|
122
|
-
def attributes_from_module_fields
|
123
|
-
self.class.register_module_fields unless module_fields_registered?
|
124
|
-
fields = {}
|
125
|
-
self.class.module_fields.keys.sort.each do |k|
|
126
|
-
fields[k.to_s] = nil
|
127
|
-
end
|
128
|
-
fields
|
129
|
-
end
|
130
|
-
|
131
|
-
# Wrapper around attributes hash
|
132
|
-
def read_attribute(key)
|
133
|
-
@attributes[key]
|
134
|
-
end
|
135
|
-
|
136
|
-
# Wrapper around attributes hash
|
137
|
-
def write_attribute(key, value)
|
138
|
-
@attributes[key] = value
|
139
|
-
end
|
140
|
-
|
141
|
-
end
|
142
4
|
|
143
|
-
|
5
|
+
require 'sugarcrm/module_methods'
|
6
|
+
require 'sugarcrm/base'
|
7
|
+
require 'sugarcrm/connection'
|
8
|
+
require 'sugarcrm/exceptions'
|
9
|
+
require 'sugarcrm/module'
|
10
|
+
require 'sugarcrm/request'
|
11
|
+
require 'sugarcrm/response'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SugarCRM; module AssociationMethods
|
2
|
+
|
3
|
+
# Returns an array of the module link fields
|
4
|
+
def associations_from_module_link_fields
|
5
|
+
self.class._module.link_fields.keys
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generates the association proxy methods for related modules
|
9
|
+
def define_association_methods
|
10
|
+
return if association_methods_generated?
|
11
|
+
@associations.each do |k|
|
12
|
+
self.class.module_eval %Q?
|
13
|
+
def #{k}
|
14
|
+
query_association :#{k}
|
15
|
+
end
|
16
|
+
def #{k}=(value)
|
17
|
+
update_association :#{k},value
|
18
|
+
end
|
19
|
+
?
|
20
|
+
end
|
21
|
+
self.class.association_methods_generated = true
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# {"email_addresses"=>
|
26
|
+
# {"name"=>"email_addresses",
|
27
|
+
# "module"=>"EmailAddress",
|
28
|
+
# "bean_name"=>"EmailAddress",
|
29
|
+
# "relationship"=>"users_email_addresses",
|
30
|
+
# "type"=>"link"},
|
31
|
+
#
|
32
|
+
def query_association(association)
|
33
|
+
klass = self.class._module.link_fields[association.to_s]["module"]
|
34
|
+
objects = SugarCRM.connection.get_relationships(
|
35
|
+
self.class._module.name,
|
36
|
+
self.id,
|
37
|
+
association.to_s
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def update_association(association, value)
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
end; end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module SugarCRM; module AttributeMethods
|
2
|
+
|
3
|
+
# Returns a hash of the module fields from the
|
4
|
+
def attributes_from_module_fields
|
5
|
+
fields = {}
|
6
|
+
self.class._module.fields.keys.sort.each do |k|
|
7
|
+
fields[k.to_s] = nil
|
8
|
+
end
|
9
|
+
fields
|
10
|
+
end
|
11
|
+
|
12
|
+
# Generates get/set methods for keys in the attributes hash
|
13
|
+
def define_attribute_methods
|
14
|
+
return if attribute_methods_generated?
|
15
|
+
@attributes.each_pair do |k,v|
|
16
|
+
self.class.module_eval %Q?
|
17
|
+
def #{k}
|
18
|
+
read_attribute :#{k}
|
19
|
+
end
|
20
|
+
def #{k}=(value)
|
21
|
+
write_attribute :#{k},value
|
22
|
+
end
|
23
|
+
?
|
24
|
+
end
|
25
|
+
self.class.attribute_methods_generated = true
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns an <tt>#inspect</tt>-like string for the value of the
|
29
|
+
# attribute +attr_name+. String attributes are elided after 50
|
30
|
+
# characters, and Date and Time attributes are returned in the
|
31
|
+
# <tt>:db</tt> format. Other attributes return the value of
|
32
|
+
# <tt>#inspect</tt> without modification.
|
33
|
+
#
|
34
|
+
# person = Person.create!(:name => "David Heinemeier Hansson " * 3)
|
35
|
+
#
|
36
|
+
# person.attribute_for_inspect(:name)
|
37
|
+
# # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
|
38
|
+
#
|
39
|
+
# person.attribute_for_inspect(:created_at)
|
40
|
+
# # => '"2009-01-12 04:48:57"'
|
41
|
+
def attribute_for_inspect(attr_name)
|
42
|
+
value = read_attribute(attr_name)
|
43
|
+
if value.is_a?(String) && value.length > 50
|
44
|
+
"#{value[0..50]}...".inspect
|
45
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
46
|
+
%("#{value.to_s(:db)}")
|
47
|
+
else
|
48
|
+
value.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
# Wrapper around attributes hash
|
55
|
+
def read_attribute(key)
|
56
|
+
@attributes[key]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Wrapper around attributes hash
|
60
|
+
def write_attribute(key, value)
|
61
|
+
@attributes[key] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
end; end
|
65
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'sugarcrm/attribute_methods'
|
2
|
+
require 'sugarcrm/association_methods'
|
3
|
+
|
4
|
+
module SugarCRM; class Base
|
5
|
+
|
6
|
+
# Unset all of the instance methods we don't need.
|
7
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^define_method$|^class$|^instance_of.$)/ }
|
8
|
+
|
9
|
+
# This holds our connection
|
10
|
+
cattr_accessor :connection, :instance_writer => false
|
11
|
+
|
12
|
+
# Tracks if we have extended our class with attribute methods yet.
|
13
|
+
class_attribute :attribute_methods_generated
|
14
|
+
self.attribute_methods_generated = false
|
15
|
+
|
16
|
+
class_attribute :association_methods_generated
|
17
|
+
self.association_methods_generated = false
|
18
|
+
|
19
|
+
class_attribute :_module
|
20
|
+
self._module = nil
|
21
|
+
|
22
|
+
# Contains a list of attributes
|
23
|
+
attr :attributes, true
|
24
|
+
attr :id, true
|
25
|
+
attr :debug, true
|
26
|
+
|
27
|
+
class << self # Class methods
|
28
|
+
def establish_connection(url, user, pass, opts={})
|
29
|
+
options = {
|
30
|
+
:debug => false,
|
31
|
+
}.merge(opts)
|
32
|
+
@debug = options[:debug]
|
33
|
+
@@connection = SugarCRM::Connection.new(url, user, pass, @debug)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Runs a find against the remote service
|
37
|
+
def find(id)
|
38
|
+
response = SugarCRM.connection.get_entry(self._module.name, id, {:fields => self._module.fields.keys})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Creates an instance of a Module Class, i.e. Account, User, Contact, etc.
|
43
|
+
# This call depends upon SugarCRM.modules having actual data in it. If you
|
44
|
+
# are using Base.establish_connection, you should be fine. But if you are
|
45
|
+
# using the Connection class by itself, you may need to prime the pump with
|
46
|
+
# a call to Module.register_all
|
47
|
+
def initialize(id=nil, attributes={})
|
48
|
+
@id = id
|
49
|
+
@attributes = attributes_from_module_fields.merge(attributes)
|
50
|
+
@associations = associations_from_module_link_fields
|
51
|
+
define_attribute_methods
|
52
|
+
define_association_methods
|
53
|
+
end
|
54
|
+
|
55
|
+
def inspect
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
attrs = []
|
61
|
+
@attributes.each_key do |k|
|
62
|
+
attrs << "#{k}: #{attribute_for_inspect(k)}"
|
63
|
+
end
|
64
|
+
"#<#{self.class} #{attrs.join(", ")}>"
|
65
|
+
end
|
66
|
+
|
67
|
+
def save
|
68
|
+
response = SugarCRM.connection.set_entry(self._module.name, @attributes)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Wrapper around class attribute
|
72
|
+
def attribute_methods_generated?
|
73
|
+
self.class.attribute_methods_generated
|
74
|
+
end
|
75
|
+
|
76
|
+
def association_methods_generated?
|
77
|
+
self.class.association_methods_generated
|
78
|
+
end
|
79
|
+
|
80
|
+
Base.class_eval do
|
81
|
+
include AttributeMethods
|
82
|
+
include AssociationMethods
|
83
|
+
end
|
84
|
+
|
85
|
+
end; end
|
data/lib/sugarcrm/connection.rb
CHANGED
@@ -1,112 +1,135 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
begin
|
33
|
-
register_module(m)
|
34
|
-
rescue SugarCRM::InvalidRequest
|
35
|
-
next
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Check to see if we are logged in
|
41
|
-
def logged_in?
|
42
|
-
@session ? true : false
|
43
|
-
end
|
1
|
+
|
2
|
+
require 'uri'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
require 'sugarcrm/connection/helper'
|
9
|
+
Dir["#{File.dirname(__FILE__)}/connection/api/*.rb"].each { |f| load(f) }
|
10
|
+
|
11
|
+
module SugarCRM; class Connection
|
12
|
+
|
13
|
+
URL = "/service/v2/rest.php"
|
14
|
+
DONT_SHOW_DEBUG_FOR = [:get_available_modules]
|
15
|
+
RESPONSE_IS_NOT_JSON = [:get_user_id, :get_user_team_id]
|
16
|
+
|
17
|
+
attr :url, true
|
18
|
+
attr :user, false
|
19
|
+
attr :pass, false
|
20
|
+
attr :session, true
|
21
|
+
attr :connection, true
|
22
|
+
attr :options, true
|
23
|
+
attr :request, true
|
24
|
+
attr :response, true
|
25
|
+
|
26
|
+
# This is the singleton connection class.
|
27
|
+
def initialize(url, user, pass, options={})
|
28
|
+
@options = {
|
29
|
+
:debug => false,
|
30
|
+
:register_modules => true
|
31
|
+
}.merge(options)
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
33
|
+
@url = URI.parse(url)
|
34
|
+
@user = user
|
35
|
+
@pass = pass
|
36
|
+
@request = ""
|
37
|
+
@response = ""
|
38
|
+
|
39
|
+
resolve_url
|
40
|
+
login!
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Check to see if we are logged in
|
45
|
+
def logged_in?
|
46
|
+
@session ? true : false
|
47
|
+
end
|
48
|
+
|
49
|
+
# Login
|
50
|
+
def login!
|
51
|
+
@session = login["id"]
|
52
|
+
raise SugarCRM::LoginError, "Invalid Login" unless logged_in?
|
53
|
+
SugarCRM.connection = self
|
54
|
+
SugarCRM::Base.connection = self
|
55
|
+
Module.register_all if @options[:register_modules]
|
56
|
+
end
|
50
57
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
# Check to see if we are connected
|
59
|
+
def connected?
|
60
|
+
return false unless @connection
|
61
|
+
return false unless @connection.started?
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
# Connect
|
66
|
+
def connect!
|
67
|
+
@connection = Net::HTTP.new(@url.host, @url.port)
|
68
|
+
if @url.scheme == "https"
|
69
|
+
@connection.use_ssl = true
|
70
|
+
@connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
56
71
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
72
|
+
@connection.start
|
73
|
+
end
|
74
|
+
|
75
|
+
# Send a GET request to the Sugar Instance
|
76
|
+
def send!(method, json)
|
77
|
+
@request = SugarCRM::Request.new(@url, method, json, @options[:debug])
|
78
|
+
if @request.length > 3900
|
79
|
+
@response = @connection.post(@url.path, @request)
|
80
|
+
else
|
81
|
+
@response = @connection.get(@url.path.dup + "?" + @request.to_s)
|
82
|
+
end
|
83
|
+
handle_response
|
84
|
+
end
|
85
|
+
|
86
|
+
def debug=(debug)
|
87
|
+
options[:debug] = debug
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def handle_response
|
93
|
+
case @response
|
94
|
+
when Net::HTTPOK
|
95
|
+
return process_response
|
96
|
+
when Net::HTTPNotFound
|
97
|
+
raise SugarCRM::InvalidSugarCRMUrl, "#{@url} is invalid"
|
98
|
+
when Net::HTTPInternalServerError
|
99
|
+
raise SugarCRM::InvalidRequest, "#{@request} is invalid"
|
100
|
+
else
|
101
|
+
if @options[:debug]
|
102
|
+
puts "#{@request.method}: Raw Response:"
|
103
|
+
puts @response.body
|
104
|
+
puts "\n"
|
64
105
|
end
|
65
|
-
@
|
106
|
+
raise SugarCRM::UnhandledResponse, "Can't handle response #{@response}"
|
66
107
|
end
|
108
|
+
end
|
67
109
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
83
|
-
return response_json
|
84
|
-
when Net::HTTPNotFound
|
85
|
-
raise SugarCRM::InvalidSugarCRMUrl, "#{@url} is invalid"
|
86
|
-
when Net::HTTPInternalServerError
|
87
|
-
raise SugarCRM::InvalidRequest, "#{request} is invalid"
|
88
|
-
else
|
89
|
-
if @debug
|
90
|
-
puts "#{method}: Raw Response:"
|
91
|
-
puts response.body
|
92
|
-
puts "\n"
|
93
|
-
end
|
94
|
-
raise SugarCRM::UnhandledResponse, "Can't handle response #{response}"
|
95
|
-
end
|
110
|
+
def process_response
|
111
|
+
# Complain if our body is empty.
|
112
|
+
raise SugarCRM::EmptyResponse unless @response.body
|
113
|
+
# Some methods are dumb and don't return a JSON Response
|
114
|
+
return @response.body if RESPONSE_IS_NOT_JSON.include? @request.method
|
115
|
+
# Push it through the old meat grinder.
|
116
|
+
response_json = JSON.parse @response.body
|
117
|
+
# Empty result. Is this wise?
|
118
|
+
return false if response_json["result_count"] == 0
|
119
|
+
# Filter debugging on REALLY BIG responses
|
120
|
+
if @options[:debug] && !(DONT_SHOW_DEBUG_FOR.include? @request.method)
|
121
|
+
puts "#{@request.method}: JSON Response:"
|
122
|
+
pp response_json
|
123
|
+
puts "\n"
|
96
124
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
klass = Class.new(SugarCRM::Base) do
|
105
|
-
self.module_name = module_name
|
106
|
-
end
|
107
|
-
mod.const_set klass_name, klass
|
108
|
-
klass
|
125
|
+
return response_json
|
126
|
+
end
|
127
|
+
|
128
|
+
def resolve_url
|
129
|
+
# Appends the rest.php path onto the end of the URL if it's not included
|
130
|
+
if @url.path !~ /rest.php$/
|
131
|
+
@url.path += URL
|
109
132
|
end
|
110
|
-
|
111
133
|
end
|
112
|
-
|
134
|
+
|
135
|
+
end; end
|