From a2771f9d20bcdb872619c8b69aeb9e2b4ae0bab9 Mon Sep 17 00:00:00 2001 From: b5 Date: Mon, 5 Mar 2018 12:45:10 -0500 Subject: [PATCH] feat(api.List): allow /list/[peer_id] --- api/datasets.go | 32 +++++++++++++++++++++----------- api/peers.go | 35 +++++++++++++++++++++++++++++++++-- api/server.go | 2 ++ core/datasets.go | 9 +++++++++ core/params.go | 1 + repo/profile/profile.go | 5 +++++ 6 files changed, 71 insertions(+), 13 deletions(-) diff --git a/api/datasets.go b/api/datasets.go index a62f54e2a..835381796 100644 --- a/api/datasets.go +++ b/api/datasets.go @@ -12,7 +12,6 @@ import ( "strings" util "github.com/datatogether/api/apiutil" - // "github.com/ipfs/go-datastore" "github.com/qri-io/cafs/memfs" "github.com/qri-io/dataset/dsutil" "github.com/qri-io/dsdiff" @@ -97,6 +96,7 @@ func (h *DatasetHandlers) DiffHandler(w http.ResponseWriter, r *http.Request) { // PeerListHandler is a dataset list endpoint func (h *DatasetHandlers) PeerListHandler(w http.ResponseWriter, r *http.Request) { + h.log.Infof("%s %s", r.Method, r.URL.Path) switch r.Method { case "OPTIONS": util.EmptyOkHandler(w, r) @@ -189,6 +189,7 @@ func (h *DatasetHandlers) zipDatasetHandler(w http.ResponseWriter, r *http.Reque func (h *DatasetHandlers) listHandler(w http.ResponseWriter, r *http.Request) { args := core.ListParamsFromRequest(r) args.OrderBy = "created" + res := []repo.DatasetRef{} if err := h.List(&args, &res); err != nil { h.log.Infof("error listing datasets: %s", err.Error()) @@ -286,18 +287,27 @@ func (h *DatasetHandlers) diffHandler(w http.ResponseWriter, r *http.Request) { } func (h *DatasetHandlers) peerListHandler(w http.ResponseWriter, r *http.Request) { + h.log.Info(r.URL.Path) p := core.ListParamsFromRequest(r) - ref, err := DatasetRefFromPath(r.URL.Path[len("/list/"):]) - if err != nil { - util.WriteErrResponse(w, http.StatusBadRequest, err) - return - } - if !ref.IsPeerRef() { - util.WriteErrResponse(w, http.StatusBadRequest, errors.New("request needs to be in the form '/list/[peername]'")) - return - } - p.Peername = ref.Peername p.OrderBy = "created" + + // TODO - cheap peerId detection + peerID := r.URL.Path[len("/list/"):] + if len(peerID) > 0 && peerID[:2] == "Qm" { + p.PeerID = peerID + } else { + ref, err := DatasetRefFromPath(r.URL.Path[len("/list/"):]) + if err != nil { + util.WriteErrResponse(w, http.StatusBadRequest, err) + return + } + if !ref.IsPeerRef() { + util.WriteErrResponse(w, http.StatusBadRequest, errors.New("request needs to be in the form '/list/[peername]'")) + return + } + p.Peername = ref.Peername + } + res := []repo.DatasetRef{} if err := h.List(&p, &res); err != nil { h.log.Infof("error listing peer's datasets: %s", err.Error()) diff --git a/api/peers.go b/api/peers.go index 7e073f0c8..b2a6cd33d 100644 --- a/api/peers.go +++ b/api/peers.go @@ -15,13 +15,14 @@ import ( // PeerHandlers wraps a requests struct to interface with http.HandlerFunc type PeerHandlers struct { core.PeerRequests - log logging.Logger + repo repo.Repo + log logging.Logger } // NewPeerHandlers allocates a PeerHandlers pointer func NewPeerHandlers(log logging.Logger, r repo.Repo, node *p2p.QriNode) *PeerHandlers { req := core.NewPeerRequests(node, nil) - h := PeerHandlers{*req, log} + h := PeerHandlers{*req, r, log} return &h } @@ -37,6 +38,18 @@ func (h *PeerHandlers) PeersHandler(w http.ResponseWriter, r *http.Request) { } } +// PeerHandler gets info on a single peer +func (h *PeerHandlers) PeerHandler(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case "OPTIONS": + util.EmptyOkHandler(w, r) + case "GET": + h.peerHandler(w, r) + default: + util.NotFoundHandler(w, r) + } +} + // TODO: add back connect endpoint // ConnectToPeerHandler is the endpoint for explicitly connecting to a peer // func (h *PeerHandlers) ConnectToPeerHandler(w http.ResponseWriter, r *http.Request) { @@ -89,6 +102,24 @@ func (h *PeerHandlers) listConnectionsHandler(w http.ResponseWriter, r *http.Req util.WriteResponse(w, peers) } +func (h *PeerHandlers) peerHandler(w http.ResponseWriter, r *http.Request) { + p := &core.PeerInfoParams{ + PeerID: r.URL.Path[len("/peers/"):], + } + res := &profile.Profile{} + if err := h.Info(p, res); err != nil { + h.log.Infof("error getting peer info: %s", err.Error()) + util.WriteErrResponse(w, http.StatusInternalServerError, err) + return + } + + util.WriteResponse(w, res) +} + +func (h *PeerHandlers) namespaceHandler(w http.ResponseWriter, r *http.Request) { + +} + // TODO: add back connect endpoint // func (h *PeerHandlers) connectToPeerHandler(w http.ResponseWriter, r *http.Request) { // b58pid := r.URL.Path[len("/connect/"):] diff --git a/api/server.go b/api/server.go index 0061cb835..8dc83167c 100644 --- a/api/server.go +++ b/api/server.go @@ -168,11 +168,13 @@ func NewServerRoutes(s *Server) *http.ServeMux { ph := NewPeerHandlers(s.log, s.qriNode.Repo, s.qriNode) m.Handle("/peers", s.middleware(ph.PeersHandler)) + m.Handle("/peers/", s.middleware(ph.PeerHandler)) // TODO - add back connect endpoint // m.Handle("/connect/", s.middleware(ph.ConnectToPeerHandler)) m.Handle("/connections", s.middleware(ph.ConnectionsHandler)) dsh := NewDatasetHandlers(s.log, s.qriNode.Repo) + // TODO - stupid hack for now. dsh.DatasetRequests.Node = s.qriNode m.Handle("/list", s.middleware(dsh.ListHandler)) diff --git a/core/datasets.go b/core/datasets.go index 30d187b61..e127bc84c 100644 --- a/core/datasets.go +++ b/core/datasets.go @@ -25,6 +25,7 @@ import ( "github.com/qri-io/jsonschema" "github.com/qri-io/qri/p2p" "github.com/qri-io/qri/repo" + "github.com/qri-io/qri/repo/profile" "github.com/qri-io/varName" ) @@ -69,6 +70,14 @@ func (r *DatasetRequests) List(p *ListParams, res *[]repo.DatasetRef) error { return fmt.Errorf("error canonicalizing peername: %s", err.Error()) } + if p.PeerID != "" { + if pid, err := profile.NewB58PeerID(p.PeerID); err == nil { + if peer, err := r.repo.Peers().GetPeer(pid); err == nil { + p.Peername = peer.Peername + } + } + } + if p.Peername != "" && r.Node != nil { replies, err := r.Node.RequestDatasetsList(p.Peername) *res = replies diff --git a/core/params.go b/core/params.go index 979a11782..b3ae7d19b 100644 --- a/core/params.go +++ b/core/params.go @@ -22,6 +22,7 @@ type GetParams struct { // ListParams define limits & offsets, not pages & page sizes. // TODO - rename this to PageParams. type ListParams struct { + PeerID string Peername string OrderBy string Limit int diff --git a/repo/profile/profile.go b/repo/profile/profile.go index 09233662b..dbe12bdaf 100644 --- a/repo/profile/profile.go +++ b/repo/profile/profile.go @@ -60,3 +60,8 @@ func (p *Profile) IPFSPeerID() (peer.ID, error) { } return "", fmt.Errorf("no IPFS Peer ID found") } + +// NewB58PeerID creates a peer.ID from a base58-encoded string +func NewB58PeerID(pid string) (peer.ID, error) { + return peer.IDB58Decode(pid) +}