mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Close #204. Add Trello dependency to /vendor
This commit is contained in:
28
vendor/github.com/adlio/trello/.gitignore
generated
vendored
Normal file
28
vendor/github.com/adlio/trello/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
coverage.sh
|
||||
coverage.out
|
||||
coverage.html
|
||||
11
vendor/github.com/adlio/trello/.travis.yml
generated
vendored
Normal file
11
vendor/github.com/adlio/trello/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
||||
|
||||
21
vendor/github.com/adlio/trello/LICENSE
generated
vendored
Normal file
21
vendor/github.com/adlio/trello/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Aaron Longwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
232
vendor/github.com/adlio/trello/README.md
generated
vendored
Normal file
232
vendor/github.com/adlio/trello/README.md
generated
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
Go Trello API
|
||||
================
|
||||
|
||||
[](https://www.trello.com)
|
||||
|
||||
[](http://godoc.org/github.com/adlio/trello)
|
||||
[](https://travis-ci.org/adlio/trello)
|
||||
[](https://coveralls.io/github/adlio/trello?branch=master)
|
||||
|
||||
A #golang package to access the [Trello API](https://developers.trello.com/v1.0/reference). Nearly 100% of the
|
||||
read-only surface area of the API is covered, as is creation and modification of Cards.
|
||||
Low-level infrastructure for features to modify Lists and Boards are easy to add... just not
|
||||
done yet.
|
||||
|
||||
Pull requests are welcome for missing features.
|
||||
|
||||
My current development focus is documentation, especially enhancing this README.md with more
|
||||
example use cases.
|
||||
|
||||
## Installation
|
||||
|
||||
The Go Trello API has been Tested compatible with Go 1.7 on up. Its only dependency is
|
||||
the `github.com/pkg/errors` package. It otherwise relies only on the Go standard library.
|
||||
|
||||
```
|
||||
go get github.com/adlio/trello
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
All interaction starts with a `trello.Client`. Create one with your appKey and token:
|
||||
|
||||
```Go
|
||||
client := trello.NewClient(appKey, token)
|
||||
```
|
||||
|
||||
All API requests accept a trello.Arguments object. This object is a simple
|
||||
`map[string]string`, converted to query string arguments in the API call.
|
||||
Trello has sane defaults on API calls. We have a `trello.Defaults()` utility function
|
||||
which can be used when you desire the default Trello arguments. Internally,
|
||||
`trello.Defaults()` is an empty map, which translates to an empty query string.
|
||||
|
||||
```Go
|
||||
board, err := client.GetBoard("bOaRdID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Client Longevity
|
||||
|
||||
When getting Lists from Boards or Cards from Lists, the original `trello.Client` pointer
|
||||
is carried along in returned child objects. It's important to realize that this enables
|
||||
you to make additional API calls via functions invoked on the objects you receive:
|
||||
|
||||
```Go
|
||||
client := trello.NewClient(appKey, token)
|
||||
board, err := client.GetBoard("ID", trello.Defaults())
|
||||
|
||||
// GetLists makes an API call to /boards/:id/lists using credentials from `client`
|
||||
lists, err := board.GetLists(trello.Defaults())
|
||||
|
||||
for _, list := range lists {
|
||||
// GetCards makes an API call to /lists/:id/cards using credentials from `client`
|
||||
cards, err := list.GetCards(trello.Defaults())
|
||||
}
|
||||
```
|
||||
|
||||
## Get Trello Boards for a User
|
||||
|
||||
Boards can be retrieved directly by their ID (see example above), or by asking
|
||||
for all boards for a member:
|
||||
|
||||
```Go
|
||||
member, err := client.GetMember("usernameOrId", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
boards, err := member.GetBoards(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Get Trello Lists on a Board
|
||||
|
||||
```Go
|
||||
board, err := client.GetBoard("bOaRdID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
lists, err := board.GetLists(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Get Trello Cards on a Board
|
||||
|
||||
```Go
|
||||
board, err := client.GetBoard("bOaRdID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
cards, err := board.GetCards(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Get Trello Cards on a List
|
||||
|
||||
```Go
|
||||
list, err := client.GetList("lIsTID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
cards, err := list.GetCards(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Creating a Card
|
||||
|
||||
The API provides several mechanisms for creating new cards.
|
||||
|
||||
### Creating Cards from Scratch on the Client
|
||||
|
||||
This approach requires the most input data on the card:
|
||||
|
||||
```Go
|
||||
card := trello.Card{
|
||||
Name: "Card Name",
|
||||
Desc: "Card description",
|
||||
Pos: 12345.678,
|
||||
IDList: "iDOfaLiSt",
|
||||
IDLabels: []string{"labelID1", "labelID2"},
|
||||
}
|
||||
err := client.CreateCard(card, trello.Defaults())
|
||||
```
|
||||
|
||||
|
||||
### Creating Cards On a List
|
||||
|
||||
```Go
|
||||
list, err := client.GetList("lIsTID", trello.Defaults())
|
||||
list.AddCard(trello.Card{ Name: "Card Name", Description: "Card description" }, trello.Defaults())
|
||||
```
|
||||
|
||||
### Creating a Card by Copying Another Card
|
||||
|
||||
```Go
|
||||
err := card.CopyToList("listIdNUmber", trello.Defaults())
|
||||
```
|
||||
|
||||
## Get Actions on a Board
|
||||
|
||||
```Go
|
||||
board, err := client.GetBoard("bOaRdID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
actions, err := board.GetActions(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Get Actions on a Card
|
||||
|
||||
```Go
|
||||
card, err := client.GetCard("cArDID", trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
actions, err := card.GetActions(trello.Defaults())
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Rearrange Cards Within a List
|
||||
|
||||
```Go
|
||||
err := card.MoveToTopOfList()
|
||||
err = card.MoveToBottomOfList()
|
||||
err = card.SetPos(12345.6789)
|
||||
```
|
||||
|
||||
|
||||
## Moving a Card to Another List
|
||||
|
||||
```Go
|
||||
err := card.MoveToList("listIdNUmber", trello.Defaults())
|
||||
```
|
||||
|
||||
|
||||
## Card Ancestry
|
||||
|
||||
Trello provides ancestry tracking when cards are created as copies of other cards. This package
|
||||
provides functions for working with this data:
|
||||
|
||||
```Go
|
||||
|
||||
// ancestors will hold a slice of *trello.Cards, with the first
|
||||
// being the card's parent, and the last being parent's parent's parent...
|
||||
ancestors, err := card.GetAncestorCards(trello.Defaults())
|
||||
|
||||
// GetOriginatingCard() is an alias for the last element in the slice
|
||||
// of ancestor cards.
|
||||
ultimateParentCard, err := card.GetOriginatingCard(trello.Defaults())
|
||||
|
||||
```
|
||||
|
||||
## Debug Logging
|
||||
|
||||
If you'd like to see all API calls logged, you can attach a `.Logger` (implementing `Debugf(string, ...interface{})`)
|
||||
to your client. The interface for the logger mimics logrus. Example usage:
|
||||
|
||||
```Go
|
||||
logger := logrus.New()
|
||||
logger.SetLevel(logrus.DebugLevel)
|
||||
client := trello.NewClient(appKey, token)
|
||||
client.Logger = logger
|
||||
```
|
||||
5
vendor/github.com/adlio/trello/TODO.txt
generated
vendored
Normal file
5
vendor/github.com/adlio/trello/TODO.txt
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
- Create List
|
||||
- Delete Card
|
||||
- Archive Card
|
||||
- Reorder Cards in List
|
||||
|
||||
57
vendor/github.com/adlio/trello/action-collection.go
generated
vendored
Normal file
57
vendor/github.com/adlio/trello/action-collection.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package trello
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// ActionCollection is an alias of []*Action, which sorts by the Action's ID.
|
||||
// Which is the same as sorting by the Action's time of occurrence
|
||||
type ActionCollection []*Action
|
||||
|
||||
func (c ActionCollection) Len() int { return len(c) }
|
||||
func (c ActionCollection) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c ActionCollection) Less(i, j int) bool { return c[i].ID < c[j].ID }
|
||||
|
||||
func (actions ActionCollection) FirstCardCreateAction() *Action {
|
||||
sort.Sort(actions)
|
||||
for _, action := range actions {
|
||||
if action.DidCreateCard() {
|
||||
return action
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (actions ActionCollection) ContainsCardCreation() bool {
|
||||
return actions.FirstCardCreateAction() != nil
|
||||
}
|
||||
|
||||
func (c ActionCollection) FilterToCardCreationActions() ActionCollection {
|
||||
newSlice := make(ActionCollection, 0, len(c))
|
||||
for _, action := range c {
|
||||
if action.DidCreateCard() {
|
||||
newSlice = append(newSlice, action)
|
||||
}
|
||||
}
|
||||
return newSlice
|
||||
}
|
||||
|
||||
func (c ActionCollection) FilterToListChangeActions() ActionCollection {
|
||||
newSlice := make(ActionCollection, 0, len(c))
|
||||
for _, action := range c {
|
||||
if action.DidChangeListForCard() {
|
||||
newSlice = append(newSlice, action)
|
||||
}
|
||||
}
|
||||
return newSlice
|
||||
}
|
||||
|
||||
func (c ActionCollection) FilterToCardMembershipChangeActions() ActionCollection {
|
||||
newSlice := make(ActionCollection, 0, len(c))
|
||||
for _, action := range c {
|
||||
if action.DidChangeCardMembership() || action.DidArchiveCard() || action.DidUnarchiveCard() {
|
||||
newSlice = append(newSlice, action)
|
||||
}
|
||||
}
|
||||
return newSlice
|
||||
}
|
||||
148
vendor/github.com/adlio/trello/action.go
generated
vendored
Normal file
148
vendor/github.com/adlio/trello/action.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Action struct {
|
||||
ID string `json:"id"`
|
||||
IDMemberCreator string `json:"idMemberCreator"`
|
||||
Type string `json:"type"`
|
||||
Date time.Time `json:"date"`
|
||||
Data *ActionData `json:"data,omitempty"`
|
||||
MemberCreator *Member `json:"memberCreator,omitempty"`
|
||||
Member *Member `json:"member,omitempty"`
|
||||
}
|
||||
|
||||
type ActionData struct {
|
||||
Text string `json:"text,omitempty"`
|
||||
List *List `json:"list,omitempty"`
|
||||
Card *Card `json:"card,omitempty"`
|
||||
CardSource *Card `json:"cardSource,omitempty"`
|
||||
Board *Board `json:"board,omitempty"`
|
||||
Old *Card `json:"old,omitempty"`
|
||||
ListBefore *List `json:"listBefore,omitempty"`
|
||||
ListAfter *List `json:"listAfter,omitempty"`
|
||||
DateLastEdited time.Time `json:"dateLastEdited"`
|
||||
|
||||
CheckItem *CheckItem `json:"checkItem"`
|
||||
Checklist *Checklist `json:"checklist"`
|
||||
}
|
||||
|
||||
func (b *Board) GetActions(args Arguments) (actions ActionCollection, err error) {
|
||||
path := fmt.Sprintf("boards/%s/actions", b.ID)
|
||||
err = b.client.Get(path, args, &actions)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *List) GetActions(args Arguments) (actions ActionCollection, err error) {
|
||||
path := fmt.Sprintf("lists/%s/actions", l.ID)
|
||||
err = l.client.Get(path, args, &actions)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Card) GetActions(args Arguments) (actions ActionCollection, err error) {
|
||||
path := fmt.Sprintf("cards/%s/actions", c.ID)
|
||||
err = c.client.Get(path, args, &actions)
|
||||
return
|
||||
}
|
||||
|
||||
// GetListChangeActions retrieves a slice of Actions which resulted in changes
|
||||
// to the card's active List. This includes the createCard and copyCard action (which
|
||||
// place the card in its first list, and the updateCard:closed action, which remove it
|
||||
// from its last list.
|
||||
//
|
||||
// This function is just an alias for:
|
||||
// card.GetActions(Arguments{"filter": "createCard,copyCard,updateCard:idList,updateCard:closed", "limit": "1000"})
|
||||
//
|
||||
func (c *Card) GetListChangeActions() (actions ActionCollection, err error) {
|
||||
return c.GetActions(Arguments{"filter": "createCard,copyCard,updateCard:idList,updateCard:closed"})
|
||||
}
|
||||
|
||||
func (c *Card) GetMembershipChangeActions() (actions ActionCollection, err error) {
|
||||
// We include updateCard:closed as if the member is implicitly removed from the card when it's closed.
|
||||
// This allows us to "close out" the duration length.
|
||||
return c.GetActions(Arguments{"filter": "addMemberToCard,removeMemberFromCard,updateCard:closed"})
|
||||
}
|
||||
|
||||
// DidCreateCard() returns true if this action created a card, false otherwise.
|
||||
func (a *Action) DidCreateCard() bool {
|
||||
switch a.Type {
|
||||
case "createCard", "emailCard", "copyCard", "convertToCardFromCheckItem":
|
||||
return true
|
||||
case "moveCardToBoard":
|
||||
return true // Unsure about this one
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Action) DidArchiveCard() bool {
|
||||
return (a.Type == "updateCard") && a.Data != nil && a.Data.Card != nil && a.Data.Card.Closed
|
||||
}
|
||||
|
||||
func (a *Action) DidUnarchiveCard() bool {
|
||||
return (a.Type == "updateCard") && a.Data != nil && a.Data.Old != nil && a.Data.Old.Closed
|
||||
}
|
||||
|
||||
// Returns true if this action created the card (in which case it caused it to enter its
|
||||
// first list), archived the card (in which case it caused it to leave its last List),
|
||||
// or was an updateCard action involving a change to the list. This is supporting
|
||||
// functionality for ListDuration.
|
||||
//
|
||||
func (a *Action) DidChangeListForCard() bool {
|
||||
if a.DidCreateCard() {
|
||||
return true
|
||||
}
|
||||
if a.DidArchiveCard() {
|
||||
return true
|
||||
}
|
||||
if a.DidUnarchiveCard() {
|
||||
return true
|
||||
}
|
||||
if a.Type == "updateCard" {
|
||||
if a.Data != nil && a.Data.ListAfter != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *Action) DidChangeCardMembership() bool {
|
||||
switch a.Type {
|
||||
case "addMemberToCard":
|
||||
return true
|
||||
case "removeMemberFromCard":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ListAfterAction calculates which List the card ended up in after this action
|
||||
// completed. Returns nil when the action resulted in the card being archived (in
|
||||
// which case we consider it to not be in a list anymore), or when the action isn't
|
||||
// related to a list at all (in which case this is a nonsensical question to ask).
|
||||
//
|
||||
func ListAfterAction(a *Action) *List {
|
||||
switch a.Type {
|
||||
case "createCard", "copyCard", "emailCard", "convertToCardFromCheckItem":
|
||||
return a.Data.List
|
||||
case "updateCard":
|
||||
if a.DidArchiveCard() {
|
||||
return nil
|
||||
} else if a.DidUnarchiveCard() {
|
||||
return a.Data.List
|
||||
}
|
||||
if a.Data.ListAfter != nil {
|
||||
return a.Data.ListAfter
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
24
vendor/github.com/adlio/trello/arguments.go
generated
vendored
Normal file
24
vendor/github.com/adlio/trello/arguments.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Arguments map[string]string
|
||||
|
||||
func Defaults() Arguments {
|
||||
return make(Arguments)
|
||||
}
|
||||
|
||||
func (args Arguments) ToURLValues() url.Values {
|
||||
v := url.Values{}
|
||||
for key, value := range args {
|
||||
v.Set(key, value)
|
||||
}
|
||||
return v
|
||||
}
|
||||
29
vendor/github.com/adlio/trello/attachment.go
generated
vendored
Normal file
29
vendor/github.com/adlio/trello/attachment.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
type Attachment struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Pos float32 `json:"pos"`
|
||||
Bytes int `json:"int"`
|
||||
Date string `json:"date"`
|
||||
EdgeColor string `json:"edgeColor"`
|
||||
IDMember string `json:"idMember"`
|
||||
IsUpload bool `json:"isUpload"`
|
||||
MimeType string `json:"mimeType"`
|
||||
Previews []AttachmentPreview `json:"previews"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type AttachmentPreview struct {
|
||||
ID string `json:"_id"`
|
||||
URL string `json:"url"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Bytes int `json:"bytes"`
|
||||
Scaled bool `json:"scaled"`
|
||||
}
|
||||
89
vendor/github.com/adlio/trello/board.go
generated
vendored
Normal file
89
vendor/github.com/adlio/trello/board.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Board struct {
|
||||
client *Client
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Desc string `json:"desc"`
|
||||
Closed bool `json:"closed"`
|
||||
IdOrganization string `json:"idOrganization"`
|
||||
Pinned bool `json:"pinned"`
|
||||
Url string `json:"url"`
|
||||
ShortUrl string `json:"shortUrl"`
|
||||
Prefs struct {
|
||||
PermissionLevel string `json:"permissionLevel"`
|
||||
Voting string `json:"voting"`
|
||||
Comments string `json:"comments"`
|
||||
Invitations string `json:"invitations"`
|
||||
SelfJoin bool `json:"selfjoin"`
|
||||
CardCovers bool `json:"cardCovers"`
|
||||
CardAging string `json:"cardAging"`
|
||||
CalendarFeedEnabled bool `json:"calendarFeedEnabled"`
|
||||
Background string `json:"background"`
|
||||
BackgroundColor string `json:"backgroundColor"`
|
||||
BackgroundImage string `json:"backgroundImage"`
|
||||
BackgroundImageScaled []BackgroundImage `json:"backgroundImageScaled"`
|
||||
BackgroundTile bool `json:"backgroundTile"`
|
||||
BackgroundBrightness string `json:"backgroundBrightness"`
|
||||
CanBePublic bool `json:"canBePublic"`
|
||||
CanBeOrg bool `json:"canBeOrg"`
|
||||
CanBePrivate bool `json:"canBePrivate"`
|
||||
CanInvite bool `json:"canInvite"`
|
||||
} `json:"prefs"`
|
||||
LabelNames struct {
|
||||
Black string `json:"black,omitempty"`
|
||||
Blue string `json:"blue,omitempty"`
|
||||
Green string `json:"green,omitempty"`
|
||||
Lime string `json:"lime,omitempty"`
|
||||
Orange string `json:"orange,omitempty"`
|
||||
Pink string `json:"pink,omitempty"`
|
||||
Purple string `json:"purple,omitempty"`
|
||||
Red string `json:"red,omitempty"`
|
||||
Sky string `json:"sky,omitempty"`
|
||||
Yellow string `json:"yellow,omitempty"`
|
||||
} `json:"labelNames"`
|
||||
Lists []*List `json:"lists"`
|
||||
Actions []*Action `json:"actions"`
|
||||
}
|
||||
|
||||
type BackgroundImage struct {
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (b *Board) CreatedAt() time.Time {
|
||||
t, _ := IDToTime(b.ID)
|
||||
return t
|
||||
}
|
||||
|
||||
/**
|
||||
* Board retrieves a Trello board by its ID.
|
||||
*/
|
||||
func (c *Client) GetBoard(boardID string, args Arguments) (board *Board, err error) {
|
||||
path := fmt.Sprintf("boards/%s", boardID)
|
||||
err = c.Get(path, args, &board)
|
||||
if board != nil {
|
||||
board.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Member) GetBoards(args Arguments) (boards []*Board, err error) {
|
||||
path := fmt.Sprintf("members/%s/boards", m.ID)
|
||||
err = m.client.Get(path, args, &boards)
|
||||
for i := range boards {
|
||||
boards[i].client = m.client
|
||||
}
|
||||
return
|
||||
}
|
||||
388
vendor/github.com/adlio/trello/card.go
generated
vendored
Normal file
388
vendor/github.com/adlio/trello/card.go
generated
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Card struct {
|
||||
client *Client
|
||||
|
||||
// Key metadata
|
||||
ID string `json:"id"`
|
||||
IDShort int `json:"idShort"`
|
||||
Name string `json:"name"`
|
||||
Pos float64 `json:"pos"`
|
||||
Email string `json:"email"`
|
||||
ShortLink string `json:"shortLink"`
|
||||
ShortUrl string `json:"shortUrl"`
|
||||
Url string `json:"url"`
|
||||
Desc string `json:"desc"`
|
||||
Due *time.Time `json:"due"`
|
||||
DueComplete bool `json:"dueComplete"`
|
||||
Closed bool `json:"closed"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
DateLastActivity *time.Time `json:"dateLastActivity"`
|
||||
|
||||
// Board
|
||||
Board *Board
|
||||
IDBoard string `json:"idBoard"`
|
||||
|
||||
// List
|
||||
List *List
|
||||
IDList string `json:"idList"`
|
||||
|
||||
// Badges
|
||||
Badges struct {
|
||||
Votes int `json:"votes"`
|
||||
ViewingMemberVoted bool `json:"viewingMemberVoted"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
Fogbugz string `json:"fogbugz,omitempty"`
|
||||
CheckItems int `json:"checkItems"`
|
||||
CheckItemsChecked int `json:"checkItemsChecked"`
|
||||
Comments int `json:"comments"`
|
||||
Attachments int `json:"attachments"`
|
||||
Description bool `json:"description"`
|
||||
Due *time.Time `json:"due,omitempty"`
|
||||
} `json:"badges"`
|
||||
|
||||
// Actions
|
||||
Actions ActionCollection `json:"actions,omitempty"`
|
||||
|
||||
// Checklists
|
||||
IDCheckLists []string `json:"idCheckLists"`
|
||||
Checklists []*Checklist `json:"checklists,omitempty"`
|
||||
CheckItemStates []*CheckItemState `json:"checkItemStates,omitempty"`
|
||||
|
||||
// Members
|
||||
IDMembers []string `json:"idMembers,omitempty"`
|
||||
IDMembersVoted []string `json:"idMembersVoted,omitempty"`
|
||||
Members []*Member `json:"members,omitempty"`
|
||||
|
||||
// Attachments
|
||||
IDAttachmentCover string `json:"idAttachmentCover"`
|
||||
ManualCoverAttachment bool `json:"manualCoverAttachment"`
|
||||
Attachments []*Attachment `json:"attachments,omitempty"`
|
||||
|
||||
// Labels
|
||||
IDLabels []string `json:"idLabels,omitempty"`
|
||||
Labels []*Label `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Card) CreatedAt() time.Time {
|
||||
t, _ := IDToTime(c.ID)
|
||||
return t
|
||||
}
|
||||
|
||||
func (c *Card) MoveToList(listID string, args Arguments) error {
|
||||
path := fmt.Sprintf("cards/%s", c.ID)
|
||||
args["idList"] = listID
|
||||
return c.client.Put(path, args, &c)
|
||||
}
|
||||
|
||||
func (c *Card) SetPos(newPos float64) error {
|
||||
path := fmt.Sprintf("cards/%s", c.ID)
|
||||
return c.client.Put(path, Arguments{"pos": fmt.Sprintf("%f", newPos)}, c)
|
||||
}
|
||||
|
||||
func (c *Card) RemoveMember(memberID string) error {
|
||||
path := fmt.Sprintf("cards/%s/idMembers/%s", c.ID, memberID)
|
||||
return c.client.Delete(path, Defaults(), nil)
|
||||
}
|
||||
|
||||
func (c *Card) AddMemberID(memberID string) (member []*Member, err error) {
|
||||
path := fmt.Sprintf("cards/%s/idMembers", c.ID)
|
||||
err = c.client.Post(path, Arguments{"value": memberID}, &member)
|
||||
return member, err
|
||||
}
|
||||
|
||||
func (c *Card) MoveToTopOfList() error {
|
||||
path := fmt.Sprintf("cards/%s", c.ID)
|
||||
return c.client.Put(path, Arguments{"pos": "top"}, c)
|
||||
}
|
||||
|
||||
func (c *Card) MoveToBottomOfList() error {
|
||||
path := fmt.Sprintf("cards/%s", c.ID)
|
||||
return c.client.Put(path, Arguments{"pos": "bottom"}, c)
|
||||
}
|
||||
|
||||
func (c *Card) Update(args Arguments) error {
|
||||
path := fmt.Sprintf("cards/%s", c.ID)
|
||||
return c.client.Put(path, args, c)
|
||||
}
|
||||
|
||||
func (c *Client) CreateCard(card *Card, extraArgs Arguments) error {
|
||||
path := "cards"
|
||||
args := Arguments{
|
||||
"name": card.Name,
|
||||
"desc": card.Desc,
|
||||
"pos": strconv.FormatFloat(card.Pos, 'g', -1, 64),
|
||||
"idList": card.IDList,
|
||||
"idMembers": strings.Join(card.IDMembers, ","),
|
||||
"idLabels": strings.Join(card.IDLabels, ","),
|
||||
}
|
||||
if card.Due != nil {
|
||||
args["due"] = card.Due.Format(time.RFC3339)
|
||||
}
|
||||
// Allow overriding the creation position with 'top' or 'botttom'
|
||||
if pos, ok := extraArgs["pos"]; ok {
|
||||
args["pos"] = pos
|
||||
}
|
||||
err := c.Post(path, args, &card)
|
||||
if err == nil {
|
||||
card.client = c
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *List) AddCard(card *Card, extraArgs Arguments) error {
|
||||
path := fmt.Sprintf("lists/%s/cards", l.ID)
|
||||
args := Arguments{
|
||||
"name": card.Name,
|
||||
"desc": card.Desc,
|
||||
"idMembers": strings.Join(card.IDMembers, ","),
|
||||
"idLabels": strings.Join(card.IDLabels, ","),
|
||||
}
|
||||
if card.Due != nil {
|
||||
args["due"] = card.Due.Format(time.RFC3339)
|
||||
}
|
||||
// Allow overwriting the creation position with 'top' or 'bottom'
|
||||
if pos, ok := extraArgs["pos"]; ok {
|
||||
args["pos"] = pos
|
||||
}
|
||||
err := l.client.Post(path, args, &card)
|
||||
if err == nil {
|
||||
card.client = l.client
|
||||
} else {
|
||||
err = errors.Wrapf(err, "Error adding card to list %s", l.ID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Try these Arguments
|
||||
//
|
||||
// Arguments["keepFromSource"] = "all"
|
||||
// Arguments["keepFromSource"] = "none"
|
||||
// Arguments["keepFromSource"] = "attachments,checklists,comments"
|
||||
//
|
||||
func (c *Card) CopyToList(listID string, args Arguments) (*Card, error) {
|
||||
path := "cards"
|
||||
args["idList"] = listID
|
||||
args["idCardSource"] = c.ID
|
||||
newCard := Card{}
|
||||
err := c.client.Post(path, args, &newCard)
|
||||
if err == nil {
|
||||
newCard.client = c.client
|
||||
} else {
|
||||
err = errors.Wrapf(err, "Error copying card '%s' to list '%s'.", c.ID, listID)
|
||||
}
|
||||
return &newCard, err
|
||||
}
|
||||
|
||||
func (c *Card) AddComment(comment string, args Arguments) (*Action, error) {
|
||||
path := fmt.Sprintf("cards/%s/actions/comments", c.ID)
|
||||
args["text"] = comment
|
||||
action := Action{}
|
||||
err := c.client.Post(path, args, &action)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "Error commenting on card %s", c.ID)
|
||||
}
|
||||
return &action, err
|
||||
}
|
||||
|
||||
// If this Card was created from a copy of another Card, this func retrieves
|
||||
// the originating Card. Returns an error only when a low-level failure occurred.
|
||||
// If this Card has no parent, a nil card and nil error are returned. In other words, the
|
||||
// non-existence of a parent is not treated as an error.
|
||||
//
|
||||
func (c *Card) GetParentCard(args Arguments) (*Card, error) {
|
||||
|
||||
// Hopefully the card came pre-loaded with Actions including the card creation
|
||||
action := c.Actions.FirstCardCreateAction()
|
||||
|
||||
if action == nil {
|
||||
// No luck. Go get copyCard actions for this card.
|
||||
c.client.log("Creation action wasn't supplied before GetParentCard() on '%s'. Getting copyCard actions.", c.ID)
|
||||
actions, err := c.GetActions(Arguments{"filter": "copyCard"})
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetParentCard() failed to GetActions() for card '%s'", c.ID)
|
||||
return nil, err
|
||||
}
|
||||
action = actions.FirstCardCreateAction()
|
||||
}
|
||||
|
||||
if action != nil && action.Data != nil && action.Data.CardSource != nil {
|
||||
card, err := c.client.GetCard(action.Data.CardSource.ID, args)
|
||||
return card, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *Card) GetAncestorCards(args Arguments) (ancestors []*Card, err error) {
|
||||
|
||||
// Get the first parent
|
||||
parent, err := c.GetParentCard(args)
|
||||
if IsNotFound(err) || IsPermissionDenied(err) {
|
||||
c.client.log("[trello] Can't get details about the parent of card '%s' due to lack of permissions or card deleted.", c.ID)
|
||||
return ancestors, nil
|
||||
}
|
||||
|
||||
for parent != nil {
|
||||
ancestors = append(ancestors, parent)
|
||||
parent, err = parent.GetParentCard(args)
|
||||
if IsNotFound(err) || IsPermissionDenied(err) {
|
||||
c.client.log("[trello] Can't get details about the parent of card '%s' due to lack of permissions or card deleted.", c.ID)
|
||||
return ancestors, nil
|
||||
} else if err != nil {
|
||||
return ancestors, err
|
||||
}
|
||||
}
|
||||
|
||||
return ancestors, err
|
||||
}
|
||||
|
||||
func (c *Card) GetOriginatingCard(args Arguments) (*Card, error) {
|
||||
ancestors, err := c.GetAncestorCards(args)
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
if len(ancestors) > 0 {
|
||||
return ancestors[len(ancestors)-1], nil
|
||||
} else {
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Card) CreatorMember() (*Member, error) {
|
||||
var actions ActionCollection
|
||||
var err error
|
||||
|
||||
if len(c.Actions) == 0 {
|
||||
c.Actions, err = c.GetActions(Arguments{"filter": "all", "limit": "1000", "memberCreator_fields": "all"})
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetActions() call failed.")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
actions = c.Actions.FilterToCardCreationActions()
|
||||
|
||||
if len(actions) > 0 {
|
||||
return actions[0].MemberCreator, nil
|
||||
}
|
||||
return nil, errors.Errorf("No card creation actions on Card %s with a .MemberCreator", c.ID)
|
||||
}
|
||||
|
||||
func (c *Card) CreatorMemberID() (string, error) {
|
||||
|
||||
var actions ActionCollection
|
||||
var err error
|
||||
|
||||
if len(c.Actions) == 0 {
|
||||
c.client.log("[trello] CreatorMemberID() called on card '%s' without any Card.Actions. Fetching fresh.", c.ID)
|
||||
c.Actions, err = c.GetActions(Defaults())
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetActions() call failed.")
|
||||
}
|
||||
}
|
||||
actions = c.Actions.FilterToCardCreationActions()
|
||||
|
||||
if len(actions) > 0 {
|
||||
if actions[0].IDMemberCreator != "" {
|
||||
return actions[0].IDMemberCreator, err
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.Wrapf(err, "No Actions on card '%s' could be used to find its creator.", c.ID)
|
||||
}
|
||||
|
||||
func (b *Board) ContainsCopyOfCard(cardID string, args Arguments) (bool, error) {
|
||||
args["filter"] = "copyCard"
|
||||
actions, err := b.GetActions(args)
|
||||
if err != nil {
|
||||
err := errors.Wrapf(err, "GetCards() failed inside ContainsCopyOf() for board '%s' and card '%s'.", b.ID, cardID)
|
||||
return false, err
|
||||
}
|
||||
for _, action := range actions {
|
||||
if action.Data != nil && action.Data.CardSource != nil && action.Data.CardSource.ID == cardID {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetCard(cardID string, args Arguments) (card *Card, err error) {
|
||||
path := fmt.Sprintf("cards/%s", cardID)
|
||||
err = c.Get(path, args, &card)
|
||||
if card != nil {
|
||||
card.client = c
|
||||
}
|
||||
return card, err
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all Cards on a Board
|
||||
*
|
||||
* If before
|
||||
*/
|
||||
func (b *Board) GetCards(args Arguments) (cards []*Card, err error) {
|
||||
path := fmt.Sprintf("boards/%s/cards", b.ID)
|
||||
|
||||
err = b.client.Get(path, args, &cards)
|
||||
|
||||
// Naive implementation would return here. To make sure we get all
|
||||
// cards, we begin
|
||||
if len(cards) > 0 {
|
||||
moreCards := true
|
||||
for moreCards == true {
|
||||
nextCardBatch := make([]*Card, 0)
|
||||
args["before"] = EarliestCardID(cards)
|
||||
err = b.client.Get(path, args, &nextCardBatch)
|
||||
if len(nextCardBatch) > 0 {
|
||||
cards = append(cards, nextCardBatch...)
|
||||
} else {
|
||||
moreCards = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range cards {
|
||||
cards[i].client = b.client
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all Cards in a List
|
||||
*/
|
||||
func (l *List) GetCards(args Arguments) (cards []*Card, err error) {
|
||||
path := fmt.Sprintf("lists/%s/cards", l.ID)
|
||||
err = l.client.Get(path, args, &cards)
|
||||
for i := range cards {
|
||||
cards[i].client = l.client
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func EarliestCardID(cards []*Card) string {
|
||||
if len(cards) == 0 {
|
||||
return ""
|
||||
}
|
||||
earliest := cards[0].ID
|
||||
for _, card := range cards {
|
||||
if card.ID < earliest {
|
||||
earliest = card.ID
|
||||
}
|
||||
}
|
||||
return earliest
|
||||
}
|
||||
30
vendor/github.com/adlio/trello/checklist.go
generated
vendored
Normal file
30
vendor/github.com/adlio/trello/checklist.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
type Checklist struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IDBoard string `json:"idBoard,omitempty"`
|
||||
IDCard string `json:"idCard,omitempty"`
|
||||
Pos float64 `json:"pos,omitempty"`
|
||||
CheckItems []CheckItem `json:"checkItems,omitempty"`
|
||||
}
|
||||
|
||||
type CheckItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
IDChecklist string `json:"idChecklist,omitempty"`
|
||||
Pos float64 `json:"pos,omitempty"`
|
||||
}
|
||||
|
||||
// Manifestation of CheckItem when it appears in CheckItemStates
|
||||
// on a Card.
|
||||
type CheckItemState struct {
|
||||
IDCheckItem string `json:"idCheckItem"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
239
vendor/github.com/adlio/trello/client.go
generated
vendored
Normal file
239
vendor/github.com/adlio/trello/client.go
generated
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const DEFAULT_BASEURL = "https://api.trello.com/1"
|
||||
|
||||
type Client struct {
|
||||
Client *http.Client
|
||||
Logger logger
|
||||
BaseURL string
|
||||
Key string
|
||||
Token string
|
||||
throttle <-chan time.Time
|
||||
testMode bool
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type logger interface {
|
||||
Debugf(string, ...interface{})
|
||||
}
|
||||
|
||||
func NewClient(key, token string) *Client {
|
||||
return &Client{
|
||||
Client: http.DefaultClient,
|
||||
BaseURL: DEFAULT_BASEURL,
|
||||
Key: key,
|
||||
Token: token,
|
||||
throttle: time.Tick(time.Second / 8), // Actually 10/second, but we're extra cautious
|
||||
testMode: false,
|
||||
ctx: context.Background(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) WithContext(ctx context.Context) *Client {
|
||||
newC := *c
|
||||
newC.ctx = ctx
|
||||
return &newC
|
||||
}
|
||||
|
||||
func (c *Client) Throttle() {
|
||||
if !c.testMode {
|
||||
<-c.throttle
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Get(path string, args Arguments, target interface{}) error {
|
||||
|
||||
// Trello prohibits more than 10 seconds/second per token
|
||||
c.Throttle()
|
||||
|
||||
params := args.ToURLValues()
|
||||
c.log("[trello] GET %s?%s", path, params.Encode())
|
||||
|
||||
if c.Key != "" {
|
||||
params.Set("key", c.Key)
|
||||
}
|
||||
|
||||
if c.Token != "" {
|
||||
params.Set("token", c.Token)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", c.BaseURL, path)
|
||||
urlWithParams := fmt.Sprintf("%s?%s", url, params.Encode())
|
||||
|
||||
req, err := http.NewRequest("GET", urlWithParams, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Invalid GET request %s", url)
|
||||
}
|
||||
req = req.WithContext(c.ctx)
|
||||
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP request failure on %s", url)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
return makeHttpClientError(url, resp)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
err = decoder.Decode(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "JSON decode failed on %s", url)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Put(path string, args Arguments, target interface{}) error {
|
||||
|
||||
// Trello prohibits more than 10 seconds/second per token
|
||||
c.Throttle()
|
||||
|
||||
params := args.ToURLValues()
|
||||
c.log("[trello] PUT %s?%s", path, params.Encode())
|
||||
|
||||
if c.Key != "" {
|
||||
params.Set("key", c.Key)
|
||||
}
|
||||
|
||||
if c.Token != "" {
|
||||
params.Set("token", c.Token)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", c.BaseURL, path)
|
||||
urlWithParams := fmt.Sprintf("%s?%s", url, params.Encode())
|
||||
|
||||
req, err := http.NewRequest("PUT", urlWithParams, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Invalid PUT request %s", url)
|
||||
}
|
||||
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP request failure on %s", url)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
return makeHttpClientError(url, resp)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
err = decoder.Decode(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "JSON decode failed on %s", url)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Post(path string, args Arguments, target interface{}) error {
|
||||
|
||||
// Trello prohibits more than 10 seconds/second per token
|
||||
c.Throttle()
|
||||
|
||||
params := args.ToURLValues()
|
||||
c.log("[trello] POST %s?%s", path, params.Encode())
|
||||
|
||||
if c.Key != "" {
|
||||
params.Set("key", c.Key)
|
||||
}
|
||||
|
||||
if c.Token != "" {
|
||||
params.Set("token", c.Token)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", c.BaseURL, path)
|
||||
urlWithParams := fmt.Sprintf("%s?%s", url, params.Encode())
|
||||
|
||||
req, err := http.NewRequest("POST", urlWithParams, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Invalid POST request %s", url)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP request failure on %s", url)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP Read error on response for %s", url)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(b))
|
||||
err = decoder.Decode(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "JSON decode failed on %s:\n%s", url, string(b))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Delete(path string, args Arguments, target interface{}) error {
|
||||
|
||||
c.Throttle()
|
||||
|
||||
params := args.ToURLValues()
|
||||
c.log("[trello] DELETE %s?%s", path, params.Encode())
|
||||
|
||||
if c.Key != "" {
|
||||
params.Set("key", c.Key)
|
||||
}
|
||||
|
||||
if c.Token != "" {
|
||||
params.Set("token", c.Token)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", c.BaseURL, path)
|
||||
urlWithParams := fmt.Sprintf("%s?%s", url, params.Encode())
|
||||
|
||||
req, err := http.NewRequest("DELETE", urlWithParams, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Invalid DELETE request %s", url)
|
||||
}
|
||||
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP request failure on %s", url)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "HTTP Read error on response for %s", url)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(b))
|
||||
err = decoder.Decode(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "JSON decode failed on %s:\n%s", url, string(b))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) log(format string, args ...interface{}) {
|
||||
if c.Logger != nil {
|
||||
c.Logger.Debugf(format, args)
|
||||
}
|
||||
}
|
||||
55
vendor/github.com/adlio/trello/errors.go
generated
vendored
Normal file
55
vendor/github.com/adlio/trello/errors.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type notFoundError interface {
|
||||
IsNotFound() bool
|
||||
}
|
||||
|
||||
type rateLimitError interface {
|
||||
IsRateLimit() bool
|
||||
}
|
||||
|
||||
type permissionDeniedError interface {
|
||||
IsPermissionDenied() bool
|
||||
}
|
||||
|
||||
type httpClientError struct {
|
||||
msg string
|
||||
code int
|
||||
}
|
||||
|
||||
func makeHttpClientError(url string, resp *http.Response) error {
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
msg := fmt.Sprintf("HTTP request failure on %s:\n%d: %s", url, resp.StatusCode, string(body))
|
||||
|
||||
return &httpClientError{
|
||||
msg: msg,
|
||||
code: resp.StatusCode,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *httpClientError) Error() string { return e.msg }
|
||||
func (e *httpClientError) IsRateLimit() bool { return e.code == 429 }
|
||||
func (e *httpClientError) IsNotFound() bool { return e.code == 404 }
|
||||
func (e *httpClientError) IsPermissionDenied() bool { return e.code == 401 }
|
||||
|
||||
func IsRateLimit(err error) bool {
|
||||
re, ok := err.(rateLimitError)
|
||||
return ok && re.IsRateLimit()
|
||||
}
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
nf, ok := err.(notFoundError)
|
||||
return ok && nf.IsNotFound()
|
||||
}
|
||||
|
||||
func IsPermissionDenied(err error) bool {
|
||||
pd, ok := err.(permissionDeniedError)
|
||||
return ok && pd.IsPermissionDenied()
|
||||
}
|
||||
14
vendor/github.com/adlio/trello/label.go
generated
vendored
Normal file
14
vendor/github.com/adlio/trello/label.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
type Label struct {
|
||||
ID string `json:"id"`
|
||||
IDBoard string `json:"idBoard"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Uses int `json:"uses"`
|
||||
}
|
||||
9
vendor/github.com/adlio/trello/list-duration-sort.go
generated
vendored
Normal file
9
vendor/github.com/adlio/trello/list-duration-sort.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package trello
|
||||
|
||||
type ByFirstEntered []*ListDuration
|
||||
|
||||
func (durs ByFirstEntered) Len() int { return len(durs) }
|
||||
func (durs ByFirstEntered) Less(i, j int) bool {
|
||||
return durs[i].FirstEntered.Before(durs[j].FirstEntered)
|
||||
}
|
||||
func (durs ByFirstEntered) Swap(i, j int) { durs[i], durs[j] = durs[j], durs[i] }
|
||||
82
vendor/github.com/adlio/trello/list-duration.go
generated
vendored
Normal file
82
vendor/github.com/adlio/trello/list-duration.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package trello
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type ListDuration struct {
|
||||
ListID string
|
||||
ListName string
|
||||
Duration time.Duration
|
||||
FirstEntered time.Time
|
||||
TimesInList int
|
||||
}
|
||||
|
||||
func (l *ListDuration) AddDuration(d time.Duration) {
|
||||
l.Duration = l.Duration + d
|
||||
l.TimesInList++
|
||||
}
|
||||
|
||||
// Analytzes a Cards actions to figure out how long it was in each List
|
||||
func (c *Card) GetListDurations() (durations []*ListDuration, err error) {
|
||||
|
||||
var actions ActionCollection
|
||||
if len(c.Actions) == 0 {
|
||||
// Get all actions which affected the Card's List
|
||||
c.client.log("[trello] GetListDurations() called on card '%s' without any Card.Actions. Fetching fresh.", c.ID)
|
||||
actions, err = c.GetListChangeActions()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "GetListChangeActions() call failed.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
actions = c.Actions.FilterToListChangeActions()
|
||||
}
|
||||
|
||||
return actions.GetListDurations()
|
||||
}
|
||||
|
||||
func (actions ActionCollection) GetListDurations() (durations []*ListDuration, err error) {
|
||||
sort.Sort(actions)
|
||||
|
||||
var prevTime time.Time
|
||||
var prevList *List
|
||||
|
||||
durs := make(map[string]*ListDuration)
|
||||
for _, action := range actions {
|
||||
if action.DidChangeListForCard() {
|
||||
if prevList != nil {
|
||||
duration := action.Date.Sub(prevTime)
|
||||
_, durExists := durs[prevList.ID]
|
||||
if !durExists {
|
||||
durs[prevList.ID] = &ListDuration{ListID: prevList.ID, ListName: prevList.Name, Duration: duration, TimesInList: 1, FirstEntered: prevTime}
|
||||
} else {
|
||||
durs[prevList.ID].AddDuration(duration)
|
||||
}
|
||||
}
|
||||
prevList = ListAfterAction(action)
|
||||
prevTime = action.Date
|
||||
}
|
||||
}
|
||||
|
||||
if prevList != nil {
|
||||
duration := time.Now().Sub(prevTime)
|
||||
_, durExists := durs[prevList.ID]
|
||||
if !durExists {
|
||||
durs[prevList.ID] = &ListDuration{ListID: prevList.ID, ListName: prevList.Name, Duration: duration, TimesInList: 1, FirstEntered: prevTime}
|
||||
} else {
|
||||
durs[prevList.ID].AddDuration(duration)
|
||||
}
|
||||
}
|
||||
|
||||
durations = make([]*ListDuration, 0, len(durs))
|
||||
for _, ld := range durs {
|
||||
durations = append(durations, ld)
|
||||
}
|
||||
sort.Sort(ByFirstEntered(durations))
|
||||
|
||||
return durations, nil
|
||||
}
|
||||
51
vendor/github.com/adlio/trello/list.go
generated
vendored
Normal file
51
vendor/github.com/adlio/trello/list.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type List struct {
|
||||
client *Client
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IDBoard string `json:"idBoard,omitempty"`
|
||||
Closed bool `json:"closed"`
|
||||
Pos float32 `json:"pos,omitempty"`
|
||||
Board *Board `json:"board,omitempty"`
|
||||
Cards []*Card `json:"cards,omitempty"`
|
||||
}
|
||||
|
||||
func (l *List) CreatedAt() time.Time {
|
||||
t, _ := IDToTime(l.ID)
|
||||
return t
|
||||
}
|
||||
|
||||
func (c *Client) GetList(listID string, args Arguments) (list *List, err error) {
|
||||
path := fmt.Sprintf("lists/%s", listID)
|
||||
err = c.Get(path, args, &list)
|
||||
if list != nil {
|
||||
list.client = c
|
||||
for i := range list.Cards {
|
||||
list.Cards[i].client = c
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Board) GetLists(args Arguments) (lists []*List, err error) {
|
||||
path := fmt.Sprintf("boards/%s/lists", b.ID)
|
||||
err = b.client.Get(path, args, &lists)
|
||||
for i := range lists {
|
||||
lists[i].client = b.client
|
||||
for j := range lists[i].Cards {
|
||||
lists[i].Cards[j].client = b.client
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
118
vendor/github.com/adlio/trello/member-duration.go
generated
vendored
Normal file
118
vendor/github.com/adlio/trello/member-duration.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
package trello
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Used to track the periods of time which a user (member) is attached to a card.
|
||||
//
|
||||
type MemberDuration struct {
|
||||
MemberID string
|
||||
MemberName string
|
||||
FirstAdded time.Time
|
||||
Duration time.Duration
|
||||
active bool
|
||||
lastAdded time.Time
|
||||
}
|
||||
|
||||
type ByLongestDuration []*MemberDuration
|
||||
|
||||
func (d ByLongestDuration) Len() int { return len(d) }
|
||||
func (d ByLongestDuration) Less(i, j int) bool { return d[i].Duration > d[j].Duration }
|
||||
func (d ByLongestDuration) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
||||
|
||||
func (d *MemberDuration) addAsOf(t time.Time) {
|
||||
d.active = true
|
||||
if d.FirstAdded.IsZero() {
|
||||
d.FirstAdded = t
|
||||
}
|
||||
d.startTimerAsOf(t)
|
||||
}
|
||||
|
||||
func (d *MemberDuration) startTimerAsOf(t time.Time) {
|
||||
if d.active {
|
||||
d.lastAdded = t
|
||||
}
|
||||
}
|
||||
|
||||
func (d *MemberDuration) removeAsOf(t time.Time) {
|
||||
d.stopTimerAsOf(t)
|
||||
d.active = false
|
||||
d.lastAdded = time.Time{}
|
||||
}
|
||||
|
||||
func (d *MemberDuration) stopTimerAsOf(t time.Time) {
|
||||
if d.active {
|
||||
d.Duration = d.Duration + t.Sub(d.lastAdded)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Card) GetMemberDurations() (durations []*MemberDuration, err error) {
|
||||
var actions ActionCollection
|
||||
if len(c.Actions) == 0 {
|
||||
c.client.log("[trello] GetMemberDurations() called on card '%s' without any Card.Actions. Fetching fresh.", c.ID)
|
||||
actions, err = c.GetMembershipChangeActions()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "GetMembershipChangeActions() call failed.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
actions = c.Actions.FilterToCardMembershipChangeActions()
|
||||
}
|
||||
|
||||
return actions.GetMemberDurations()
|
||||
}
|
||||
|
||||
// Similar to GetListDurations(), this function returns a slice of MemberDuration objects,
|
||||
// which describes the length of time each member was attached to this card. Durations are
|
||||
// calculated such that being added to a card starts a timer for that member, and being removed
|
||||
// starts it again (so that if a person is added and removed multiple times, the duration
|
||||
// captures only the times which they were attached). Archiving the card also stops the timer.
|
||||
//
|
||||
func (actions ActionCollection) GetMemberDurations() (durations []*MemberDuration, err error) {
|
||||
sort.Sort(actions)
|
||||
durs := make(map[string]*MemberDuration)
|
||||
for _, action := range actions {
|
||||
if action.DidChangeCardMembership() {
|
||||
_, durExists := durs[action.Member.ID]
|
||||
if !durExists {
|
||||
switch action.Type {
|
||||
case "addMemberToCard":
|
||||
durs[action.Member.ID] = &MemberDuration{MemberID: action.Member.ID, MemberName: action.Member.FullName}
|
||||
durs[action.Member.ID].addAsOf(action.Date)
|
||||
case "removeMemberFromCard":
|
||||
// Surprisingly, this is possible. If a card was copied, and members were preserved, those
|
||||
// members exist on the card without a corresponding addMemberToCard action.
|
||||
t, _ := IDToTime(action.Data.Card.ID)
|
||||
durs[action.Member.ID] = &MemberDuration{MemberID: action.Member.ID, MemberName: action.Member.FullName, lastAdded: t}
|
||||
durs[action.Member.ID].removeAsOf(action.Date)
|
||||
}
|
||||
} else {
|
||||
switch action.Type {
|
||||
case "addMemberToCard":
|
||||
durs[action.Member.ID].addAsOf(action.Date)
|
||||
case "removeMemberFromCard":
|
||||
durs[action.Member.ID].removeAsOf(action.Date)
|
||||
}
|
||||
}
|
||||
} else if action.DidArchiveCard() {
|
||||
for id, _ := range durs {
|
||||
durs[id].stopTimerAsOf(action.Date)
|
||||
}
|
||||
} else if action.DidUnarchiveCard() {
|
||||
for id, _ := range durs {
|
||||
durs[id].startTimerAsOf(action.Date)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
durations = make([]*MemberDuration, 0, len(durs))
|
||||
for _, md := range durs {
|
||||
durations = append(durations, md)
|
||||
}
|
||||
// sort.Sort(ByLongestDuration(durations))
|
||||
return durations, nil
|
||||
}
|
||||
56
vendor/github.com/adlio/trello/member.go
generated
vendored
Normal file
56
vendor/github.com/adlio/trello/member.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Member struct {
|
||||
client *Client
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
FullName string `json:"fullName"`
|
||||
Initials string `json:"initials"`
|
||||
AvatarHash string `json:"avatarHash"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
func (c *Client) GetMember(memberID string, args Arguments) (member *Member, err error) {
|
||||
path := fmt.Sprintf("members/%s", memberID)
|
||||
err = c.Get(path, args, &member)
|
||||
if err == nil {
|
||||
member.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Organization) GetMembers(args Arguments) (members []*Member, err error) {
|
||||
path := fmt.Sprintf("organizations/%s/members", o.ID)
|
||||
err = o.client.Get(path, args, &members)
|
||||
for i := range members {
|
||||
members[i].client = o.client
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Board) GetMembers(args Arguments) (members []*Member, err error) {
|
||||
path := fmt.Sprintf("boards/%s/members", b.ID)
|
||||
err = b.client.Get(path, args, &members)
|
||||
for i := range members {
|
||||
members[i].client = b.client
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Card) GetMembers(args Arguments) (members []*Member, err error) {
|
||||
path := fmt.Sprintf("cards/%s/members", c.ID)
|
||||
err = c.client.Get(path, args, &members)
|
||||
for i := range members {
|
||||
members[i].client = c.client
|
||||
}
|
||||
return
|
||||
}
|
||||
31
vendor/github.com/adlio/trello/organization.go
generated
vendored
Normal file
31
vendor/github.com/adlio/trello/organization.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Organization struct {
|
||||
client *Client
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Desc string `json:"desc"`
|
||||
URL string `json:"url"`
|
||||
Website string `json:"website"`
|
||||
Products []string `json:"products"`
|
||||
PowerUps []string `json:"powerUps"`
|
||||
}
|
||||
|
||||
func (c *Client) GetOrganization(orgID string, args Arguments) (organization *Organization, err error) {
|
||||
path := fmt.Sprintf("organizations/%s", orgID)
|
||||
err = c.Get(path, args, &organization)
|
||||
if organization != nil {
|
||||
organization.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
57
vendor/github.com/adlio/trello/search.go
generated
vendored
Normal file
57
vendor/github.com/adlio/trello/search.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
type SearchResult struct {
|
||||
Options SearchOptions `json:"options"`
|
||||
Actions []*Action `json:"actions,omitempty"`
|
||||
Cards []*Card `json:"cards,omitempty"`
|
||||
Boards []*Board `json:"boards,omitempty"`
|
||||
Members []*Member `json:"members,omitempty"`
|
||||
}
|
||||
|
||||
type SearchOptions struct {
|
||||
Terms []SearchTerm `json:"terms"`
|
||||
Modifiers []SearchModifier `json:"modifiers,omitempty"`
|
||||
ModelTypes []string `json:"modelTypes,omitempty"`
|
||||
Partial bool `json:"partial"`
|
||||
}
|
||||
|
||||
type SearchModifier struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type SearchTerm struct {
|
||||
Text string `json:"text"`
|
||||
Negated bool `json:"negated,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Client) SearchCards(query string, args Arguments) (cards []*Card, err error) {
|
||||
args["query"] = query
|
||||
args["modelTypes"] = "cards"
|
||||
res := SearchResult{}
|
||||
err = c.Get("search", args, &res)
|
||||
cards = res.Cards
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) SearchBoards(query string, args Arguments) (boards []*Board, err error) {
|
||||
args["query"] = query
|
||||
args["modelTypes"] = "boards"
|
||||
res := SearchResult{}
|
||||
err = c.Get("search", args, &res)
|
||||
boards = res.Boards
|
||||
for _, board := range boards {
|
||||
board.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) SearchMembers(query string, args Arguments) (members []*Member, err error) {
|
||||
args["query"] = query
|
||||
err = c.Get("search/members", args, &members)
|
||||
return
|
||||
}
|
||||
37
vendor/github.com/adlio/trello/token.go
generated
vendored
Normal file
37
vendor/github.com/adlio/trello/token.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Token struct {
|
||||
client *Client
|
||||
ID string `json:"id"`
|
||||
DateCreated time.Time `json:"dateCreated"`
|
||||
DateExpires *time.Time `json:"dateExpires"`
|
||||
IDMember string `json:"idMember"`
|
||||
Identifier string `json:"identifier"`
|
||||
Permissions []Permission `json:"permissions"`
|
||||
}
|
||||
|
||||
type Permission struct {
|
||||
IDModel string `json:"idModel"`
|
||||
ModelType string `json:"modelType"`
|
||||
Read bool `json:"read"`
|
||||
Write bool `json:"write"`
|
||||
}
|
||||
|
||||
func (c *Client) GetToken(tokenID string, args Arguments) (token *Token, err error) {
|
||||
path := fmt.Sprintf("tokens/%s", tokenID)
|
||||
err = c.Get(path, args, &token)
|
||||
if token != nil {
|
||||
token.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
BIN
vendor/github.com/adlio/trello/trello-logo.png
generated
vendored
Normal file
BIN
vendor/github.com/adlio/trello/trello-logo.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
27
vendor/github.com/adlio/trello/trello.go
generated
vendored
Normal file
27
vendor/github.com/adlio/trello/trello.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func IDToTime(id string) (t time.Time, err error) {
|
||||
if id == "" {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
// The first 8 characters in the object ID are a Unix timestamp
|
||||
ts, err := strconv.ParseUint(id[:8], 16, 64)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "ID '%s' failed to convert to timestamp.", id)
|
||||
} else {
|
||||
t = time.Unix(int64(ts), 0)
|
||||
}
|
||||
return
|
||||
}
|
||||
111
vendor/github.com/adlio/trello/webhook.go
generated
vendored
Normal file
111
vendor/github.com/adlio/trello/webhook.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright © 2016 Aaron Longwell
|
||||
//
|
||||
// Use of this source code is governed by an MIT licese.
|
||||
// Details in the LICENSE file.
|
||||
|
||||
package trello
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Webhook is the Go representation of a webhook registered in Trello's systems.
|
||||
// Used when creating, modifying or deleting webhooks.
|
||||
//
|
||||
type Webhook struct {
|
||||
client *Client
|
||||
ID string `json:"id,omitempty"`
|
||||
IDModel string `json:"idModel"`
|
||||
Description string `json:"description"`
|
||||
CallbackURL string `json:"callbackURL"`
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
// BoardWebhookRequest is the object sent by Trello to a Webhook for Board-triggered
|
||||
// webhooks.
|
||||
//
|
||||
type BoardWebhookRequest struct {
|
||||
Model *Board
|
||||
Action *Action
|
||||
}
|
||||
|
||||
// ListWebhookRequest is the object sent by Trello to a Webhook for List-triggered
|
||||
// webhooks.
|
||||
//
|
||||
type ListWebhookRequest struct {
|
||||
Model *List
|
||||
Action *Action
|
||||
}
|
||||
|
||||
// CardWebhookRequest is the object sent by Trello to a Webhook for Card-triggered
|
||||
// webhooks.
|
||||
//
|
||||
type CardWebhookRequest struct {
|
||||
Model *Card
|
||||
Action *Action
|
||||
}
|
||||
|
||||
func (c *Client) CreateWebhook(webhook *Webhook) error {
|
||||
path := "webhooks"
|
||||
args := Arguments{"idModel": webhook.IDModel, "description": webhook.Description, "callbackURL": webhook.CallbackURL}
|
||||
err := c.Post(path, args, webhook)
|
||||
if err == nil {
|
||||
webhook.client = c
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) GetWebhook(webhookID string, args Arguments) (webhook *Webhook, err error) {
|
||||
path := fmt.Sprintf("webhooks/%s", webhookID)
|
||||
err = c.Get(path, args, &webhook)
|
||||
if webhook != nil {
|
||||
webhook.client = c
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *Token) GetWebhooks(args Arguments) (webhooks []*Webhook, err error) {
|
||||
path := fmt.Sprintf("tokens/%s/webhooks", t.ID)
|
||||
err = t.client.Get(path, args, &webhooks)
|
||||
return
|
||||
}
|
||||
|
||||
func GetBoardWebhookRequest(r *http.Request) (whr *BoardWebhookRequest, err error) {
|
||||
if r.Method == "HEAD" {
|
||||
return &BoardWebhookRequest{}, nil
|
||||
}
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err = decoder.Decode(&whr)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetBoardWebhookRequest() failed to decode '%s'.", r.URL)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetListWebhookRequest(r *http.Request) (whr *ListWebhookRequest, err error) {
|
||||
if r.Method == "HEAD" {
|
||||
return &ListWebhookRequest{}, nil
|
||||
}
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err = decoder.Decode(&whr)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetListWebhookRequest() failed to decode '%s'.", r.URL)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetCardWebhookRequest(r *http.Request) (whr *CardWebhookRequest, err error) {
|
||||
if r.Method == "HEAD" {
|
||||
return &CardWebhookRequest{}, nil
|
||||
}
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err = decoder.Decode(&whr)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "GetCardWebhookRequest() failed to decode '%s'.", r.URL)
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user