Module: Asana

Defined in:
lib/asana-client.rb

Defined Under Namespace

Classes: Project, Task, User, Workspace

Constant Summary collapse

API_URL =
"https://app.asana.com/api/1.0/"

Class Method Summary collapse

Class Method Details

.get(url) ⇒ Object

perform a GET request and return the response body as an object



127
128
129
# File 'lib/asana-client.rb', line 127

def Asana.get(url)
    return Asana.http_request(Net::HTTP::Get, url, nil, nil)
end

.http_request(type, url, data, query) ⇒ Object

perform an HTTP request to the Asana API



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/asana-client.rb', line 142

def Asana.http_request(type, url, data, query)
    # set up http object
    uri = URI.parse API_URL + url
    http = Net::HTTP.new uri.host, uri.port
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER

    # all requests are json
    header = {
        "Content-Type" => "application/json"
    }

    # make request
    req = type.new("#{uri.path}?#{uri.query}", header)
    req.basic_auth @@config["api_key"], ''
    if req.respond_to?(:set_form_data) && !data.nil?
        req.set_form_data data 
    end
    res = http.start { |http| http.request req  }

    # return request object
    return JSON.parse(res.body)
end

.initObject

initialize config values



20
21
22
23
24
25
26
# File 'lib/asana-client.rb', line 20

def Asana.init
    begin
        @@config = YAML.load_file File.expand_path "~/.asana-client"
    rescue
        abort "Configuration file could not be found.\nSee https://github.com/tmacwill/asana-client for installation instructions."
    end
end

.parse(args) ⇒ Object

parse argumens



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/asana-client.rb', line 29

def Asana.parse(args)
    # no arguments given
    if args.empty?
        abort "Nothing to do here."
    end

    # concatenate array into a string
    string = args.join " "

    # finish n: complete the task with id n
    if string =~ /^finish (\d+)$/
        Asana::Task.finish $1
        puts "Task completed!"
        exit
    end

    # workspace: display tasks in that workspace
    if string =~ /^(\w+)$/
        # get corresponding workspace object
        workspace = Asana::Workspace.find $1
        abort "Workspace not found!" unless workspace

        # display all tasks in workspace
        puts workspace.tasks unless workspace.tasks.empty?
        exit
    end

    # workspace/project: display tasks in that project
    if string =~ /^(\w+)\/(\w+)$/
        # get corresponding workspace
        workspace = Asana::Workspace.find $1
        abort "Workspace not found!" unless workspace

        # get corresponding project
        project = Asana::Project.find workspace, $2
        abort "Project not found!" unless project

        # display all tasks in project
        puts project.tasks unless project.tasks.empty?
        exit
    end

    # extract assignee, if any
    assignee = nil
    args.each do |word|
        if word =~ /^@(\w+)$/
            assignee = word[1..-1]
            args.delete word
        end
    end

    # extract due date, if any
    due = Chronic.parse(args.reverse[0..1].reverse.join(" "))
    if !due.nil? && due.to_s =~ /(\d+)-(\d+)-(\d+)/
        # penultimate word is part of the date or a stop word, so remove it
        if Chronic.parse(args.reverse[1]) || ["due", "on", "for"].include?(args.reverse[1].downcase)
            args.pop
        end

        # extract date from datetime and remove date from task name
        args.pop
        due = "#{$1}-#{$2}-#{$3}"
    end

    # reset string, because we modifed argv
    string = args.join " "

    # workspace task name: create task in that workspace
    if string =~ /^(\w+) (.+)/
        # get corresponding workspace 
        workspace = Asana::Workspace.find $1

        # create task in workspace
        Asana::Task.create workspace, $2, assignee, due
        puts "Task created in #{workspace.name}!"
        exit
    end

    # workspace/project task name: create task in that workspace
    if string =~ /^(\w+)\/(\w+) (.+)/
        # get corresponding workspace 
        workspace = Asana::Workspace.find $1

        # create task in workspace
        task = Asana::Task.create workspace, $3, assignee, due

        # get corresponding project
        project = Asana::Project.find workspace, $2
        abort "Project not found!" unless project

        # add task to project
        Asana.post "tasks/#{task['data']['id']}/addProject", { "project" => project.id }
        puts "Task created in #{workspace.name}/#{project.name}!"
        exit
    end
end

.post(url, data, query = nil) ⇒ Object

perform a POST request and return the response body as an object



137
138
139
# File 'lib/asana-client.rb', line 137

def Asana.post(url, data, query = nil)
    return Asana.http_request(Net::HTTP::Post, url, data, query)
end

.put(url, data, query = nil) ⇒ Object

perform a PUT request and return the response body as an object



132
133
134
# File 'lib/asana-client.rb', line 132

def Asana.put(url, data, query = nil)
    return Asana.http_request(Net::HTTP::Put, url, data, query)
end

.workspacesObject

get all of the users workspaces



167
168
169
170
171
172
173
174
175
176
177
# File 'lib/asana-client.rb', line 167

def Asana.workspaces
    spaces = self.get "workspaces" 
    list = []

    # convert array to hash indexed on workspace name
    spaces["data"].each do |space|
        list.push Workspace.new :id => space["id"], :name => space["name"]
    end

    list
end