From aeae0569f8b7bbc9c166c830a606cb443e930d65 Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Wed, 8 Jun 2016 13:17:54 +0100 Subject: [PATCH] moved trello key to config, refactored s/s code --- .../components/section/github/type-editor.js | 3 +- .../components/section/trello/type-editor.js | 49 ++-- .../database/scripts/autobuild/db_00000.sql | 3 +- documize/section/gemini/gemini.go | 76 ------ documize/section/gemini/model.go | 89 +++++++ documize/section/github/github.go | 141 ++-------- documize/section/github/model.go | 107 ++++++++ documize/section/github/sort.go | 29 +++ documize/section/provider/provider.go | 6 + documize/section/trello/model.go | 200 ++++++++++++++ documize/section/trello/trello.go | 245 +++--------------- 11 files changed, 521 insertions(+), 427 deletions(-) create mode 100644 documize/section/gemini/model.go create mode 100644 documize/section/github/model.go create mode 100644 documize/section/github/sort.go create mode 100644 documize/section/trello/model.go diff --git a/app/app/components/section/github/type-editor.js b/app/app/components/section/github/type-editor.js index 3cbba94e..b942d596 100644 --- a/app/app/components/section/github/type-editor.js +++ b/app/app/components/section/github/type-editor.js @@ -24,7 +24,6 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, noRepos: false, didReceiveAttrs() { - let self = this; let page = this.get('page'); @@ -213,4 +212,4 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, }); } } -}); \ No newline at end of file +}); diff --git a/app/app/components/section/trello/type-editor.js b/app/app/components/section/trello/type-editor.js index aa30bc6c..e5aa6b7b 100644 --- a/app/app/components/section/trello/type-editor.js +++ b/app/app/components/section/trello/type-editor.js @@ -23,6 +23,7 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, config: {}, boards: null, noBoards: false, + appKey: "", boardStyle: Ember.computed('config.board', function() { let board = this.get('config.board'); @@ -36,16 +37,17 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, }), didReceiveAttrs() { - let config = {}; + let page = this.get('page'); + let config = {}; + let self = this; - try { + try { config = JSON.parse(this.get('meta.config')); } catch (e) {} if (is.empty(config)) { config = { - appKey: "8e00492ee9a8934cfb8604d3a51f8f70", token: "", user: null, board: null, @@ -55,23 +57,30 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, this.set('config', config); - // On auth callback capture user token - let hashToken = window.location.hash; - if (is.not.undefined(hashToken) && is.not.null(hashToken)) { - let token = hashToken.replace("#token=", ""); - if (is.not.empty(token)) { - this.set('config.token', token); - } - } + this.get('sectionService').fetch(page, "config", {}) + .then(function(s) { + self.set('appKey', s.appKey); - if (this.get('config.appKey') !== "" && this.get('config.token') !== "") { - this.send('auth'); - } - else { - Ember.$.getScript("https://api.trello.com/1/client.js?key=" + this.get('config.appKey'), function() { - Trello.deauthorize(); + // On auth callback capture user token + let hashToken = window.location.hash; + if (is.not.undefined(hashToken) && is.not.null(hashToken)) { + let token = hashToken.replace("#token=", ""); + if (is.not.empty(token)) { + self.set('config.token', token); + } + } + + if (self.get('appKey') !== "" && self.get('config.token') !== "") { + self.send('auth'); + } + else { + Ember.$.getScript("https://api.trello.com/1/client.js?key=" + self.get('appKey'), function() { + Trello.deauthorize(); + }); + } + }, function(error) { //jshint ignore: line + console.log(error); }); - } }, willDestroyElement() { @@ -144,7 +153,7 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, }, auth() { - if (this.get('config.appKey') === "") { + if (this.get('appKey') === "") { $("#trello-appkey").addClass('error').focus(); this.set('authenticated', false); return; @@ -155,7 +164,7 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, self.set('busy', true); - Ember.$.getScript("https://api.trello.com/1/client.js?key=" + this.get('config.appKey'), function() { + Ember.$.getScript("https://api.trello.com/1/client.js?key=" + this.get('appKey'), function() { Trello.authorize({ type: "redirect", interactive: true, diff --git a/documize/database/scripts/autobuild/db_00000.sql b/documize/database/scripts/autobuild/db_00000.sql index 5a632ebd..0c247b31 100644 --- a/documize/database/scripts/autobuild/db_00000.sql +++ b/documize/database/scripts/autobuild/db_00000.sql @@ -264,4 +264,5 @@ INSERT INTO `config` VALUES ('FILEPLUGINS', '[{\"Comment\": \"Disable (or not) built-in html import (NOTE: no Plugin name)\",\"Disabled\": false,\"API\": \"Convert\",\"Actions\": [\"htm\",\"html\"]},{\"Comment\": \"Disable (or not) built-in Documize API import used from SDK (NOTE: no Plugin name)\",\"Disabled\": false,\"API\": \"Convert\",\"Actions\": [\"documizeapi\"]}]'); INSERT INTO `config` VALUES ('LICENSE','{\"token\": \"\",\"endpoint\": \"https://api.documize.com\"}'); INSERT INTO `config` VALUES ('META','{\"database\": \"db_00000.sql\"}'); -INSERT INTO `documize`.`config` VALUES ( 'SECTION-GITHUB', '{\"clientID\": \"\", \"clientSecret\": \"\", \"authorizationCallbackURL\": \"https://localhost:5001/api/public/validate?section=github\"}' ); \ No newline at end of file +INSERT INTO `config` VALUES ('SECTION-GITHUB', '{\"clientID\": \"\", \"clientSecret\": \"\", \"authorizationCallbackURL\": \"https://localhost:5001/api/public/validate?section=github\"}'); +INSERT INTO `config` VALUES ('SECTION-TRELLO','{\"appKey\": \"\"}'); diff --git a/documize/section/gemini/gemini.go b/documize/section/gemini/gemini.go index 27b8332e..4478c286 100644 --- a/documize/section/gemini/gemini.go +++ b/documize/section/gemini/gemini.go @@ -19,43 +19,11 @@ import ( "html/template" "io/ioutil" "net/http" - "strings" "github.com/documize/community/documize/section/provider" "github.com/documize/community/wordsmith/log" ) -// the HTML that is rendered by this section. -const renderTemplate = ` -{{if .Authenticated}} -

The Gemini workspace {{.Config.WorkspaceName}} contains {{.Config.ItemCount}} items.

- - - - - - - - - - - {{$wid := .Config.WorkspaceID}} - {{$app := .Config.URL}} - {{range $item := .Items}} - - - - - - - {{end}} - -
Item KeyTitleTypeStatus
{{ $item.IssueKey }}{{ $item.Title }} {{ $item.Type }} {{ $item.Status }}
-{{else}} -

Authenticate with Gemini to see items.

-{{end}} -` - // Provider represents Gemini type Provider struct { } @@ -182,50 +150,6 @@ func (*Provider) Refresh(config, data string) (newData string) { return } -// Gemini helpers -type geminiRender struct { - Config geminiConfig - Items []geminiItem - Authenticated bool -} - -type geminiItem struct { - ID int64 - IssueKey string - Title string - Type string - TypeImage string - Status string - StatusImage string -} - -type geminiUser struct { - BaseEntity struct { - ID int `json:"id"` - Username string `json:"username"` - Firstname string `json:"firstname"` - Surname string `json:"surname"` - Email string `json:"email"` - } -} - -type geminiConfig struct { - URL string `json:"url"` - Username string `json:"username"` - APIKey string `json:"apikey"` - UserID int64 `json:"userId"` - WorkspaceID int64 `json:"workspaceId"` - WorkspaceName string `json:"workspaceName"` - ItemCount int `json:"itemCount"` - Filter map[string]interface{} `json:"filter"` -} - -func (c *geminiConfig) Clean() { - c.APIKey = strings.TrimSpace(c.APIKey) - c.Username = strings.TrimSpace(c.Username) - c.URL = strings.TrimSpace(c.URL) -} - func auth(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) diff --git a/documize/section/gemini/model.go b/documize/section/gemini/model.go new file mode 100644 index 00000000..edf68383 --- /dev/null +++ b/documize/section/gemini/model.go @@ -0,0 +1,89 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package gemini + +import "strings" + +// the HTML that is rendered by this section. +const renderTemplate = ` +{{if .Authenticated}} +

The Gemini workspace {{.Config.WorkspaceName}} contains {{.Config.ItemCount}} items.

+ + + + + + + + + + + {{$wid := .Config.WorkspaceID}} + {{$app := .Config.URL}} + {{range $item := .Items}} + + + + + + + {{end}} + +
Item KeyTitleTypeStatus
{{ $item.IssueKey }}{{ $item.Title }} {{ $item.Type }} {{ $item.Status }}
+{{else}} +

Authenticate with Gemini to see items.

+{{end}} +` + +// Gemini helpers +type geminiRender struct { + Config geminiConfig + Items []geminiItem + Authenticated bool +} + +type geminiItem struct { + ID int64 + IssueKey string + Title string + Type string + TypeImage string + Status string + StatusImage string +} + +type geminiUser struct { + BaseEntity struct { + ID int `json:"id"` + Username string `json:"username"` + Firstname string `json:"firstname"` + Surname string `json:"surname"` + Email string `json:"email"` + } +} + +type geminiConfig struct { + URL string `json:"url"` + Username string `json:"username"` + APIKey string `json:"apikey"` + UserID int64 `json:"userId"` + WorkspaceID int64 `json:"workspaceId"` + WorkspaceName string `json:"workspaceName"` + ItemCount int `json:"itemCount"` + Filter map[string]interface{} `json:"filter"` +} + +func (c *geminiConfig) Clean() { + c.APIKey = strings.TrimSpace(c.APIKey) + c.Username = strings.TrimSpace(c.Username) + c.URL = strings.TrimSpace(c.URL) +} diff --git a/documize/section/github/github.go b/documize/section/github/github.go index cbb888cc..671d2d2e 100644 --- a/documize/section/github/github.go +++ b/documize/section/github/github.go @@ -19,7 +19,6 @@ import ( "io/ioutil" "net/http" "net/url" - "sort" "strings" "time" @@ -31,36 +30,36 @@ import ( "golang.org/x/oauth2" ) +var meta provider.TypeMeta + +func init() { + meta = provider.TypeMeta{} + + meta.ID = "38c0e4c5-291c-415e-8a4d-262ee80ba5df" + meta.Title = "GitHub" + meta.Description = "Code commits and branches" + meta.ContentType = "github" + meta.Callback = Callback +} + // Provider represents GitHub type Provider struct { } // Meta describes us. func (*Provider) Meta() provider.TypeMeta { - section := provider.TypeMeta{} - - section.ID = "38c0e4c5-291c-415e-8a4d-262ee80ba5df" - section.Title = "GitHub" - section.Description = "Code commits and branches" - section.ContentType = "github" - //section.Preview = true - - section.Callback = Callback - - return section + return meta } -const configKey = "SECTION-GITHUB" - func clientID() string { - return request.ConfigString(configKey, "clientID") + return request.ConfigString(meta.ConfigHandle(), "clientID") } func clientSecret() string { - return request.ConfigString(configKey, "clientSecret") + return request.ConfigString(meta.ConfigHandle(), "clientSecret") } func authorizationCallbackURL() string { // NOTE: URL value must have the path and query "/api/public/validate?section=github" - return request.ConfigString(configKey, "authorizationCallbackURL") + return request.ConfigString(meta.ConfigHandle(), "authorizationCallbackURL") } // Command to run the various functions required... @@ -359,34 +358,7 @@ func (*Provider) Render(config, data string) string { t := template.New("github") var err error - t, err = t.Parse(` -
-

There are {{ .CommitCount }} commits for branch {{.Config.Branch}} of repository {{.Repo.Name}}.

-
- {{range $data := .Data}} -
- Commits on {{ $data.Day }} -
- - {{end}} -
-
-`) + t, err = t.Parse(renderTemplate) if err != nil { log.Error("github render template.Parse error:", err) @@ -403,85 +375,6 @@ func (*Provider) Render(config, data string) string { return buffer.String() } -type githubRepo struct { - ID string `json:"id"` - Name string `json:"name"` - Included bool `json:"included"` - Owner string `json:"owner"` - Repo string `json:"repo"` - Private bool `json:"private"` // TODO review field use - URL string `json:"url"` -} - -// sort repos in order that that should be presented. -type reposToSort []githubRepo - -func (s reposToSort) Len() int { return len(s) } -func (s reposToSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s reposToSort) Less(i, j int) bool { - return s[i].Name < s[j].Name -} - -func sortRepos(in []githubRepo) []githubRepo { - sts := reposToSort(in) - sort.Sort(sts) - return []githubRepo(sts) -} - -type githubBranch struct { - ID string `json:"id"` - Name string `json:"name"` - Included bool `json:"included"` - URL string `json:"url"` -} - -type githubBranchCommits struct { - Name string `json:"name"` - Day string `json:"day"` - Commits []githubCommit -} - -type githubCommit struct { - Date string `json:"date"` - Message string `json:"message"` - URL string `json:"url"` - Name string `json:"name"` - Avatar string `json:"avatar"` -} - -type githubConfig struct { - AppKey string `json:"appKey"` // TODO keep? - Token string `json:"token"` - Owner string `json:"owner"` - Repo string `json:"repo_name"` - Branch string `json:"branch"` - BranchURL string `json:"branchURL"` - BranchSince string `json:"branchSince"` - BranchLines int `json:"branchLines"` - RepoInfo githubRepo `json:"repo"` - ClientID string `json:"clientId"` - CallbackURL string `json:"callbackUrl"` - Lists []githubBranch `json:"lists"` -} - -func (c *githubConfig) Clean() { - c.AppKey = strings.TrimSpace(c.AppKey) // TODO keep? - c.Token = strings.TrimSpace(c.Token) - c.Owner = c.RepoInfo.Owner - c.Repo = c.RepoInfo.Repo - for _, l := range c.Lists { - if l.Included { - c.Branch = l.Name - c.BranchURL = l.URL - break - } - } -} - -type githubCallbackT struct { - AccessToken string `json:"access_token"` -} - // Callback is called by a browser redirect from Github, via the validation endpoint func Callback(res http.ResponseWriter, req *http.Request) error { diff --git a/documize/section/github/model.go b/documize/section/github/model.go new file mode 100644 index 00000000..0452906a --- /dev/null +++ b/documize/section/github/model.go @@ -0,0 +1,107 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +import "strings" + +const renderTemplate = ` +
+

There are {{ .CommitCount }} commits for branch {{.Config.Branch}} of repository {{.Repo.Name}}.

+
+ {{range $data := .Data}} +
+ Commits on {{ $data.Day }} +
+ + {{end}} +
+
+` + +type githubRepo struct { + ID string `json:"id"` + Name string `json:"name"` + Included bool `json:"included"` + Owner string `json:"owner"` + Repo string `json:"repo"` + Private bool `json:"private"` // TODO review field use + URL string `json:"url"` +} + +type githubBranch struct { + ID string `json:"id"` + Name string `json:"name"` + Included bool `json:"included"` + URL string `json:"url"` +} + +type githubBranchCommits struct { + Name string `json:"name"` + Day string `json:"day"` + Commits []githubCommit +} + +type githubCommit struct { + Date string `json:"date"` + Message string `json:"message"` + URL string `json:"url"` + Name string `json:"name"` + Avatar string `json:"avatar"` +} + +type githubConfig struct { + AppKey string `json:"appKey"` // TODO keep? + Token string `json:"token"` + Owner string `json:"owner"` + Repo string `json:"repo_name"` + Branch string `json:"branch"` + BranchURL string `json:"branchURL"` + BranchSince string `json:"branchSince"` + BranchLines int `json:"branchLines"` + RepoInfo githubRepo `json:"repo"` + ClientID string `json:"clientId"` + CallbackURL string `json:"callbackUrl"` + Lists []githubBranch `json:"lists"` +} + +func (c *githubConfig) Clean() { + c.AppKey = strings.TrimSpace(c.AppKey) // TODO keep? + c.Token = strings.TrimSpace(c.Token) + c.Owner = c.RepoInfo.Owner + c.Repo = c.RepoInfo.Repo + for _, l := range c.Lists { + if l.Included { + c.Branch = l.Name + c.BranchURL = l.URL + break + } + } +} + +type githubCallbackT struct { + AccessToken string `json:"access_token"` +} diff --git a/documize/section/github/sort.go b/documize/section/github/sort.go new file mode 100644 index 00000000..34ee9749 --- /dev/null +++ b/documize/section/github/sort.go @@ -0,0 +1,29 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package github + +import "sort" + +// sort repos in order that that should be presented. +type reposToSort []githubRepo + +func (s reposToSort) Len() int { return len(s) } +func (s reposToSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s reposToSort) Less(i, j int) bool { + return s[i].Name < s[j].Name +} + +func sortRepos(in []githubRepo) []githubRepo { + sts := reposToSort(in) + sort.Sort(sts) + return []githubRepo(sts) +} diff --git a/documize/section/provider/provider.go b/documize/section/provider/provider.go index 88f857ac..cffd3cc3 100644 --- a/documize/section/provider/provider.go +++ b/documize/section/provider/provider.go @@ -17,6 +17,7 @@ import ( "fmt" "net/http" "sort" + "strings" "github.com/documize/community/wordsmith/log" ) @@ -35,6 +36,11 @@ type TypeMeta struct { Callback func(http.ResponseWriter, *http.Request) error `json:"-"` } +// ConfigHandle returns the key name for database config table +func (t *TypeMeta) ConfigHandle() string { + return fmt.Sprintf("SECTION-%s", strings.ToUpper(t.ContentType)) +} + // Provider represents a 'page' in a document. type Provider interface { Meta() TypeMeta // Meta returns section details diff --git a/documize/section/trello/model.go b/documize/section/trello/model.go new file mode 100644 index 00000000..7e3380b1 --- /dev/null +++ b/documize/section/trello/model.go @@ -0,0 +1,200 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +package trello + +import "strings" + +const renderTemplate = ` +
+

There are {{ .CardCount }} cards across {{ .ListCount }} lists for board {{.Board.Name}}.

+
+
{{.Board.Name}}
+ {{range $data := .Data}} +
+
{{ $data.List.Name }}
+ {{range $card := $data.Cards}} + +
+ {{ $card.Name }} +
+
+ {{end}} +
+ {{end}} +
+
+` + +type trelloConfig struct { + AppKey string `json:"appKey"` + Token string `json:"token"` + Board trelloBoard `json:"board"` + Lists []trelloList `json:"lists"` +} + +func (c *trelloConfig) Clean() { + c.AppKey = strings.TrimSpace(c.AppKey) + c.Token = strings.TrimSpace(c.Token) +} + +// Trello objects based upon https://github.com/VojtechVitek/go-trello +type trelloMember struct { + ID string `json:"id"` + AvatarHash string `json:"avatarHash"` + Bio string `json:"bio"` + BioData struct { + Emoji interface{} `json:"emoji,omitempty"` + } `json:"bioData"` + Confirmed bool `json:"confirmed"` + FullName string `json:"fullName"` + PremOrgsAdminID []string `json:"idPremOrgsAdmin"` + Initials string `json:"initials"` + MemberType string `json:"memberType"` + Products []int `json:"products"` + Status string `json:"status"` + URL string `json:"url"` + Username string `json:"username"` + AvatarSource string `json:"avatarSource"` + Email string `json:"email"` + GravatarHash string `json:"gravatarHash"` + BoardsID []string `json:"idBoards"` + BoardsPinnedID []string `json:"idBoardsPinned"` + OrganizationsID []string `json:"idOrganizations"` + LoginTypes []string `json:"loginTypes"` + NewEmail string `json:"newEmail"` + OneTimeMessagesDismissed []string `json:"oneTimeMessagesDismissed"` + Prefs struct { + SendSummaries bool `json:"sendSummaries"` + MinutesBetweenSummaries int `json:"minutesBetweenSummaries"` + MinutesBeforeDeadlineToNotify int `json:"minutesBeforeDeadlineToNotify"` + ColorBlind bool `json:"colorBlind"` + Locale string `json:"locale"` + } `json:"prefs"` + Trophies []string `json:"trophies"` + UploadedAvatarHash string `json:"uploadedAvatarHash"` + PremiumFeatures []string `json:"premiumFeatures"` +} + +type trelloBoard struct { + ID string `json:"id"` + Name string `json:"name"` + Closed bool `json:"closed"` + OrganizationID string `json:"idOrganization"` + Pinned bool `json:"pinned"` + URL string `json:"url"` + ShortURL string `json:"shortUrl"` + Desc string `json:"desc"` + DescData struct { + Emoji struct{} `json:"emoji"` + } `json:"descData"` + 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 []trelloBoardBackground `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 { + Red string `json:"red"` + Orange string `json:"orange"` + Yellow string `json:"yellow"` + Green string `json:"green"` + Blue string `json:"blue"` + Purple string `json:"purple"` + } `json:"labelNames"` +} + +type trelloBoardBackground struct { + Width int `json:"width"` + Height int `json:"height"` + URL string `json:"url"` +} + +type trelloList struct { + ID string `json:"id"` + Name string `json:"name"` + Closed bool `json:"closed"` + BoardID string `json:"idBoard"` + Pos float32 `json:"pos"` + Included bool `json:"included"` // indicates whether we display cards from this list +} + +type trelloCard struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + ShortID int `json:"idShort"` + AttachmentCoverID string `json:"idAttachmentCover"` + CheckListsID []string `json:"idCheckLists"` + BoardID string `json:"idBoard"` + ListID string `json:"idList"` + MembersID []string `json:"idMembers"` + MembersVotedID []string `json:"idMembersVoted"` + ManualCoverAttachment bool `json:"manualCoverAttachment"` + Closed bool `json:"closed"` + Pos float32 `json:"pos"` + ShortLink string `json:"shortLink"` + DateLastActivity string `json:"dateLastActivity"` + ShortURL string `json:"shortUrl"` + Subscribed bool `json:"subscribed"` + URL string `json:"url"` + Due string `json:"due"` + Desc string `json:"desc"` + DescData struct { + Emoji struct{} `json:"emoji"` + } `json:"descData"` + CheckItemStates []struct { + CheckItemID string `json:"idCheckItem"` + State string `json:"state"` + } `json:"checkItemStates"` + Badges struct { + Votes int `json:"votes"` + ViewingMemberVoted bool `json:"viewingMemberVoted"` + Subscribed bool `json:"subscribed"` + Fogbugz string `json:"fogbugz"` + CheckItems int `json:"checkItems"` + CheckItemsChecked int `json:"checkItemsChecked"` + Comments int `json:"comments"` + Attachments int `json:"attachments"` + Description bool `json:"description"` + Due string `json:"due"` + } `json:"badges"` + Labels []struct { + Color string `json:"color"` + Name string `json:"name"` + } `json:"labels"` +} + +type trelloListCards struct { + List trelloList + Cards []trelloCard +} + +type trelloRender struct { + Board trelloBoard + Data []trelloListCards + CardCount int + ListCount int +} diff --git a/documize/section/trello/trello.go b/documize/section/trello/trello.go index 4b8f52a2..e088c02d 100644 --- a/documize/section/trello/trello.go +++ b/documize/section/trello/trello.go @@ -18,25 +18,30 @@ import ( "html/template" "io/ioutil" "net/http" - "strings" + "github.com/documize/community/documize/api/request" "github.com/documize/community/documize/section/provider" "github.com/documize/community/wordsmith/log" ) +var meta provider.TypeMeta +var appKey string + +func init() { + meta = provider.TypeMeta{} + meta.ID = "c455a552-202e-441c-ad79-397a8152920b" + meta.Title = "Trello" + meta.Description = "Embed cards from boards and lists" + meta.ContentType = "trello" +} + // Provider represents Trello type Provider struct { } // Meta describes us func (*Provider) Meta() provider.TypeMeta { - section := provider.TypeMeta{} - section.ID = "c455a552-202e-441c-ad79-397a8152920b" - section.Title = "Trello" - section.Description = "Embed cards from boards and lists" - section.ContentType = "trello" - - return section + return meta } // Command stub. @@ -65,16 +70,23 @@ func (*Provider) Command(w http.ResponseWriter, r *http.Request) { return } - config.Clean() - - if len(config.AppKey) == 0 { - provider.WriteMessage(w, "trello", "Missing appKey") - return + if appKey == "" { + appKey = request.ConfigString(meta.ConfigHandle(), "appKey") } - if len(config.Token) == 0 { - provider.WriteMessage(w, "trello", "Missing token") - return + config.Clean() + config.AppKey = appKey + + if method != "config" { + if len(config.AppKey) == 0 { + provider.WriteMessage(w, "trello", "Missing appKey") + return + } + + if len(config.Token) == 0 { + provider.WriteMessage(w, "trello", "Missing token") + return + } } switch method { @@ -110,6 +122,18 @@ func (*Provider) Command(w http.ResponseWriter, r *http.Request) { } provider.WriteJSON(w, render) + + case "config": + if method == "config" { + var config struct { + AppKey string `json:"appKey"` + } + + fmt.Println(appKey) + config.AppKey = appKey + provider.WriteJSON(w, config) + return + } } } @@ -131,7 +155,7 @@ func (*Provider) Render(config, data string) string { } t := template.New("trello") - t, _ = t.Parse(trelloTemplate) + t, _ = t.Parse(renderTemplate) buffer := new(bytes.Buffer) t.Execute(buffer, payload) @@ -260,190 +284,3 @@ func getCards(config trelloConfig) (listCards []trelloListCards, err error) { return listCards, nil } - -type trelloConfig struct { - AppKey string `json:"appKey"` - Token string `json:"token"` - Board trelloBoard `json:"board"` - Lists []trelloList `json:"lists"` -} - -func (c *trelloConfig) Clean() { - c.AppKey = strings.TrimSpace(c.AppKey) - c.Token = strings.TrimSpace(c.Token) -} - -// Trello objects based upon https://github.com/VojtechVitek/go-trello -type trelloMember struct { - ID string `json:"id"` - AvatarHash string `json:"avatarHash"` - Bio string `json:"bio"` - BioData struct { - Emoji interface{} `json:"emoji,omitempty"` - } `json:"bioData"` - Confirmed bool `json:"confirmed"` - FullName string `json:"fullName"` - PremOrgsAdminID []string `json:"idPremOrgsAdmin"` - Initials string `json:"initials"` - MemberType string `json:"memberType"` - Products []int `json:"products"` - Status string `json:"status"` - URL string `json:"url"` - Username string `json:"username"` - AvatarSource string `json:"avatarSource"` - Email string `json:"email"` - GravatarHash string `json:"gravatarHash"` - BoardsID []string `json:"idBoards"` - BoardsPinnedID []string `json:"idBoardsPinned"` - OrganizationsID []string `json:"idOrganizations"` - LoginTypes []string `json:"loginTypes"` - NewEmail string `json:"newEmail"` - OneTimeMessagesDismissed []string `json:"oneTimeMessagesDismissed"` - Prefs struct { - SendSummaries bool `json:"sendSummaries"` - MinutesBetweenSummaries int `json:"minutesBetweenSummaries"` - MinutesBeforeDeadlineToNotify int `json:"minutesBeforeDeadlineToNotify"` - ColorBlind bool `json:"colorBlind"` - Locale string `json:"locale"` - } `json:"prefs"` - Trophies []string `json:"trophies"` - UploadedAvatarHash string `json:"uploadedAvatarHash"` - PremiumFeatures []string `json:"premiumFeatures"` -} - -type trelloBoard struct { - ID string `json:"id"` - Name string `json:"name"` - Closed bool `json:"closed"` - OrganizationID string `json:"idOrganization"` - Pinned bool `json:"pinned"` - URL string `json:"url"` - ShortURL string `json:"shortUrl"` - Desc string `json:"desc"` - DescData struct { - Emoji struct{} `json:"emoji"` - } `json:"descData"` - 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 []trelloBoardBackground `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 { - Red string `json:"red"` - Orange string `json:"orange"` - Yellow string `json:"yellow"` - Green string `json:"green"` - Blue string `json:"blue"` - Purple string `json:"purple"` - } `json:"labelNames"` -} - -type trelloBoardBackground struct { - Width int `json:"width"` - Height int `json:"height"` - URL string `json:"url"` -} - -type trelloList struct { - ID string `json:"id"` - Name string `json:"name"` - Closed bool `json:"closed"` - BoardID string `json:"idBoard"` - Pos float32 `json:"pos"` - Included bool `json:"included"` // indicates whether we display cards from this list -} - -type trelloCard struct { - ID string `json:"id"` - Name string `json:"name"` - Email string `json:"email"` - ShortID int `json:"idShort"` - AttachmentCoverID string `json:"idAttachmentCover"` - CheckListsID []string `json:"idCheckLists"` - BoardID string `json:"idBoard"` - ListID string `json:"idList"` - MembersID []string `json:"idMembers"` - MembersVotedID []string `json:"idMembersVoted"` - ManualCoverAttachment bool `json:"manualCoverAttachment"` - Closed bool `json:"closed"` - Pos float32 `json:"pos"` - ShortLink string `json:"shortLink"` - DateLastActivity string `json:"dateLastActivity"` - ShortURL string `json:"shortUrl"` - Subscribed bool `json:"subscribed"` - URL string `json:"url"` - Due string `json:"due"` - Desc string `json:"desc"` - DescData struct { - Emoji struct{} `json:"emoji"` - } `json:"descData"` - CheckItemStates []struct { - CheckItemID string `json:"idCheckItem"` - State string `json:"state"` - } `json:"checkItemStates"` - Badges struct { - Votes int `json:"votes"` - ViewingMemberVoted bool `json:"viewingMemberVoted"` - Subscribed bool `json:"subscribed"` - Fogbugz string `json:"fogbugz"` - CheckItems int `json:"checkItems"` - CheckItemsChecked int `json:"checkItemsChecked"` - Comments int `json:"comments"` - Attachments int `json:"attachments"` - Description bool `json:"description"` - Due string `json:"due"` - } `json:"badges"` - Labels []struct { - Color string `json:"color"` - Name string `json:"name"` - } `json:"labels"` -} - -type trelloListCards struct { - List trelloList - Cards []trelloCard -} - -type trelloRender struct { - Board trelloBoard - Data []trelloListCards - CardCount int - ListCount int -} - -// the HTML that is rendered by this section -const trelloTemplate = ` -
-

There are {{ .CardCount }} cards across {{ .ListCount }} lists for board {{.Board.Name}}.

-
-
{{.Board.Name}}
- {{range $data := .Data}} -
-
{{ $data.List.Name }}
- {{range $card := $data.Cards}} - -
- {{ $card.Name }} -
-
- {{end}} -
- {{end}} -
-
-`