pipedrive.rb 0.1.0

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.cane +5 -0
  3. data/.gitignore +23 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +17 -0
  6. data/.travis.yml +10 -0
  7. data/Gemfile +20 -0
  8. data/Guardfile +24 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +100 -0
  11. data/Rakefile +27 -0
  12. data/defaults.reek +11 -0
  13. data/lib/pipedrive.rb +92 -0
  14. data/lib/pipedrive/activity.rb +8 -0
  15. data/lib/pipedrive/activity_type.rb +12 -0
  16. data/lib/pipedrive/base.rb +87 -0
  17. data/lib/pipedrive/deal.rb +8 -0
  18. data/lib/pipedrive/deal_field.rb +11 -0
  19. data/lib/pipedrive/file.rb +8 -0
  20. data/lib/pipedrive/filter.rb +6 -0
  21. data/lib/pipedrive/goal.rb +8 -0
  22. data/lib/pipedrive/note.rb +8 -0
  23. data/lib/pipedrive/operations/create.rb +11 -0
  24. data/lib/pipedrive/operations/delete.rb +15 -0
  25. data/lib/pipedrive/operations/read.rb +29 -0
  26. data/lib/pipedrive/operations/update.rb +15 -0
  27. data/lib/pipedrive/organization.rb +8 -0
  28. data/lib/pipedrive/organization_field.rb +11 -0
  29. data/lib/pipedrive/person.rb +18 -0
  30. data/lib/pipedrive/person_field.rb +11 -0
  31. data/lib/pipedrive/product.rb +8 -0
  32. data/lib/pipedrive/product_field.rb +11 -0
  33. data/lib/pipedrive/railties.rb +7 -0
  34. data/lib/pipedrive/role.rb +8 -0
  35. data/lib/pipedrive/stage.rb +8 -0
  36. data/lib/pipedrive/utils.rb +18 -0
  37. data/lib/pipedrive/version.rb +3 -0
  38. data/pipedrive.gemspec +29 -0
  39. data/spec/lib/pipedrive/activity_spec.rb +9 -0
  40. data/spec/lib/pipedrive/activity_type_spec.rb +9 -0
  41. data/spec/lib/pipedrive/base_spec.rb +122 -0
  42. data/spec/lib/pipedrive/deal_field_spec.rb +9 -0
  43. data/spec/lib/pipedrive/deal_spec.rb +9 -0
  44. data/spec/lib/pipedrive/file_spec.rb +9 -0
  45. data/spec/lib/pipedrive/filter_spec.rb +9 -0
  46. data/spec/lib/pipedrive/goal_spec.rb +9 -0
  47. data/spec/lib/pipedrive/note_spec.rb +9 -0
  48. data/spec/lib/pipedrive/ogranization_spec.rb +9 -0
  49. data/spec/lib/pipedrive/operations/create_spec.rb +16 -0
  50. data/spec/lib/pipedrive/operations/delete_spec.rb +22 -0
  51. data/spec/lib/pipedrive/operations/read_spec.rb +69 -0
  52. data/spec/lib/pipedrive/operations/update_spec.rb +20 -0
  53. data/spec/lib/pipedrive/organization_field_spec.rb +9 -0
  54. data/spec/lib/pipedrive/person_field_spec.rb +9 -0
  55. data/spec/lib/pipedrive/person_spec.rb +24 -0
  56. data/spec/lib/pipedrive/product_field_spec.rb +9 -0
  57. data/spec/lib/pipedrive/product_spec.rb +9 -0
  58. data/spec/lib/pipedrive_spec.rb +65 -0
  59. data/spec/spec_helper.rb +17 -0
  60. metadata +235 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11021dff174077aefb3589a979112cedc1677918
