pipedrive-client 0.0.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37486380ffaa9ba770ac49319bb0f2a52aa25b53
4
+ data.tar.gz: 44cebb818094f3903ad985329d8214902df5dd34
5
+ SHA512:
6
+ metadata.gz: 47eceb5218da8d2ef256443f6fc71913eb441dd5277c6a81add1401c4db8a357b63feec6d40bb2c83da602072f72f3126085085e4d3bad8cba3f4b83885fa69d
7
+ data.tar.gz: dc8e96f561b2124093589d8f074c1ac6dfea208ac51ba531bb5a2fb3d69ceeda0305d51f8c08778832e9dc9f60fcc63bb15027751e93e5f3afe0a126a21373e0
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source "https://rubygems.org"
2
+ ruby '2.1.1'
3
+
4
+ gemspec
5
+
6
+ gem 'rake'
7
+
8
+ group :development do
9
+ gem 'pry'
10
+ # gem 'rspec'
11
+
12
+ # gem 'guard'
13
+ # gem 'guard-rspec', require: false
14
+ # gem 'guard-bundler'
15
+
16
+ # gem 'rb-fchange', :require=>false
17
+ # gem 'rb-fsevent', :require=>false
18
+ # gem 'rb-inotify', :require=>false
19
+ # gem 'terminal-notifier-guard'
20
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pipedrive (0.0.2)
5
+ activesupport
6
+ faraday (>= 0.9.0)
7
+ faraday_middleware (>= 0.9.1)
8
+ multi_json
9
+ multi_xml
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ activesupport (4.1.5)
15
+ i18n (~> 0.6, >= 0.6.9)
16
+ json (~> 1.7, >= 1.7.7)
17
+ minitest (~> 5.1)
18
+ thread_safe (~> 0.1)
19
+ tzinfo (~> 1.1)
20
+ coderay (1.1.0)
21
+ faraday (0.9.0)
22
+ multipart-post (>= 1.2, < 3)
23
+ faraday_middleware (0.9.1)
24
+ faraday (>= 0.7.4, < 0.10)
25
+ i18n (0.6.11)
26
+ json (1.8.1)
27
+ method_source (0.8.2)
28
+ minitest (5.4.1)
29
+ multi_json (1.10.1)
30
+ multi_xml (0.5.5)
31
+ multipart-post (2.0.0)
32
+ pry (0.10.1)
33
+ coderay (~> 1.1.0)
34
+ method_source (~> 0.8.1)
35
+ slop (~> 3.4)
36
+ rake (10.3.2)
37
+ slop (3.6.0)
38
+ thread_safe (0.3.4)
39
+ tzinfo (1.2.2)
40
+ thread_safe (~> 0.1)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ pipedrive!
47
+ pry
48
+ rake
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ task :console do
5
+ require 'pry'
6
+ require 'pipedrive'
7
+
8
+ CLIENT = Pipedrive::Client.new(api_token: '008f7b7f04e0737f1d3b2cbfc0ee0708461ca843')
9
+
10
+ ARGV.clear
11
+ Pry.start
12
+ end
13
+
14
+ task :default => :console
data/lib/.DS_Store ADDED
Binary file
data/lib/pipedrive.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/object'
3
+
4
+ require 'faraday'
5
+ require 'faraday_middleware'
6
+
7
+ require 'pipedrive/version'
8
+ require 'pipedrive/headers'
9
+ require 'pipedrive/errors'
10
+ require 'pipedrive/base'
11
+ require 'pipedrive/client'
12
+ require 'pipedrive/activities'
13
+ require 'pipedrive/activity_types'
14
+ require 'pipedrive/deals'
15
+ require 'pipedrive/emails'
16
+ require 'pipedrive/files'
17
+ require 'pipedrive/filters'
18
+ require 'pipedrive/goals'
19
+ require 'pipedrive/notes'
20
+ require 'pipedrive/organizations'
21
+ require 'pipedrive/persons'
22
+ require 'pipedrive/pipelines'
23
+ require 'pipedrive/products'
24
+ require 'pipedrive/roles'
25
+ require 'pipedrive/stages'
26
+ require 'pipedrive/users'
27
+
28
+ module Pipedrive
29
+
30
+ end
@@ -0,0 +1,14 @@
1
+ module Pipedrive
2
+ class Activities < Base
3
+ def prepare_options(options = {})
4
+ type_name = options.delete(:filter)
5
+ options[:params] = (options[:params]||{}).merge({type: type_name})
6
+
7
+ options
8
+ end
9
+
10
+ def types
11
+ resource(:activity_types).all
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class ActivityTypes < Base; end
3
+ end
@@ -0,0 +1,145 @@
1
+ module Pipedrive
2
+ class Base
3
+
4
+ include Enumerable
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ authenticate
9
+ end
10
+
11
+ def authenticate(token = @options[:api_token])
12
+ default_params.merge! api_token: token
13
+ end
14
+
15
+ def get(options = @options)
16
+ return to_enum(__callee__, options) unless block_given?
17
+
18
+ response = _get_resource(options)
19
+ if response.success?
20
+ data = [(response.body['data'] || [])].flatten
21
+ data.each do |item|
22
+ yield OpenStruct.new item
23
+ end
24
+
25
+ if next_start(response)
26
+ options[:params] = (options[:params]||{}).merge({start: next_start(response)})
27
+ send(__callee__, options) do |data|
28
+ yield data
29
+ end
30
+ end
31
+ else
32
+ error_class = case response.status
33
+ when 401 then AuthenticationError
34
+ else
35
+ ServiceError
36
+ end
37
+ fail error_class, JSON.parse(response.body)['error']
38
+ end
39
+
40
+ end
41
+ alias_method :each, :get
42
+
43
+ def metrics
44
+ metrics = {total: all.count}
45
+
46
+ get.each do |item|
47
+ key = metric_key(item)
48
+ break if key.nil?
49
+
50
+ metrics[key] ||= 0
51
+ metrics[key] += 1
52
+ end
53
+
54
+ metrics
55
+ end
56
+
57
+ def metric_key(item)
58
+ (item.try(:type) || item.try(:status)).try(:to_sym)
59
+ end
60
+
61
+ def all(options = @options)
62
+ data = []
63
+ each(options).collect {|i| data << i}
64
+ data
65
+ end
66
+
67
+ def prepare_options(options = @options)
68
+ if options.has_key?(:sort_by)
69
+ key = options.delete(:sort_by)
70
+ dir = options.delete(:sort_mode) || :desc
71
+ options[:params] = (options[:params]||{}).merge({sort_by: key, sort_mode: dir})
72
+ end
73
+
74
+ options
75
+ end
76
+
77
+ def protocol
78
+ 'http://'
79
+ end
80
+
81
+ def base_uri
82
+ protocol + 'api.pipedrive.com/v1'
83
+ end
84
+
85
+ def resource_path
86
+ # The resource path should match the camelCased class name with the
87
+ # first letter downcased. Pipedrive API is sensitive to capitalisation
88
+ klass = self.class.name.split('::').last
89
+ klass[0] = klass[0].chr.downcase
90
+ klass
91
+ end
92
+
93
+ def resource(klass_name, options = {})
94
+ klass_name = klass_name.to_s.split('_').map(&:capitalize).join
95
+ _klasses[klass_name] ||= begin
96
+ klass = Object.const_get "::Pipedrive::#{klass_name}"
97
+ klass.new @options.merge(options)
98
+ end
99
+ end
100
+
101
+ def [](id)
102
+ path = [resource_path, id.to_s].join '/'
103
+ get(resource_path: path).first
104
+ end
105
+
106
+ private
107
+ def _get_resource(options = {})
108
+
109
+ options = prepare_options(options)
110
+ params = default_params.merge (options.delete(:params) || {})
111
+
112
+
113
+ response = connection.get do |req|
114
+ req.url (options.delete(:resource_path) || resource_path)
115
+ req.headers = HEADERS
116
+ req.params.merge! params
117
+ end
118
+ end
119
+
120
+ def _klasses
121
+ @_klasses ||= {}
122
+ end
123
+
124
+ def next_start(response)
125
+ additional_data = response.body['additional_data']
126
+ if !additional_data.nil? && additional_data['pagination'] && additional_data['pagination']['more_items_in_collection']
127
+ additional_data['pagination']['next_start']
128
+ end
129
+ end
130
+
131
+ def default_params
132
+ @default_params ||= {}
133
+ end
134
+
135
+ def connection
136
+ @connection ||= ::Faraday.new(url: base_uri) do |conn|
137
+ conn.request :url_encoded
138
+ conn.adapter ::Faraday.default_adapter
139
+
140
+ conn.response :json, content_type: /\bjson$/
141
+ conn.response :xml, content_type: /\bxml$/
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,41 @@
1
+ module Pipedrive
2
+ class Client < Base
3
+ # This class doesn't represent anything on the API
4
+ # so we undefine the methods that could get us into
5
+ # trouble by attempting to talk to the server.
6
+
7
+ undef get
8
+ undef resource_path
9
+
10
+ def metrics
11
+ metrics = {}
12
+
13
+ %i{activities deals organizations persons}.each do |source|
14
+ metrics[source] = send(source).metrics
15
+ end
16
+
17
+ metrics
18
+ end
19
+
20
+ def validate_authorization
21
+ begin
22
+ users.metrics
23
+ true
24
+ rescue AuthenticationError
25
+ false
26
+ end
27
+ end
28
+
29
+ def method_missing(name, options, &block)
30
+ begin
31
+ resource(name, options)
32
+ rescue NameError
33
+ # Since we're silently loading a Resource Class
34
+ # we transform this into a NoMethodError to
35
+ # mask that. Not sure if this is the best idea ever,
36
+ # but I like it for now.
37
+ raise NoMethodError, "undefined method '#{name}' for #{self}"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module Pipedrive
2
+ class Deals < Base
3
+ def prepare_options(options = {})
4
+ filter_name = options.delete(:filter)
5
+ if filter_name.present?
6
+ filter = resource(:filters)[filter_name]
7
+ if filter.present?
8
+ options[:params] = (options[:params]||{}).merge({filter_id: filter[:id]})
9
+ end
10
+ end
11
+
12
+ options
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Pipedrive
2
+ class Emails < Base
3
+ def resource_path
4
+ "emailThreads"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Pipedrive
2
+ class AuthenticationError < StandardError; end
3
+ class ServiceError < StandardError; end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Files < Base; end
3
+ end
@@ -0,0 +1,21 @@
1
+ module Pipedrive
2
+ class Filters < Base
3
+ %w{deals people products organizations}.each do |type|
4
+ define_method type do |*options|
5
+ for_type(type, options.first)
6
+ end
7
+ end
8
+
9
+ def for_type(type, options = {})
10
+ type = type.to_sym
11
+ type = :org if type == :organizations
12
+
13
+ get (options || {}).merge!({params: {type: type}})
14
+ end
15
+
16
+ def [](name_key)
17
+ name = name_key.to_s.humanize
18
+ get.select{|filter| filter['name'] == name}.first
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Goals < Base; end
3
+ end
@@ -0,0 +1,7 @@
1
+ module Pipedrive
2
+ HEADERS = {
3
+ "User-Agent" => "Ruby.Pipedrive.Api",
4
+ "Accept" => "application/json",
5
+ "Content-Type" => "application/x-www-form-urlencoded"
6
+ }
7
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Notes < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Organizations < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Persons < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Pipelines < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Products < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Roles < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Stages < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ class Users < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipedrive
2
+ VERSION = "0.0.3"
3
+ end
data/pipedrive.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ require './lib/pipedrive/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'pipedrive-client'
5
+ s.version = Pipedrive::VERSION
6
+ s.author = 'Ryan Faerman'
7
+ s.email = 'ryan@trepscore.com'
8
+ s.homepage = 'http://github.com/25-ventures/pipedrive'
9
+ s.summary = s.description = 'Interact with Pipedrive'
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files test`.split("\n")
13
+ s.require_path = 'lib'
14
+
15
+ s.add_dependency 'activesupport', '~> 4.1'
16
+ s.add_dependency 'faraday', '~> 0.9'
17
+ s.add_dependency 'faraday_middleware', '~> 0.9'
18
+ s.add_dependency 'multi_xml', '~>0.5'
19
+ s.add_dependency 'multi_json', '~>1.10'
20
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pipedrive-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Faerman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: multi_xml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: multi_json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.10'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.10'
83
+ description: Interact with Pipedrive
84
+ email: ryan@trepscore.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - ".ruby-version"
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - Rakefile
93
+ - lib/.DS_Store
94
+ - lib/pipedrive.rb
95
+ - lib/pipedrive/activities.rb
96
+ - lib/pipedrive/activity_types.rb
97
+ - lib/pipedrive/base.rb
98
+ - lib/pipedrive/client.rb
99
+ - lib/pipedrive/deals.rb
100
+ - lib/pipedrive/emails.rb
101
+ - lib/pipedrive/errors.rb
102
+ - lib/pipedrive/files.rb
103
+ - lib/pipedrive/filters.rb
104
+ - lib/pipedrive/goals.rb
105
+ - lib/pipedrive/headers.rb
106
+ - lib/pipedrive/notes.rb
107
+ - lib/pipedrive/organizations.rb
108
+ - lib/pipedrive/persons.rb
109
+ - lib/pipedrive/pipelines.rb
110
+ - lib/pipedrive/products.rb
111
+ - lib/pipedrive/roles.rb
112
+ - lib/pipedrive/stages.rb
113
+ - lib/pipedrive/users.rb
114
+ - lib/pipedrive/version.rb
115
+ - pipedrive.gemspec
116
+ homepage: http://github.com/25-ventures/pipedrive
117
+ licenses: []
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.2.2
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Interact with Pipedrive
139
+ test_files: []