omnifocus-attask 1.0.3

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,6 @@
1
+ === 1.0.0 / 2012-02-26
2
+
3
+ * First Major Release
4
+
5
+ * Added AtTask Support for OmniFocus
6
+
@@ -0,0 +1,5 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/omnifocus/attask.rb
@@ -0,0 +1,8 @@
1
+ = omnifocus-attask
2
+
3
+ home :: https://github.com/samilton/omnifocus-attask
4
+
5
+ == DESCRIPTION:
6
+
7
+ OmniFocus AtTask Integration
8
+
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugin :samilton
7
+
8
+ Hoe.spec 'omnifocus-attask' do
9
+ developer 'Sam Hamilton', 'samilton@gmail.com'
10
+
11
+ dependency "omnifocus", "~> 1.4"
12
+ dependency "json", "~> 1.5.0"
13
+
14
+ self.rubyforge_name = 'samilton'
15
+ end
16
+
17
+ # vim: syntax=ruby
@@ -0,0 +1,215 @@
1
+ # Copyright (c) 2010 AtTask, Inc.
2
+
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
6
+ # permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9
+ # Software.
10
+
11
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+
16
+ require 'net/http'
17
+ require 'uri'
18
+ require 'json'
19
+ require 'yaml'
20
+
21
+ class Project
22
+ attr_accessor :name, :id, :tasks
23
+
24
+ def initialize(name, id)
25
+ @name = name
26
+ @id = id
27
+ @tasks = []
28
+ end
29
+
30
+ def add_task task
31
+ tasks.push task
32
+ end
33
+ end
34
+
35
+ module OmniFocus::AtTask
36
+ VERSION = '1.0.3'
37
+ PREFIX = 'AT'
38
+
39
+ AT_API_DEFAULT = "https://pragma.attask-ondemand.com/attask/api"
40
+
41
+ OBJCODE_GROUP = "GROUP"
42
+ OBJCODE_PROJECT = "PROJ"
43
+ OBJCODE_TASK = "TASK"
44
+ OBJCODE_OPTTASK = "OPTASK"
45
+
46
+ def load_or_create_config
47
+ path = File.expand_path "~/.omnifocus-attask.yml"
48
+ config = YAML.load(File.read(path)) rescue nil
49
+
50
+ unless config then
51
+ config = { :username => "USER", :password => "PASSWORD" }
52
+
53
+ File.open(path, "w") { |f|
54
+ YAML.dump(config, f)
55
+ }
56
+
57
+ abort "Created default config in #{path}. Go fill it out."
58
+ end
59
+
60
+ config
61
+ end
62
+
63
+ def populate_attask_tasks
64
+ @projects = {}
65
+ config = load_or_create_config
66
+ user_name = config[:username]
67
+ password = config[:password]
68
+ process(user_name, password)
69
+ end
70
+
71
+ def process(user_name, password)
72
+
73
+ begin
74
+ sc = StreamClient.new(AT_API_DEFAULT)
75
+ sc.login(user_name, password)
76
+ taskList = []
77
+ # get tasks by doing a search
78
+ %w(TASK).each do |opcode|
79
+ taskList << sc.search(opcode, {'assignedToID' => sc.userID}, ["name", "projectID", "taskNumber", "description"])
80
+ end
81
+
82
+ taskList.each do |tasks|
83
+ tasks.each do |task|
84
+ if(@projects.include? task['projectID'])
85
+ project = @projects[task['projectID']]
86
+ project.add_task task
87
+ else
88
+ project = sc.get('PROJECT', task['projectID'], ["name"])
89
+ id = project['ID']
90
+ project = Project.new(project['name'], project['ID'])
91
+ project.add_task task
92
+ @projects[id] = project
93
+ end
94
+ end
95
+ end
96
+
97
+ @projects.each do |id, p|
98
+ project = p.name
99
+ p.tasks.each do |task|
100
+ ticket_id = "#{PREFIX}-#{project.gsub(/ /,'')}##{task['taskNumber']}"
101
+ title = task['name']
102
+ note = task['description'] || ""
103
+
104
+ if existing[ticket_id] then
105
+ bug_db[existing[ticket_id]][ticket_id] = true
106
+ next
107
+ end
108
+
109
+ bug_db[project][ticket_id] = [title, note]
110
+ end
111
+ end
112
+
113
+ rescue Exception => e
114
+ puts e
115
+ end
116
+
117
+ sc.logout()
118
+
119
+ end
120
+ end
121
+
122
+ class StreamClient
123
+
124
+ PATH_LOGIN = "/login";
125
+ PATH_LOGOUT = "/logout";
126
+ PATH_SEARCH = "/search";
127
+
128
+ def initialize(apiURL)
129
+ @apiURL = apiURL
130
+ @sessionID = nil
131
+ @userID = nil;
132
+ end
133
+
134
+ def userID
135
+ @userID
136
+ end
137
+
138
+ def login(username, password)
139
+ data = request(PATH_LOGIN,
140
+ {'username' => username, 'password' => password}, nil, "GET")
141
+ @sessionID = data['sessionID']
142
+ @userID = data['userID']
143
+ end
144
+
145
+ def logout
146
+ request(PATH_LOGOUT, {'sessionID' => @sessionID}, nil, "GET")
147
+ @sessionID = nil
148
+ @userID = nil
149
+ end
150
+
151
+ def search(objCode, query, fields=nil)
152
+ request("/#{objCode}#{PATH_SEARCH}", query, fields, "GET")
153
+ end
154
+
155
+ def getList(objCode, ids, fields=nil)
156
+ request("/#{objCode}", {'id' => ids.join(',')}, fields, "GET")
157
+ end
158
+
159
+ # create
160
+ def post(objCode, message, fields=nil)
161
+ request("/#{objCode}", message, fields, "POST")
162
+ end
163
+
164
+ # update
165
+ def put(objCode, objID, message, fields=nil)
166
+ request("/#{objCode}/#{objID}", message, fields, "PUT")
167
+ end
168
+
169
+ # retrieve
170
+ def get(objCode, objID, fields=nil)
171
+ request("/#{objCode}/#{objID}", nil, fields, "GET")
172
+ end
173
+
174
+ # delete
175
+ def delete(objCode, objID, force=false)
176
+ request("/#{objCode}/#{objID}", {'force' => force}, nil, "DELETE")
177
+ end
178
+
179
+ private
180
+
181
+ def request(path, params, fields, method)
182
+ url = URI.parse(@apiURL + path)
183
+
184
+ # Send HTTP method type as a parameter.
185
+ if (!params)
186
+ params = {}
187
+ end
188
+ params['method'] = method
189
+ params['sessionID'] = @sessionID
190
+
191
+ if (fields)
192
+ params['fields'] = fields.join(',')
193
+ end
194
+
195
+ http = Net::HTTP.new(url.host, url.port)
196
+ if (/^https/.match(@apiURL))
197
+ http.use_ssl = true
198
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
199
+ end
200
+ req = Net::HTTP::Post.new(url.request_uri)
201
+ req.set_form_data(params)
202
+ res = http.request(req)
203
+
204
+ case res
205
+ when Net::HTTPSuccess, Net::HTTPRedirection
206
+ data = JSON(res.body)['data'] #convert the response to a map
207
+ else
208
+ puts res.body
209
+ res.error!
210
+ end
211
+ data
212
+ end
213
+ end
214
+
215
+
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omnifocus-attask
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sam Hamilton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: omnifocus
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.4'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ - !ruby/object:Gem::Dependency
31
+ name: json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.5.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rdoc
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '3.10'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.10'
62
+ - !ruby/object:Gem::Dependency
63
+ name: hoe
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '3.5'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.5'
78
+ description: OmniFocus AtTask Integration
79
+ email:
80
+ - samilton@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files:
84
+ - History.txt
85
+ - Manifest.txt
86
+ - README.txt
87
+ files:
88
+ - History.txt
89
+ - Manifest.txt
90
+ - README.txt
91
+ - Rakefile
92
+ - lib/omnifocus/attask.rb
93
+ homepage: https://github.com/samilton/omnifocus-attask
94
+ licenses: []
95
+ post_install_message:
96
+ rdoc_options:
97
+ - --main
98
+ - README.txt
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project: samilton
115
+ rubygems_version: 1.8.23
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: OmniFocus AtTask Integration
119
+ test_files: []