Question

I have been struggling to post a diff to ReviewBoard through their API. I've managed to login to the server and create a new post, but I've failed to post correctly the contents of the diff file.

I'm new to writing this kind of application, but my goal is to have a one step script to:

  1. diff a file (pre-commit) with the svn repository,
  2. add a review request to ReviewBoard and post the diff from the current file,

May be later, the script can be part of a svn pre-commit hook.

My python attempt looks like:

import urllib.request
import urllib.parse
import os.path

... login to the reviewboard server with
urllib.request.HTTPBasicAuthHandler ...

diff_path = '/path/to/file'
diff_name = 'my.diff'
diff_path = os.path.join(diff_path, diff_name)

diff_val = open(diff_path,'r')

# load the diff into the http data POST request
diff_header =                                                    \
     '-- SoMe BoUnDaRy   \n'                                     \
  +  'Content-Disposition: form-data; name=path; filename='      \
  +  '"' + diff_name + '"\n\n'                                   \
  +  diff_val.read()  + '\n'                                     \
  +  '-- SoMe BoUnDaRy --'

data ={'path': diff_header, 'basedir': '/path/to/file/in/rep'}
print( data['path'] )
data = urllib.parse.urlencode(data)
data = data.encode('utf-8')

opener.open(                                      \
    'http://xxx.xxx.x.xxx/api/review-requests/26/diffs/', data)

With this code I get a BAD REQUEST(400) error, specifically: "One or more fields had errors" (105).

I'm aware that there are some libraries out there that can talk with the ReviewBoard API. I'm also aware that post-review exists. I'd rather not have to distribute to the other developers another python library and post-review seems less flexible when diffing files from multiple locations.

From the suggestion below, I've add the server response here:

CREATING PASSWD MANAGER...
CREATING PASSWD MANAGER... done
CREATING PASSWD HANDLER...
CREATING PASSWD HANDLER... done
CREATING URL OPENER...
CREATING URL OPENER... done
LOADING DIFF... 
send: b'POST /api/review-requests/26/diffs/ HTTP/1.1\r\nAccept-Encoding: 
  identity\r\nContent-Length: 723\r\nHost: xxx.xxx.x.xxx\r\nContent-Type: 
  application/x-www-form-urlencoded\r\nConnection: close\r\nUser-Agent: 
  [empty no username+password] Python-urllib/3.2\r\n\r\
  npath=--+SoMe+BoUnDaRy+++%...[the rest of my post]
reply: 'HTTP/1.1 401 UNAUTHORIZED\r\n'
header: Date header: Server header: Content-Language header: Expires header: 
  Vary header: Cache-Control header: WWW-Authenticate header: 
  Content-Length header: Last-Modified header: Connection header: 
  Content-Type send: b'POST /api/review-requests/26/diffs/ 
  HTTP/1.1\r\nAccept-Encoding: identity\r\nContent-Length: 723\r\nHost: 
  xxx.xxx.x.xxx\r\nUser-Agent: Python-urllib/3.2\r\nConnection: 
  close\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: 
  Basic [with username+password]\r\n\r\npath=
  --+SoMe+BoUnDaRy+++%0AContent-Disposition%...
reply: 'HTTP/1.1 400 BAD REQUEST\r\n'
header: Date header: Server header: Content-Language header: Expires header: 
  Vary header: Cache-Control header: Set-Cookie header: Content-Length header: 
  Last-Modified header: Connection header: Content-Type HTTPError thrown

At first glance my guess is that something is happening to my password handler. I'm not sure what is happening to it. Just in case, this is how I'm generate my authentication:

manager_passwd = urllib.request.HTTPPasswordMgr()
manager_passwd.add_password(...)
handler_passwd = urllib.request.HTTPBasicAuthHandler(manager_passwd)
opener = urllib.request.build_opener(handler_passwd)

The authentication seems to working. I've tested it by create a new review post. So it is when I post the diff that the authentication fails.

Was it helpful?

Solution

Reviewboard have already a python tool for posting diff with their API, it's called postreview.py. You can found it at :

http://reviewboard.googlecode.com/svn/trunk/wxpostreview/postreview.py

Grab and use their ReviewBoardServer for login and post a diff !

(In addition, in your request, the authentification is required yes, but also the cookie file. That's why you need 2 requests (one for login and get the cookie, another one for sending the diff.))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top