def getCategories(self, blogid, username, password):
     """See IMetaWeblogAPI.
     """
     weblog = IUIDManager(self.context).getByUID(blogid)
     weblog = IWeblog(weblog)
     topics = weblog.getTopics()
     # 2005-12-13 tomster:
     # this is kind of ugly: according to the RFC we should return an array
     # of structs, but according to http://typo.leetsoft.com/trac/ticket/256
     # (at least) MarsEdit and ecto expect an array of strings containing the
     # category id.
     # Nigel: To accommodate ecto and other blogging clients we are going to
     # do this test to decide what format the topics should be returned in
     useragent = self.request['HTTP_USER_AGENT']
     if "ecto" in useragent or "Mars" in useragent:
         #self.plone_log("MetaWeblogAPI", "Using ecto/MarsEdit hack")
         categories = [topic.getId() for topic in topics]
     else:
         categories = []
         for topic in topics:
              categories.append(
                  {'description' : topic.getId(),
                   'htmlUrl' : topic.absolute_url(),
                   'rssUrl' : '%s/rss.xml' % topic.absolute_url(),
                  })
     return categories