changeset 8:f71a067fe81a

add most of what is needed to post a new bug....getting there
author Jeff Hammel <jhammel@mozilla.com>
date Thu, 04 Nov 2010 16:23:35 -0700
parents 873a703555e9
children b350ae6fe3c9
files bzconsole/main.py bzconsole/utils.py
diffstat 2 files changed, 74 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/bzconsole/main.py	Tue Nov 02 12:50:28 2010 -0700
+++ b/bzconsole/main.py	Thu Nov 04 16:23:35 2010 -0700
@@ -3,30 +3,41 @@
 console API to bugzilla
 """
 
+import json
 import os
 import subprocess
 import sys
+import urllib
+import urllib2
 
 from command import CommandParser
+from utils import tmpbuffer
 
-import json
-import urllib
-import urllib2
 
 class BZapi(object):
     """
     console API to bugzilla
     """
 
-    def __init__(self, server='https://api-dev.bugzilla.mozilla.org/latest',
-                 username=None, password=None):
+    config_cache = '.bzconfiguration'
+    # XXX currently this is hard coded for one server
+
+    def __init__(self,
+                 server='https://api-dev.bugzilla.mozilla.org/latest',
+                 refresh=False,
+                 username=None,
+                 password=None):
+        """
+        - refresh : refresh the (cached) configuration        
+        """
         self.server = server
+        self.refresh = refresh
         self.username = username
         self.password = password
 
     def products(self, classification=None):
         """list bugzilla products"""
-        configuration = self._configuration()
+        configuration = self.configuration()
         if classification:
             products = [i for i in configuration['product'] if configuration['product'][i]['classification'] == 'Components']
             return sorted(products)
@@ -35,24 +46,68 @@
 
     def components(self, product):
         """list bugzilla components for a particular product"""
-        configuration = self._configuration()
+        configuration = self.configuration()
         assert product in configuration['product'], 'Product %s not found' % product
         return sorted(configuration['product'][product]['component'].keys())
 
-    def new(self, title, product, component):
-        raise NotImplementedError
+    def new(self, product, component, title, version=None):
+        """file a new bug"""
+
+        # sanity check
+        assert product in self.products(), "Product not found"
+        assert component in self.components(product), "Component not found"
+        assert title, 'Must provide a bug summary'
+        assert self.username and self.password, "Must be authenticated"
+
+        # infer version if not given
+        if version is None:
+            version = 'unspecified'
+        assert version in self._configuration['product'][product]['version'], 'Version not found'
+        
+        # get the bug description
+        description = tmpbuffer()
+        assert description, "Must provide a non-empty description"
 
-    def _configuration(self):
-        if not hasattr(self, '__configuration'):
-            self.__configuration = self._request('/configuration')
-        return self.__configuration
+        # create the needed data structure
+        request = dict(product=product, component=component,
+                       summary=title, version=version,
+                       comments=[description])
+        
+        import pdb; pdb.set_trace()
+
+    def configuration(self):
+        """bugzilla configuration"""
+        
+        if not hasattr(self, '_configuration'):
+            config_cache = os.path.join(os.environ['HOME'], self.config_cache)
+            if not self.refresh:
+                try:
+                    self._configuration = json.loads(file(config_cache).read())
+
+                except:
+                    pass
+            if not hasattr(self, '_configuration'):
+                self._configuration = self._request('/configuration')
+                f = file(config_cache, 'w')
+                print >> f, json.dumps(self._configuration)
+            self.refresh = False
+        return self._configuration
+
+    ### internal methods
 
     def _request(self, path, data=None):
         url = self.server + path
+        query = []
+        if self.username:
+            query.append(self.username)
+        if self.password:
+            query.append(self.password)
+        if query:
+            url += '?' + '&'.join(query) # TODO: urlencode this
         headers = {'Accept': 'application/json',
                    'Content-Type': 'application/json'}
         if data:
-            raise NotImplementedError
+            data = json.dumps(data)
         req = urllib2.Request(url, data, headers)
         response = urllib2.urlopen(req)
         the_page = response.read()
@@ -60,7 +115,6 @@
 
 def main(args=sys.argv[1:]):
     parser = CommandParser(BZapi)
-    options, args = parser.parse_args(args)
     parser.invoke(args)
 
 if __name__ == '__main__':
--- a/bzconsole/utils.py	Tue Nov 02 12:50:28 2010 -0700
+++ b/bzconsole/utils.py	Thu Nov 04 16:23:35 2010 -0700
@@ -1,3 +1,7 @@
+import os
+import subprocess
+import tempfile
+
 def tmpbuffer(editor=None):
     """open an editor and retreive the resulting editted buffer"""
     if not editor:
@@ -8,4 +12,4 @@
     edit = subprocess.call(cmdline)
     buffer = file(tmpfile).read().strip()
     os.remove(tmpfile)
-    return buffer
\ No newline at end of file
+    return buffer