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.
Files changed (4) hide show
  1. data/README.rdoc +23 -13
  2. data/TODO +0 -11
  3. data/lib/fogbugz-api.rb +159 -10
  4. metadata +2 -2
@@ -1,28 +1,38 @@
1
1
  = Ruby FogBugz API Wrapper
2
2
 
3
- My attempt at creating a wrapper for the FogBugz API in Ruby.
3
+ An attempt at creating a wrapper for the FogBugz API in Ruby.
4
4
 
5
- More about FogBugz: http://www.fogbugz.com
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
- This is very much a work in progress. Any questions, concerns, or if you want to help out please e-mail me: austin.moody@gmail.com
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
- GEM coming soon hopefully. For now nab the fogbugz-api.rb file and require in your Ruby script.
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
- fb = FogBugz.new("my.fogbugz.com",true)
23
-
24
- fb.logon("me@email.com","mypassword")
25
-
26
- case_search = fb.search("API errors")
27
-
28
- fb.logoff
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
@@ -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/"version").inner_html.to_i
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
- "cmd" => "search",
237
- "token" => @token,
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.3
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-03 00:00:00 -07:00
13
+ date: 2008-07-09 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency