2018-08-21 08:50:30 +00:00
|
|
|
package main
|
|
|
|
|
2019-08-23 10:23:33 +00:00
|
|
|
import "github.com/davecgh/go-spew/spew"
|
|
|
|
|
2018-08-21 08:57:59 +00:00
|
|
|
import (
|
2018-08-22 10:29:14 +00:00
|
|
|
"bytes"
|
2018-08-22 00:39:08 +00:00
|
|
|
"fmt"
|
2018-11-23 12:22:03 +00:00
|
|
|
// "github.com/adlio/trello"
|
2019-08-23 10:23:33 +00:00
|
|
|
|
2018-11-23 12:22:03 +00:00
|
|
|
trello "github.com/glenux/contrib-trello"
|
2018-11-22 16:24:19 +00:00
|
|
|
"github.com/russross/blackfriday/v2"
|
2018-08-22 10:34:33 +00:00
|
|
|
"log"
|
2018-08-22 00:39:08 +00:00
|
|
|
"net/url"
|
2018-12-27 13:14:31 +00:00
|
|
|
"os"
|
2018-08-21 08:57:59 +00:00
|
|
|
"os/exec"
|
2018-12-27 13:14:31 +00:00
|
|
|
"path"
|
2018-08-22 00:39:08 +00:00
|
|
|
"strings"
|
2018-11-23 11:41:16 +00:00
|
|
|
"text/template"
|
2018-08-21 23:50:50 +00:00
|
|
|
)
|
|
|
|
|
2018-08-21 17:21:46 +00:00
|
|
|
type TrelloCtx struct {
|
2018-08-21 23:50:50 +00:00
|
|
|
Token string
|
2019-09-04 05:35:49 +00:00
|
|
|
ApiKey string
|
2018-08-21 23:50:50 +00:00
|
|
|
Client *trello.Client
|
2018-08-21 17:21:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type TrelloBoard struct {
|
2018-11-23 12:22:03 +00:00
|
|
|
Ctx *TrelloCtx
|
|
|
|
Ptr *trello.Board
|
|
|
|
Starred bool
|
|
|
|
Closed bool
|
|
|
|
Name string
|
2018-08-21 17:21:46 +00:00
|
|
|
}
|
|
|
|
|
2018-08-21 08:57:59 +00:00
|
|
|
func runcmd(command string) string {
|
|
|
|
shell := "/bin/sh"
|
|
|
|
flag := "-c"
|
|
|
|
|
|
|
|
out, err := exec.Command(shell, flag, command).Output()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(out)
|
|
|
|
}
|
|
|
|
|
2019-09-04 05:35:49 +00:00
|
|
|
func MessageForApiKey() string {
|
|
|
|
/*
|
|
|
|
url := strings.Join([]string{
|
|
|
|
"https://trello.com/1/authorize?expiration=never",
|
|
|
|
"name=Trello-To-Mail",
|
|
|
|
"scope=read",
|
|
|
|
"response_type=token",
|
|
|
|
fmt.Sprintf("key=%s", apiKey),
|
|
|
|
}, "&")
|
|
|
|
*/
|
|
|
|
|
|
|
|
url := "https://trello.com/app-key/"
|
|
|
|
|
|
|
|
text := strings.Join([]string{
|
|
|
|
"Wrong or empty TRELLO_API_KEY value. Please visit:",
|
|
|
|
url,
|
|
|
|
"Then enable developper account.",
|
|
|
|
"When you have your user api key, set TRELLO_API_KEY=<your-api-key>",
|
|
|
|
}, "\n\n")
|
|
|
|
|
|
|
|
return text
|
|
|
|
}
|
|
|
|
|
|
|
|
func MessageForToken(apiKey string) string {
|
2018-08-22 10:29:14 +00:00
|
|
|
url := strings.Join([]string{
|
|
|
|
"https://trello.com/1/authorize?expiration=never",
|
2019-09-04 05:35:49 +00:00
|
|
|
"name=Trello-To-Mail",
|
2018-08-22 10:29:14 +00:00
|
|
|
"scope=read",
|
|
|
|
"response_type=token",
|
2019-09-04 05:35:49 +00:00
|
|
|
fmt.Sprintf("key=%s", apiKey),
|
2018-08-22 10:29:14 +00:00
|
|
|
}, "&")
|
|
|
|
|
|
|
|
text := strings.Join([]string{
|
|
|
|
"Wrong TRELLO_TOKEN value. Please visit:",
|
|
|
|
url,
|
|
|
|
"When you have your access token, set TRELLO_TOKEN=<your-token>",
|
|
|
|
}, "\n\n")
|
|
|
|
|
|
|
|
return text
|
|
|
|
}
|
|
|
|
|
2019-09-04 05:35:49 +00:00
|
|
|
func NewTrello(apiKey string, token string) *TrelloCtx {
|
|
|
|
if len(apiKey) == 0 {
|
|
|
|
fmt.Println(MessageForApiKey())
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if len(token) == 0 {
|
|
|
|
fmt.Println(MessageForToken(apiKey))
|
|
|
|
return nil
|
|
|
|
}
|
2018-08-22 10:29:14 +00:00
|
|
|
|
2018-08-21 23:50:50 +00:00
|
|
|
ctx := TrelloCtx{}
|
2019-09-04 05:35:49 +00:00
|
|
|
ctx.ApiKey = apiKey
|
2018-08-21 23:50:50 +00:00
|
|
|
ctx.Token = token
|
2019-09-04 05:35:49 +00:00
|
|
|
|
|
|
|
client := trello.NewClient(apiKey, token)
|
2018-08-21 23:50:50 +00:00
|
|
|
ctx.Client = client
|
|
|
|
|
|
|
|
return &ctx
|
2018-08-21 17:21:46 +00:00
|
|
|
}
|
|
|
|
|
2018-11-23 12:22:03 +00:00
|
|
|
func (ctx *TrelloCtx) GetBoards() []TrelloBoard {
|
|
|
|
var result []TrelloBoard
|
|
|
|
|
|
|
|
token, err := ctx.Client.GetToken(ctx.Token, trello.Defaults())
|
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
member, err := ctx.Client.GetMember(token.IDMember, trello.Defaults())
|
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
boards, err := member.GetBoards(trello.Defaults())
|
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
for _, board := range boards {
|
|
|
|
result = append(result, TrelloBoard{
|
|
|
|
Ctx: ctx,
|
|
|
|
Starred: board.Starred,
|
|
|
|
Closed: board.Closed,
|
|
|
|
Ptr: board,
|
|
|
|
Name: board.Name,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2019-09-04 05:36:49 +00:00
|
|
|
func (ctx *TrelloCtx) GetBoard(boardURL string) TrelloBoard {
|
|
|
|
parsedURL, err := url.Parse(boardURL)
|
2018-08-22 00:39:08 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-09-04 05:36:49 +00:00
|
|
|
boardId := strings.Split(parsedURL.Path, "/")[2]
|
2018-08-22 00:39:08 +00:00
|
|
|
|
|
|
|
board, err := ctx.Client.GetBoard(boardId, trello.Defaults())
|
2018-11-23 10:46:12 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
2019-08-23 10:23:33 +00:00
|
|
|
|
|
|
|
// fmt.Printf("%#v\n", board)
|
|
|
|
spew.Dump(board)
|
2018-11-23 12:22:03 +00:00
|
|
|
return TrelloBoard{
|
|
|
|
Ctx: ctx,
|
|
|
|
Starred: board.Starred,
|
|
|
|
Closed: board.Closed,
|
|
|
|
Ptr: board,
|
|
|
|
Name: board.Name,
|
|
|
|
}
|
2018-08-21 17:21:46 +00:00
|
|
|
}
|
|
|
|
|
2018-11-23 11:41:16 +00:00
|
|
|
type CardData struct {
|
|
|
|
Name string
|
2019-09-04 05:36:49 +00:00
|
|
|
URL string
|
2018-11-23 11:41:16 +00:00
|
|
|
}
|
2018-08-22 00:39:08 +00:00
|
|
|
|
2018-11-23 11:41:16 +00:00
|
|
|
type ListData struct {
|
|
|
|
Name string
|
|
|
|
Cards []CardData
|
|
|
|
}
|
|
|
|
|
|
|
|
type BoardData struct {
|
|
|
|
Name string
|
2019-09-04 05:36:49 +00:00
|
|
|
URL string
|
2018-11-23 11:41:16 +00:00
|
|
|
Lists []ListData
|
|
|
|
}
|
|
|
|
|
|
|
|
func (board *TrelloBoard) ExportData() BoardData {
|
|
|
|
var boardData = BoardData{
|
|
|
|
Name: board.Ptr.Name,
|
2019-09-04 05:36:49 +00:00
|
|
|
URL: board.Ptr.ShortURL,
|
2018-11-23 11:41:16 +00:00
|
|
|
Lists: make([]ListData, 0),
|
|
|
|
}
|
|
|
|
|
|
|
|
// get lists
|
2018-08-22 10:34:33 +00:00
|
|
|
lists, err := board.Ptr.GetLists(trello.Defaults())
|
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
|
2018-11-23 11:41:16 +00:00
|
|
|
// fill in reverse order
|
2018-08-22 10:29:14 +00:00
|
|
|
for listIdx := len(lists) - 1; listIdx >= 0; listIdx -= 1 {
|
|
|
|
list := lists[listIdx]
|
2018-11-23 11:41:16 +00:00
|
|
|
listData := ListData{
|
|
|
|
Name: list.Name,
|
|
|
|
Cards: make([]CardData, 0),
|
|
|
|
}
|
2018-08-22 10:29:14 +00:00
|
|
|
|
2018-08-22 10:34:33 +00:00
|
|
|
cards, err := list.GetCards(trello.Defaults())
|
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
2018-08-22 10:29:14 +00:00
|
|
|
for _, card := range cards {
|
2018-11-23 11:41:16 +00:00
|
|
|
cardData := CardData{
|
|
|
|
Name: card.Name,
|
2019-09-04 05:36:49 +00:00
|
|
|
URL: card.URL,
|
2018-11-23 11:41:16 +00:00
|
|
|
}
|
|
|
|
listData.Cards = append(listData.Cards, cardData)
|
2018-08-22 10:29:14 +00:00
|
|
|
}
|
2018-11-23 11:41:16 +00:00
|
|
|
|
|
|
|
boardData.Lists = append(boardData.Lists, listData)
|
2018-08-22 00:39:08 +00:00
|
|
|
}
|
2018-11-23 11:41:16 +00:00
|
|
|
|
|
|
|
return boardData
|
|
|
|
}
|
|
|
|
|
|
|
|
func (board *TrelloBoard) ExportToMarkdown() string {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
data := board.ExportData()
|
|
|
|
|
2018-12-27 13:14:31 +00:00
|
|
|
wd, err := os.Getwd()
|
|
|
|
t, err := template.ParseFiles(path.Join(wd, "templates/markdown.tmpl"))
|
2018-11-23 11:41:16 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Panic("Unable to parse template files")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := t.Execute(&buf, data); err != nil {
|
|
|
|
log.Panicf("Template execution: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf.String()
|
2018-08-21 08:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 12:02:06 +00:00
|
|
|
func (board *TrelloBoard) ExportToHtml() string {
|
|
|
|
markdown := board.ExportToMarkdown()
|
|
|
|
html := blackfriday.Run([]byte(markdown))
|
|
|
|
return string(html)
|
|
|
|
}
|