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的更多相关文章

  1. .NET Core Web API使用HttpClient提交文件的二进制流(multipart/form-data内容类型)

    需求背景: 在需要通过服务端请求传递文件二进制文件流数据到相关的服务端保存时,如对接第三方接口很多情况下都会提供一个上传文件的接口,但是当你直接通过前端Ajax的方式将文件流上传到对方提供的接口的时候 ...

  2. [WinAPI] API 10 [创建、打开、读写文件,获取文件大小]

    在Windows系统中,创建和打开文件都是使用API函数CreateFile,CreateFile通过指定不同的参数来表示是新建一个文件,打开已经存在的文件,还是重新建立文件等.读写文件最为直接的方式 ...

  3. Git 怎么创建本地库,向本地库提交文件

    创建版本库是非常简单的,首先选择一个自己想放的位置,创建一个空目录: (用windows的git bash,这个工具的操作命令和linux下类似) $ mkdir gitRespository     ...

  4. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  5. Hadoop-1.2.1学习之Job创建和提交源码分析

    在Hadoop中,MapReduce的Java作业通常由编写Mapper和Reducer開始.接着创建Job对象.然后使用该对象的set方法设置Mapper和Reducer以及诸如输入输出等參数,最后 ...

  6. ASP.NET Web API 过滤器创建、执行过程(二)

    ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...

  7. ASP.NET Web API 过滤器创建、执行过程(一)

    ASP.NET Web API 过滤器创建.执行过程(一) 前言 在上一篇中我们讲到控制器的执行过程系列,这个系列要搁置一段时间了,因为在控制器执行的过程中包含的信息都是要单独的用一个系列来描述的,就 ...

  8. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  9. js实现无刷新表单提交文件,将ajax请求转换为form请求方法

    最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...

随机推荐

  1. Android开发——导入github安卓项目源码

    之前在Github上看见其他人的安卓项目源码,便是想下载源码来学习学习,但是下载之后一直导入失败,经过了漫长的摸索终于是成功了,便是分享一下经验 首先进入Github官网,找到想要学习的安卓源码 右上 ...

  2. 微信小程序教学第四章第二节(含视频):小程序中级实战教程:详情-视图渲染

    § 详情 - 数据渲染 本文配套视频地址: https://v.qq.com/x/page/x055550lrvd.html 开始前请把 ch4-2 分支中的 code/ 目录导入微信开发工具 这一节 ...

  3. 对Java中堆栈的解析

    Java把内存分为两种:一种是栈内存,一种是堆内存 栈内存:在函数中定义的一些基本类型的变量和对象的引用变量,当超过变量的作用域之后,Java自动释放该变量内存 堆内存:存放new创建的对象和数组,由 ...

  4. ABAP中的枚举对象

    枚举对象是枚举类型的数据对象.枚举对象只能包含类型为枚举类型的枚举值.ABAP从版本7.51开始支持它们. 这是一种常见的模式.在ABAP 7.51之前,人们通常用如下方式实现类似的功能: CLASS ...

  5. 页面重绘(repaint)和回流(reflow)

    前言 页面显示到浏览器上的过程: 1.1.生成一个DOM树. 浏览器将获取到的HTML代码解析成1个DOM树,包含了所有标签,包括display:none和动态添加的节点. 1.2.生成样式结构体. ...

  6. Scala 安装 Exception in thread "main" java.lang.VerifyError: Uninitialized object exists on backward branch 96

    windows下载安装完最新版本的Scala(2.12.4)后,终端如下错误 C:\Users\Administrator>scala -versionException in thread & ...

  7. caffe CuDNN报错问题解决

    解决cudnn问题:Loaded runtime CuDNN library: 5005 (compatibility version 5000) but source was compiled wi ...

  8. bzoj 4824: [Cqoi2017]老C的键盘

    Description 老 C 是个程序员.     作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序 在某种神奇力量的驱使之下跑得非常快.小 ...

  9. CSS3 文字与字体相关样式

    给文字添加阴影 文字换行 客户端文字 font-size-adjust属性 给文字添加阴影-text-shadow属性 text-shadow:length length length color 前 ...

  10. 2.移植uboot-添加2440单板,并实现NOR、NAND启动

    上章分析了uboot启动流程后,接下来便来配置新的单板,实现nor.nand启动 1.首先在uboot里新建单板2440 : cd board/samsung/ cp smdk2410 smdk244 ...