justrelate_sdk 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +840 -0
- data/README.md +114 -0
- data/UPGRADE.md +509 -0
- data/config/ca-bundle.crt +4484 -0
- data/lib/justrelate/account.rb +17 -0
- data/lib/justrelate/activity.rb +143 -0
- data/lib/justrelate/collection.rb +41 -0
- data/lib/justrelate/contact.rb +121 -0
- data/lib/justrelate/core/attachment_store.rb +122 -0
- data/lib/justrelate/core/basic_resource.rb +68 -0
- data/lib/justrelate/core/configuration.rb +65 -0
- data/lib/justrelate/core/connection_manager.rb +98 -0
- data/lib/justrelate/core/item_enumerator.rb +61 -0
- data/lib/justrelate/core/log_subscriber.rb +41 -0
- data/lib/justrelate/core/mixins/attribute_provider.rb +135 -0
- data/lib/justrelate/core/mixins/change_loggable.rb +98 -0
- data/lib/justrelate/core/mixins/findable.rb +24 -0
- data/lib/justrelate/core/mixins/inspectable.rb +27 -0
- data/lib/justrelate/core/mixins/merge_and_deletable.rb +17 -0
- data/lib/justrelate/core/mixins/modifiable.rb +102 -0
- data/lib/justrelate/core/mixins/searchable.rb +88 -0
- data/lib/justrelate/core/mixins.rb +6 -0
- data/lib/justrelate/core/rest_api.rb +148 -0
- data/lib/justrelate/core/search_configurator.rb +207 -0
- data/lib/justrelate/core.rb +6 -0
- data/lib/justrelate/errors.rb +169 -0
- data/lib/justrelate/event.rb +17 -0
- data/lib/justrelate/event_contact.rb +16 -0
- data/lib/justrelate/mailing.rb +111 -0
- data/lib/justrelate/template_set.rb +81 -0
- data/lib/justrelate/type.rb +78 -0
- data/lib/justrelate.rb +149 -0
- metadata +147 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
module JustRelate
|
2
|
+
# +TemplateSet+ represents the JustRelate template set singleton.
|
3
|
+
# The templates of the {.singleton template set singleton} can be used to render customized text,
|
4
|
+
# e.g. a mailing greeting or a password request e-mail body (+password_request_email_body+).
|
5
|
+
#
|
6
|
+
# JustRelate uses the {http://liquidmarkup.org/ Liquid template engine} for evaluating
|
7
|
+
# the templates.
|
8
|
+
# @api public
|
9
|
+
class TemplateSet < Core::BasicResource
|
10
|
+
include Core::Mixins::ChangeLoggable
|
11
|
+
include Core::Mixins::Inspectable
|
12
|
+
|
13
|
+
def self.path
|
14
|
+
resource_name
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the template set singleton.
|
18
|
+
# @return [TemplateSet]
|
19
|
+
# @api public
|
20
|
+
def self.singleton
|
21
|
+
new({}).reload
|
22
|
+
end
|
23
|
+
|
24
|
+
# Updates the attributes of this template set.
|
25
|
+
# See {Core::Mixins::Modifiable#update Modifiable#update} for details.
|
26
|
+
# @return [self] the updated template set singleton.
|
27
|
+
# @api public
|
28
|
+
def update(attributes)
|
29
|
+
load_attributes(
|
30
|
+
Core::RestApi.instance.put(path, attributes, if_match_header))
|
31
|
+
end
|
32
|
+
|
33
|
+
# Renders a preview of the template set using the specified context items.
|
34
|
+
# This is for testing your (future) templates.
|
35
|
+
#
|
36
|
+
# * All templates contained in the set are rendered.
|
37
|
+
# * You may temporally add any number of +templates+ to the set
|
38
|
+
# (just for the purpose of rendering).
|
39
|
+
# * Pass as +context+ items all the instances (e.g. contact, acticity)
|
40
|
+
# for which the templates should be rendered.
|
41
|
+
#
|
42
|
+
# Templates have access to the context items.
|
43
|
+
# You can use the following keys to represent context items:
|
44
|
+
# * +account+
|
45
|
+
# * +contact+
|
46
|
+
# * +activity+
|
47
|
+
# * +mailing+
|
48
|
+
# * +event+
|
49
|
+
# The keys expect an ID as input. For example, <tt>{"account" => "23"}</tt> allows
|
50
|
+
# the template to access +account.name+ of the account with the ID +23+.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# contact.first_name
|
54
|
+
# # => 'Michael'
|
55
|
+
#
|
56
|
+
# template_set.templates['digest_email_subject']
|
57
|
+
# # => 'Summary for {{contact.first_name}}'
|
58
|
+
#
|
59
|
+
# template_set.render_preview(
|
60
|
+
# templates: { greeting: 'Dear {{contact.first_name}}, {{foo}}' },
|
61
|
+
# context: {contact: contact.id, foo: 'welcome!'}
|
62
|
+
# )
|
63
|
+
# # => {
|
64
|
+
# # ...
|
65
|
+
# # 'digest_email_subject' => 'Summary for Michael',
|
66
|
+
# # 'greeting' => 'Dear Michael, welcome!',
|
67
|
+
# # ...
|
68
|
+
# # }
|
69
|
+
# @param templates [Hash{String => String}]
|
70
|
+
# the set of additional or temporary replacement templates to render.
|
71
|
+
# @param context [Hash{String => String}] the context items of the preview.
|
72
|
+
# @return [Hash{String => String}] the processed templates.
|
73
|
+
# @api public
|
74
|
+
def render_preview(templates: {}, context: {})
|
75
|
+
Core::RestApi.instance.post("#{path}/render_preview", {
|
76
|
+
'templates' => templates,
|
77
|
+
'context' => context,
|
78
|
+
})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module JustRelate
|
2
|
+
# A JustRelate type defines a set of attributes associated with every instance of the type.
|
3
|
+
# @example Listing all attributes of a type
|
4
|
+
# account_type = JustRelate::Type.find('account')
|
5
|
+
# # => JustRelate::Type
|
6
|
+
#
|
7
|
+
# # Listing all standard attributes
|
8
|
+
# account_type.standard_attribute_definitions.keys
|
9
|
+
# # => ['name', 'created_at', 'updated_at', ...]
|
10
|
+
#
|
11
|
+
# # Listing all custom attributes
|
12
|
+
# account_type.attribute_definitions.keys
|
13
|
+
# # => ['custom_plan', ...]
|
14
|
+
#
|
15
|
+
# @example Inspecting an attribute definition of a type
|
16
|
+
# account_type.standard_attribute_definitions["name"]
|
17
|
+
# # => {
|
18
|
+
# # 'attribute_type' => 'string',
|
19
|
+
# # 'create' => true,
|
20
|
+
# # 'mandatory' => true,
|
21
|
+
# # 'read' => true,
|
22
|
+
# # 'title' => 'Name',
|
23
|
+
# # 'update' => true,
|
24
|
+
# # }
|
25
|
+
#
|
26
|
+
# @example Adding a new custom attribute to a type
|
27
|
+
# account_type.attribute_definitions.keys
|
28
|
+
# # => ['custom_plan']
|
29
|
+
#
|
30
|
+
# # Add a new custom attribute named "custom_shipping_details"
|
31
|
+
# attr_defs = account_type.attribute_definitions.merge({
|
32
|
+
# custom_shipping_details: {
|
33
|
+
# attribute_type: 'text',
|
34
|
+
# title: 'Shipping Details',
|
35
|
+
# }
|
36
|
+
# })
|
37
|
+
# account_type.update({
|
38
|
+
# attribute_definitions: attr_defs,
|
39
|
+
# })
|
40
|
+
# # => JustRelate::Type
|
41
|
+
#
|
42
|
+
# account_type.attribute_definitions.keys
|
43
|
+
# # => ['custom_plan', 'custom_shipping_details']
|
44
|
+
#
|
45
|
+
# @example Removing a custom attribute from a type
|
46
|
+
# account_type.attribute_definitions.keys
|
47
|
+
# # => ['custom_plan', 'custom_shipping_details']
|
48
|
+
#
|
49
|
+
# attr_defs = account_type.attribute_definitions.except('custom_shipping_details')
|
50
|
+
# account_type.update({
|
51
|
+
# attribute_definitions: attr_defs,
|
52
|
+
# })
|
53
|
+
# # => JustRelate::Type
|
54
|
+
#
|
55
|
+
# account_type.attribute_definitions.keys
|
56
|
+
# # => ['custom_plan']
|
57
|
+
# @api public
|
58
|
+
class Type < Core::BasicResource
|
59
|
+
include Core::Mixins::Findable
|
60
|
+
include Core::Mixins::Modifiable
|
61
|
+
include Core::Mixins::ChangeLoggable
|
62
|
+
include Core::Mixins::Inspectable
|
63
|
+
inspectable :id, :item_base_type
|
64
|
+
|
65
|
+
# @!parse extend Core::Mixins::Findable::ClassMethods
|
66
|
+
# @!parse extend Core::Mixins::Modifiable::ClassMethods
|
67
|
+
|
68
|
+
# Returns all types.
|
69
|
+
# @param include_deleted [Boolean] whether to include deleted types. Default: +false+.
|
70
|
+
# @return [Array<Type>]
|
71
|
+
# @api public
|
72
|
+
def self.all(include_deleted: false)
|
73
|
+
Core::RestApi.instance.get('types', { include_deleted: include_deleted }).map do |item|
|
74
|
+
new(item)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/justrelate.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'net/http/post/multipart'
|
3
|
+
require 'justrelate/errors'
|
4
|
+
|
5
|
+
# @api public
|
6
|
+
module JustRelate
|
7
|
+
# Configures the JustRelate SDK.
|
8
|
+
# The config keys +tenant+, +login+ and +api_key+ must be provided.
|
9
|
+
# @example
|
10
|
+
# JustRelate.configure do |config|
|
11
|
+
# config.tenant = 'my_tenant'
|
12
|
+
# config.login = 'my_login'
|
13
|
+
# config.api_key = 'my_api_key'
|
14
|
+
# end
|
15
|
+
# @yieldparam config [JustRelate::Core::Configuration]
|
16
|
+
# @return [void]
|
17
|
+
# @api public
|
18
|
+
def self.configure
|
19
|
+
config = ::JustRelate::Core::Configuration.new
|
20
|
+
yield config
|
21
|
+
config.validate!
|
22
|
+
Core::RestApi.instance = Core::RestApi.new(config.endpoint_uri, config.login, config.api_key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.autoload_module(mod, mod_source)
|
26
|
+
mod_dir = mod_source.gsub(/\.rb$/, '')
|
27
|
+
Dir.glob("#{mod_dir}/*.rb").each do |file|
|
28
|
+
name = File.basename(file, ".rb")
|
29
|
+
mod.autoload name.camelcase, file
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Fetches multiple items by +ids+.
|
34
|
+
# The base type of the items can be mixed (e.g. a {JustRelate::Contact} or {JustRelate::Account}).
|
35
|
+
# @example
|
36
|
+
# JustRelate.find('e70a7123f499c5e0e9972ab4dbfb8fe3')
|
37
|
+
# # => JustRelate::Contact
|
38
|
+
#
|
39
|
+
# JustRelate.find('e70a7123f499c5e0e9972ab4dbfb8fe3', '2185dd25c2f4fa41fbef422c1b9cfc38')
|
40
|
+
# # => JustRelate::Core::ItemEnumerator
|
41
|
+
#
|
42
|
+
# JustRelate.find(['e70a7123f499c5e0e9972ab4dbfb8fe3', '2185dd25c2f4fa41fbef422c1b9cfc38'])
|
43
|
+
# # => JustRelate::Core::ItemEnumerator
|
44
|
+
# @param ids [String, Array<String>] A single ID or a list of IDs.
|
45
|
+
# @return [JustRelate::Core::BasicResource]
|
46
|
+
# A {JustRelate::Core::BasicResource single item} if the method was called with a single ID.
|
47
|
+
# @return [JustRelate::Core::ItemEnumerator]
|
48
|
+
# An {JustRelate::Core::ItemEnumerator enumerator} if the method was called with multiple IDs.
|
49
|
+
# @raise [Errors::ResourceNotFound] if at least one of the IDs could not be found.
|
50
|
+
# @api public
|
51
|
+
def self.find(*ids)
|
52
|
+
enumerator = Core::ItemEnumerator.new(ids.flatten)
|
53
|
+
|
54
|
+
if ids.size == 1 && !ids.first.kind_of?(Array)
|
55
|
+
enumerator.first
|
56
|
+
else
|
57
|
+
enumerator
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Performs a search.
|
62
|
+
# Retrieves only IDs and passes them to an {Core::ItemEnumerator ItemEnumerator}.
|
63
|
+
# The {Core::ItemEnumerator ItemEnumerator} then fetches the items on demand.
|
64
|
+
#
|
65
|
+
# The search considers the following base types:
|
66
|
+
# * {JustRelate::Account Account}
|
67
|
+
# * {JustRelate::Activity Activity}
|
68
|
+
# * {JustRelate::Collection Collection}
|
69
|
+
# * {JustRelate::Contact Contact}
|
70
|
+
# * {JustRelate::Event Event}
|
71
|
+
# * {JustRelate::EventContact EventContact}
|
72
|
+
# * {JustRelate::Mailing Mailing}
|
73
|
+
# @example
|
74
|
+
# JustRelate.search([{field: 'last_name', condition: 'equals', value: 'Johnson'}])
|
75
|
+
# # => JustRelate::Core::ItemEnumerator with max 10 contacts with last name Johnson.
|
76
|
+
#
|
77
|
+
# JustRelate.search(
|
78
|
+
# [
|
79
|
+
# {field: 'last_name', condition: 'equals', value: 'Johnson'},
|
80
|
+
# {field: 'locality', condition: 'equals', value: 'Boston'}
|
81
|
+
# ],
|
82
|
+
# limit: 20,
|
83
|
+
# offset: 10,
|
84
|
+
# sort_by: 'created_at',
|
85
|
+
# sort_order: 'desc',
|
86
|
+
# include_deleted: true
|
87
|
+
# )
|
88
|
+
# # => JustRelate::Core::ItemEnumerator with max 20 contacts with last name Johnson from Boston.
|
89
|
+
# @param filters [Array<Hash{String => String}>]
|
90
|
+
# Array of filters, each filter is a hash with three properties:
|
91
|
+
# +field+, +condition+, +value+. Filters are AND expressions.
|
92
|
+
# @param query [String]
|
93
|
+
# The search term of a full-text search for words starting with the term
|
94
|
+
# (case-insensitive prefix search). Affects score.
|
95
|
+
# @param limit [Fixnum] The number of results to return at most. Minimum: +0+.
|
96
|
+
# Use +:none+ to specify no limit. Default: +10+.
|
97
|
+
# @param offset [Fixnum] The number of results to skip. Minimum: +0+. Default: +0+.
|
98
|
+
# @param sort_by [String] The name of the attribute by which the result is to be sorted:
|
99
|
+
# * +base_type+
|
100
|
+
# * +created_at+ (server default)
|
101
|
+
# * +dtstart_at+
|
102
|
+
# * +first_name+
|
103
|
+
# * +last_name+
|
104
|
+
# * +score+
|
105
|
+
# * +title+
|
106
|
+
# * +updated_at+
|
107
|
+
# @param sort_order [String] One of +asc+ (ascending) or +desc+ (descending).
|
108
|
+
# For +sort_by+ +score+, the only valid sort order is +desc+ (can be omitted).
|
109
|
+
# @param include_deleted [Boolean]
|
110
|
+
# whether to include deleted items in the results. Server default: +false+.
|
111
|
+
# @return [JustRelate::Core::ItemEnumerator]
|
112
|
+
# An {JustRelate::Core::ItemEnumerator enumerator} to iterate over the found items.
|
113
|
+
# @api public
|
114
|
+
def self.search(filters: nil, query: nil, limit: nil, offset: nil, sort_by: nil,
|
115
|
+
sort_order: nil, include_deleted: nil)
|
116
|
+
server_limit = 1000
|
117
|
+
limit ||= 10
|
118
|
+
limit = Float::INFINITY if limit == :none
|
119
|
+
offset ||= 0
|
120
|
+
|
121
|
+
ids = []
|
122
|
+
total = nil
|
123
|
+
initial_offset = offset
|
124
|
+
|
125
|
+
loop do
|
126
|
+
params = {
|
127
|
+
'filters' => filters,
|
128
|
+
'query' => query,
|
129
|
+
'limit' => [limit, server_limit].min,
|
130
|
+
'offset' => offset,
|
131
|
+
'sort_by' => sort_by,
|
132
|
+
'sort_order' => sort_order,
|
133
|
+
'include_deleted' => include_deleted,
|
134
|
+
}.reject { |k, v| v.nil? }
|
135
|
+
search_results = Core::RestApi.instance.post('search', params)
|
136
|
+
ids.concat(search_results['results'].map { |r| r['id'] })
|
137
|
+
total = search_results['total']
|
138
|
+
break if ids.size >= [limit, (total - initial_offset)].min
|
139
|
+
limit -= server_limit
|
140
|
+
offset += server_limit
|
141
|
+
end
|
142
|
+
|
143
|
+
Core::ItemEnumerator.new(ids, total: total)
|
144
|
+
end
|
145
|
+
|
146
|
+
autoload_module(self, File.expand_path(__FILE__))
|
147
|
+
end
|
148
|
+
|
149
|
+
JustRelate::Core::LogSubscriber.attach_to :justrelate
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: justrelate_sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.rc1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Infopark AG
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: multipart-post
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: addressable
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
description: "\n JustRelate is a professional cloud CRM built for Ruby.\n For
|
84
|
+
more information about JustRelate, please visit https://justrelate.com/.\n "
|
85
|
+
email: info@infopark.de
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- UPGRADE.md
|
93
|
+
- config/ca-bundle.crt
|
94
|
+
- lib/justrelate.rb
|
95
|
+
- lib/justrelate/account.rb
|
96
|
+
- lib/justrelate/activity.rb
|
97
|
+
- lib/justrelate/collection.rb
|
98
|
+
- lib/justrelate/contact.rb
|
99
|
+
- lib/justrelate/core.rb
|
100
|
+
- lib/justrelate/core/attachment_store.rb
|
101
|
+
- lib/justrelate/core/basic_resource.rb
|
102
|
+
- lib/justrelate/core/configuration.rb
|
103
|
+
- lib/justrelate/core/connection_manager.rb
|
104
|
+
- lib/justrelate/core/item_enumerator.rb
|
105
|
+
- lib/justrelate/core/log_subscriber.rb
|
106
|
+
- lib/justrelate/core/mixins.rb
|
107
|
+
- lib/justrelate/core/mixins/attribute_provider.rb
|
108
|
+
- lib/justrelate/core/mixins/change_loggable.rb
|
109
|
+
- lib/justrelate/core/mixins/findable.rb
|
110
|
+
- lib/justrelate/core/mixins/inspectable.rb
|
111
|
+
- lib/justrelate/core/mixins/merge_and_deletable.rb
|
112
|
+
- lib/justrelate/core/mixins/modifiable.rb
|
113
|
+
- lib/justrelate/core/mixins/searchable.rb
|
114
|
+
- lib/justrelate/core/rest_api.rb
|
115
|
+
- lib/justrelate/core/search_configurator.rb
|
116
|
+
- lib/justrelate/errors.rb
|
117
|
+
- lib/justrelate/event.rb
|
118
|
+
- lib/justrelate/event_contact.rb
|
119
|
+
- lib/justrelate/mailing.rb
|
120
|
+
- lib/justrelate/template_set.rb
|
121
|
+
- lib/justrelate/type.rb
|
122
|
+
homepage: https://justrelate.com
|
123
|
+
licenses:
|
124
|
+
- LGPL-3.0
|
125
|
+
metadata: {}
|
126
|
+
post_install_message:
|
127
|
+
rdoc_options: []
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 1.3.1
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 2.4.1
|
143
|
+
signing_key:
|
144
|
+
specification_version: 4
|
145
|
+
summary: 'JustRelate: A professional cloud CRM.'
|
146
|
+
test_files: []
|
147
|
+
has_rdoc:
|