4
+ data.tar.gz: 76c18fb73b4f56968d580352c6b7590959570bdc
5
+ SHA512:
6
+ metadata.gz: 96a28445400ffc9cb4a59da4ed0a300c7a2aab5df6a81081dcfeca4b4d2daf0446372fa5608b0f631ee4feff20412c5ac8c8bc9488df29ed9a04714e7ab91056
7
+ data.tar.gz: fcffc1f3a0b89de8a9b5a7b99c180964645007fef72972e57dbf20e1d3ad8cda0002684acc1b993f809d4b458ab996c23416520e2b8b4ae1faedb735949421df
data/.cane ADDED
@@ -0,0 +1,5 @@
1
+ --no-doc
2
+ --no-style
3
+ --style-measure 99
4
+ --abc-max 18
5
+ --style-exclude spec/**/*
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,17 @@
1
+ AllCops:
2
+ Include:
3
+ - '**/Rakefile'
4
+ Exclude:
5
+ - 'spec/**/*'
6
+ Style/LineLength:
7
+ Max: 99
8
+ Style/FileName:
9
+ Enabled: false
10
+ Style/ModuleFunction:
11
+ Enabled: false
12
+ Style/Encoding:
13
+ Enabled: false
14
+ Documentation:
15
+ Enabled: false
16
+ Style/MethodLength:
17
+ Max: 15
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ - ruby-head
6
+ - jruby-19mode
7
+ - rbx-2
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pipedrive.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'simplecov', '>= 0.9.0', :require => false
8
+ gem 'coveralls', :require => false
9
+ end
10
+
11
+ group :local_development do
12
+ gem 'terminal-notifier-guard', require: false if RUBY_PLATFORM.downcase.include?('darwin')
13
+ gem 'guard-rspec', '>= 4.3.1' ,require: false
14
+ gem 'guard-bundler', require: false
15
+ gem 'guard-preek', require: false
16
+ gem 'guard-rubocop', require: false
17
+ gem 'guard-cane', require: false
18
+ gem 'guard-reek', github: 'pericles/guard-reek', require: false
19
+ gem 'pry'
20
+ end
@@ -0,0 +1,24 @@
1
+ guard 'rspec', cmd: 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'bundler' do
8
+ watch('Gemfile')
9
+ watch('pipedrive.gemspec')
10
+ end
11
+
12
+ guard :cane do
13
+ watch(%r{^(.+)\.rb$})
14
+ end
15
+
16
+ guard :rubocop do
17
+ watch(%r{.+\.rb$})
18
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
19
+ end
20
+
21
+ guard :preek, run_all_dir: 'lib' do
22
+ watch(/^lib\/(.*).rb/)
23
+ end
24
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alexander Simonov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ # Pipedrive
2
+
3
+ [![Build Status](https://travis-ci.org/dotpromo/pipedrive.rb.svg?branch=master)](https://travis-ci.org/dotpromo/pipedrive.rb)
4
+ [![Code Climate](https://codeclimate.com/github/dotpromo/pipedrive.rb.png)](https://codeclimate.com/github/dotpromo/pipedrive.rb)
5
+ [![Coverage Status](https://img.shields.io/coveralls/dotpromo/pipedrive.rb.svg)](https://coveralls.io/r/dotpromo/pipedrive.rb)
6
+
7
+ Pipedrive.com API wrapper
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'pipedrive.rb'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install pipedrive.rb
22
+
23
+ ## Usage
24
+
25
+ ### Person
26
+
27
+ You need initialize Person client:
28
+
29
+ ```ruby
30
+ client = ::Pipedrive::Person.new('api_token')
31
+ ```
32
+
33
+ You can get person's JSON data:
34
+
35
+ ```ruby
36
+ person = client.find(12345)
37
+ person.success? # check what request was successful
38
+ person.data # JSON data of person entity
39
+ ```
40
+
41
+ You can update person:
42
+
43
+ ```ruby
44
+ res = client.update(12345, name: 'New Name', 'custom_field_key' => 'value')
45
+ res.success? # check what request was successful
46
+ res.data # updated JSON data of person
47
+ ```
48
+
49
+ Or you can update person with only hash what include id:
50
+
51
+ ```ruby
52
+ res = client.update(id: 12345, name: 'New Name', 'custom_field_key' => 'value')
53
+ ```
54
+
55
+ You can get the list of all persons:
56
+
57
+ ```ruby
58
+ all_persons = client.all # all persons - can be a time consume operation
59
+ all_persons = client.all(start: 200) # Skipping first 200 persons
60
+ ```
61
+
62
+ Or you can get first page of persons:
63
+
64
+ ```ruby
65
+ first_page = client.chunk(start: 200, limit: 10) # get 10 records after skipping 200
66
+ ```
67
+
68
+ Or you can iterate by all persons:
69
+
70
+ ```ruby
71
+ client.each(start: 200) do |json_item|
72
+ # some logic
73
+ end
74
+ ```
75
+
76
+ Or you can work with enumerate:
77
+
78
+ ```ruby
79
+ client.each(start: 100).select {|x| x['company_id'] == 12345}
80
+ ```
81
+
82
+ ### Rails integration
83
+
84
+ If you need use only one pipedrive account for whole application, then you can create `config/initializer/pipedrive.rb` file with next content:
85
+
86
+ ```ruby
87
+ Pipedrive.setup do |n|
88
+ n.api_token = ENV['PIPEDRIVE_API_TOKEN']
89
+ end
90
+ ```
91
+
92
+ And you can skip providing `api_token` to the entities classes.
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork it ( https://github.com/simonoff/pipedrive/fork )
97
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
98
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
99
+ 4. Push to the branch (`git push origin my-new-feature`)
100
+ 5. Create a new Pull Request
@@ -0,0 +1,27 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ # rubocop
7
+ require 'rubocop/rake_task'
8
+ RuboCop::RakeTask.new(:rubocop)
9
+
10
+ # reek
11
+ require 'reek/rake/task'
12
+
13
+ Reek::Rake::Task.new do |t|
14
+ t.fail_on_error = false
15
+ t.source_files = Dir['lib/**/*.rb']
16
+ end
17
+
18
+ default_tasks = [:spec, :rubocop, :reek]
19
+
20
+ unless defined? ::Rubinius
21
+ # cane
22
+ require 'cane/rake_task'
23
+ Cane::RakeTask.new
24
+ default_tasks << :cane
25
+ end
26
+
27
+ task default: default_tasks
@@ -0,0 +1,11 @@
1
+ ---
2
+ NestedIterators:
3
+ max_allowed_nesting: 2
4
+ UtilityFunction:
5
+ enabled: false
6
+ IrresponsibleModule:
7
+ enabled: false
8
+ DuplicateMethodCall:
9
+ max_calls: 5
10
+ FeatureEnvy:
11
+ enabled: false
@@ -0,0 +1,92 @@
1
+ require 'logger'
2
+ require 'active_support/core_ext/hash'
3
+ require 'active_support/concern'
4
+ require 'active_support/inflector'
5
+
6
+ ActiveSupport::Inflector.inflections do |inflect|
7
+ inflect.irregular 'person', 'persons'
8
+ end
9
+
10
+ require 'hashie'
11
+ require 'faraday'
12
+ require 'faraday_middleware'
13
+ require 'pipedrive/version'
14
+
15
+ module Pipedrive
16
+ extend self
17
+ attr_accessor :api_token, :debug
18
+ attr_writer :user_agent, :logger
19
+
20
+ # ensures the setup only gets run once
21
+ @_ran_once = false
22
+
23
+ def reset!
24
+ @logger = nil
25
+ @_ran_once = false
26
+ @user_agent = nil
27
+ @api_token = nil
28
+ end
29
+
30
+ def user_agent
31
+ @user_agent ||= "Pipedrive Ruby Client v#{::Pipedrive::VERSION}"
32
+ end
33
+
34
+ def setup
35
+ yield self unless @_ran_once
36
+ @_ran_once = true
37
+ end
38
+
39
+ def logger
40
+ @logger ||= Logger.new(STDOUT)
41
+ end
42
+
43
+ reset!
44
+ end
45
+
46
+ require 'pipedrive/railties' if defined?(::Rails)
47
+
48
+ # Core
49
+ require 'pipedrive/base'
50
+ require 'pipedrive/utils'
51
+ require 'pipedrive/operations/create'
52
+ require 'pipedrive/operations/read'
53
+ require 'pipedrive/operations/update'
54
+ require 'pipedrive/operations/delete'
55
+
56
+ # Persons
57
+ require 'pipedrive/person_field'
58
+ require 'pipedrive/person'
59
+
60
+ # Organizations
61
+ require 'pipedrive/organization_field'
62
+ require 'pipedrive/organization'
63
+
64
+ # Filters
65
+ require 'pipedrive/filter'
66
+
67
+ # Products
68
+ require 'pipedrive/product_field'
69
+ require 'pipedrive/product'
70
+
71
+ # Roles
72
+ require 'pipedrive/role'
73
+
74
+ # Stages
75
+ require 'pipedrive/stage'
76
+
77
+ # Goals
78
+ require 'pipedrive/goal'
79
+
80
+ # Activities
81
+ require 'pipedrive/activity'
82
+ require 'pipedrive/activity_type'
83
+
84
+ # Deals
85
+ require 'pipedrive/deal_field'
86
+ require 'pipedrive/deal'
87
+
88
+ # Files
89
+ require 'pipedrive/file'
90
+
91
+ # Notes
92
+ require 'pipedrive/note'
@@ -0,0 +1,8 @@
1
+ module Pipedrive
2
+ class Activity < Base
3
+ include ::Pipedrive::Operations::Create
4
+ include ::Pipedrive::Operations::Read
5
+ include ::Pipedrive::Operations::Update
6
+ include ::Pipedrive::Operations::Delete
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ module Pipedrive
2
+ class ActivityType < Base
3
+ include ::Pipedrive::Operations::Create
4
+ include ::Pipedrive::Operations::Read
5
+ include ::Pipedrive::Operations::Update
6
+ include ::Pipedrive::Operations::Delete
7
+
8
+ def entity_name
9
+ 'activityTypes'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,87 @@
1
+ module Pipedrive
2
+ class Base
3
+ def initialize(api_token = ::Pipedrive.api_token)
4
+ fail 'api_token should be set' unless api_token.present?
5
+ @api_token = api_token
6
+ end
7
+
8
+ def connection
9
+ self.class.connection.dup
10
+ end
11
+
12
+ def make_api_call(*args)
13
+ params = args.extract_options!
14
+ method = args[0]
15
+ fail 'method param missing' unless method.present?
16
+ url = build_url(args, params.delete(:fields_to_select))
17
+ begin
18
+ res = connection.__send__(method.to_sym, url, params)
19
+ rescue Errno::ETIMEDOUT
20
+ retry
21
+ end
22
+ process_response(res)
23
+ end
24
+
25
+ def build_url(args, fields_to_select = nil)
26
+ url = "/v1/#{entity_name}"
27
+ url << "/#{args[1]}" if args[1]
28
+ if fields_to_select.is_a?(::Array) && fields_to_select.size > 0
29
+ url << ":(#{fields_to_select.join(',')})"
30
+ end
31
+ url << "?api_token=#{@api_token}"
32
+ url
33
+ end
34
+
35
+ def process_response(res)
36
+ if res.success?
37
+ data = if res.body.is_a?(::Hashie::Mash)
38
+ res.body.merge(success: true)
39
+ else
40
+ ::Hashie::Mash.new(success: true)
41
+ end
42
+ return data
43
+ end
44
+ failed_response(res)
45
+ end
46
+
47
+ def failed_response(res)
48
+ failed_res = res.body.merge(success: false, not_authorized: false,
49
+ failed: false)
50
+ case res.status
51
+ when 401
52
+ failed_res.merge! not_authorized: true
53
+ when 420
54
+ failed_res.merge! failed: true
55
+ end
56
+ failed_res
57
+ end
58
+
59
+ def entity_name
60
+ self.class.name.split('::')[-1].downcase.pluralize
61
+ end
62
+
63
+ class << self
64
+ def faraday_options
65
+ {
66
+ url: 'https://api.pipedrive.com',
67
+ headers: {
68
+ accept: 'application/json',
69
+ user_agent: ::Pipedrive.user_agent
70
+ }
71
+ }
72
+ end
73
+
74
+ # This method smells of :reek:TooManyStatements
75
+ def connection # :nodoc
76
+ @connection ||= Faraday.new(faraday_options) do |conn|
77
+ conn.request :url_encoded
78
+ conn.response :mashify
79
+ conn.response :json, content_type: /\bjson$/
80
+ conn.adapter Faraday.default_adapter
81
+ conn.use FaradayMiddleware::ParseJson
82
+ conn.response :logger, ::Pipedrive.logger if ::Pipedrive.debug
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end