austinmoody-fogbugz-api 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +23 -13
- data/TODO +0 -11
- data/lib/fogbugz-api.rb +159 -10
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -1,28 +1,38 @@
|
|
1
1
|
= Ruby FogBugz API Wrapper
|
2
2
|
|
3
|
-
|
3
|
+
An attempt at creating a wrapper for the FogBugz API in Ruby.
|
4
4
|
|
5
|
-
|
6
|
-
More about FogBugz API: http://www.fogcreek.com/FogBugz/docs/60/topics/advanced/API.html
|
5
|
+
FogBugz: http://www.fogbugz.com/
|
7
6
|
|
8
|
-
|
7
|
+
FogBugz API Docs: http://www.fogcreek.com/FogBugz/docs/60/topics/advanced/API.html
|
8
|
+
|
9
|
+
This is very much a work in progress. I needed to scratch an itch with an internal project and started on this. There are many functions of the API which are not yet implemented as a result. Please check the code to see what is done and what is not.
|
10
|
+
|
11
|
+
If you want to help out please e-mail Austin (austin.moody@gmail.com) and he can add you as a collaborator.
|
9
12
|
|
10
13
|
== Installation
|
11
14
|
|
12
|
-
|
15
|
+
You can install the gem from github.com by using these commands:
|
16
|
+
|
17
|
+
gem sources -a http://gems.github.com
|
18
|
+
|
19
|
+
sudo gem install austinmoody-fogbugz-api
|
13
20
|
|
14
21
|
== Requirements
|
15
22
|
|
16
23
|
* Hpricot (http://code.whytheluckystiff.net/hpricot/)
|
17
|
-
* net/https
|
18
24
|
* A login to a FogBugz server
|
19
25
|
|
20
26
|
== Example Usage
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
fb = FogBugz.new("my.fogbugzserver.com",true) # create instance
|
29
|
+
|
30
|
+
fb.logon("mylogin","mypassword") # logs into FogBugz and sets token
|
31
|
+
|
32
|
+
mycases = fb.search("AssignedTo:\"Austin Moody\"") # search terms just as in FogBugz
|
33
|
+
|
34
|
+
projects = fb.projects # get a list of projects
|
35
|
+
|
36
|
+
fb.logoff # logout
|
37
|
+
|
38
|
+
See the code and potentially the wiki at github.com for more information.
|
data/TODO
CHANGED
@@ -4,17 +4,6 @@
|
|
4
4
|
* Case manipulation
|
5
5
|
* edit, assign, reactivate, reopen, resolve, close, email, reply, forward
|
6
6
|
* file uploads
|
7
|
-
* new area
|
8
|
-
* new person
|
9
|
-
* new fix for
|
10
|
-
* view project
|
11
|
-
* view area
|
12
|
-
* view person
|
13
|
-
* view fix for
|
14
|
-
* view category
|
15
|
-
* view priority
|
16
|
-
* view status
|
17
|
-
* view mailbox
|
18
7
|
* working schedule
|
19
8
|
* time tracking
|
20
9
|
* source control
|
data/lib/fogbugz-api.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems' rescue nil
|
|
2
2
|
require 'hpricot'
|
3
3
|
require 'net/https'
|
4
4
|
require 'cgi'
|
5
|
+
require 'date'
|
5
6
|
|
6
7
|
class FogBugzError < StandardError; end
|
7
8
|
|
@@ -56,7 +57,7 @@ class FogBugz
|
|
56
57
|
result = Hpricot.XML(@connection.get("/api.xml").body)
|
57
58
|
|
58
59
|
@api_version = (result/"version").inner_html.to_i
|
59
|
-
@api_minversion = (result/"
|
60
|
+
@api_minversion = (result/"minversion").inner_html.to_i
|
60
61
|
@api_url = "/" + (result/"url").inner_html
|
61
62
|
|
62
63
|
# Make sure this class will work w/ API version
|
@@ -117,8 +118,8 @@ class FogBugz
|
|
117
118
|
def projects(fWrite=false, ixProject=nil)
|
118
119
|
return_value = Hash.new
|
119
120
|
cmd = {"cmd" => "listProjects", "token" => @token}
|
120
|
-
{"fWrite"=>"1"}.merge(cmd) if fWrite
|
121
|
-
{"ixProject"=>ixProject}.merge(cmd) if ixProject
|
121
|
+
cmd = {"fWrite"=>"1"}.merge(cmd) if fWrite
|
122
|
+
cmd = {"ixProject"=>ixProject}.merge(cmd) if ixProject
|
122
123
|
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
123
124
|
return list_process(result,"project","sProject")
|
124
125
|
end
|
@@ -142,6 +143,21 @@ class FogBugz
|
|
142
143
|
return (result/"ixProject").inner_html.to_i
|
143
144
|
end
|
144
145
|
|
146
|
+
# Returns details about a specific project.
|
147
|
+
#
|
148
|
+
# * project: Either the id (ixProject) or the name (sProject).
|
149
|
+
#
|
150
|
+
# Value returned is a Hash containing all properties of the located project. nil is returned for unsuccessful search.
|
151
|
+
def project(project=nil)
|
152
|
+
return nil if not project
|
153
|
+
cmd = {"cmd" => "viewProject", "token" => @token}
|
154
|
+
cmd = {"ixProject" => project.to_s}.merge(cmd) if project.class == Fixnum
|
155
|
+
cmd = {"sProject" => project}.merge(cmd) if project.class == String
|
156
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
157
|
+
return_value = list_process(result,"project","sProject")
|
158
|
+
return_value[return_value.keys[0]]
|
159
|
+
end
|
160
|
+
|
145
161
|
def areas(fWrite=false, ixProject=nil, ixArea=nil)
|
146
162
|
return_value = Hash.new
|
147
163
|
cmd = {"cmd" => "listAreas", "token" => @token}
|
@@ -151,6 +167,34 @@ class FogBugz
|
|
151
167
|
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
152
168
|
return list_process(result,"area","sArea")
|
153
169
|
end
|
170
|
+
|
171
|
+
# Creates a new area within a specific project
|
172
|
+
#
|
173
|
+
# * ixProject: ID of the project to contain the new area.
|
174
|
+
# * sArea: Title of the new area.
|
175
|
+
# * ixPersonPrimaryContact: ID of the person who will be the primary contact for this area. -1 will set to the Project's primary contact, which is the default if not specified.
|
176
|
+
def new_area(ixProject,sArea,ixPersonPrimaryContact=-1)
|
177
|
+
cmd = {"cmd" => "newArea", "token" => @token, "ixProject" => ixProject.to_s, "sArea" => sArea.to_s, "ixPersonPrimaryContact" => ixPersonPrimaryContact.to_s}
|
178
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
179
|
+
return (result/"ixArea").inner_html.to_i
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns details about a specific area
|
183
|
+
#
|
184
|
+
# * area: Either the id of an area (ixArea) or the name of an area (sArea). If passing name, then the ID of the project the area belongs to needs to be passed.
|
185
|
+
# * ixProject: ID of a project which contains specific area. Needed if wanting details for area by name.
|
186
|
+
#
|
187
|
+
# Value returned is a Hash of containing all properties of the located area. nil is returned for unsuccessful search.
|
188
|
+
def area(area=nil,ixProject=nil)
|
189
|
+
return nil if not area
|
190
|
+
cmd = {"cmd" => "viewArea", "token" => @token}
|
191
|
+
cmd = {"ixArea" => area.to_s}.merge(cmd) if area.class == Fixnum
|
192
|
+
cmd = {"sArea" => area}.merge(cmd) if area.class == String
|
193
|
+
cmd = {"ixProject" => ixProject.to_s}.merge(cmd) if ixProject
|
194
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
195
|
+
return_value = list_process(result,"area","sArea")
|
196
|
+
return_value[return_value.keys[0]]
|
197
|
+
end
|
154
198
|
|
155
199
|
def fix_fors(ixProject=nil,ixFixFor=nil)
|
156
200
|
return_value = Hash.new
|
@@ -161,17 +205,72 @@ class FogBugz
|
|
161
205
|
return list_process(result,"fixfor","sFixFor")
|
162
206
|
end
|
163
207
|
|
208
|
+
# Returns details about a specific Fix For (releases)
|
209
|
+
#
|
210
|
+
# * fix_for: Either the id of a Fix For (ixFixFor) or the name of a Fix For (sFixFor). If passing name, then the ID of the project the area belongs to needs to be passed.
|
211
|
+
# * ixProject: ID of a project which contains specific Fix For. Needed if wanting details for Fix For by name.
|
212
|
+
#
|
213
|
+
# Value returned is a Hash containing all properties of the located Fix For. nil is returned for unsuccessful search.
|
214
|
+
def fix_for(fix_for,ixProject=nil)
|
215
|
+
return nil if not fix_for
|
216
|
+
cmd = {"cmd" => "viewFixFor", "token" => @token}
|
217
|
+
cmd = {"ixFixFor" => fix_for.to_s}.merge(cmd) if fix_for.class == Fixnum
|
218
|
+
cmd = {"sFixFor" => fix_for}.merge(cmd) if fix_for.class == String
|
219
|
+
cmd = {"ixProject" => ixProject.to_s}.merge(cmd) if ixProject
|
220
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
221
|
+
return_value = list_process(result,"fixfor","sFixFor")
|
222
|
+
return_value[return_value.keys[0]]
|
223
|
+
end
|
224
|
+
|
225
|
+
# Creates a new FixFor within FogBugz.
|
226
|
+
#
|
227
|
+
# * sFixFor: Title for the new FixFor
|
228
|
+
# * fAssignable: Can cases be assigned to this FixFor? true/false Default is true.
|
229
|
+
# * ixProject: ID of the project this FixFor belongs to. If -1 (which is default when not specified) this will be a global FixFor.
|
230
|
+
# * dtRelease: Release date for the new FixFor. If not passed, no release date will be set. Expecting DateTime class if value is passed.
|
231
|
+
def new_fix_for(sFixFor,fAssignable=true,ixProject=-1,dtRelease=nil)
|
232
|
+
return nil if dtRelease and dtRelease.class != DateTime
|
233
|
+
cmd = {"cmd" => "newFixFor","token"=>@token,"sFixFor"=>sFixFor,"fAssignable"=>(fAssignable) ? "1" : "0","ixProject"=>ixProject.to_s}
|
234
|
+
cmd = {"dtRelease"=>dtRelease}.merge(cmd) if dtRelease
|
235
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
236
|
+
return (result/"ixFixFor").inner_html.to_i
|
237
|
+
end
|
238
|
+
|
164
239
|
def categories
|
165
240
|
cmd = {"cmd" => "listCategories", "token" => @token}
|
166
241
|
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
167
242
|
return list_process(result,"category","sCategory")
|
168
243
|
end
|
244
|
+
|
245
|
+
# Returns details about a specific Category
|
246
|
+
#
|
247
|
+
# * ixCategory: The id of the Category to view.
|
248
|
+
#
|
249
|
+
# Value returned is a Hash containing all properties of the located Category. nil is returned for unsucessful search.
|
250
|
+
def category(ixCategory)
|
251
|
+
cmd = {"cmd" => "viewCategory", "token" => @token, "ixCategory" => ixCategory.to_s}
|
252
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
253
|
+
return_value = list_process(result,"category","sCategory")
|
254
|
+
return_value[return_value.keys[0]]
|
255
|
+
end
|
169
256
|
|
170
257
|
def priorities
|
171
258
|
cmd = {"cmd" => "listPriorities", "token" => @token}
|
172
259
|
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
173
260
|
return list_process(result,"priority","sPriority")
|
174
261
|
end
|
262
|
+
|
263
|
+
# Returns details about a specific priority
|
264
|
+
#
|
265
|
+
# * ixPriority: The id of the Priority to view
|
266
|
+
#
|
267
|
+
# Value returned is a Hash containing all properties of the located Priority. nil is returned for unsuccessful search.
|
268
|
+
def priority(ixPriority)
|
269
|
+
cmd = {"cmd" => "viewPriority", "token" => @token, "ixPriority" => ixPriority.to_s}
|
270
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
271
|
+
return_value = list_process(result,"priority","sPriority")
|
272
|
+
return_value[return_value.keys[0]]
|
273
|
+
end
|
175
274
|
|
176
275
|
# Returns list of people in corresponding categories.
|
177
276
|
#
|
@@ -191,6 +290,36 @@ class FogBugz
|
|
191
290
|
return list_process(result,"person","sFullName")
|
192
291
|
end
|
193
292
|
|
293
|
+
# Returns details for a specific FogBugz user. Can search by person's ID or their email address.
|
294
|
+
#
|
295
|
+
# * ixPerson: ID for the person to display
|
296
|
+
# * sEmail: Email address for the person to display.
|
297
|
+
#
|
298
|
+
# Note: If you specify both, Email search seems to take precedence.
|
299
|
+
#
|
300
|
+
# Value returned is a Hash of containing all properties of the located person. nil is returned for unsuccessful search.
|
301
|
+
def person(ixPerson=nil,sEmail=nil)
|
302
|
+
return nil if not ixPerson || sEmail
|
303
|
+
cmd = {"cmd" => "viewPerson", "token" => @token}
|
304
|
+
cmd = {"ixPerson" => ixPerson.to_s}.merge(cmd) if ixPerson
|
305
|
+
cmd = {"sEmail" => sEmail}.merge(cmd) if sEmail
|
306
|
+
result = Hpricot.XML(@connection.post(@api_url, to_params(cmd)).body)
|
307
|
+
return_value = list_process(result,"person","sFullName")
|
308
|
+
return_value[return_value.keys[0]]
|
309
|
+
end
|
310
|
+
|
311
|
+
# Creates a new Person within FogBugz.
|
312
|
+
#
|
313
|
+
# * sEmail: Email address of the new Person.
|
314
|
+
# * sFullname: Fullname of the new Person.
|
315
|
+
# * nType: Type for the new user. 0 = Normal User, 1 = Administrator, 2 = Community User, 3 = Virtual User
|
316
|
+
# * fActive: Is the new Person active? true/false
|
317
|
+
def new_person(sEmail,sFullname,nType,fActive=true)
|
318
|
+
cmd = {"cmd" => "newPerson", "token" => @token, "sEmail" => sEmail.to_s, "sFullname" => sFullname.to_s, "nType" => nType.to_s, "fActive" => (fActive) ? "1" : "0"}
|
319
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
320
|
+
return (result/"ixPerson").inner_html.to_i
|
321
|
+
end
|
322
|
+
|
194
323
|
# Returns a list of statuses for a particular category.
|
195
324
|
#
|
196
325
|
# * ixCategory => category to return statuses for. If not specified, then all are returned.
|
@@ -206,6 +335,18 @@ class FogBugz
|
|
206
335
|
return list_process(result,"status","sStatus")
|
207
336
|
end
|
208
337
|
|
338
|
+
# Returns details about a specific status
|
339
|
+
#
|
340
|
+
# * ixStatus: The id of the Status to view
|
341
|
+
#
|
342
|
+
# Value returned is a Hash containing all properties of the located Status. nil is returned for unsuccessful search.
|
343
|
+
def status(ixStatus)
|
344
|
+
cmd = {"cmd" => "viewStatus", "token" => @token, "ixStatus" => ixStatus.to_s}
|
345
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
346
|
+
return_value = list_process(result,"status","sStatus")
|
347
|
+
return_value[return_value.keys[0]]
|
348
|
+
end
|
349
|
+
|
209
350
|
# Returns a list of mailboxes that you have access to.
|
210
351
|
def mailboxes
|
211
352
|
cmd = {
|
@@ -218,6 +359,18 @@ class FogBugz
|
|
218
359
|
return list_process(result,"mailbox","ixMailbox")
|
219
360
|
end
|
220
361
|
|
362
|
+
# Returns details about a specific mailbox
|
363
|
+
#
|
364
|
+
# * ixMailbox: The id of the Mailbox to view
|
365
|
+
#
|
366
|
+
# Value returned is a Hash containing all properties of the located Mailbox. nil is returned for unsuccessful search.
|
367
|
+
def mailbox(ixMailbox)
|
368
|
+
cmd = {"cmd" => "viewMailbox", "token" => @token, "ixMailbox" => ixMailbox.to_s}
|
369
|
+
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
370
|
+
return_value = list_process(result,"mailbox","ixMailbox")
|
371
|
+
return_value[return_value.keys[0]]
|
372
|
+
end
|
373
|
+
|
221
374
|
# Searches for FogBugz cases
|
222
375
|
#
|
223
376
|
# * q: Query for searching. Should hopefully work just like the Search box
|
@@ -232,13 +385,9 @@ class FogBugz
|
|
232
385
|
# TODO - shoudl I worry about the "operations" returned
|
233
386
|
# in the <case>?
|
234
387
|
|
235
|
-
cmd = {
|
236
|
-
|
237
|
-
|
238
|
-
"q" => q,
|
239
|
-
# ixBug is the key for the hash returned so I'm adding it to the cols array just in case
|
240
|
-
"cols" => (cols + ["ixBug"]).join(",")
|
241
|
-
}
|
388
|
+
cmd = {"cmd" => "search","token" => @token,"q" => q, "cols" => cols.join(",")}
|
389
|
+
# ixBug is the key for the hash returned so I'm adding it to the cols array just in case
|
390
|
+
cmd = {"cols" => (cols + ["ixBug"])}.merge(cmd) if not cols.include?("ixBug")
|
242
391
|
cmd = {"max" => max}.merge(cmd) if max
|
243
392
|
result = Hpricot.XML(@connection.post(@api_url,to_params(cmd)).body)
|
244
393
|
return_value = list_process(result,"case","ixBug")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: austinmoody-fogbugz-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Moody
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2008-07-
|
13
|
+
date: 2008-07-09 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|