Class: Basecamp

Inherits:
Object
  • Object
show all
Defined in:
lib/basecamp.rb

Overview

An interface to the Basecamp web-services API. Usage is straightforward:

session = Basecamp.new('your.basecamp.com', 'username', 'password')
puts "projects: #{session.projects.length}"

Defined Under Namespace

Classes: FileUpload, Record

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, user_name, password, use_ssl = false) ⇒ Basecamp

Connects



97
98
99
100
101
# File 'lib/basecamp.rb', line 97

def initialize(url, user_name, password, use_ssl = false)
  @use_xml = false
  @user_name, @password = user_name, password
  connect!(url, use_ssl)
end

Instance Attribute Details

#use_xmlObject

Returns the value of attribute use_xml.



94
95
96
# File 'lib/basecamp.rb', line 94

def use_xml
  @use_xml
end

Instance Method Details

#comment(id) ⇒ Object

Retrieve a specific comment



205
206
207
# File 'lib/basecamp.rb', line 205

def comment(id)
  record "/msg/comment/#{id}"
end

#comments(post_id) ⇒ Object

Return a list of the comments for the specified message.



200
201
202
# File 'lib/basecamp.rb', line 200

def comments(post_id)
  records "comment", "/msg/comments/#{post_id}"
end

#company(id) ⇒ Object

Return information for the company with the given id



119
120
121
# File 'lib/basecamp.rb', line 119

def company(id)
  record "/contacts/company/#{id}"
end

#complete_item(id) ⇒ Object

Marks the given item completed.



235
236
237
# File 'lib/basecamp.rb', line 235

def complete_item(id)
  record "/todos/complete_item/#{id}"
end

#complete_milestone(id) ⇒ Object

Complete the milestone with the given id



304
305
306
# File 'lib/basecamp.rb', line 304

def complete_milestone(id)
  record "/milestones/complete/#{id}"
end

#create_comment(post_id, comment, attachments = []) ⇒ Object

Add a new comment to a message. comment must be a hash describing the comment. You can add attachments to the comment, too, by giving them in an array. See the #post_message method for a description of how to do that.



212
213
214
215
216
# File 'lib/basecamp.rb', line 212

def create_comment(post_id, comment, attachments=[])
  prepare_attachments(attachments)
  record "/msg/create_comment", :comment => comment.merge(:post_id => post_id),
    :attachments => attachments
end

#create_item(list_id, content, responsible_party = nil, notify = true) ⇒ Object

Creates a new to-do item.



245
246
247
248
249
# File 'lib/basecamp.rb', line 245

def create_item(list_id, content, responsible_party=nil, notify=true)
  record "/todos/create_item/#{list_id}",
    :content => content, :responsible_party => responsible_party,
    :notify => notify
end

#create_list(project_id, list) ⇒ Object

Creates a new list using the given hash of list metadata.



252
253
254
# File 'lib/basecamp.rb', line 252

def create_list(project_id, list)
  record "/projects/#{project_id}/todos/create_list", list
end

#create_milestone(project_id, data) ⇒ Object

Create a new milestone for the given project. data must be hash of the values to set, including title, deadline, responsible_party, and notify.



311
312
313
# File 'lib/basecamp.rb', line 311

def create_milestone(project_id, data)
  create_milestones(project_id, [data]).first
end

#create_milestones(project_id, milestones) ⇒ Object

As #create_milestone, but can create multiple milestones in a single request. The milestones parameter must be an array of milestone values as descrbed in #create_milestone.



318
319
320
# File 'lib/basecamp.rb', line 318

def create_milestones(project_id, milestones)
  records "milestone", "/projects/#{project_id}/milestones/create", :milestone => milestones
end

#delete_comment(id) ⇒ Object

Deletes (and returns) the given comment.



226
227
228
# File 'lib/basecamp.rb', line 226

def delete_comment(id)
  record "/msg/delete_comment/#{id}"
end

#delete_item(id) ⇒ Object

Deletes the given item from it’s parent list.



257
258
259
# File 'lib/basecamp.rb', line 257

def delete_item(id)
  record "/todos/delete_item/#{id}"
end

#delete_list(id) ⇒ Object

Deletes the given list and all of its items.



262
263
264
# File 'lib/basecamp.rb', line 262

def delete_list(id)
  record "/todos/delete_list/#{id}"
end

#delete_message(id) ⇒ Object

Deletes the message with the given id, and returns it.



