From 3268032ec31716f802f76c9649cc6787c8c22484 Mon Sep 17 00:00:00 2001 From: michael dewar Date: Sun, 27 Sep 2015 16:37:29 -0400 Subject: [PATCH] basic anon gist upload; starting on user token added super basic settings file functionality updated server test with settings moving to github package for gists export working gist import by id removed debug logging odd typo removed references to Autosave --- server/block.go | 2 +- server/group.go | 140 +++++++++++++++++++++++++++++++++++++++++++++-- server/router.go | 12 ++++ server/server.go | 2 - 4 files changed, 148 insertions(+), 8 deletions(-) diff --git a/server/block.go b/server/block.go index 3671f8b..2d9b0e6 100644 --- a/server/block.go +++ b/server/block.go @@ -134,7 +134,7 @@ func (s *Server) BlockModifyPositionHandler(w http.ResponseWriter, r *http.Reque func (s *Server) CreateBlock(p ProtoBlock) (*BlockLedger, error) { blockSpec, ok := s.library[p.Type] if !ok { - return nil, errors.New("spec not found") + return nil, errors.New("spec " + p.Type + " not found") } block := core.NewBlock(blockSpec) diff --git a/server/group.go b/server/group.go index 3f46e0e..cfb5373 100644 --- a/server/group.go +++ b/server/group.go @@ -4,14 +4,19 @@ import ( "encoding/json" "errors" "io/ioutil" + "log" "net/http" "strconv" + "strings" + "github.com/google/go-github/github" "github.com/gorilla/mux" "github.com/nytlabs/st-core/core" + "golang.org/x/oauth2" ) type Pattern struct { + Label string `json:"label"` Blocks []BlockLedger `json:"blocks"` Connections []ConnectionLedger `json:"connections"` Groups []Group `json:"groups"` @@ -295,8 +300,92 @@ func (s *Server) GroupExportHandler(w http.ResponseWriter, r *http.Request) { writeJSON(w, p) } +func (s *Server) newGithubClient() *github.Client { + client := github.NewClient(nil) + + // check to see if we should auth into github + if s.settings.GithubUserToken != "" { + log.Println("authenticating with github") + // auth + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: s.settings.GithubUserToken}, + ) + tc := oauth2.NewClient(oauth2.NoContext, ts) + + client = github.NewClient(tc) + } + return client + +} + +func (s *Server) GroupExportGistHandler(w http.ResponseWriter, r *http.Request) { + id, err := getIDFromMux(mux.Vars(r)) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, err) + return + } + + s.Lock() + defer s.Unlock() + p, err := s.Export(id) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + + client := s.newGithubClient() + + contentBytes, err := json.Marshal(p) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + + fname := strings.Replace(p.Label, " ", "_", -1) + ".json" + + public := true + content := string(contentBytes) + + g := github.Gist{ + Description: &p.Label, + Public: &public, + Files: map[github.GistFilename]github.GistFile{ + github.GistFilename(fname): github.GistFile{ + Content: &content, + }, + }, + } + + gist, _, err := client.Gists.Create(&g) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + + gistBytes, err := json.Marshal(gist) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.Write(gistBytes) +} + func (s *Server) ExportGroup(id int) (*Pattern, error) { + + g, ok := s.groups[id] + if !ok { + return nil, errors.New("could not find group to export") + } + p := &Pattern{ + Label: g.Label, Blocks: []BlockLedger{}, Sources: []SourceLedger{}, Groups: []Group{}, @@ -304,11 +393,6 @@ func (s *Server) ExportGroup(id int) (*Pattern, error) { Links: []LinkLedger{}, } - g, ok := s.groups[id] - if !ok { - return nil, errors.New("could not find group to export") - } - p.Groups = append(p.Groups, *g) for _, c := range g.Children { if b, ok := s.blocks[c]; ok { @@ -372,6 +456,52 @@ func (s *Server) Export(id int) (*Pattern, error) { return p, nil } +func (s *Server) GroupImportGistHandler(w http.ResponseWriter, r *http.Request) { + + gist_id := r.URL.Query().Get("id") + if gist_id == "" { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, errors.New("must provide gist id to import")) + } + c := s.newGithubClient() + g, _, err := c.Gists.Get(gist_id) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, err) + return + } + + id, err := getIDFromMux(mux.Vars(r)) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, err) + return + } + + for filename, file := range g.Files { + var p Pattern + p.Label = strings.TrimSuffix(string(filename), ".json") + err = json.Unmarshal([]byte(*file.Content), &p) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + s.Lock() + defer s.Unlock() + + _, err = s.ImportGroup(id, p) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + writeJSON(w, Error{err.Error()}) + return + } + } + w.WriteHeader(http.StatusOK) + //writeJSON(w, snew) + +} + func (s *Server) GroupImportHandler(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { diff --git a/server/router.go b/server/router.go index 1b3e56c..ce03534 100644 --- a/server/router.go +++ b/server/router.go @@ -57,12 +57,24 @@ func (s *Server) NewRouter() *mux.Router { "GET", s.GroupExportHandler, }, + Route{ + "GroupExportGist", + "/groups/{id}/export/gist", + "GET", + s.GroupExportGistHandler, + }, Route{ "GroupImport", "/groups/{id}/import", "POST", s.GroupImportHandler, }, + Route{ + "GroupImportGist", + "/groups/{id}/import/gist", + "GET", + s.GroupImportGistHandler, + }, Route{ "GroupModifyLabel", "/groups/{id}/label", diff --git a/server/server.go b/server/server.go index 3ab6a8d..1c60626 100644 --- a/server/server.go +++ b/server/server.go @@ -29,14 +29,12 @@ const ( // user-session specific settings type Settings struct { - Autosave bool GithubUserToken string } // NewSettings returns the default settings object func NewSettings() Settings { return Settings{ - Autosave: true, GithubUserToken: "", } }