logan18 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/logan/HashConstructed.rb +13 -0
- data/lib/logan/client.rb +74 -0
- data/lib/logan/event.rb +11 -0
- data/lib/logan/person.rb +14 -0
- data/lib/logan/project.rb +61 -0
- data/lib/logan/todo.rb +35 -0
- data/lib/logan/todolist.rb +84 -0
- data/lib/logan.rb +9 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA512:
|
3
|
+
metadata.gz: c75432a4b58cfdc008d493ded925490158eb3338e26dbbb8de2a6bcc3a14339d4967bf88bf1aaa994138876670451588f8a76663bf354e182fd726af2c817c54
|
4
|
+
data.tar.gz: 4f6404b95da08e945195b04dabdfa080c2bcc695393a2305bad70fdfec7eca68cc4f8f7b6f1eaa870b23ad92c56a76f0122b458b1882f00f754b2be14650f740
|
5
|
+
SHA1:
|
6
|
+
metadata.gz: f0fca7f22143c534cd25571c23799c03ea71e8d6
|
7
|
+
data.tar.gz: 9a01ca0abc5ec9c8aea48a34df8ecc6a60f48713
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# this module is taken from the accepted answer here
|
2
|
+
# http://stackoverflow.com/questions/1572660/is-there-a-way-to-initialize-an-object-through-a-hash
|
3
|
+
|
4
|
+
module HashConstructed
|
5
|
+
|
6
|
+
# initalizes the object by pulling key-value pairs from the hash and
|
7
|
+
# mapping them to the object's instance variables
|
8
|
+
#
|
9
|
+
# @param [Hash] h hash containing key-value pairs to map to object instance variables
|
10
|
+
def initialize(h)
|
11
|
+
h.each { |k,v| send("#{k}=",v) if respond_to?("#{k}=") }
|
12
|
+
end
|
13
|
+
end
|
data/lib/logan/client.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'logan/project'
|
2
|
+
|
3
|
+
module Logan
|
4
|
+
class Client
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
# Initializes the Logan shared client with information required to communicate with Basecamp
|
8
|
+
#
|
9
|
+
# @param basecamp_id [String] the Basecamp company ID
|
10
|
+
# @param auth_hash [Hash] authorization hash consisting of a username and password combination (:username, :password) or an access_token (:access_token)
|
11
|
+
# @param user_agent [String] the user-agent string to include in header of requests
|
12
|
+
def initialize(basecamp_id, auth_hash, user_agent)
|
13
|
+
self.class.base_uri "https://basecamp.com/#{basecamp_id}/api/v1"
|
14
|
+
self.class.headers 'User-Agent' => user_agent
|
15
|
+
self.auth = auth_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
# Updates authorization information for Logan shared client
|
19
|
+
#
|
20
|
+
# @param auth_hash [Hash] authorization hash consisting of a username and password combination (:username, :password) or an access_token (:access_token)
|
21
|
+
def auth=(auth_hash)
|
22
|
+
# symbolize the keys
|
23
|
+
auth_hash = auth_hash.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
|
24
|
+
|
25
|
+
if auth_hash.has_key? :access_token
|
26
|
+
# clear the basic_auth, if it's set
|
27
|
+
self.class.default_options.reject!{ |k| k == :basic_auth }
|
28
|
+
|
29
|
+
# set the Authorization headers
|
30
|
+
self.class.headers.merge!("Authorization" => "Bearer #{auth_hash[:access_token]}")
|
31
|
+
elsif auth_hash.has_key?(:username) && auth_hash.has_key?(:password)
|
32
|
+
self.class.basic_auth auth_hash[:username], auth_hash[:password]
|
33
|
+
|
34
|
+
# remove the access_token from the headers, if it exists
|
35
|
+
self.class.headers.reject!{ |k| k == "Authorization" }
|
36
|
+
else
|
37
|
+
raise """
|
38
|
+
Incomplete authorization information passed in authorization hash.
|
39
|
+
You must have either an :access_token or a username password combination (:username, :password).
|
40
|
+
"""
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# get projects from Basecamp API
|
45
|
+
#
|
46
|
+
# @return [Array<Logan::Project>] array of {Logan::Project} instances
|
47
|
+
def projects
|
48
|
+
response = self.class.get '/projects.json'
|
49
|
+
response.parsed_response.map { |h| p = Logan::Project.new(h) }
|
50
|
+
end
|
51
|
+
|
52
|
+
# get active Todo lists for all projects from Basecamp API
|
53
|
+
#
|
54
|
+
# @return [Array<Logan::TodoList>] array of {Logan::TodoList} instances
|
55
|
+
def todolists
|
56
|
+
response = self.class.get '/todolists.json'
|
57
|
+
|
58
|
+
response.parsed_response.map do |h|
|
59
|
+
list = Logan::TodoList.new(h)
|
60
|
+
|
61
|
+
# grab the project ID for this list from the url
|
62
|
+
list.project_id = list.url.scan( /projects\/(\d+)/).last.first
|
63
|
+
|
64
|
+
# return the list so this method returns an array of lists
|
65
|
+
list
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def events(since_time, page = 1)
|
70
|
+
response = self.class.get "/events.json?since=#{since_time.to_s}&page=#{page}"
|
71
|
+
response.map { |h| e = Logan::Event.new(h) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/logan/event.rb
ADDED
data/lib/logan/person.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'logan/HashConstructed'
|
2
|
+
require 'logan/todolist'
|
3
|
+
|
4
|
+
module Logan
|
5
|
+
class Project
|
6
|
+
include HashConstructed
|
7
|
+
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# get active todo lists for this project from Basecamp API
|
12
|
+
#
|
13
|
+
# @return [Array<Logan::TodoList>] array of active todo lists for this project
|
14
|
+
def todolists
|
15
|
+
active_response = Logan::Client.get "/projects/#{@id}/todolists.json"
|
16
|
+
lists_array = active_response.parsed_response.map do |h|
|
17
|
+
Logan::TodoList.new h.merge({ :project_id => @id })
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# get completed todo lists for this project from Basecamp API
|
22
|
+
#
|
23
|
+
# @return [Array<Logan::TodoList>] array of completed todo lists for this project
|
24
|
+
def completed_todolists
|
25
|
+
completed_response = Logan::Client.get "/projects/#{@id}/todolists/completed.json"
|
26
|
+
lists_array = completed_response.parsed_response.map do |h|
|
27
|
+
Logan::TodoList.new h.merge({ :project_id => @id })
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# get both active and completed todo lists for this project from Basecamp API
|
32
|
+
#
|
33
|
+
# @return [Array<Logan::TodoList>] array of active and completed todo lists for this project
|
34
|
+
def all_todolists
|
35
|
+
todolists + completed_todolists
|
36
|
+
end
|
37
|
+
|
38
|
+
# get an individual todo list for this project from Basecamp API
|
39
|
+
#
|
40
|
+
# @param [String] list_id id for the todo list
|
41
|
+
# @return [Logan::TodoList] todo list instance
|
42
|
+
def todolist(list_id)
|
43
|
+
response = Logan::Client.get "/projects/#{@id}/todolists/#{list_id}.json"
|
44
|
+
Logan::TodoList.new response.parsed_response.merge({ :project_id => @id })
|
45
|
+
end
|
46
|
+
|
47
|
+
# create a todo list in this project via Basecamp API
|
48
|
+
#
|
49
|
+
# @param [Logan::TodoList] todo_list todo list instance to be created
|
50
|
+
# @return [Logan::TodoList] todo list instance from Basecamp API response
|
51
|
+
def create_todolist(todo_list)
|
52
|
+
post_params = {
|
53
|
+
:body => todo_list.post_json,
|
54
|
+
:headers => Logan::Client.headers.merge({'Content-Type' => 'application/json'})
|
55
|
+
}
|
56
|
+
|
57
|
+
response = Logan::Client.post "/projects/#{@id}/todolists.json", post_params
|
58
|
+
Logan::TodoList.new response.merge({ :project_id => @id })
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/logan/todo.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'logan/HashConstructed'
|
2
|
+
require 'logan/person'
|
3
|
+
|
4
|
+
module Logan
|
5
|
+
class Todo
|
6
|
+
include HashConstructed
|
7
|
+
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :content
|
10
|
+
attr_accessor :completed
|
11
|
+
attr_accessor :assignee
|
12
|
+
attr_accessor :due_at
|
13
|
+
|
14
|
+
def post_json
|
15
|
+
{
|
16
|
+
:content => @content,
|
17
|
+
:due_at => @due_at,
|
18
|
+
:assignee => @assignee.to_hash
|
19
|
+
}.to_json
|
20
|
+
end
|
21
|
+
|
22
|
+
def put_json
|
23
|
+
{
|
24
|
+
:content => @content,
|
25
|
+
:due_at => @due_at,
|
26
|
+
:assignee => @assignee.to_hash,
|
27
|
+
:completed => @completed
|
28
|
+
}.to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
def assignee=(assignee)
|
32
|
+
@assignee = assignee.is_a?(Hash) ? Logan::Person.new(assignee) : assignee
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'logan/HashConstructed'
|
2
|
+
require 'logan/todo'
|
3
|
+
|
4
|
+
module Logan
|
5
|
+
class TodoList
|
6
|
+
include HashConstructed
|
7
|
+
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :project_id
|
10
|
+
attr_accessor :name
|
11
|
+
attr_accessor :description
|
12
|
+
attr_accessor :completed
|
13
|
+
attr_accessor :remaining_todos
|
14
|
+
attr_accessor :completed_todos
|
15
|
+
attr_accessor :url
|
16
|
+
|
17
|
+
# intializes a todo list by calling the HashConstructed initialize method and
|
18
|
+
# setting both @remaining_todos and @completed_todos to empty arrays
|
19
|
+
def initialize(h)
|
20
|
+
@remaining_todos = []
|
21
|
+
@completed_todos = []
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def post_json
|
26
|
+
{ :name => @name, :description => @description }.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
# assigns the {#remaining_todos} and {#completed_todos} from the associated keys
|
30
|
+
# in the passed hash
|
31
|
+
#
|
32
|
+
# @param [Hash] todo_hash hash possibly containing todos under 'remaining' and 'completed' keys
|
33
|
+
def todos=(todo_hash)
|
34
|
+
@remaining_todos = todo_hash['remaining'].map { |h| Logan::Todo.new h }
|
35
|
+
@completed_todos = todo_hash['completed'].map { |h| Logan::Todo.new h }
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# searches the remaining and completed todos for the first todo with the substring in its content
|
40
|
+
#
|
41
|
+
# @param [String] substring substring to look for
|
42
|
+
# @return [Logan::Todo] the matched todo, or nil if there wasn't one
|
43
|
+
def todo_with_substring(substring)
|
44
|
+
issue_todo = @remaining_todos.detect{ |t| !t.content.index(substring).nil? }
|
45
|
+
issue_todo ||= @completed_todos.detect { |t| !t.content.index(substring).nil? }
|
46
|
+
end
|
47
|
+
|
48
|
+
# create a todo in this todo list via the Basecamp API
|
49
|
+
#
|
50
|
+
# @param [Logan::Todo] todo the todo instance to create in this todo lost
|
51
|
+
# @return [Logan::Todo] the created todo returned from the Basecamp API
|
52
|
+
def create_todo(todo)
|
53
|
+
post_params = {
|
54
|
+
:body => todo.post_json,
|
55
|
+
:headers => Logan::Client.headers.merge({'Content-Type' => 'application/json'})
|
56
|
+
}
|
57
|
+
|
58
|
+
response = Logan::Client.post "/projects/#{@project_id}/todolists/#{@id}/todos.json", post_params
|
59
|
+
Logan::Todo.new response
|
60
|
+
end
|
61
|
+
|
62
|
+
# update a todo in this todo list via the Basecamp API
|
63
|
+
#
|
64
|
+
# @param [Logan::Todo] todo the todo instance to update in this todo list
|
65
|
+
# @return [Logan::Todo] the updated todo instance returned from the Basecamp API
|
66
|
+
def update_todo(todo)
|
67
|
+
put_params = {
|
68
|
+
:body => todo.put_json,
|
69
|
+
:headers => Logan::Client.headers.merge({'Content-Type' => 'application/json'})
|
70
|
+
}
|
71
|
+
|
72
|
+
response = Logan::Client.put "/projects/#{@project_id}/todos/#{todo.id}.json", put_params
|
73
|
+
Logan::Todo.new response
|
74
|
+
end
|
75
|
+
|
76
|
+
# delete a todo in this todo list via delete call to Basecamp API
|
77
|
+
#
|
78
|
+
# @param [Logan::Todo] todo the todo instance to be delete from this todo list
|
79
|
+
# @return [HTTParty::response] response from Basecamp for delete request
|
80
|
+
def delete_todo(todo)
|
81
|
+
response = Logan::Client.delete "/projects/#{@project_id}/todos/#{todo.id}.json"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/logan.rb
ADDED
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logan18
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Birarda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2014-01-31 00:00:00 Z
|
13
|
+
dependencies: []
|
14
|
+
|
15
|
+
description:
|
16
|
+
email: logan@birarda.com
|
17
|
+
executables: []
|
18
|
+
|
19
|
+
extensions: []
|
20
|
+
|
21
|
+
extra_rdoc_files: []
|
22
|
+
|
23
|
+
files:
|
24
|
+
- lib/logan.rb
|
25
|
+
- lib/logan/client.rb
|
26
|
+
- lib/logan/event.rb
|
27
|
+
- lib/logan/HashConstructed.rb
|
28
|
+
- lib/logan/person.rb
|
29
|
+
- lib/logan/project.rb
|
30
|
+
- lib/logan/todo.rb
|
31
|
+
- lib/logan/todolist.rb
|
32
|
+
homepage: https://github.com/birarda/logan
|
33
|
+
licenses:
|
34
|
+
- MIT
|
35
|
+
metadata: {}
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- &id001
|
45
|
+
- ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- *id001
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.1.11
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: ruby gem to communicate with new Basecamp API
|
58
|
+
test_files: []
|
59
|
+
|