Phabricator API Go 创建task/提交文件到Phabricator
Go Phabricator API 代码/程序创建task/提交文件到Phabricator
Creat Task or upload file to phabricator with code in go
之前写一个服务往phabricator 上提交task,上传文件;当时查了好久,发现官方文档很不明确,而网上又几乎没有资料,所以把最终写的整理一下给需要的做一个参考。
Several days ago,I have writing a service to submit tasks or upload files to the phabricator.At that time , search for a long time, found that the official document is not very clear, and almost no information on the Internet, so share something about this.
upload file/image or other info to phabricator by program in Go
Go语言,通过程序往phabricator上传文件/图片,新建task.
最终是要在phabricator上提交一个task,func3,通过调用调用func1,上传一个file,通过func2,获取这个file的id。在func3中创建task的时候,可以通过“F【 + id】”的格式引用这个文件或者图片。
The final target is to submit a task to the phabricator. Func3, by calling func1 upload a file, through func2, get the id of this file. In the func3 create a task, you can use "F [+ id]" format to quoted the file(or picture).
上传文件
upload file
注意 phabricator接收base64数据,而且不要开头的格式声明部分,即只要“,”后边的。
Pay attention,phabricator receive a data of base64 format,and deny the chars befor ",".
//1,文件上传:file.upload ,拿回来phid;在task里可以通过phid引用。
//1,upload file. api:file.upload. Get back the phid of this file which can be quoted in a task page。
func UploadFile(imageBase64List [imageMaxNum]string) ([]string, error) {
phidList := make([]string, 0)
urlStr := "https://ph.com/api/file.upload"
for _, imageBase64 := range imageBase64List {
if imageBase64 == "" {
continue
}
//截取“,”后边的字符串,
//Get chars after ","
imageData := strings.Split(imageBase64, ",")
if len(imageData) != 2 || !utils.JudgeBase64(imageData[1]) {
return phidList, errors.New("图片数据格式错误")
}
form := url.Values{}
form.Add("data_base64", imageData[1])
req, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(form.Encode()))
q := req.URL.Query()
q.Set("api.token", common.Config.ApiToken)
req.URL.RawQuery = q.Encode()
req.Header.Add("content-type", "application/x-www-form-urlencoded")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return phidList, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return phidList, err
}
//解析body,并且添加到切片
//Unmarshal body and add to slice
var uploadResp UploadFileResp
if err := json.Unmarshal(body, &uploadResp); err != nil {
err := errors.New("文件上传时发生未知错误:" + err.Error())
return phidList, err
}
phidList = append(phidList, uploadResp.Result)
}
return phidList, nil
}
根据文件的phid获取id
get the id of file by phid
// 2,获取文件/图片id:file.info 拿回来一个file id
// 2,get the id of file/image though file.info .
func getImageId(phidList []string) (imageIdlist []string, err error) {
imageIdList := make([]string, 0)
urlStr := "https://ph.com/api/file.info"
for _, phid := range phidList {
if phid == "" {
continue
}
form := url.Values{}
form.Add("phid", phid)
req, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(form.Encode()))
req.Header.Add("content-type", "application/x-www-form-urlencoded")
q := req.URL.Query()
q.Set("api.token", common.Config.ApiToken)
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
return imageIdList, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return imageIdList, err
}
var findImageResp FindImageIdResp
if err := json.Unmarshal(body, &findImageResp); err != nil {
err := errors.New("获取文件信息时发生未知错误" + err.Error())
return imageIdList, err
}
imageIdList = append(imageIdList, findImageResp.Result.ObjectName)
}
return imageIdList, nil
}
入口函数
entrance func
conduit api 测试页面参数示例
conduit pages api test parameters example
[ { "type":"title", "value":"Test API in conduit" },
{ "type":"view", "value":"users" },
{ "type":"projects.add", "value":["bug_管理","生 产环境"] },
{ "type":"description", "value":"Nothing , need not to be concerned. " },
{ "type":"priority", "value":"low"},
{ "type":"custom.mq.customer_id_and_name","value":"coustomId and name"}
]
接收参数,并调用fun1、fun2,最终提交task。
Get parameters ,call func1、func2,submit a task at last。
// 3,接收bug信息,上传文件/图片,获取文件id,提交bug信息,返回提示信息。
// 3,receive the infomation from pages,get the id of file/image ,submit info and sendback tips.
func ReceiptBugInfo(w http.ResponseWriter, r *http.Request) {
var reqInfo ReceiptBugInfoRequest
if err := utils.BindJSON(r, &reqInfo); err != nil {
render.BindError(w, r, err)
return
}
desc := reqInfo.Desc + "\n\n终端信息:" + reqInfo.EndPointInfo + "\nbug提交位置参考路径:" + reqInfo.BugPageUrl
customIdAndName := "用户名:" + reqInfo.CustomerName + " 用户ID:" + reqInfo.CustomerId + " 租户ID" + reqInfo.TenantId
desc += "\n" + customIdAndName + "\n"
//检查,不为空则调用getImgId,并拼入desc
if reqInfo.ImagesData[0] != "" {
phidList, err := UploadFile(reqInfo.ImagesData)
if err != nil {
render.InternalError(w, r, err)
}
imageIdSlice, err := getImageId(phidList)
if err != nil {
render.InternalError(w, r, err)
}
for _, images := range imageIdSlice {
if images == "" {
break
}
desc += "\nbug截图:\n{" + images + "}"
}
}
urlStr := "https://ph.com/api/maniphest.edit"
form := url.Values{}
form.Add("transactions[0][type]", "title")
form.Add("transactions[0][value]", reqInfo.Title)
form.Add("transactions[1][type]", "description")
form.Add("transactions[1][value]", desc)
form.Add("transactions[2][type]", "priority")
form.Add("transactions[2][value]", reqInfo.Priority)
form.Add("transactions[3][type]", "projects.add")
form.Add("transactions[3][value][0]", "bug_管理")
form.Add("transactions[3][value][1]", "生产环境")
form.Add("transactions[4][type]", "space")
form.Add("transactions[4][value]", "PHID-SPCE-cnulhg6i3r4m5evgb4wc")
req, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(form.Encode()))
req.Header.Add("content-type", "application/x-www-form-urlencoded")
q := req.URL.Query()
q.Set("api.token", common.Config.ApiToken)
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
render.InternalNetError(w, r, err)
}
defer resp.Body.Close()
//解析这个body,error不为空则报错,图片上传.
//Unmarshal body,if error is not nil,panic.else upload file/image.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
render.InternalError(w, r, err)
return
}
var bugInfoResp BugInfoUploadResp
if err := json.Unmarshal(body, &bugInfoResp); err != nil {
error := errors.New("解析反馈信息时发生未知错误" + err.Error())
render.InternalError(w, r, error)
return
}
if bugInfoResp.ErrorCode != "" {
err := errors.New("提交信息时发生未知错误" + bugInfoResp.ErrorInfo)
render.InternalError(w, r, err)
return
}
render.Success(w, r)
}
结构体定义如下
definition struct as below
type BugInfoUploadResp struct {
Result BugRespResult `json:"result" binding:"omitempty`
ErrorCode string `json:"error_code" binding:"omitempty`
ErrorInfo string `json:"error_info" binding:"omitempty`
}
type BugRespResult struct {
Object BugRespObject `json:"object" binding:"omitempty`
Transactions Phids `json:"transactions" binding:"omitempty`
}
type BugRespObject struct {
Id int `json:"id" binding:"omitempty`
Phid string `json:"phid" binding:"omitempty`
}
type Phids []Phid
type Phid struct {
Phid string `json:"phid" binding:"omitempty`
}
type UploadFileResp struct {
Result string `json:"result" binding:"omitempty`
ErrorCode string `json:"error_code" binding:"omitempty`
ErrorInfo string `json:"error_info" binding:"omitempty`
}
type FindImageIdResp struct {
Result ImgIdRespInfo `json:"result" binding:"omitempty`
ErrorCode string `json:"error_code" binding:"omitempty`
ErrorInfo string `json:"error_info" binding:"omitempty`
}
type ImgIdRespInfo struct {
Id string `json:"id" binding:"omitempty"`
Phid string `json:"phid" binding:"omitempty"`
ObjectName string `json:"objectName" binding:"omitempty"`
Name string `json:"name" binding:"omitempty"`
MimeType string `json:"mimeType" binding:"omitempty"`
ByteSize string `json:"byteSize" binding:"omitempty"`
AuthorPHID string `json:"authorPHID" binding:"omitempty"`
DateCreated string `json:"dateCreated" binding:"omitempty"`
DateModified string `json:"dateModified" binding:"omitempty"`
Uri string `json:"uri" binding:"omitempty"`
}
type ReceiptBugInfoRequest struct {
TenantId string `json:"tenantId" binding:"required"`
CustomerName string `json:"customerName" binding:"required"`
CustomerId string `json:"customerId" binding:"required"`
Desc string `json:"desc" binding:"required"`
Title string `json:"title" binding:"required"`
Priority string `json:"priority" binding:"required"`
EndPointInfo string `json:"endPointInfo" binding:"required"`
BugPageUrl string `json:"bugPageUrl" binding:"omitempty`
ImagesData ImageList `json:"imageData" binding:"omitempty"`
}
type ImageList [imageMaxNum]string
//反馈,图片最大支持数目。
//feedback,the max number of image
const imageMaxNum = 10
转载注明出处----名白
http://www.cnblogs.com/mingbai/p/GoPhabricator.html
Phabricator API Go 创建task/提交文件到Phabricator的更多相关文章
- .NET Core Web API使用HttpClient提交文件的二进制流(multipart/form-data内容类型)
需求背景: 在需要通过服务端请求传递文件二进制文件流数据到相关的服务端保存时,如对接第三方接口很多情况下都会提供一个上传文件的接口,但是当你直接通过前端Ajax的方式将文件流上传到对方提供的接口的时候 ...
- [WinAPI] API 10 [创建、打开、读写文件,获取文件大小]
在Windows系统中,创建和打开文件都是使用API函数CreateFile,CreateFile通过指定不同的参数来表示是新建一个文件,打开已经存在的文件,还是重新建立文件等.读写文件最为直接的方式 ...
- Git 怎么创建本地库,向本地库提交文件
创建版本库是非常简单的,首先选择一个自己想放的位置,创建一个空目录: (用windows的git bash,这个工具的操作命令和linux下类似) $ mkdir gitRespository ...
- ASP.NET Web API 控制器创建过程(一)
ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...
- Hadoop-1.2.1学习之Job创建和提交源码分析
在Hadoop中,MapReduce的Java作业通常由编写Mapper和Reducer開始.接着创建Job对象.然后使用该对象的set方法设置Mapper和Reducer以及诸如输入输出等參数,最后 ...
- ASP.NET Web API 过滤器创建、执行过程(二)
ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...
- ASP.NET Web API 过滤器创建、执行过程(一)
ASP.NET Web API 过滤器创建.执行过程(一) 前言 在上一篇中我们讲到控制器的执行过程系列,这个系列要搁置一段时间了,因为在控制器执行的过程中包含的信息都是要单独的用一个系列来描述的,就 ...
- ASP.NET Web API 控制器创建过程(二)
ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...
- js实现无刷新表单提交文件,将ajax请求转换为form请求方法
最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...
随机推荐
- 【python】递归(阶乘、斐波纳契、汉诺塔)
- [array] leetcode - 54. Spiral Matrix - Medium
leetcode-54. Spiral Matrix - Medium descrition GGiven a matrix of m x n elements (m rows, n columns) ...
- MySQL数据库 Event 定时执行任务.
一.背景 由于项目的业务是不断往前跑的,所以难免数据库的表的量会越来越庞大,不断的挤占硬盘空间.即使再大的空间也支撑不起业务的增长,所以定期删除不必要的数据是很有必要的.在我们项目中由于不清理数据,一 ...
- http性能测试工具wrk源码学习之开篇
1.前言 最近工作需要测试nginx反向代理的性能,于是找了一些http测试工具,例如经典的Apache的ab.siege.wrk.wrk使用多线程事件驱动方式,支持lua脚本扩展.关于wrk介绍可以 ...
- bzoj 1150: [CTSC2007]数据备份Backup
Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...
- java-FFmpeg(一) 实现视频的转码和截图功能
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...
- 正则表达式与grep
一.回溯引用 1.将页面中合法的标题找出来,使用回溯引用匹配 (需要使用 -E 或 -P 来扩展grep语法支持) 2.查找连续出现的单词 二.前后查找 (grep 只能使用 -P 选项) 1. 向前 ...
- 不写一行代码,利用常用工具和软件批量下载URL资源
有时候会遇到这种情况:想从某个网站下载一批东西,目标URL是比较规整的,而且结构都一样(仅某些字段不同).但又懒得开IDE专门写个脚本去弄,今天就和大家分享一下,如何利用手边常用的软件和工具,不用写一 ...
- 跟我一起学JQuery插件开发教程
在逛codeproject网站的时候,突然看到一篇文章:How to write plugin in Jquery. 如果对E文好的同学 ,可以看上面的连接.现在我把上面网站的及结合自己的想法写这篇文 ...
- 关于recycleview 滑动item变长(item变形)问题
昨天在做项目的时候出现了bug,表现是在滑动的时候,整个item会被拉长了,松手后就回归正常大小了, 出现这个的主要原因是因为你的item布局中最大的那个根布局是 match_parent状态,因此导 ...