camper 0.0.6 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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