Changeset 2a85ddb94365…
Parent a48e85fe1ac2…
by Tyler G. Hicks-Wright <tghw@fogcreek.com>
Changes to 2 files · Browse files at 2a85ddb94365 Showing diff from parent a48e85fe1ac2 Diff from another changeset...
@@ -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
|
@@ -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]
+
|
Loading...