如何通过API向ReviewBoard提交差异?

6 投票
1 回答
2153 浏览
提问于 2025-04-17 06:37

我一直在尝试通过ReviewBoard的API提交一个差异文件(diff),但遇到了困难。我已经成功登录到服务器并创建了一个新的帖子,但在正确提交差异文件的内容时失败了。

我对写这种应用程序还不太熟悉,但我的目标是写一个一步到位的脚本,来:

  1. 将一个文件(提交前)与svn仓库进行比较,
  2. 向ReviewBoard添加一个审核请求,并提交当前文件的差异,

以后,这个脚本可能会成为svn提交前的一个钩子。

我用Python写的代码如下:

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)

使用这段代码时,我遇到了一个错误,提示是BAD REQUEST(400),具体内容是:“一个或多个字段有错误”(105)。

我知道有一些库可以与ReviewBoard的API进行交互。我也知道有post-review这个工具。但我不想让其他开发者再去安装另一个Python库,而且post-review在处理来自多个位置的文件差异时似乎不够灵活。

根据下面的建议,我把服务器的响应添加在这里:

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

乍一看,我猜我的密码处理程序可能出了问题。我不太确定发生了什么。为了保险起见,这是我生成身份验证的方式:

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

身份验证似乎是有效的。我通过创建一个新的审核帖子进行了测试。所以在我提交差异时,身份验证才失败。

1 个回答

2

Reviewboard已经有一个用Python写的工具,可以通过他们的API来发布代码差异,这个工具叫做postreview.py。你可以在这里找到它:

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

下载这个工具,然后用它的ReviewBoardServer来登录和发布代码差异!

(另外,在你的请求中,确实需要身份验证,但还需要一个cookie文件。这就是为什么你需要发两个请求(一个是登录并获取cookie,另一个是发送代码差异)。)

撰写回答