forked from tangled.org/core
Something went wrong. Try again.
6.3 kB · 285 lines
Go
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286package knotclient
import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "strconv" "time"
"tangled.sh/tangled.sh/core/types")
type UnsignedClient struct { Url *url.URL client *http.Client}
func NewUnsignedClient(domain string, dev bool) (*UnsignedClient, error) { client := &http.Client{ Timeout: 5 * time.Second, }
scheme := "https" if dev { scheme = "http" } url, err := url.Parse(fmt.Sprintf("%s://%s", scheme, domain)) if err != nil { return nil, err }
unsignedClient := &UnsignedClient{ client: client, Url: url, }
return unsignedClient, nil}
func (us *UnsignedClient) newRequest(method, endpoint string, query url.Values, body []byte) (*http.Request, error) { reqUrl := us.Url.JoinPath(endpoint)
// add query parameters if query != nil { reqUrl.RawQuery = query.Encode() }
return http.NewRequest(method, reqUrl.String(), bytes.NewReader(body))}
func do[T any](us *UnsignedClient, req *http.Request) (*T, error) { resp, err := us.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("Error reading response body: %v", err) return nil, err }
var result T err = json.Unmarshal(body, &result) if err != nil { log.Printf("Error unmarshalling response body: %v", err) return nil, err }
return &result, nil}
func (us *UnsignedClient) Index(ownerDid, repoName, ref string) (*types.RepoIndexResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/tree/%s", ownerDid, repoName, ref) if ref == "" { endpoint = fmt.Sprintf("/%s/%s", ownerDid, repoName) }
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
return do[types.RepoIndexResponse](us, req)}
func (us *UnsignedClient) Log(ownerDid, repoName, ref string, page int) (*types.RepoLogResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/log/%s", ownerDid, repoName, url.PathEscape(ref))
query := url.Values{} query.Add("page", strconv.Itoa(page)) query.Add("per_page", strconv.Itoa(60))
req, err := us.newRequest(Method, endpoint, query, nil) if err != nil { return nil, err }
return do[types.RepoLogResponse](us, req)}
func (us *UnsignedClient) Branches(ownerDid, repoName string) (*types.RepoBranchesResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/branches", ownerDid, repoName)
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
return do[types.RepoBranchesResponse](us, req)}
func (us *UnsignedClient) Tags(ownerDid, repoName string) (*types.RepoTagsResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/tags", ownerDid, repoName)
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
return do[types.RepoTagsResponse](us, req)}
func (us *UnsignedClient) Branch(ownerDid, repoName, branch string) (*types.RepoBranchResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/branches/%s", ownerDid, repoName, url.PathEscape(branch))
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
return do[types.RepoBranchResponse](us, req)}
func (us *UnsignedClient) DefaultBranch(ownerDid, repoName string) (*types.RepoDefaultBranchResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/branches/default", ownerDid, repoName)
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
resp, err := us.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close()
var defaultBranch types.RepoDefaultBranchResponse if err := json.NewDecoder(resp.Body).Decode(&defaultBranch); err != nil { return nil, err }
return &defaultBranch, nil}
func (us *UnsignedClient) Capabilities() (*types.Capabilities, error) { const ( Method = "GET" Endpoint = "/capabilities" )
req, err := us.newRequest(Method, Endpoint, nil, nil) if err != nil { return nil, err }
resp, err := us.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close()
var capabilities types.Capabilities if err := json.NewDecoder(resp.Body).Decode(&capabilities); err != nil { return nil, err }
return &capabilities, nil}
func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoFormatPatchResponse, error) { const ( Method = "GET" )
endpoint := fmt.Sprintf("/%s/%s/compare/%s/%s", ownerDid, repoName, url.PathEscape(rev1), url.PathEscape(rev2))
req, err := us.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, fmt.Errorf("Failed to create request.") }
compareResp, err := us.client.Do(req) if err != nil { return nil, fmt.Errorf("Failed to create request.") } defer compareResp.Body.Close()
switch compareResp.StatusCode { case 404: case 400: return nil, fmt.Errorf("Branch comparisons not supported on this knot.") }
respBody, err := io.ReadAll(compareResp.Body) if err != nil { log.Println("failed to compare across branches") return nil, fmt.Errorf("Failed to compare branches.") } defer compareResp.Body.Close()
var formatPatchResponse types.RepoFormatPatchResponse err = json.Unmarshal(respBody, &formatPatchResponse) if err != nil { log.Println("failed to unmarshal format-patch response", err) return nil, fmt.Errorf("failed to compare branches.") }
return &formatPatchResponse, nil}
func (s *UnsignedClient) RepoLanguages(ownerDid, repoName, ref string) (*types.RepoLanguageResponse, error) { const ( Method = "GET" ) endpoint := fmt.Sprintf("/%s/%s/languages/%s", ownerDid, repoName, url.PathEscape(ref))
req, err := s.newRequest(Method, endpoint, nil, nil) if err != nil { return nil, err }
resp, err := s.client.Do(req) if err != nil { return nil, err }
var result types.RepoLanguageResponse if resp.StatusCode != http.StatusOK { log.Println("failed to calculate languages", resp.Status) return &types.RepoLanguageResponse{}, nil }
body, err := io.ReadAll(resp.Body) if err != nil { return nil, err }
err = json.Unmarshal(body, &result) if err != nil { return nil, err }
return &result, nil}