FogBugz » FogBugzPy A Python wrapper for the FogBugz API Read More
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.9.1, 0.9.2, and 0.9.3

Fix CData and add notes to readme.

Changeset 2a85ddb94365

Parent a48e85fe1ac2

by Profile picture of User 10Tyler G. Hicks-Wright <tghw@fogcreek.com>

Changes to 2 files · Browse files at 2a85ddb94365 Showing diff from parent a48e85fe1ac2 Diff from another changeset...

Change 1 of 1 Show Entire File README.txt Stacked
 
31
32
33
 
 
34
35
36
 
31
32
33
34
35
36
37
38
@@ -31,6 +31,8 @@
 >>> resp  <response><case ixbug="1" operations="edit,assign,resolve,email,remind"></case></response>   +Note that, per API v5.0, all data between tags, such as the token, is now wrapped in CDATA. BeautifulSoup's implementation of CData generally allows for it to be treated as a string, except for one important case: CData.__str__() (a.k.a. str(CData)) returns the full text, including the CDATA wrapper (e.g. "<![CDATA[foo]]>"). To avoid accidentally including the CDATA tage, use CData.encode('utf-8') +  For more info on the API:  http://our.fogbugz.com/help/topics/advanced/API.html  
Change 1 of 1 Show Entire File fogbugz.py Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
@@ -1,83 +1,83 @@
-import urllib -import urllib2 - -from BeautifulSoup import BeautifulSoup - -class FogBugzAPIError(Exception): - pass - -class FogBugzLogonError(FogBugzAPIError): - pass - -class FogBugzConnectionError(FogBugzAPIError): - pass - -class FogBugz: - def __init__(self, url): - self.__handlerCache = {} - if not url.endswith('/'): - url += '/' - - self._token = None - self._opener = urllib2.build_opener() - try: - soup = BeautifulSoup(self._opener.open(url + 'api.xml')) - except URLError: - raise FogBugzConnectionError("Library could not connect to the FogBugz API. Either this installation of FogBugz does not support the API, or the url, %s, is incorrect." % (self._url,)) - self._url = url + soup.response.url.string - self.currentFilter = None - - def logon(self, username, password): - """ - Logs the user on to FogBugz. - - Returns None for a successful login, otherwise returns a list - of logins to choose from if the username provided is - ambiguous. - """ - if self._token: - logoff() - try: - response = self.__makerequest('logon', email=username, password=password) - except FogBugzAPIError, e: - raise FogBugzLogonError(e) - - self._token = response.token.string - - def logoff(self): - """ - Logs off the current user. - """ - self.__makerequest('logoff') - self._token = None - - def __makerequest(self, cmd, **kwargs): - kwargs["cmd"] = cmd - if self._token: - kwargs["token"] = self._token - try: - response = BeautifulSoup(self._opener.open(self._url+urllib.urlencode(kwargs))).response - except urllib2.URLError, e: - raise FogBugzConnectionError(e) - if response.error: - raise FogBugzAPIError('Error Code %s: %s' % (response.error['code'], response.error.string,)) - return response - - def __getattr__(self, name): - """ - Handle all FogBugz API calls. - - >>> fb.logon(email@example.com, password) - >>> response = fb.search(q="assignedto:email") - """ - - # Let's leave the private stuff to Python - if name.startswith("__"): - raise AttributeError("No such attribute '%s'" % name) - - if not self.__handlerCache.has_key(name): - def handler(**kwargs): - return self.__makerequest(name, **kwargs) - self.__handlerCache[name] = handler - return self.__handlerCache[name] - \ No newline at end of file
+import urllib +import urllib2 + +from BeautifulSoup import BeautifulSoup, CData + +class FogBugzAPIError(Exception): + pass + +class FogBugzLogonError(FogBugzAPIError): + pass + +class FogBugzConnectionError(FogBugzAPIError): + pass + +class FogBugz: + def __init__(self, url): + self.__handlerCache = {} + if not url.endswith('/'): + url += '/' + + self._token = None + self._opener = urllib2.build_opener() + try: + soup = BeautifulSoup(self._opener.open(url + 'api.xml')) + except URLError: + raise FogBugzConnectionError("Library could not connect to the FogBugz API. Either this installation of FogBugz does not support the API, or the url, %s, is incorrect." % (self._url,)) + self._url = url + soup.response.url.string + self.currentFilter = None + + def logon(self, username, password): + """ + Logs the user on to FogBugz. + + Returns None for a successful login. + """ + if self._token: + self.logoff() + try: + response = self.__makerequest('logon', email=username, password=password) + except FogBugzAPIError, e: + raise FogBugzLogonError(e) + + self._token = response.token.string + if type(self._token) == CData: + self._token = self._token.encode('utf-8') + + def logoff(self): + """ + Logs off the current user. + """ + self.__makerequest('logoff') + self._token = None + + def __makerequest(self, cmd, **kwargs): + kwargs["cmd"] = cmd + if self._token: + kwargs["token"] = self._token + try: + response = BeautifulSoup(self._opener.open(self._url+urllib.urlencode(kwargs))).response + except urllib2.URLError, e: + raise FogBugzConnectionError(e) + if response.error: + raise FogBugzAPIError('Error Code %s: %s' % (response.error['code'], response.error.string,)) + return response + + def __getattr__(self, name): + """ + Handle all FogBugz API calls. + + >>> fb.logon(email@example.com, password) + >>> response = fb.search(q="assignedto:email") + """ + + # Let's leave the private stuff to Python + if name.startswith("__"): + raise AttributeError("No such attribute '%s'" % name) + + if not self.__handlerCache.has_key(name): + def handler(**kwargs): + return self.__makerequest(name, **kwargs) + self.__handlerCache[name] = handler + return self.__handlerCache[name] +