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.
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Camper::Client
4
+ # Defines methods related to projects.
5
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md
6
+ module ProjectsAPI
7
+ # Get the projects visible to the current user
8
+ #
9
+ # @example
10
+ # client.projects
11
+ # @example
12
+ # client.projects(status: 'trashed')
13
+ #
14
+ # @param options [Hash] extra options to filter the list of todolist
15
+ # @return [PaginatedResponse<Project>]
16
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md#get-all-projects
17
+ def projects(options = {})
18
+ get('/projects', query: options)
19
+ end
20
+
21
+ # Get a project with a given id, granted they have access to it
22
+ #
23
+ # @example
24
+ # client.project(82564)
25
+ # @example
26
+ # client.project('7364183')
27
+ #
28
+ # @param id [Integet|String] id of the project to retrieve
29
+ # @return [Project]
30
+ # @raise [Error::InvalidParameter] if id is blank (nil or empty string)
31
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md#get-a-project
32
+ def project(id)
33
+ raise Camper::Error::InvalidParameter, id if id.blank?
34
+
35
+ get("/projects/#{id}")
36
+ end
37
+
38
+ # Create a project
39
+ #
40
+ # @example
41
+ # client.create_project("Marketing Campaign")
42
+ # @example
43
+ # client.create_project('Better Marketing Campaign', "For Client: XYZ")
44
+ #
45
+ # @param name [String] name of the project to create
46
+ # @param description [String] description of the project
47
+ # @return [Project]
48
+ # @raise [Error::InvalidParameter] if name is blank (nil or empty string)
49
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md#create-a-project
50
+ def create_project(name, description = '')
51
+ raise Camper::Error::InvalidParameter, name if name.blank?
52
+
53
+ post('/projects', body: { name: name, description: description })
54
+ end
55
+
56
+ # Update a project
57
+ # description can be set to empty by passing an empty string
58
+ #
59
+ # @example
60
+ # client.update_project(12324, name: 'Retros')
61
+ # @example
62
+ # client.update_project('157432', description: 'A new description')
63
+ # @example
64
+ # client.update_project('157432', description: '')
65
+ # @example
66
+ # client.update_project(my_project, name: 'A new name', description: 'A new description')
67
+ #
68
+ # @param project [Integer|String|Project] either a project object or a project id
69
+ # @param name [String] optional new name of the project
70
+ # @param description [String] optinal new description of the project
71
+ # @return [Project]
72
+ # @raise [Error::InvalidParameter] if both name and description are blank (nil or empty strings)
73
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md#update-a-project
74
+ def update_project(project, name: '', description: nil)
75
+ if name.blank? && description.blank?
76
+ raise Camper::Error::InvalidParameter, 'name and description cannot both be blank'
77
+ end
78
+
79
+ id = project.respond_to?(:id) ? project.id : project
80
+
81
+ options = {}
82
+ options[:name] = name unless name.blank?
83
+ options[:description] = description unless description.nil?
84
+
85
+ put("/projects/#{id}", body: { **options })
86
+ end
87
+
88
+ # Delete a project
89
+ #
90
+ # @example
91
+ # client.delete_project(12324)
92
+ # @example
93
+ # client.delete_project('157432')
94
+ # @example
95
+ # client.delete_project(my_project)
96
+ #
97
+ # @param project [Integer|String|Project] either a project object or a project id
98
+ # @raise [Error::InvalidParameter] if project param is blank
99
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/projects.md#trash-a-project
100
+ def delete_project(project)
101
+ raise Camper::Error::InvalidParameter, 'project cannot be blank' if project.blank?
102
+
103
+ id = project.respond_to?(:id) ? project.id : project
104
+
105
+ delete("/projects/#{id}")
106
+ end
107
+
108
+ alias trash_project delete_project
109
+
110
+ def message_board(project)
111
+ board = project.message_board
112
+ get(board.url, override_path: true)
113
+ end
114
+
115
+ def todoset(project)
116
+ todoset = project.todoset
117
+ get(todoset.url, override_path: true)
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Camper
4
+ class Client
5
+ # Defines methods related to recordings.
6
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md
7
+ module RecordingsAPI
8
+ # Get a paginated response of recordings of a given type
9
+ #
10
+ # @example
11
+ # client.recordings('Todo')
12
+ # @example
13
+ # client.recordings(
14
+ # 'Document',
15
+ # bucket: [1,2],
16
+ # status: 'archived',
17
+ # sort: 'updated_at',
18
+ # direction: 'asc'
19
+ # )
20
+ #
21
+ # @param type [String] type of the recording
22
+ # @param options [Hash] extra options to filter the recordings to be resulted
23
+ # @return [PaginatedResponse<Resource>]
24
+ # @raise [Error::InvalidParameter] if type is not one of the allowed types
25
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#get-recordings
26
+ def recordings(type, options = {})
27
+ raise Error::InvalidParameter, type unless RecordingTypes.all.include?(type)
28
+
29
+ get('/projects/recordings', query: options.merge(type: type))
30
+ end
31
+
32
+ # Trash a given recording
33
+ #
34
+ # @example
35
+ # client.trash_recording(my_todo)
36
+ # @example
37
+ # client.trash_recording(my_message)
38
+ #
39
+ # @param recording [Resource] a resource of a valid recording type
40
+ # @raise [Error::InvalidParameter] if type field in recording param
41
+ # is not one of the allowed types
42
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#trash-a-recording
43
+ def trash_recording(recording)
44
+ raise Error::InvalidParameter, recording unless RecordingTypes.all.include?(recording.type)
45
+
46
+ put("/buckets/#{recording.bucket.id}/recordings/#{recording.id}/status/trashed")
47
+ end
48
+
49
+ # Archive a given recording
50
+ #
51
+ # @example
52
+ # client.archive_recording(my_todo)
53
+ # @example
54
+ # client.archive_recording(my_message)
55
+ #
56
+ # @param recording [Resource] a resource of a valid recording type
57
+ # @raise [Error::InvalidParameter] if type field in recording param
58
+ # is not one of the allowed types
59
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#archive-a-recording
60
+ def archive_recording(recording)
61
+ raise Error::InvalidParameter, recording unless RecordingTypes.all.include?(recording.type)
62
+
63
+ put("/buckets/#{recording.bucket.id}/recordings/#{recording.id}/status/archived")
64
+ end
65
+
66
+ # Unarchive a given recording
67
+ #
68
+ # @example
69
+ # client.unarchive_recording(my_todo)
70
+ # @example
71
+ # client.unarchive_recording(my_message)
72
+ #
73
+ # @param recording [Resource] a resource of a valid recording type
74
+ # @raise [Error::InvalidParameter] if type field in recording param
75
+ # is not one of the allowed types
76
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#unarchive-a-recording
77
+ def unarchive_recording(recording)
78
+ raise Error::InvalidParameter, recording unless RecordingTypes.all.include?(recording.type)
79
+
80
+ put("/buckets/#{recording.bucket.id}/recordings/#{recording.id}/status/active")
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Camper::Client
4
+ # Defines methods related to todolists.
5
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md
6
+ module TodolistsAPI
7
+ # Get the todolists associated with the todoset
8
+ #
9
+ # @example
10
+ # client.todolists(todoset)
11
+ # @example
12
+ # client.todolists(todoset, status: 'archived')
13
+ #
14
+ # @param todoset [Resource] the parent todoset resource
15
+ # @param options [Hash] extra options to filter the list of todolist
16
+ # @return [PaginatedResponse<Resource>]
17
+ # @raise [Error::InvalidParameter] if todolists_url field in todoset param
18
+ # is not a valid basecamp url
19
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#get-to-do-lists
20
+ def todolists(todoset, options = {})
21
+ url = todoset.todolists_url
22
+
23
+ raise Camper::Error::InvalidParameter, todoset unless Camper::UrlUtils.basecamp_url?(url)
24
+
25
+ get(url, query: options, override_path: true)
26
+ end
27
+
28
+ # Get a todolist with a given id
29
+ #
30
+ # @example
31
+ # client.todolist(todoset, '2345')
32
+ #
33
+ # @param todoset [Resource] the parent todoset resource
34
+ # @param id [Integer, String] the id of the todolist to get
35
+ # @return [Resource]
36
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#get-a-to-do-list
37
+ def todolist(todoset, id)
38
+ get("/buckets/#{todoset.bucket.id}/todolists/#{id}")
39
+ end
40
+
41
+ # Create a todolist within the given todoset
42
+ #
43
+ # @example
44
+ # client.create_todolist(todoset, 'Launch', "<div><em>Finish it!</em></div>")
45
+ #
46
+ # @param todoset [Resource] the parent todoset resource
47
+ # @param name [String] the name of the new todolist
48
+ # @param description [String] an optional description for the todolist
49
+ # @return [Resource]
50
+ # @raise [Error::InvalidParameter] if todolists_url field in todoset param
51
+ # is not a valid basecamp url
52
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#create-a-to-do-list
53
+ def create_todolist(todoset, name, description = '')
54
+ url = todoset.todolists_url
55
+
56
+ raise Camper::Error::InvalidParameter, todoset unless Camper::UrlUtils.basecamp_url?(url)
57
+
58
+ post(url, body: { name: name, description: description }, override_path: true)
59
+ end
60
+
61
+ # Update a todolist to change name and description
62
+ #
63
+ # @example
64
+ # client.update_todolist(todolist, 'Launch')
65
+ # @example
66
+ # client.update_todolist(todolist, 'Launch', "<div><em>Finish it!</em></div>")
67
+ # @example
68
+ # client.update_todolist(todolist, 'Launch', '')
69
+ #
70
+ # @param todolist [Resource] the todolist resource to update
71
+ # @param name [String] the new name of the todolist
72
+ # @param description [String] a new optional description for the todolist. If not specified,
73
+ # it will be set to the current description value
74
+ # @return [Resource]
75
+ # @raise [Error::InvalidParameter] if url field in todolist param
76
+ # is not a valid basecamp url
77
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todolists.md#update-a-to-do-list
78
+ def update_todolist(todolist, name, description = nil)
79
+ url = todolist.url
80
+
81
+ raise Camper::Error::InvalidParameter, todolist unless Camper::UrlUtils.basecamp_url?(url)
82
+
83
+ body = { name: name }
84
+ body[:description] = description.nil? ? todolist.description : description
85
+
86
+ put(url, body: body, override_path: true)
87
+ end
88
+
89
+ # Trash a todolist
90
+ # it calls the trash_recording endpoint under the hood
91
+ #
92
+ # @example
93
+ # client.trash_todolist(todolist)
94
+ #
95
+ # @param todolist [Resource] the todolist to be trashed
96
+ # @raise [Error::InvalidParameter] if the type field in todolist param
97
+ # is not an allowed type in the recording API
98
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#trash-a-recording
99
+ def trash_todolist(todolist)
100
+ trash_recording(todolist)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Camper::Client
4
+ # Defines methods related to todos.
5
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md
6
+ module TodosAPI
7
+ PARAMETERS = %w[
8
+ content
9
+ description
10
+ assignee_ids
11
+ completion_subscriber_ids
12
+ notify
13
+ due_on
14
+ starts_on
15
+ ].freeze
16
+
17
+ # Get the todos in a todolist
18
+ #
19
+ # @example
20
+ # client.todos(todolist)
21
+ # @example
22
+ # client.todos(todolist, completed: true)
23
+ #
24
+ # @param todolist [Resource] the parent todoset resource
25
+ # @param options [Hash] options to filter the list of todos
26
+ # @return [Resource]
27
+ # @raise [Error::InvalidParameter] if todos_url field in todolist param
28
+ # is not a valid basecamp url
29
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#get-to-dos
30
+ def todos(todolist, options = {})
31
+ url = todolist.todos_url
32
+
33
+ raise Camper::Error::InvalidParameter, todolist unless Camper::UrlUtils.basecamp_url?(url)
34
+
35
+ get(url, query: options, override_path: true)
36
+ end
37
+
38
+ # Get a todo with a given id using a particular parent resource.
39
+ #
40
+ # @example
41
+ # client.todo(my_project, '10')
42
+ # @example
43
+ # client.todo(new_todolist, 134)
44
+ # @example
45
+ # client.todo(67543, '2440')
46
+ #
47
+ # @param parent [Integer|String|Project|Resource] can be either a project id, a project or a todolist resource
48
+ # @param id [Integer|String] id of the todo
49
+ # @return [Resource]
50
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#get-a-to-do
51
+ def todo(parent, id)
52
+ bucket_id = parent
53
+
54
+ if parent.is_a? Camper::Project
55
+ bucket_id = parent.id
56
+ elsif parent.respond_to?(:type)
57
+ bucket_id = parent.bucket.id
58
+ end
59
+
60
+ get("/buckets/#{bucket_id}/todos/#{id}")
61
+ end
62
+
63
+ # Create a todo within a todolist
64
+ #
65
+ # @example
66
+ # client.create_todo(todolist, 'First Todo')
67
+ # @example
68
+ # client.create_todo(
69
+ # todolist,
70
+ # 'Program it',
71
+ # description: "<div><em>Try that new language!</em></div>, due_on: "2016-05-01"
72
+ # )
73
+ #
74
+ # @param todolist [Resource] the todolist where the todo is going to be created
75
+ # @param content [String] what the to-do is for
76
+ # @param options [Hash] extra parameters for the todo such as due_date and description
77
+ # @return [Resource]
78
+ # @raise [Error::InvalidParameter] if todos_url field in todolist param
79
+ # is not a valid basecamp url
80
+ # @raise [Error::InvalidParameter] if content parameter is blank
81
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#create-a-to-do
82
+ def create_todo(todolist, content, options = {})
83
+ url = todolist.todos_url
84
+
85
+ raise Camper::Error::InvalidParameter, todolist unless Camper::UrlUtils.basecamp_url?(url)
86
+ raise Camper::Error::InvalidParameter, content if content.blank?
87
+
88
+ post(url, body: { content: content, **options }, override_path: true)
89
+ end
90
+
91
+ # Update a todo.
92
+ #
93
+ # @example
94
+ # client.update_todo(todo, 'Todo')
95
+ # @example
96
+ # client.update_todo(
97
+ # todo,
98
+ # 'Program it',
99
+ # description: "<div><em>Try that new language!</em></div>,
100
+ # due_on: "2016-05-01",
101
+ # starts_on: "2016-04-30"
102
+ # )
103
+ #
104
+ # @param todo [Resource] the todo to be updated
105
+ # @param options [Hash] parameters to be changed. The ones that are not specified
106
+ # will be set to the current values of the todo object
107
+ # @return [Resource]
108
+ # @raise [Error::InvalidParameter] if url field in todo param
109
+ # is not a valid basecamp url
110
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#update-a-to-do
111
+ def update_todo(todo, options)
112
+ url = todo.url
113
+
114
+ raise Camper::Error::InvalidParameter, url unless Camper::UrlUtils.basecamp_url?(url)
115
+
116
+ body = {}.merge(options)
117
+ PARAMETERS.each { |p| body[p.to_sym] = todo[p] unless key_is_present?(body, p) }
118
+
119
+ put(url, body: body, override_path: true)
120
+ end
121
+
122
+ # Complete a todo
123
+ #
124
+ # @example
125
+ # client.complete_todo(todo)
126
+ #
127
+ # @param todo [Resource] the todo to be marked as completed
128
+ # @raise [Error::InvalidParameter] if url field in todo param
129
+ # is not a valid basecamp url
130
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#complete-a-to-do
131
+ def complete_todo(todo)
132
+ url = todo.url
133
+
134
+ raise Camper::Error::InvalidParameter, todo unless Camper::UrlUtils.basecamp_url?(url)
135
+
136
+ post("#{url}/completion", override_path: true)
137
+ end
138
+
139
+ # Uncomplete a todo
140
+ #
141
+ # @example
142
+ # client.uncomplete_todo(todo)
143
+ #
144
+ # @param todo [Resource] the todo to be marked as uncompleted
145
+ # @raise [Error::InvalidParameter] if url field in todo param
146
+ # is not a valid basecamp url
147
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#uncomplete-a-to-do
148
+ def uncomplete_todo(todo)
149
+ url = todo.url
150
+
151
+ raise Camper::Error::InvalidParameter, todo unless Camper::UrlUtils.basecamp_url?(url)
152
+
153
+ delete("#{url}/completion", override_path: true)
154
+ end
155
+
156
+ # Reposition a todo
157
+ #
158
+ # @example
159
+ # client.uncomplete_todo(todo)
160
+ #
161
+ # @param todo [Resource] the todo to be repositioned
162
+ # @param position [Integer|String] new position for the todo
163
+ # @raise [Error::InvalidParameter] if url field in todo param
164
+ # is not a valid basecamp url
165
+ # @raise [Error::InvalidParameter] if position param is less than 1
166
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/todos.md#reposition-a-to-do
167
+ def reposition_todo(todo, position)
168
+ url = todo.url
169
+ raise Camper::Error::InvalidParameter, todo unless Camper::UrlUtils.basecamp_url?(url)
170
+
171
+ raise Camper::Error::InvalidParameter, position if position.to_i < 1
172
+
173
+ put("#{url}/position", position: position, override_path: true)
174
+ end
175
+
176
+ # Trash a todo
177
+ # it calls the trash_recording endpoint under the hood
178
+ #
179
+ # @example
180
+ # client.trash_todo(todo)
181
+ #
182
+ # @param todo [Resource] the todo to be trashed
183
+ # @raise [Error::InvalidParameter] if url field in todo param
184
+ # is not a valid basecamp url
185
+ # @see https://github.com/basecamp/bc3-api/blob/master/sections/recordings.md#trash-a-recording
186
+ def trash_todo(todo)
187
+ raise Camper::Error::InvalidParameter, todo unless Camper::UrlUtils.basecamp_url?(todo.url)
188
+
189
+ trash_recording(todo)
190
+ end
191
+
192
+ private
193
+
194
+ def key_is_present?(hash, key)
195
+ hash.key?(key.to_sym) || hash.key?(key.to_s)
196
+ end
197
+ end
198
+ end