sugarcrm 0.6.2 → 0.7.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/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
|