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. ios 中的循环引用问题及解决

    循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存.其实有点类似死锁. 举个例子:A->B->C->....->X->B   - ...

  2. StreamCQL编写jstorm拓扑任务入门

    一,什么是 StreamCQL StreamCQL(Stream Continuous Query Language)是一个类似SQL的声明式语言, 目的是在流计算平台(目前也就是jstrom)的基础 ...

  3. 入门级Nginx反向代理nodejs

    本着想实现前后端分离开发的初衷,我决定学习一下关于nignx反向代理的配置. 1.下载Nginx稳定版本 2.打开nginx配置文件 nginx.conf: 3.在http模块的server部分配置 ...

  4. Python图片爬虫

    1.今天给大家介绍自己写的一个图片爬虫,说白了就是从网页自动上下载需要的图片 2.首先选取目标为:http://www.zhangzishi.cc/涨姿势这个网站如下图,我们的目标就是爬取该网站福利社 ...

  5. kafka 消费​

    前置资料  kafka kafka消费中的问题及解决方法: 情况1: 问题:脚本读取kafka 数据,写入到数据库,有时候出现MySQL server has gone away,导致脚本死掉.再次启 ...

  6. K:线性表的实现—链表

    单链表的概念:  采用链式存储方式存储的线性表称之为链表,链表中每个节点包含存放数据元素的值的数据域和存放指向逻辑上相邻节点的指针域.若一个节点中只包含一个指针域,则称此链表为单链表. 单链表的特点: ...

  7. 如何用Visio画venn(维恩)图

    今天需要换几个Venn(维恩)图,按照以前的套路是用画图工具来画的,但是这次不是画给自己看,并且也要很迅速的画好,那就迅速的来学习了. 参考网址:https://support.office.com/ ...

  8. LeetCode题目总结(三)

    我的代码在github上,https://github.com/WINTERFELLS/LeetCode-Answers 这里只提供个人的解题思路,不一定是最好的. 41-60: 给定一个排好序的数组 ...

  9. 记一次Hbase查询速度优化经历

    项目背景: 在这次影像系统中,我们利用大数据平台做的是文件(图片.视频等)批次的增删改查,每个批次都包含多个文件,上传完成以后要添加文件索引(文件信息及批次信息),由于在Hbase存储的过程中,每个文 ...

  10. golang map

    Our friend Monk has been made teacher for the day today by his school professors . He is going to te ...