mirror of
https://github.com/therootcompany/golib.git
synced 2026-11-04 06:55:00 +00:00
feat(gsheet2csv): add context and custom-client APIs
Add non-breaking context-aware and custom-HTTP-client variants of the existing reader and fetch functions: - NewReaderFromContext / NewReaderFromContextWith - NewReaderFromURLContext / NewReaderFromURLWith - NewReaderFromIDsContext - GetSheetContext All existing function signatures are unchanged. The shared response handling is extracted into newReaderFromResponse, and the legacy GetSheet path is refactored through getSheetWithGet for clarity.
This commit is contained in:
parent
bb488fe230
commit
a16ec976bb
@ -12,6 +12,7 @@
|
|||||||
package gsheet2csv
|
package gsheet2csv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -48,6 +49,19 @@ type Reader struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReaderFromContext is NewReaderFrom with request cancellation.
|
||||||
|
func NewReaderFromContext(ctx context.Context, urlOrPath string) *Reader {
|
||||||
|
return NewReaderFromContextWith(ctx, httpClient, urlOrPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReaderFromContextWith is NewReaderFromContext with a custom HTTP client.
|
||||||
|
func NewReaderFromContextWith(ctx context.Context, client *http.Client, urlOrPath string) *Reader {
|
||||||
|
if strings.HasPrefix(urlOrPath, "https://") || strings.HasPrefix(urlOrPath, "http://") {
|
||||||
|
return NewReaderFromURLWith(ctx, client, urlOrPath)
|
||||||
|
}
|
||||||
|
return NewReaderFrom(urlOrPath)
|
||||||
|
}
|
||||||
|
|
||||||
func NewReaderFrom(urlOrPath string) *Reader {
|
func NewReaderFrom(urlOrPath string) *Reader {
|
||||||
if strings.HasPrefix(urlOrPath, "https://") || strings.HasPrefix(urlOrPath, "http://") {
|
if strings.HasPrefix(urlOrPath, "https://") || strings.HasPrefix(urlOrPath, "http://") {
|
||||||
return NewReaderFromURL(urlOrPath)
|
return NewReaderFromURL(urlOrPath)
|
||||||
@ -64,14 +78,34 @@ func NewReaderFrom(urlOrPath string) *Reader {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewReaderFromURLContext(ctx context.Context, url string) *Reader {
|
||||||
|
return NewReaderFromURLWith(ctx, httpClient, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReaderFromURLWith is NewReaderFromURLContext with a custom HTTP client.
|
||||||
|
func NewReaderFromURLWith(ctx context.Context, client *http.Client, url string) *Reader {
|
||||||
|
docid, gid := ParseIDs(url)
|
||||||
|
return NewReaderFromIDsContext(ctx, client, docid, gid)
|
||||||
|
}
|
||||||
|
|
||||||
func NewReaderFromURL(url string) *Reader {
|
func NewReaderFromURL(url string) *Reader {
|
||||||
docid, gid := ParseIDs(url)
|
docid, gid := ParseIDs(url)
|
||||||
|
|
||||||
return NewReaderFromIDs(docid, gid)
|
return NewReaderFromIDs(docid, gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReaderFromIDsContext uses client and ctx for the sheet request.
|
||||||
|
// It leaves NewReaderFromIDs unchanged for compatibility.
|
||||||
|
func NewReaderFromIDsContext(ctx context.Context, client *http.Client, docid, gid string) *Reader {
|
||||||
|
resp, err := GetSheetContext(ctx, client, docid, gid)
|
||||||
|
return newReaderFromResponse(resp, err, docid, gid)
|
||||||
|
}
|
||||||
|
|
||||||
func NewReaderFromIDs(docid, gid string) *Reader {
|
func NewReaderFromIDs(docid, gid string) *Reader {
|
||||||
resp, err := GetSheet(docid, gid)
|
resp, err := GetSheet(docid, gid)
|
||||||
|
return newReaderFromResponse(resp, err, docid, gid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newReaderFromResponse(resp *http.Response, err error, docid, gid string) *Reader {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r := NewReader(nil)
|
r := NewReader(nil)
|
||||||
r.err = err
|
r.err = err
|
||||||
@ -91,10 +125,16 @@ func ToCSVURL(docid, gid string) string {
|
|||||||
return fmt.Sprintf("https://docs.google.com/spreadsheets/d/%s/export?format=csv&usp=sharing&gid=%s", docid, gid)
|
return fmt.Sprintf("https://docs.google.com/spreadsheets/d/%s/export?format=csv&usp=sharing&gid=%s", docid, gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSheet(docid, gid string) (*http.Response, error) {
|
func GetSheetContext(ctx context.Context, client *http.Client, docid, gid string) (*http.Response, error) {
|
||||||
downloadURL := ToCSVURL(docid, gid)
|
downloadURL := ToCSVURL(docid, gid)
|
||||||
|
request, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
|
||||||
resp, err := httpGet(downloadURL)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if client == nil {
|
||||||
|
client = httpClient
|
||||||
|
}
|
||||||
|
resp, err := client.Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -107,6 +147,22 @@ func GetSheet(docid, gid string) (*http.Response, error) {
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSheet(docid, gid string) (*http.Response, error) {
|
||||||
|
return getSheetWithGet(ToCSVURL(docid, gid), httpGet)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSheetWithGet(downloadURL string, get func(string) (*http.Response, error)) (*http.Response, error) {
|
||||||
|
resp, err := get(downloadURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
_ = resp.Body.Close()
|
||||||
|
return nil, ErrHTTPGet
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewReader(r io.Reader) *Reader {
|
func NewReader(r io.Reader) *Reader {
|
||||||
csvr := csv.NewReader(r)
|
csvr := csv.NewReader(r)
|
||||||
csvr.Comma = ','
|
csvr.Comma = ','
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user