camper 0.0.6 → 0.0.11

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.
@@ -12,12 +12,15 @@ module Camper
12
12
 
13
13
  # Keep in alphabetical order
14
14
  include Authorization
15
- include CommentAPI
15
+ include CommentsAPI
16
16
  include Logging
17
- include MessageAPI
18
- include ProjectAPI
17
+ include MessagesAPI
18
+ include PeopleAPI
19
+ include ProjectsAPI
20
+ include RecordingsAPI
19
21
  include ResourceAPI
20
- include TodoAPI
22
+ include TodolistsAPI
23
+ include TodosAPI
21
24
 
22
25
  # Creates a new Client instance.
23
26
  # @raise [Error:MissingCredentials]
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+ # Copied from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb
3
+
4
+ require 'concurrent/map'
5
+
6
+ class Object
7
+ # An object is blank if it's false, empty, or a whitespace string.
8
+ # For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
9
+ #
10
+ # This simplifies
11
+ #
12
+ # !address || address.empty?
13
+ #
14
+ # to
15
+ #
16
+ # address.blank?
17
+ #
18
+ # @return [true, false]
19
+ def blank?
20
+ respond_to?(:empty?) ? !!empty? : !self
21
+ end
22
+
23
+ # An object is present if it's not blank.
24
+ #
25
+ # @return [true, false]
26
+ def present?
27
+ !blank?
28
+ end
29
+
30
+ # Returns the receiver if it's present otherwise returns +nil+.
31
+ # <tt>object.presence</tt> is equivalent to
32
+ #
33
+ # object.present? ? object : nil
34
+ #
35
+ # For example, something like
36
+ #
37
+ # state = params[:state] if params[:state].present?
38
+ # country = params[:country] if params[:country].present?
39
+ # region = state || country || 'US'
40
+ #
41
+ # becomes
42
+ #
43
+ # region = params[:state].presence || params[:country].presence || 'US'
44
+ #
45
+ # @return [Object]
46
+ def presence
47
+ self if present?
48
+ end
49
+ end
50
+
51
+ class NilClass
52
+ # +nil+ is blank:
53
+ #
54
+ # nil.blank? # => true
55
+ #
56
+ # @return [true]
57
+ def blank?
58
+ true
59
+ end
60
+ end
61
+
62
+ class FalseClass
63
+ # +false+ is blank:
64
+ #
65
+ # false.blank? # => true
66
+ #
67
+ # @return [true]
68
+ def blank?
69
+ true
70
+ end
71
+ end
72
+
73
+ class TrueClass
74
+ # +true+ is not blank:
75
+ #
76
+ # true.blank? # => false
77
+ #
78
+ # @return [false]
79
+ def blank?
80
+ false
81
+ end
82
+ end
83
+
84
+ class Array
85
+ # An array is blank if it's empty:
86
+ #
87
+ # [].blank? # => true
88
+ # [1,2,3].blank? # => false
89
+ #
90
+ # @return [true, false]
91
+ alias_method :blank?, :empty?
92
+ end
93
+
94
+ class Hash
95
+ # A hash is blank if it's empty:
96
+ #
97
+ # {}.blank? # => true
98
+ # { key: 'value' }.blank? # => false
99
+ #
100
+ # @return [true, false]
101
+ alias_method :blank?, :empty?
102
+ end
103
+
104
+ class String
105
+ BLANK_RE = /\A[[:space:]]*\z/
106
+ ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
107
+ h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
108
+ end
109
+
110
+ # A string is blank if it's empty or contains whitespaces only:
111
+ #
112
+ # ''.blank? # => true
113
+ # ' '.blank? # => true
114
+ # "\t\n\r".blank? # => true
115
+ # ' blah '.blank? # => false
116
+ #
117
+ # Unicode whitespace is supported:
118
+ #
119
+ # "\u00a0".blank? # => true
120
+ #
121
+ # @return [true, false]
122
+ def blank?
123
+ # The regexp that matches blank strings is expensive. For the case of empty
124
+ # strings we can speed up this method (~3.5x) with an empty? call. The
125
+ # penalty for the rest of strings is marginal.
126
+ empty? ||
127
+ begin
128
+ BLANK_RE.match?(self)
129
+ rescue Encoding::CompatibilityError
130
+ ENCODED_BLANKS[self.encoding].match?(self)
131
+ end
132
+ end
133
+ end
134
+
135
+ class Numeric #:nodoc:
136
+ # No number is blank:
137
+ #
138
+ # 1.blank? # => false
139
+ # 0.blank? # => false
140
+ #
141
+ # @return [false]
142
+ def blank?
143
+ false
144
+ end
145
+ end
146
+
147
+ class Time #:nodoc:
148
+ # No Time is blank:
149
+ #
150
+ # Time.now.blank? # => false
151
+ #
152
+ # @return [false]
153
+ def blank?
154
+ false
155
+ end
156
+ end
@@ -13,6 +13,12 @@ module Camper
13
13
 
14
14
  class MissingBody < Error; end
15
15
 
16
+ class ResourceCannotBeCommented < Error; end
17
+
18
+ class RequestIsMissingParameters < Error; end
19
+
20
+ class InvalidParameter < Error; end
21
+
16
22
  # Raised when impossible to parse response body.
17
23
  class Parsing < Error; end
18
24
 
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Camper
4
+ class RecordingTypes
5
+ COMMENT = 'Comment'
6
+ DOCUMENT = 'Document'
7
+ MESSAGE = 'Message'
8
+ QUESTION_ANSWER = 'Question::Answer'
9
+ SCHEDULE_ENTRY = 'Schedule::Entry'
10
+ TODO = 'Todo'
11
+ TODOLIST = 'Todolist'
12
+ UPLOAD = 'Upload'
13
+
14
+ # rubocop:disable Style/ClassVars
15
+ def self.all
16
+ @@recordings ||= constants(false).map { |c| const_get(c) }.sort
17
+
18
+ @@recordings
19
+ end
20
+ # rubocop:enable Style/ClassVars
21
+ end
22
+ end
@@ -93,7 +93,7 @@ module Camper
93
93
 
94
94
  full_endpoint = override_path ? @path : @client.api_endpoint + @path
95
95
 
96
- full_endpoint = url_transform(full_endpoint)
96
+ full_endpoint = UrlUtils.transform(full_endpoint)
97
97
 
98
98
  return full_endpoint, params
99
99
  end
@@ -138,19 +138,8 @@ module Camper
138
138
  { 'Authorization' => "Bearer #{@client.access_token}" }
139
139
  end
140
140
 
141
- # Utility method for transforming Basecamp Web URLs into API URIs
142
- # e.g 'https://3.basecamp.com/1/buckets/2/todos/3' will be
143
- # converted into 'https://3.basecampapi.com/1/buckets/2/todos/3.json'
144
- #
145
- # @return [String]
146
- def url_transform(url)
147
- api_url = url.gsub('3.basecamp.com', '3.basecampapi.com')
148
- api_url.gsub!('.json', '')
149
- "#{api_url}.json"
150
- end
151
-
152
141
  def body_to_json?(params)
153
- @method == 'post' && params.key?(:body)
142
+ %w[post put].include?(@method) && params.key?(:body)
154
143
  end
155
144
  end
