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表单提交文件时页面刷新的 ...
随机推荐
- 《分布式系统原理介绍》【PDF】下载
内容简介 分布式系统理论体系非常庞大,涉及知识面也非常广博,本文精心选择了部分在工程实践中应用广泛.简单有效的分布式理论.算法.协议加以介绍.全文分为两大部分,第一部分介绍了分布式系统的一些基本概念并 ...
- 微信小程序教学第三章(含视频):小程序中级实战教程:列表-页面逻辑处理
§ 页面逻辑处理 本文配套视频地址: https://v.qq.com/x/page/n0554dndrez.html 开始前请把 ch3-2 分支中的 code/ 目录导入微信开发工具 修改 ind ...
- Linux配置文件注释注意:行首注释,不要行中注释
正确注释: # 注释语句 错误注释:这种注释可能导致文件读取异常或报错 有效语句 # 注释语句 # 注释语句
- php--php调java接口验签
<?php namespace Fmall_cloud\Model; use Think\Model; class DealJavaModel extends Model { /** * @ti ...
- ES6异步操作Thunk、co和async
使用Thunk函数对Generator函数进行流程管理,首先什么是Thunk函数?我们应该先说下参数的求值策略,编译器的求值策略一个是"传值调用"另一个是"传名调用&qu ...
- Python 项目实践三(Web应用程序)第一篇
一 Djangao入门 当今的网站实际上都是富应用程序(rich application),就像成熟的桌面应用程序一样.Python提供了一组开发Web应用程序的卓越工具.在本章中,你将学习如何使用D ...
- ES6 let和const命令(3)
const 用来声明常量.一旦声明,就不能改变. const在声明必须初始化,只声明不赋值会出错 const的作用域与let一样,只在声明的块级作用域有效. const命令声明的常量也不提升,同样存在 ...
- Expression Blend4安装破解
先在官网上下载Expression Blend4试用版 首先进入微软下载中心,http://www.microsoft.com/zh-cn/download/default.aspx: 搜索Expre ...
- [编织消息框架][netty源码分析]1分析切入点
在分析源码之前有几个疑问 1.BOSS线程如何转交给handle(业务)线程2.职业链在那个阶段执行3.socket accept 后转给上层对象是谁4.netty控流算法 另外要了解netty的对象 ...
- KandQ:单例模式的七种写法及其相关问题解析
设计模式中的单例模式可以有7种写法,这7种写法有各自的优点和缺点: 代码示例(java)及其分析如下: 一.懒汉式 public class Singleton { private static Si ...