195
196
197
# File 'lib/basecamp.rb', line 195

def delete_message(id)
  record "/msg/delete/#{id}"
end

#delete_milestone(id) ⇒ Object

Destroys the milestone with the given id.



323
324
325
# File 'lib/basecamp.rb', line 323

def delete_milestone(id)
  record "/milestones/delete/#{id}"
end

#file_categories(project_id) ⇒ Object

Returns the list of file categories for the given project



114
115
116
# File 'lib/basecamp.rb', line 114

def file_categories(project_id)
  records "attachment-category", "/projects/#{project_id}/attachment_categories"
end

#get_list(id) ⇒ Object

Retrieves the specified list, and all of its items.



267
268
269
# File 'lib/basecamp.rb', line 267

def get_list(id)
  record "/todos/list/#{id}"
end

#lists(project_id, complete = nil) ⇒ Object

Return all lists for a project. If complete is true, only completed lists are returned. If complete is false, only uncompleted lists are returned.



273
274
275
# File 'lib/basecamp.rb', line 273

def lists(project_id, complete=nil)
  records "todo-list", "/projects/#{project_id}/todos/lists", :complete => complete
end

#message(*ids) ⇒ Object

Return information about the message(s) with the given id(s). The API limits you to requesting 25 messages at a time, so if you need to get more than that, you’ll need to do it in multiple requests.



139
140
141
142
# File 'lib/basecamp.rb', line 139

def message(*ids)
  result = records("post", "/msg/get/#{ids.join(",")}")
  result.length == 1 ? result.first : result
end

#message_categories(project_id) ⇒ Object

Returns the list of message categories for the given project



109
110
111
# File 'lib/basecamp.rb', line 109

def message_categories(project_id)
  records "post-category", "/projects/#{project_id}/post_categories"
end

#message_list(project_id, category_id = nil) ⇒ Object

Returns a summary of all messages in the given project (and category, if specified). The summary is simply the title and category of the message, as well as the number of attachments (if any).



147
148
149
150
151
152
153
# File 'lib/basecamp.rb', line 147

def message_list(project_id, category_id=nil)
  url = "/projects/#{project_id}/msg"
  url << "/cat/#{category_id}" if category_id
  url << "/archive"
  
  records "post", url
end

#milestones(project_id, find = "all") ⇒ Object

Returns a list of all milestones for the given project, optionally filtered by whether they are completed, late, or upcoming.



329
330
331
# File 'lib/basecamp.rb', line 329

def milestones(project_id, find="all")
  records "milestone", "/projects/#{project_id}/milestones/list", :find => find
end

#move_item(id, to) ⇒ Object

Repositions an item to be at the given position in its list



278
279
280
# File 'lib/basecamp.rb', line 278

def move_item(id, to)
  record "/todos/move_item/#{id}", :to => to
end

#move_list(id, to) ⇒ Object

Repositions a list to be at the given position in its project



283
284
285
# File 'lib/basecamp.rb', line 283

def move_list(id, to)
  record "/todos/move_list/#{id}", :to => to
end

#people(company_id, project_id = nil) ⇒ Object

Return an array of the people in the given company. If the project-id is given, only people who have access to the given project will be returned.



125
126
127
128
129
# File 'lib/basecamp.rb', line 125

def people(company_id, project_id=nil)
  url = project_id ? "/projects/#{project_id}" : ""
  url << "/contacts/people/#{company_id}"
  records "person", url
end

#person(id) ⇒ Object

Return information about the person with the given id



132
133
134
# File 'lib/basecamp.rb', line 132

def person(id)
  record "/contacts/person/#{id}"
end

#post_message(project_id, message, notify = [], attachments = []) ⇒ Object

Create a new message in the given project. The message parameter should be a hash. The email_to parameter must be an array of person-id’s that should be notified of the post.

If you want to add attachments to the message, the attachments parameter should be an array of hashes, where each has has a :name key (optional), and a :file key (required). The :file key must refer to a Basecamp::FileUpload instance.

