Make git cl patch authenticate the request for the diff.

This make possible to apply private issues or rietveld instances requiring
authentication.

Forces simplejson to be installed or uses python 2.6's json

Make local_rietveld.py usable standalone.

R=dpranke@chromium.org
TEST=unit tests + manual testing, owners.sh is currentl broken, unrelated to this change.
BUG=none

Review URL: http://codereview.chromium.org/6721031

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@79734 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_cl.py b/git_cl.py
index 6f2f561..3706830 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -337,6 +337,7 @@
     self.description = None
     self.has_patchset = False
     self.patchset = None
+    self._rpc_server = None
 
   def GetBranch(self):
     """Returns the short branch name, e.g. 'master'."""
@@ -464,6 +465,13 @@
              swallow_stderr=True, error_ok=True)
     self.has_patchset = False
 
+  def GetPatchSetDiff(self, issue):
+    # Grab the last patchset of the issue first.
+    data = json.loads(self._RpcServer().Send('/api/%s' % issue))
+    patchset = data['patchsets'][-1]
+    return self._RpcServer().Send(
+        '/download/issue%s_%s.diff' % (issue, patchset))
+
   def SetIssue(self, issue):
     """Set this branch's issue.  If issue=0, clears the issue."""
     if issue:
@@ -493,8 +501,10 @@
   def _RpcServer(self):
     """Returns an upload.RpcServer() to access this review's rietveld instance.
     """
-    server = self.GetRietveldServer()
-    return upload.GetRpcServer(server, save_cookies=True)
+    if not self._rpc_server:
+      server = self.GetRietveldServer()
+      self._rpc_server = upload.GetRpcServer(server, save_cookies=True)
+    return self._rpc_server
 
   def _IssueSetting(self):
     """Return the git setting that stores this change's issue."""
@@ -1220,23 +1230,16 @@
   if re.match(r'\d+', issue_arg):
     # Input is an issue id.  Figure out the URL.
     issue = issue_arg
-    server = settings.GetDefaultServerUrl()
-    fetch = urllib2.urlopen('%s/%s' % (server, issue)).read()
-    m = re.search(r'/download/issue[0-9]+_[0-9]+.diff', fetch)
-    if not m:
-      DieWithError('Must pass an issue ID or full URL for '
-          '\'Download raw patch set\'')
-    url = '%s%s' % (server, m.group(0).strip())
+    patch_data = Changelist().GetPatchSetDiff(issue)
   else:
     # Assume it's a URL to the patch. Default to http.
     issue_url = FixUrl(issue_arg)
     match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url)
-    if match:
-      issue = match.group(1)
-      url = issue_arg
-    else:
+    if not match:
       DieWithError('Must pass an issue ID or full URL for '
           '\'Download raw patch set\'')
+    issue = match.group(1)
+    patch_data = urllib2.urlopen(issue_arg).read()
 
   if options.newbranch:
     if options.force:
@@ -1251,7 +1254,6 @@
   if top:
     os.chdir(top)
 
-  patch_data = urllib2.urlopen(url).read()
   # Git patches have a/ at the beginning of source paths.  We strip that out
   # with a sed script rather than the -p flag to patch so we can feed either
   # Git or svn-style patches into the same apply command.