From bddd47ecd074d686fce34332004629a497a0a1ff Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Tue, 18 Apr 2023 14:16:57 -0700 Subject: [PATCH] complete history initial draft --- client/history.go | 168 +++++++++++++++++++++++++++++++++++++++++- client/types/types.go | 6 +- 2 files changed, 167 insertions(+), 7 deletions(-) diff --git a/client/history.go b/client/history.go index 22b67f5..1cdc8e1 100644 --- a/client/history.go +++ b/client/history.go @@ -1,6 +1,7 @@ package client import ( + "bufio" "bytes" "context" "encoding/json" @@ -62,11 +63,35 @@ func (c Client) HistoryDownloadZipWriter(ctx context.Context, w io.Writer, id1, if err != nil { return err } + req.Header.Set("accept", "archive/zip") req.Header.Set("xi-api-key", c.apiKey) req.Header.Set("User-Agent", "github.com/taigrr/elevenlabs") res, err := client.Do(req) - io.Copy(w, req.Response.Body) + + switch res.StatusCode { + case 422: + ve := types.ValidationError{} + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&ve) + if jerr != nil { + err = errors.Join(err, jerr) + } else { + err = errors.Join(err, ve) + } + return err + case 401: + return ErrUnauthorized + case 200: + if err != nil { + return err + } + defer res.Body.Close() + io.Copy(w, res.Body) + return nil + default: + return errors.Join(err, ErrUnspecified) + } } func (c Client) HistoryDownloadZip(ctx context.Context, id1, id2 string, additionalIDs ...string) ([]byte, error) { @@ -82,10 +107,38 @@ func (c Client) HistoryDownloadZip(ctx context.Context, id1, id2 string, additio if err != nil { return []byte{}, err } + req.Header.Set("accept", "archive/zip") req.Header.Set("xi-api-key", c.apiKey) req.Header.Set("User-Agent", "github.com/taigrr/elevenlabs") res, err := client.Do(req) + + switch res.StatusCode { + case 422: + ve := types.ValidationError{} + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&ve) + if jerr != nil { + err = errors.Join(err, jerr) + } else { + err = errors.Join(err, ve) + } + return []byte{}, err + case 401: + return []byte{}, ErrUnauthorized + case 200: + if err != nil { + return []byte{}, err + } + b := bytes.Buffer{} + w := bufio.NewWriter(&b) + + defer res.Body.Close() + io.Copy(w, res.Body) + return b.Bytes(), nil + default: + return []byte{}, errors.Join(err, ErrUnspecified) + } } func (c Client) HistoryDownloadAudioWriter(ctx context.Context, w io.Writer, ID string) error { @@ -97,8 +150,32 @@ func (c Client) HistoryDownloadAudioWriter(ctx context.Context, w io.Writer, ID } req.Header.Set("xi-api-key", c.apiKey) req.Header.Set("User-Agent", "github.com/taigrr/elevenlabs") + req.Header.Set("accept", "audio/mpeg") res, err := client.Do(req) - io.Copy(w, req.Response.Body) + + switch res.StatusCode { + case 422: + ve := types.ValidationError{} + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&ve) + if jerr != nil { + err = errors.Join(err, jerr) + } else { + err = errors.Join(err, ve) + } + return err + case 401: + return ErrUnauthorized + case 200: + if err != nil { + return err + } + defer res.Body.Close() + io.Copy(w, res.Body) + return nil + default: + return errors.Join(err, ErrUnspecified) + } } func (c Client) HistoryDownloadAudio(ctx context.Context, ID string) ([]byte, error) { @@ -110,15 +187,98 @@ func (c Client) HistoryDownloadAudio(ctx context.Context, ID string) ([]byte, er } req.Header.Set("xi-api-key", c.apiKey) req.Header.Set("User-Agent", "github.com/taigrr/elevenlabs") + req.Header.Set("accept", "audio/mpeg") + res, err := client.Do(req) + + switch res.StatusCode { + case 422: + ve := types.ValidationError{} + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&ve) + if jerr != nil { + err = errors.Join(err, jerr) + } else { + err = errors.Join(err, ve) + } + return []byte{}, err + case 401: + return []byte{}, ErrUnauthorized + case 200: + if err != nil { + return []byte{}, err + } + b := bytes.Buffer{} + w := bufio.NewWriter(&b) + + defer res.Body.Close() + io.Copy(w, res.Body) + return b.Bytes(), nil + default: + return []byte{}, errors.Join(err, ErrUnspecified) + } } -func (c Client) GetHistoryList(ctx context.Context) ([]string, error) { +func (c Client) GetHistoryItemList(ctx context.Context) ([]types.HistoryItemList, error) { url := c.endpoint + "/v1/history" client := &http.Client{} req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - return []string{}, err + return []types.HistoryItemList{}, err } req.Header.Set("xi-api-key", c.apiKey) req.Header.Set("User-Agent", "github.com/taigrr/elevenlabs") + req.Header.Set("accept", "application/json") + res, err := client.Do(req) + + switch res.StatusCode { + case 422: + ve := types.ValidationError{} + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&ve) + if jerr != nil { + err = errors.Join(err, jerr) + } else { + err = errors.Join(err, ve) + } + return []types.HistoryItemList{}, err + case 401: + return []types.HistoryItemList{}, ErrUnauthorized + case 200: + if err != nil { + return []types.HistoryItemList{}, err + } + + var history types.GetHistoryResponse + defer res.Body.Close() + jerr := json.NewDecoder(res.Body).Decode(&history) + if jerr != nil { + return []types.HistoryItemList{}, jerr + } + return []types.HistoryItemList{}, err + + default: + return []types.HistoryItemList{}, errors.Join(err, ErrUnspecified) + } +} + +func (c Client) GetHistoryIDs(ctx context.Context, voiceIDs ...string) ([]string, error) { + items, err := c.GetHistoryItemList(ctx) + if err != nil { + return []string{}, err + } + ids := []string{} + voiceMap := make(map[string]struct{}) + for _, v := range voiceIDs { + voiceMap[v] = struct{}{} + } + for _, i := range items { + if len(voiceIDs) == 0 { + ids = append(ids, i.HistoryItemId) + } else { + if _, ok := voiceMap[i.VoiceId]; ok { + ids = append(ids, i.HistoryItemId) + } + } + } + return ids, err } diff --git a/client/types/types.go b/client/types/types.go index 0cbe518..7c0ed9b 100644 --- a/client/types/types.go +++ b/client/types/types.go @@ -68,13 +68,13 @@ type FineTuningResponseModel struct { VerificationAttemptsCount int32 `json:"verification_attempts_count"` SliceIds []string `json:"slice_ids"` } -type GetHistoryResponseModel struct { - History []HistoryItemResponseModel `json:"history"` +type GetHistoryResponse struct { + History []HistoryItemList `json:"history"` } type GetVoicesResponseModel struct { Voices []VoiceResponseModel `json:"voices"` } -type HistoryItemResponseModel struct { +type HistoryItemList struct { HistoryItemId string `json:"history_item_id"` RequestId string `json:"request_id"` VoiceId string `json:"voice_id"`