From 9669eb8ddf214ef47238ce2fc852e0d380dcced4 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 15 Nov 2023 14:02:15 +0100 Subject: [PATCH] refactor: removed code duplication Signed-off-by: SoXX --- pkg/e621/endpoints/executer.go | 58 +++++++++++++++++++++ pkg/e621/endpoints/favorite.go | 48 ++--------------- pkg/e621/endpoints/note.go | 95 ++-------------------------------- pkg/e621/endpoints/pool.go | 88 ++----------------------------- pkg/e621/endpoints/post.go | 89 ++----------------------------- pkg/e621/endpoints/tag.go | 89 ++----------------------------- pkg/e621/endpoints/user.go | 88 ++----------------------------- 7 files changed, 82 insertions(+), 473 deletions(-) create mode 100644 pkg/e621/endpoints/executer.go diff --git a/pkg/e621/endpoints/executer.go b/pkg/e621/endpoints/executer.go new file mode 100644 index 0000000..ee5065f --- /dev/null +++ b/pkg/e621/endpoints/executer.go @@ -0,0 +1,58 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" + "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" + "net/http" +) + +func getRequest[T any](requestContext model.RequestContext, e621Endpoint string, query map[string]string) (T, error) { + var base T + // Create a new HTTP GET request to fetch user information from the specified 'host' and 'username'. + r, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", requestContext.Host, e621Endpoint), nil) + if err != nil { + // Log the error and return an empty User struct and the error. + + return base, err + } + + // Append query parameters to the request URL. + if query != nil { + q := r.URL.Query() + for k, v := range query { + q.Add(k, v) + } + r.URL.RawQuery = q.Encode() + } + + r.Header.Set("User-Agent", requestContext.UserAgent) + r.Header.Add("Accept", "application/json") + r.SetBasicAuth(requestContext.Username, requestContext.APIKey) + + // Send the request using the provided http.Client. + resp, err := requestContext.Client.Do(r) + if err != nil { + // Log the error and return an empty User struct and the error. + + return base, err + } + + // Check if the HTTP response status code indicates success (2xx range). + if resp.StatusCode < 200 || resp.StatusCode > 300 { + // If the status code is outside the 2xx range, return an error based on the status code. + return base, utils.StatusCodesToError(resp.StatusCode) + } + + // Decode the JSON response into the User struct. + err = json.NewDecoder(resp.Body).Decode(&base) + if err != nil { + // Log the error and return an empty User struct and the error. + + return base, err + } + + // Return the user information and no error (nil). + return base, nil +} diff --git a/pkg/e621/endpoints/favorite.go b/pkg/e621/endpoints/favorite.go index ef9306a..eb564ed 100644 --- a/pkg/e621/endpoints/favorite.go +++ b/pkg/e621/endpoints/favorite.go @@ -1,11 +1,7 @@ package endpoints import ( - "encoding/json" - "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "net/http" ) // GetFavorites retrieves a user's favorite posts from the e621 API. @@ -20,45 +16,7 @@ import ( // - []model.Post: A slice of favorite posts. // - error: An error, if any, encountered during the API request or response handling. func GetFavorites(requestContext model.RequestContext, query map[string]string) ([]model.Post, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/favorites.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return nil, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a User struct to store the response data. - var favoriteResponse model.PostResponse - - // Decode the JSON response into the user struct. - err = json.NewDecoder(resp.Body).Decode(&favoriteResponse) - if err != nil { - // Log the error and return an empty User struct and the error. - - return nil, err - } - - return favoriteResponse.Posts, nil + endpoint := "favorites.json" + data, err := getRequest[model.PostResponse](requestContext, endpoint, query) + return data.Posts, err } diff --git a/pkg/e621/endpoints/note.go b/pkg/e621/endpoints/note.go index c298d27..426d71f 100644 --- a/pkg/e621/endpoints/note.go +++ b/pkg/e621/endpoints/note.go @@ -1,13 +1,8 @@ package endpoints import ( - "encoding/json" "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "io" - "net/http" - "strings" ) // GetNote retrieves a single note by its ID from the e621 API. @@ -20,45 +15,8 @@ import ( // - model.Note: The retrieved note. // - error: An error, if any, encountered during the API request or response handling. func GetNote(requestContext model.RequestContext, ID string) (model.Note, error) { - // Create a new HTTP GET request to fetch the note information. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/notes/%s.json", requestContext.Host, ID), nil) - if err != nil { - // Log the error and return an empty Note struct and the error. - - return model.Note{}, err - } - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - // Log the error and return an empty Note struct and the error. - - return model.Note{}, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return model.Note{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a Note struct to store the response data. - var noteResponse model.Note - - // Decode the JSON response into the Note struct. - err = json.NewDecoder(resp.Body).Decode(¬eResponse) - if err != nil { - // Log the error and return an empty Note struct and the error. - - return model.Note{}, err - } - - // Return the note information and no error (nil). - return noteResponse, nil + endpoint := fmt.Sprintf("notes/%s.json", ID) + return getRequest[model.Note](requestContext, endpoint, nil) } // GetNotes retrieves a list of notes from the e621 API based on query parameters. @@ -71,51 +29,6 @@ func GetNote(requestContext model.RequestContext, ID string) (model.Note, error) // - []model.Note: A slice of notes. // - error: An error, if any, encountered during the API request or response handling. func GetNotes(requestContext model.RequestContext, query map[string]string) ([]model.Note, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/notes.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return nil, utils.StatusCodesToError(resp.StatusCode) - } - - respBodyBytes, err := io.ReadAll(resp.Body) - if strings.Contains(string(respBodyBytes), "{\"notes\":[]}") { - return nil, nil - } - - // Initialize a slice of Note struct to store the response data. - var notesResponse []model.Note - - // Decode the JSON response into the slice of Note structs. - err = json.Unmarshal(respBodyBytes, ¬esResponse) - if err != nil { - // Log the error and return an empty slice and the error. - - return nil, err - } - - // Return the list of notes and no error (nil). - return notesResponse, nil + endpoint := "notes.json" + return getRequest[[]model.Note](requestContext, endpoint, query) } diff --git a/pkg/e621/endpoints/pool.go b/pkg/e621/endpoints/pool.go index 35697d1..a6d6fee 100644 --- a/pkg/e621/endpoints/pool.go +++ b/pkg/e621/endpoints/pool.go @@ -1,11 +1,8 @@ package endpoints import ( - "encoding/json" "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "net/http" ) // GetPool retrieves a pool by its ID from the e621 API. @@ -18,45 +15,8 @@ import ( // - model.Pool: The retrieved pool. // - error: An error, if any, encountered during the API request or response handling. func GetPool(requestContext model.RequestContext, ID string) (model.Pool, error) { - // Create a new HTTP GET request to fetch the pool information. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/pools/%s.json", requestContext.Host, ID), nil) - if err != nil { - // Log the error and return an empty Pool struct and the error. - - return model.Pool{}, err - } - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - // Log the error and return an empty Pool struct and the error. - - return model.Pool{}, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return model.Pool{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a Pool struct to store the response data. - var poolResponse model.Pool - - // Decode the JSON response into the Pool struct. - err = json.NewDecoder(resp.Body).Decode(&poolResponse) - if err != nil { - // Log the error and return an empty Pool struct and the error. - - return model.Pool{}, err - } - - // Return the pool information and no error (nil). - return poolResponse, nil + endpoint := fmt.Sprintf("pools/%s.json", ID) + return getRequest[model.Pool](requestContext, endpoint, nil) } // GetPools retrieves a list of pools from the e621 API based on query parameters. @@ -69,46 +29,6 @@ func GetPool(requestContext model.RequestContext, ID string) (model.Pool, error) // - []model.Pool: A slice of pools. // - error: An error, if any, encountered during the API request or response handling. func GetPools(requestContext model.RequestContext, query map[string]string) ([]model.Pool, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/pools.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return nil, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a slice of Pool struct to store the response data. - var poolsResponse []model.Pool - - // Decode the JSON response into the slice of Pool structs. - err = json.NewDecoder(resp.Body).Decode(&poolsResponse) - if err != nil { - // Log the error and return an empty slice and the error. - - return nil, err - } - - // Return the list of pools and no error (nil). - return poolsResponse, nil + endpoint := "pools.json" + return getRequest[[]model.Pool](requestContext, endpoint, query) } diff --git a/pkg/e621/endpoints/post.go b/pkg/e621/endpoints/post.go index e923cac..ea63c8a 100644 --- a/pkg/e621/endpoints/post.go +++ b/pkg/e621/endpoints/post.go @@ -1,11 +1,8 @@ package endpoints import ( - "encoding/json" "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "net/http" ) // GetPost retrieves a single post by its ID from the e621 API. @@ -17,45 +14,8 @@ import ( // - model.Post: The retrieved post. // - error: An error, if any, encountered during the API request or response handling. func GetPost(requestContext model.RequestContext, ID string) (model.Post, error) { - // Create a new HTTP GET request to fetch the post information. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/posts/%s.json", requestContext.Host, ID), nil) - if err != nil { - // Log the error and return an empty Post struct and the error. - - return model.Post{}, err - } - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - // Log the error and return an empty Post struct and the error. - - return model.Post{}, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return model.Post{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a Post struct to store the response data. - var postResponse model.PostResponse - - // Decode the JSON response into the PostResponse struct. - err = json.NewDecoder(resp.Body).Decode(&postResponse) - if err != nil { - // Log the error and return an empty Post struct and the error. - - return model.Post{}, err - } - - // Return the post information and no error (nil). - return postResponse.Post, nil + endpoint := fmt.Sprintf("posts/%s.json", ID) + return getRequest[model.Post](requestContext, endpoint, nil) } // GetPosts retrieves a list of posts from the e621 API based on query parameters. @@ -68,46 +28,7 @@ func GetPost(requestContext model.RequestContext, ID string) (model.Post, error) // - []model.Post: A slice of posts. // - error: An error, if any, encountered during the API request or response handling. func GetPosts(requestContext model.RequestContext, query map[string]string) ([]model.Post, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/posts.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return nil, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a slice of Post struct to store the response data. - var postResponse model.PostResponse - - // Decode the JSON response into the PostResponse struct. - err = json.NewDecoder(resp.Body).Decode(&postResponse) - if err != nil { - // Log the error and return an empty slice and the error. - - return nil, err - } - - // Return the list of posts and no error (nil). - return postResponse.Posts, nil + endpoint := "posts.json" + data, err := getRequest[model.PostResponse](requestContext, endpoint, query) + return data.Posts, err } diff --git a/pkg/e621/endpoints/tag.go b/pkg/e621/endpoints/tag.go index 6483eb9..756022b 100644 --- a/pkg/e621/endpoints/tag.go +++ b/pkg/e621/endpoints/tag.go @@ -1,11 +1,8 @@ package endpoints import ( - "encoding/json" "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "net/http" ) // GetTag retrieves a tag by its ID from the e621 API. @@ -18,46 +15,8 @@ import ( // - model.Tag: The retrieved tag. // - error: An error, if any, encountered during the API request or response handling. func GetTag(requestContext model.RequestContext, ID string) (model.Tag, error) { - // Create a new HTTP GET request to fetch tag information. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/tags/%s.json", requestContext.Host, ID), nil) - if err != nil { - // Log the error and return an empty Tag struct and the error. - - return model.Tag{}, err - } - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application.json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - // Log the error and return an empty Tag struct and the error. - - return model.Tag{}, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return model.Tag{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a Tag struct to store the response data. - var tag model.Tag - - // Decode the JSON response into the Tag struct. - err = json.NewDecoder(resp.Body).Decode(&tag) - if err != nil { - // Log the error and return an empty Tag struct and the error. - - return model.Tag{}, err - } - - // Return the tag information and no error (nil). - return tag, nil - + endpoint := fmt.Sprintf("tags/%s.json", ID) + return getRequest[model.Tag](requestContext, endpoint, nil) } // GetTags retrieves a list of tags from the e621 API based on query parameters. @@ -80,46 +39,6 @@ func GetTag(requestContext model.RequestContext, ID string) (model.Tag, error) { // - []model.Tag: A slice of tags. // - error: An error, if any, encountered during the API request or response handling. func GetTags(requestContext model.RequestContext, query map[string]string) ([]model.Tag, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/tags.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return []model.Tag{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a slice of Tag struct to store the response data. - var tags []model.Tag - - // Decode the JSON response into the slice of Tag structs. - err = json.NewDecoder(resp.Body).Decode(&tags) - if err != nil { - // Log the error and return an empty slice and the error. - - return []model.Tag{}, err - } - - // Return the list of tags and no error (nil). - return tags, nil + endpoint := "tags.json" + return getRequest[[]model.Tag](requestContext, endpoint, query) } diff --git a/pkg/e621/endpoints/user.go b/pkg/e621/endpoints/user.go index f3571a2..156a784 100644 --- a/pkg/e621/endpoints/user.go +++ b/pkg/e621/endpoints/user.go @@ -1,11 +1,8 @@ package endpoints import ( - "encoding/json" "fmt" "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model" - "git.dragse.it/anthrove/e621-sdk-go/pkg/e621/utils" - "net/http" ) // GetUser retrieves user information from e621.net based on the provided username. @@ -18,45 +15,8 @@ import ( // - model.User: The retrieved user. // - error: An error, if any, encountered during the API request or response handling. func GetUser(requestContext model.RequestContext, username string) (model.User, error) { - // Create a new HTTP GET request to fetch user information from the specified 'host' and 'username'. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/users/%s.json", requestContext.Host, username), nil) - if err != nil { - // Log the error and return an empty User struct and the error. - - return model.User{}, err - } - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - // Log the error and return an empty User struct and the error. - - return model.User{}, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return model.User{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a User struct to store the response data. - var user model.User - - // Decode the JSON response into the User struct. - err = json.NewDecoder(resp.Body).Decode(&user) - if err != nil { - // Log the error and return an empty User struct and the error. - - return model.User{}, err - } - - // Return the user information and no error (nil). - return user, nil + endpoint := fmt.Sprintf("users/%s.json", username) + return getRequest[model.User](requestContext, endpoint, nil) } // GetUsers retrieves a list of users from e621.net based on query parameters. @@ -69,46 +29,6 @@ func GetUser(requestContext model.RequestContext, username string) (model.User, // - []model.User: A slice of users. // - error: An error, if any, encountered during the API request or response handling. func GetUsers(requestContext model.RequestContext, query map[string]string) ([]model.User, error) { - // Create a new HTTP GET request. - r, err := http.NewRequest("GET", fmt.Sprintf("%s/users.json", requestContext.Host), nil) - if err != nil { - return nil, err - } - - // Append query parameters to the request URL. - q := r.URL.Query() - for k, v := range query { - q.Add(k, v) - } - r.URL.RawQuery = q.Encode() - - r.Header.Set("User-Agent", requestContext.UserAgent) - r.Header.Add("Accept", "application/json") - r.SetBasicAuth(requestContext.Username, requestContext.APIKey) - - // Send the request using the provided http.Client. - resp, err := requestContext.Client.Do(r) - if err != nil { - return nil, err - } - - // Check if the HTTP response status code indicates success (2xx range). - if resp.StatusCode < 200 || resp.StatusCode > 300 { - // If the status code is outside the 2xx range, return an error based on the status code. - return []model.User{}, utils.StatusCodesToError(resp.StatusCode) - } - - // Initialize a slice of User struct to store the response data. - var users []model.User - - // Decode the JSON response into the slice of User structs. - err = json.NewDecoder(resp.Body).Decode(&users) - if err != nil { - // Log the error and return an empty slice and the error. - - return []model.User{}, err - } - - // Return the list of users and no error (nil). - return users, nil + endpoint := "users.json" + return getRequest[[]model.User](requestContext, endpoint, query) }