156
145
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Camper
4
+ # Defines methods related to url operations.
5
+ module UrlUtils
6
+ def self.basecamp_url?(url)
7
+ return false if url.nil? || !url.is_a?(String) || url == ''
8
+
9
+ transformed_url = UrlUtils.transform(url)
10
+
11
+ transformed_url.match?(%r{#{Configuration.base_api_endpoint}/\d+/.*})
12
+ end
13
+
14
+ # Utility method for transforming Basecamp Web URLs into API URIs
15
+ # e.g 'https://3.basecamp.com/1/buckets/2/todos/3' will be
16
+ # converted into 'https://3.basecampapi.com/1/buckets/2/todos/3.json'
17
+ #
18
+ # @param url [String] url to test
19
+ # @return [String]
20
+ def self.transform(url)
21
+ api_url = url.gsub('3.basecamp.com', '3.basecampapi.com')
22
+ api_url.gsub!('.json', '')
23
+ "#{api_url}.json"
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camper
4
- VERSION = '0.0.6'
4
+ VERSION = '0.0.11'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - renehernandez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-01 00:00:00.000000000 Z
11
+ date: 2020-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: concurrent-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -112,23 +126,33 @@ files:
112
126
  - examples/messages.rb
113
127
  - examples/oauth.rb
114
128
  - examples/obtain_acces_token.rb
129
+ - examples/people.rb
130
+ - examples/projects.rb
131
+ - examples/recordings.rb
132
+ - examples/todolists.rb
115
133
  - examples/todos.rb
116
134
  - lib/camper.rb
117
- - lib/camper/api/comment.rb
118
- - lib/camper/api/message.rb
119
- - lib/camper/api/project.rb
135
+ - lib/camper/api/comments.rb
136
+ - lib/camper/api/messages.rb
137
+ - lib/camper/api/people.rb
138
+ - lib/camper/api/projects.rb
139
+ - lib/camper/api/recordings.rb
120
140
  - lib/camper/api/resource.rb
121
- - lib/camper/api/todo.rb
141
+ - lib/camper/api/todolists.rb
142
+ - lib/camper/api/todos.rb
122
143
  - lib/camper/authorization.rb
123
144
  - lib/camper/client.rb
124
145
  - lib/camper/configuration.rb
146
+ - lib/camper/core_extensions/object.rb
125
147
  - lib/camper/error.rb
126
148
  - lib/camper/logging.rb
127
149
  - lib/camper/paginated_response.rb
128
150
  - lib/camper/pagination_data.rb
151
+ - lib/camper/recording_types.rb
129
152
  - lib/camper/request.rb
130
153
  - lib/camper/resource.rb
131
154
  - lib/camper/resources/project.rb
155
+ - lib/camper/url_utils.rb
132
156
  - lib/camper/version.rb
133
157
  homepage: https://github.com/renehernandez/camper
134
158
  licenses:
@@ -152,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
176
  - !ruby/object:Gem::Version
153
177
  version: '0'
154
178
  requirements: []
155
- rubygems_version: 3.1.2
179
+ rubygems_version: 3.1.4
156
180
  signing_key:
157
181
  specification_version: 4
158
182
  summary: Ruby client for Basecamp 3 API
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Camper::Client
4
- module ProjectAPI
5
-
6
- def projects(options = {})
7
- get("/projects", options)
8
- end
9
-
10
- def project(id)
11
- get("/projects/#{id}")
12
- end
13
-
14
- def message_board(project)
15
- board = project.message_board
16
- get(board.url, override_path: true)
17
- end
18
-
19
- def todoset(project)
20
- todoset = project.todoset
21
- get(todoset.url, override_path: true)
22
- end
23
- end
24
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Camper::Client
4
- module TodoAPI
5
-
6
- # Get the todolists associated with the todoset
7
- #
8
- # @example
9
- # client.todolists(todoset)
10
- # @example
11
- # client.todolists(todoset, status: 'archived')
12
- #
13
- # @param todoset [Resource] the parent todoset resource
14
- # @param options [Hash] extra options to filter the list of todolist
15
- # @return [Array<Resource>]
16
- # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#get-to-do-lists
17
- def todolists(todoset, options={})
18
- get(todoset.todolists_url, options.merge(override_path: true))
19
- end
20
-
21
- # Get a todolist with a given id
22
- #
23
- # @example
24
- # client.todolist(todoset, '2345')
25
- #
26
- # @param todoset [Resource] the parent todoset resource
27
- # @param id [Integer, String] the id of the todolist to get
28
- # @return [Resource]
29
- # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#get-a-to-do-list
30
- def todolist(todoset, id)
31
- get("/buckets/#{todoset.bucket.id}/todolists/#{id}")
32
- end
33
-
34
- # Get the todos in a todolist
35
- #
36
- # @example
37
- # client.todos(todolist)
38
- # @example
39
- # client.todos(todolist, completed: true)
40
- #
41
- # @param todolist [Resource] the parent todoset resource
42
- # @param options [Hash] options to filter the list of todos
43
- # @return [Resource]
44
- # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#get-to-dos
45
- def todos(todolist, options={})
46
- get(todolist.todos_url, options.merge(override_path: true))
47
- end
48
-
49
- # Create a todo within a todolist
50
- #
51
- # @example
52
- # client.create_todo(todolist, 'First Todo')
53
- # @example
54
- # client.create_todo(
55
- # todolist,
56
- # 'Program it',
57
- # description: "<div><em>Try that new language!</em></div>, due_on: "2016-05-01"
58
- # )
59
- #
60
- # @param todolist [Resource] the todolist where the todo is going to be created
61
- # @param content [String] what the to-do is for
62
- # @param options [Hash] extra configuration for the todo such as due_date and description
63
- # @return [Resource]
64
- # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#create-a-to-do
65
- def create_todo(todolist, content, options={})
66
- post(todolist.todos_url, body: { content: content, **options }, override_path: true)
67
- end
68
-
69
- # Complete a todo
70
- #
71
- # @example
72
- # client.complete_todo(todo)
73
- #
74
- # @param todo [Resource] the todo to be marked as completed
75
- # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#complete-a-to-do
76
- def complete_todo(todo)
77
- post("#{todo.url}/completion", override_path: true)
78
- end
79
- end
80
- end