msg = session.post_message(158141,
   { :title => "Requirements",
     :body => "Here are the requirements documents you asked for.",
     :category_id => 2301121 },
   [john.id, martha.id],
   [ { :name => "Primary Requirements",
       :file => Basecamp::FileUpload.new('primary.doc", File.read('primary.doc')) },
     { :file => Basecamp::FileUpload.new('other.doc', File.read('other.doc')) } ])


172
173
174
175
176
177
178
# File 'lib/basecamp.rb', line 172

def post_message(project_id, message, notify=[], attachments=[])
  prepare_attachments(attachments)
  record "/projects/#{project_id}/msg/create",
    :post => message,
    :notify => notify,
    :attachments => attachments
end

#projectsObject

Return the list of all accessible projects.



104
105
106
# File 'lib/basecamp.rb', line 104

def projects
  records "project", "/project/list"
end

#record(path, parameters = {}) ⇒ Object

A convenience method for wrapping the result of a query in a Record object. This assumes that the result is a singleton, not a collection.



364
365
366
367
# File 'lib/basecamp.rb', line 364

def record(path, parameters={})
  result = request(path, parameters)
  (result && !result.empty?) ? Record.new(result.keys.first, result.values.first) : nil
end

#records(node, path, parameters = {}) ⇒ Object

A convenience method for wrapping the result of a query in Record objects. This assumes that the result is a collection–any singleton result will be wrapped in an array.



372
373
374
375
376
377
# File 'lib/basecamp.rb', line 372

def records(node, path, parameters={})
  result = request(path, parameters).values.first or return []
  result = result[node] or return []
  result = [result] unless Array === result
  result.map { |row| Record.new(node, row) }
end

#request(path, parameters = {}, second_try = false) ⇒ Object

Make a raw web-service request to Basecamp. This will return a Hash of Arrays of the response, and may seem a little odd to the uninitiated.



347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/basecamp.rb', line 347

def request(path, parameters = {}, second_try = false)
  response = post(path, convert_body(parameters), "Content-Type" => content_type)

  if response.code.to_i / 100 == 2
    result = XmlSimple.xml_in(response.body, 'keeproot' => true,
      'contentkey' => '__content__', 'forcecontent' => true)
    typecast_value(result)
  elsif response.code == "302" && !second_try
    connect!(@url, !@use_ssl)
    request(path, parameters, true)
  else
    raise "#{response.message} (#{response.code})"
  end
end

#uncomplete_item(id) ⇒ Object

Marks the given item uncompleted.



240
241
242
# File 'lib/basecamp.rb', line 240

def uncomplete_item(id)
  record "/todos/uncomplete_item/#{id}"
end

#uncomplete_milestone(id) ⇒ Object

Uncomplete the milestone with the given id



334
335
336
# File 'lib/basecamp.rb', line 334

def uncomplete_milestone(id)
  record "/milestones/uncomplete/#{id}"
end

#update_comment(id, comment, attachments = []) ⇒ Object

Update the given comment. Attachments follow the same format as #post_message.



219
220
221
222
223
# File 'lib/basecamp.rb', line 219

def update_comment(id, comment, attachments=[])
  prepare_attachments(attachments)
  record "/msg/update_comment", :comment_id => id,
    :comment => comment, :attachments => attachments
end

#update_item(id, content, responsible_party = nil, notify = true) ⇒ Object

Updates the given item



288
289
290
291
292
# File 'lib/basecamp.rb', line 288

def update_item(id, content, responsible_party=nil, notify=true)
  record "/todos/update_item/#{id}",
    :item => { :content => content }, :responsible_party => responsible_party,
    :notify => notify
end

#update_list(id, list) ⇒ Object

Updates the given list’s metadata



295
296
297
# File 'lib/basecamp.rb', line 295

def update_list(id, list)
  record "/todos/update_list/#{id}", :list => list
end

#update_message(id, message, notify = [], attachments = []) ⇒ Object

Edit the message with the given id. The message parameter should be a hash. The email_to parameter must be an array of person-id’s that should be notified of the post.

The attachments parameter, if used, should be the same as described for #post_message.



186
187
188
189
190
191
192
# File 'lib/basecamp.rb', line 186

def update_message(id, message, notify=[], attachments=[])
  prepare_attachments(attachments)
  record "/msg/update/#{id}",
    :post => message,
    :notify => notify,
    :attachments => attachments
end

#update_milestone(id, data, move = false, move_off_weekends = false) ⇒ Object

Updates an existing milestone.



339
340
341
342
343
# File 'lib/basecamp.rb', line 339

def update_milestone(id, data, move=false, move_off_weekends=false)
  record "/milestones/update/#{id}", :milestone => data,
    :move_upcoming_milestones => move,
    :move_upcoming_milestones_off_weekends => move_off_weekends
end