From 8024ad83a46eed4658221498949d0a5f4158503a Mon Sep 17 00:00:00 2001 From: Chris Keller Date: Sun, 19 Jan 2025 23:07:27 -0700 Subject: [PATCH] Regenerate OpenAPI Client Try number 2. --- .gitignore | 3 + .openapi-generator-ignore | 6 +- .openapi-generator/FILES | 15 ++ .openapi-generator/VERSION | 2 +- api/openapi-config.yaml | 2 + api/openapi.yaml | 6 +- api_default.go | 157 ++++++++++------ client.go | 313 +++++++++++++++++++++----------- configuration.go | 153 ++++++++++++---- docs/DefaultAPI.md | 78 ++++++++ docs/DefaultApi.md | 51 ------ docs/Request.md | 146 ++++++++++++++- docs/Response.md | 185 ++++++++++++++++++- go.mod | 9 +- go.sum | 15 +- model_request.go | 292 +++++++++++++++++++++++++++++- model_response.go | 309 +++++++++++++++++++++++++++++-- openapitools.json | 7 + regenerate.sh | 8 +- response.go | 16 +- test/api_default_test.go | 37 ++++ unmarshal.go | 40 ++-- utils.go | 362 +++++++++++++++++++++++++++++++++++++ wrapper.go | 83 ++++----- 24 files changed, 1930 insertions(+), 365 deletions(-) create mode 100644 .openapi-generator/FILES create mode 100644 docs/DefaultAPI.md create mode 100644 openapitools.json create mode 100644 test/api_default_test.go create mode 100644 utils.go diff --git a/.gitignore b/.gitignore index 84eb530..f990734 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ _testmain.go # IDE files *.iml .idea/ + +.travis.yml +git_push.sh diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index a085156..d6c6131 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -2,10 +2,6 @@ # Generated by openapi-generator https://github.com/openapitools/openapi-generator # Use this file to prevent files from being overwritten by the generator. -# The patterns follow closely to .gitignore or .dockerignore. -go.mod -git_push.sh .gitignore -.travis.yml -client.go +README.md diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES new file mode 100644 index 0000000..0005e5f --- /dev/null +++ b/.openapi-generator/FILES @@ -0,0 +1,15 @@ +.travis.yml +api/openapi.yaml +api_default.go +client.go +configuration.go +docs/DefaultAPI.md +docs/Request.md +docs/Response.md +git_push.sh +go.mod +go.sum +model_request.go +model_response.go +response.go +utils.go diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION index ecedc98..758bb9c 100644 --- a/.openapi-generator/VERSION +++ b/.openapi-generator/VERSION @@ -1 +1 @@ -4.3.1 \ No newline at end of file +7.10.0 diff --git a/api/openapi-config.yaml b/api/openapi-config.yaml index 3523b83..f2c464e 100644 --- a/api/openapi-config.yaml +++ b/api/openapi-config.yaml @@ -1,2 +1,4 @@ packageName: qrzlog withGoCodegenComment: true +globalProperties: + skipFormModel: false diff --git a/api/openapi.yaml b/api/openapi.yaml index d57ca43..9f62b46 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.0.1 info: contact: email: flloyd@qrz.com - description: + description: | This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid @@ -43,7 +43,7 @@ components: description: A QRZ supplied logbook access key type: string ACTION: - description: Type of request, i.e. INSERT, DELETE, UPLOAD, etc. + description: "Type of request, i.e. INSERT, DELETE, UPLOAD, etc." enum: - INSERT - DELETE @@ -66,7 +66,7 @@ components: Response: properties: RESULT: - description: + description: | OK when the operation succeeds, FAIL when the operation failed, AUTH when API Access lacked sufficient privileges for the operation, or other action-specific codes diff --git a/api_default.go b/api_default.go index 79f2edc..8b56112 100644 --- a/api_default.go +++ b/api_default.go @@ -1,65 +1,111 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. package qrzlog import ( - _context "context" - "github.com/antihax/optional" - _ioutil "io/ioutil" - _nethttp "net/http" - _neturl "net/url" + "bytes" + "context" + "io" + "net/http" + "net/url" ) -// Linger please -var ( - _ _context.Context -) +// DefaultAPIService DefaultAPI service +type DefaultAPIService service + +type ApiRootPostRequest struct { + ctx context.Context + ApiService *DefaultAPIService + kEY *string + aCTION *string + aDIF *string + oPTION *string + lOGIDS *string +} + +// A QRZ supplied logbook access key +func (r ApiRootPostRequest) KEY(kEY string) ApiRootPostRequest { + r.kEY = &kEY + return r +} + +// Type of request, i.e. INSERT, DELETE, UPLOAD, etc. +func (r ApiRootPostRequest) ACTION(aCTION string) ApiRootPostRequest { + r.aCTION = &aCTION + return r +} + +// ADIF formatted input data +func (r ApiRootPostRequest) ADIF(aDIF string) ApiRootPostRequest { + r.aDIF = &aDIF + return r +} + +// Action-specific options +func (r ApiRootPostRequest) OPTION(oPTION string) ApiRootPostRequest { + r.oPTION = &oPTION + return r +} -// DefaultApiService DefaultApi service -type DefaultApiService service +// A comma separated list of integer logid values +func (r ApiRootPostRequest) LOGIDS(lOGIDS string) ApiRootPostRequest { + r.lOGIDS = &lOGIDS + return r +} -// RootPostOpts Optional parameters for the method 'RootPost' -type RootPostOpts struct { - ADIF optional.String - OPTION optional.String - LOGIDS optional.String +func (r ApiRootPostRequest) Execute() (*Response, *http.Response, error) { + return r.ApiService.RootPostExecute(r) } /* RootPost The do-everything endpoint - * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param kEY A QRZ supplied logbook access key - * @param aCTION Type of request, i.e. INSERT, DELETE, UPLOAD, etc. - * @param optional nil or *RootPostOpts - Optional Parameters: - * @param "ADIF" (optional.String) - ADIF formatted input data - * @param "OPTION" (optional.String) - Action-specific options - * @param "LOGIDS" (optional.String) - A comma separated list of integer logid values -@return Response + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiRootPostRequest */ -func (a *DefaultApiService) RootPost(ctx _context.Context, kEY string, aCTION string, localVarOptionals *RootPostOpts) (Response, *_nethttp.Response, error) { +func (a *DefaultAPIService) RootPost(ctx context.Context) ApiRootPostRequest { + return ApiRootPostRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return Response +func (a *DefaultAPIService) RootPostExecute(r ApiRootPostRequest) (*Response, *http.Response, error) { var ( - localVarHTTPMethod = _nethttp.MethodPost - localVarPostBody interface{} - localVarFormFileName string - localVarFileName string - localVarFileBytes []byte - localVarReturnValue Response + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Response ) - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/" + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultAPIService.RootPost") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/" + localVarHeaderParams := make(map[string]string) - localVarQueryParams := _neturl.Values{} - localVarFormParams := _neturl.Values{} + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.kEY == nil { + return localVarReturnValue, nil, reportError("kEY is required and must be specified") + } + if r.aCTION == nil { + return localVarReturnValue, nil, reportError("aCTION is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{"application/x-www-form-urlencoded"} @@ -78,35 +124,36 @@ func (a *DefaultApiService) RootPost(ctx _context.Context, kEY string, aCTION st if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - localVarFormParams.Add("KEY", parameterToString(kEY, "")) - localVarFormParams.Add("ACTION", parameterToString(aCTION, "")) - if localVarOptionals != nil && localVarOptionals.ADIF.IsSet() { - localVarFormParams.Add("ADIF", parameterToString(localVarOptionals.ADIF.Value(), "")) + parameterAddToHeaderOrQuery(localVarFormParams, "KEY", r.kEY, "", "") + parameterAddToHeaderOrQuery(localVarFormParams, "ACTION", r.aCTION, "", "") + if r.aDIF != nil { + parameterAddToHeaderOrQuery(localVarFormParams, "ADIF", r.aDIF, "", "") } - if localVarOptionals != nil && localVarOptionals.OPTION.IsSet() { - localVarFormParams.Add("OPTION", parameterToString(localVarOptionals.OPTION.Value(), "")) + if r.oPTION != nil { + parameterAddToHeaderOrQuery(localVarFormParams, "OPTION", r.oPTION, "", "") } - if localVarOptionals != nil && localVarOptionals.LOGIDS.IsSet() { - localVarFormParams.Add("LOGIDS", parameterToString(localVarOptionals.LOGIDS.Value(), "")) + if r.lOGIDS != nil { + parameterAddToHeaderOrQuery(localVarFormParams, "LOGIDS", r.lOGIDS, "", "") } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { return localVarReturnValue, nil, err } - localVarHTTPResponse, err := a.client.callAPI(r) + localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { return localVarReturnValue, localVarHTTPResponse, err } - localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { - newErr := GenericOpenAPIError{ + newErr := &GenericOpenAPIError{ body: localVarBody, error: localVarHTTPResponse.Status, } @@ -115,7 +162,7 @@ func (a *DefaultApiService) RootPost(ctx _context.Context, kEY string, aCTION st err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { - newErr := GenericOpenAPIError{ + newErr := &GenericOpenAPIError{ body: localVarBody, error: err.Error(), } diff --git a/client.go b/client.go index a4a118d..70b7b83 100644 --- a/client.go +++ b/client.go @@ -1,11 +1,11 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. @@ -19,7 +19,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "mime/multipart" "net/http" @@ -33,14 +32,13 @@ import ( "strings" "time" "unicode/utf8" - - "golang.org/x/oauth2" ) var ( - jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`) - xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`) - formCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:html|x-www-form-urlencoded))`) + JsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?json)`) + XmlCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?xml)`) + queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`) + queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]") // k0swe customizations textPlainCheck = regexp.MustCompile(`(?i:(?:text/plain))`) ) @@ -53,7 +51,7 @@ type APIClient struct { // API Services - DefaultApi *DefaultApiService + DefaultAPI *DefaultAPIService } type service struct { @@ -72,7 +70,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.common.client = c // API Services - c.DefaultApi = (*DefaultApiService)(&c.common) + c.DefaultAPI = (*DefaultAPIService)(&c.common) return c } @@ -105,10 +103,10 @@ func selectHeaderAccept(accepts []string) string { return strings.Join(accepts, ",") } -// contains is a case insenstive match, finding needle in a haystack +// contains is a case insensitive match, finding needle in a haystack func contains(haystack []string, needle string) bool { for _, a := range haystack { - if strings.ToLower(a) == strings.ToLower(needle) { + if strings.EqualFold(a, needle) { return true } } @@ -124,33 +122,115 @@ func typeCheckParameter(obj interface{}, expected string, name string) error { // Check the type is as expected. if reflect.TypeOf(obj).String() != expected { - return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String()) + return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String()) } return nil } -// parameterToString convert interface{} parameters to string, using a delimiter if format is provided. -func parameterToString(obj interface{}, collectionFormat string) string { - var delimiter string - - switch collectionFormat { - case "pipes": - delimiter = "|" - case "ssv": - delimiter = " " - case "tsv": - delimiter = "\t" - case "csv": - delimiter = "," +func parameterValueToString(obj interface{}, key string) string { + if reflect.TypeOf(obj).Kind() != reflect.Ptr { + return fmt.Sprintf("%v", obj) + } + var param, ok = obj.(MappedNullable) + if !ok { + return "" } + dataMap, err := param.ToMap() + if err != nil { + return "" + } + return fmt.Sprintf("%v", dataMap[key]) +} - if reflect.TypeOf(obj).Kind() == reflect.Slice { - return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]") - } else if t, ok := obj.(time.Time); ok { - return t.Format(time.RFC3339) +// parameterAddToHeaderOrQuery adds the provided object to the request header or url query +// supporting deep object syntax +func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, style string, collectionType string) { + var v = reflect.ValueOf(obj) + var value = "" + if v == reflect.ValueOf(nil) { + value = "null" + } else { + switch v.Kind() { + case reflect.Invalid: + value = "invalid" + + case reflect.Struct: + if t, ok := obj.(MappedNullable); ok { + dataMap, err := t.ToMap() + if err != nil { + return + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType) + return + } + if t, ok := obj.(time.Time); ok { + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType) + return + } + value = v.Type().String() + " value" + case reflect.Slice: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + var lenIndValue = indValue.Len() + for i := 0; i < lenIndValue; i++ { + var arrayValue = indValue.Index(i) + var keyPrefixForCollectionType = keyPrefix + if style == "deepObject" { + keyPrefixForCollectionType = keyPrefix + "[" + strconv.Itoa(i) + "]" + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefixForCollectionType, arrayValue.Interface(), style, collectionType) + } + return + + case reflect.Map: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + iter := indValue.MapRange() + for iter.Next() { + k, v := iter.Key(), iter.Value() + parameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf("%s[%s]", keyPrefix, k.String()), v.Interface(), style, collectionType) + } + return + + case reflect.Interface: + fallthrough + case reflect.Ptr: + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), style, collectionType) + return + + case reflect.Int, reflect.Int8, reflect.Int16, + reflect.Int32, reflect.Int64: + value = strconv.FormatInt(v.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, + reflect.Uint32, reflect.Uint64, reflect.Uintptr: + value = strconv.FormatUint(v.Uint(), 10) + case reflect.Float32, reflect.Float64: + value = strconv.FormatFloat(v.Float(), 'g', -1, 32) + case reflect.Bool: + value = strconv.FormatBool(v.Bool()) + case reflect.String: + value = v.String() + default: + value = v.Type().String() + " value" + } } - return fmt.Sprintf("%v", obj) + switch valuesMap := headerOrQueryParams.(type) { + case url.Values: + if collectionType == "csv" && valuesMap.Get(keyPrefix) != "" { + valuesMap.Set(keyPrefix, valuesMap.Get(keyPrefix)+","+value) + } else { + valuesMap.Add(keyPrefix, value) + } + break + case map[string]string: + valuesMap[keyPrefix] = value + break + } } // helper for converting interface{} parameters to json strings @@ -184,21 +264,21 @@ func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { } log.Printf("\n%s\n", string(dump)) } - return resp, err } -// ChangeBasePath changes base path to allow switching to mocks -func (c *APIClient) ChangeBasePath(path string) { - c.cfg.BasePath = path -} - // Allow modification of underlying config for alternate implementations and testing // Caution: modifying the configuration while live can cause data races and potentially unwanted behavior func (c *APIClient) GetConfig() *Configuration { return c.cfg } +type formFile struct { + fileBytes []byte + fileName string + formFileName string +} + // prepareRequest build the request func (c *APIClient) prepareRequest( ctx context.Context, @@ -207,9 +287,7 @@ func (c *APIClient) prepareRequest( headerParams map[string]string, queryParams url.Values, formParams url.Values, - formFileName string, - fileName string, - fileBytes []byte) (localVarRequest *http.Request, err error) { + formFiles []formFile) (localVarRequest *http.Request, err error) { var body *bytes.Buffer @@ -228,7 +306,7 @@ func (c *APIClient) prepareRequest( } // add form parameters and file if available. - if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) { if body != nil { return nil, errors.New("Cannot specify postBody and multipart form at the same time.") } @@ -247,16 +325,17 @@ func (c *APIClient) prepareRequest( } } } - if len(fileBytes) > 0 && fileName != "" { - w.Boundary() - //_, fileNm := filepath.Split(fileName) - part, err := w.CreateFormFile(formFileName, filepath.Base(fileName)) - if err != nil { - return nil, err - } - _, err = part.Write(fileBytes) - if err != nil { - return nil, err + for _, formFile := range formFiles { + if len(formFile.fileBytes) > 0 && formFile.fileName != "" { + w.Boundary() + part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(formFile.fileBytes) + if err != nil { + return nil, err + } } } @@ -303,7 +382,11 @@ func (c *APIClient) prepareRequest( } // Encode the parameters. - url.RawQuery = query.Encode() + url.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string { + pieces := strings.Split(s, "=") + pieces[0] = queryDescape.Replace(pieces[0]) + return strings.Join(pieces, "=") + }) // Generate a new request if body != nil { @@ -319,7 +402,7 @@ func (c *APIClient) prepareRequest( if len(headerParams) > 0 { headers := http.Header{} for h, v := range headerParams { - headers.Set(h, v) + headers[h] = []string{v} } localVarRequest.Header = headers } @@ -333,33 +416,11 @@ func (c *APIClient) prepareRequest( // Walk through any authentication. - // OAuth2 authentication - if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok { - // We were able to grab an oauth2 token from the context - var latestToken *oauth2.Token - if latestToken, err = tok.Token(); err != nil { - return nil, err - } - - latestToken.SetAuthHeader(localVarRequest) - } - - // Basic HTTP Authentication - if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok { - localVarRequest.SetBasicAuth(auth.UserName, auth.Password) - } - - // AccessToken Authentication - if auth, ok := ctx.Value(ContextAccessToken).(string); ok { - localVarRequest.Header.Add("Authorization", "Bearer "+auth) - } - } for header, value := range c.cfg.DefaultHeader { localVarRequest.Header.Add(header, value) } - return localVarRequest, nil } @@ -371,37 +432,59 @@ func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err err *s = string(b) return nil } + if f, ok := v.(*os.File); ok { + f, err = os.CreateTemp("", "HttpClientFile") + if err != nil { + return + } + _, err = f.Write(b) + if err != nil { + return + } + _, err = f.Seek(0, io.SeekStart) + return + } if f, ok := v.(**os.File); ok { - *f, err = ioutil.TempFile("", "HttpClientFile") + *f, err = os.CreateTemp("", "HttpClientFile") if err != nil { return } _, err = (*f).Write(b) + if err != nil { + return + } _, err = (*f).Seek(0, io.SeekStart) return } - if formCheck.MatchString(contentType) { - if err = unmarshalForm(b, v); err != nil { - return err - } - return nil - } - if xmlCheck.MatchString(contentType) { + if XmlCheck.MatchString(contentType) { if err = xml.Unmarshal(b, v); err != nil { return err } return nil } - if jsonCheck.MatchString(contentType) { - if err = json.Unmarshal(b, v); err != nil { + if JsonCheck.MatchString(contentType) { + if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas + if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined + if err = unmarshalObj.UnmarshalJSON(b); err != nil { + return err + } + } else { + return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined") + } + } else if err = json.Unmarshal(b, v); err != nil { // simple model return err } return nil } // k0swe customizations if textPlainCheck.MatchString(contentType) { - if err = unmarshalForm(b, v); err != nil { - return err + if resp, ok := v.(**Response); ok { + if *resp == nil { + *resp = &Response{} + } + if err = unmarshalForm(b, *resp); err != nil { + return err + } } return nil } @@ -410,11 +493,14 @@ func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err err // Add a file to the multipart request func addFile(w *multipart.Writer, fieldName, path string) error { - file, err := os.Open(path) + file, err := os.Open(filepath.Clean(path)) + if err != nil { + return err + } + err = file.Close() if err != nil { return err } - defer file.Close() part, err := w.CreateFormFile(fieldName, filepath.Base(path)) if err != nil { @@ -425,11 +511,6 @@ func addFile(w *multipart.Writer, fieldName, path string) error { return err } -// Prevent trying to import "fmt" -func reportError(format string, a ...interface{}) error { - return fmt.Errorf(format, a...) -} - // Set request body from an interface{} func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { if bodyBuf == nil { @@ -438,16 +519,22 @@ func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err e if reader, ok := body.(io.Reader); ok { _, err = bodyBuf.ReadFrom(reader) + } else if fp, ok := body.(*os.File); ok { + _, err = bodyBuf.ReadFrom(fp) } else if b, ok := body.([]byte); ok { _, err = bodyBuf.Write(b) } else if s, ok := body.(string); ok { _, err = bodyBuf.WriteString(s) } else if s, ok := body.(*string); ok { _, err = bodyBuf.WriteString(*s) - } else if jsonCheck.MatchString(contentType) { + } else if JsonCheck.MatchString(contentType) { err = json.NewEncoder(bodyBuf).Encode(body) - } else if xmlCheck.MatchString(contentType) { - err = xml.NewEncoder(bodyBuf).Encode(body) + } else if XmlCheck.MatchString(contentType) { + var bs []byte + bs, err = xml.Marshal(body) + if err == nil { + bodyBuf.Write(bs) + } } if err != nil { @@ -455,7 +542,7 @@ func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err e } if bodyBuf.Len() == 0 { - err = fmt.Errorf("Invalid body type %s\n", contentType) + err = fmt.Errorf("invalid body type %s\n", contentType) return nil, err } return bodyBuf, nil @@ -557,3 +644,23 @@ func (e GenericOpenAPIError) Body() []byte { func (e GenericOpenAPIError) Model() interface{} { return e.model } + +// format error message using title and detail when model implements rfc7807 +func formatErrorMessage(status string, v interface{}) string { + str := "" + metaValue := reflect.ValueOf(v).Elem() + + if metaValue.Kind() == reflect.Struct { + field := metaValue.FieldByName("Title") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s", field.Interface()) + } + + field = metaValue.FieldByName("Detail") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s (%s)", str, field.Interface()) + } + } + + return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) +} diff --git a/configuration.go b/configuration.go index 8bd3eeb..85af8ad 100644 --- a/configuration.go +++ b/configuration.go @@ -1,17 +1,18 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. package qrzlog import ( + "context" "fmt" "net/http" "strings" @@ -28,17 +29,17 @@ func (c contextKey) String() string { } var ( - // ContextOAuth2 takes an oauth2.TokenSource as authentication for the request. - ContextOAuth2 = contextKey("token") + // ContextServerIndex uses a server configuration from the index. + ContextServerIndex = contextKey("serverIndex") - // ContextBasicAuth takes BasicAuth as authentication for the request. - ContextBasicAuth = contextKey("basic") + // ContextOperationServerIndices uses a server configuration from the index mapping. + ContextOperationServerIndices = contextKey("serverOperationIndices") - // ContextAccessToken takes a string oauth2 access token as authentication for the request. - ContextAccessToken = contextKey("accesstoken") + // ContextServerVariables overrides a server configuration variables. + ContextServerVariables = contextKey("serverVariables") - // ContextAPIKey takes an APIKey as authentication for the request - ContextAPIKey = contextKey("apikey") + // ContextOperationServerVariables overrides a server configuration variables using operation specific values. + ContextOperationServerVariables = contextKey("serverOperationVariables") ) // BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth @@ -62,36 +63,39 @@ type ServerVariable struct { // ServerConfiguration stores the information about a server type ServerConfiguration struct { - Url string + URL string Description string Variables map[string]ServerVariable } +// ServerConfigurations stores multiple ServerConfiguration items +type ServerConfigurations []ServerConfiguration + // Configuration stores the configuration of the API client type Configuration struct { - BasePath string `json:"basePath,omitempty"` - Host string `json:"host,omitempty"` - Scheme string `json:"scheme,omitempty"` - DefaultHeader map[string]string `json:"defaultHeader,omitempty"` - UserAgent string `json:"userAgent,omitempty"` - Debug bool `json:"debug,omitempty"` - Servers []ServerConfiguration - HTTPClient *http.Client + Host string `json:"host,omitempty"` + Scheme string `json:"scheme,omitempty"` + DefaultHeader map[string]string `json:"defaultHeader,omitempty"` + UserAgent string `json:"userAgent,omitempty"` + Debug bool `json:"debug,omitempty"` + Servers ServerConfigurations + OperationServers map[string]ServerConfigurations + HTTPClient *http.Client } // NewConfiguration returns a new Configuration object func NewConfiguration() *Configuration { cfg := &Configuration{ - BasePath: "https://logbook.qrz.com/api", DefaultHeader: make(map[string]string), UserAgent: "OpenAPI-Generator/1.0.0/go", Debug: false, - Servers: []ServerConfiguration{ + Servers: ServerConfigurations{ { - Url: "https://logbook.qrz.com/api", + URL: "https://logbook.qrz.com/api", Description: "No description provided", }, }, + OperationServers: map[string]ServerConfigurations{}, } return cfg } @@ -101,13 +105,13 @@ func (c *Configuration) AddDefaultHeader(key string, value string) { c.DefaultHeader[key] = value } -// ServerUrl returns URL based on server settings -func (c *Configuration) ServerUrl(index int, variables map[string]string) (string, error) { - if index < 0 || len(c.Servers) <= index { - return "", fmt.Errorf("Index %v out of range %v", index, len(c.Servers)-1) +// URL formats template on a index using given variables +func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) { + if index < 0 || len(sc) <= index { + return "", fmt.Errorf("index %v out of range %v", index, len(sc)-1) } - server := c.Servers[index] - url := server.Url + server := sc[index] + url := server.URL // go through variables and replace placeholders for name, variable := range server.Variables { @@ -119,7 +123,7 @@ func (c *Configuration) ServerUrl(index int, variables map[string]string) (strin } } if !found { - return "", fmt.Errorf("The variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues) + return "", fmt.Errorf("the variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues) } url = strings.Replace(url, "{"+name+"}", value, -1) } else { @@ -128,3 +132,84 @@ func (c *Configuration) ServerUrl(index int, variables map[string]string) (strin } return url, nil } + +// ServerURL returns URL based on server settings +func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) { + return c.Servers.URL(index, variables) +} + +func getServerIndex(ctx context.Context) (int, error) { + si := ctx.Value(ContextServerIndex) + if si != nil { + if index, ok := si.(int); ok { + return index, nil + } + return 0, reportError("Invalid type %T should be int", si) + } + return 0, nil +} + +func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) { + osi := ctx.Value(ContextOperationServerIndices) + if osi != nil { + if operationIndices, ok := osi.(map[string]int); !ok { + return 0, reportError("Invalid type %T should be map[string]int", osi) + } else { + index, ok := operationIndices[endpoint] + if ok { + return index, nil + } + } + } + return getServerIndex(ctx) +} + +func getServerVariables(ctx context.Context) (map[string]string, error) { + sv := ctx.Value(ContextServerVariables) + if sv != nil { + if variables, ok := sv.(map[string]string); ok { + return variables, nil + } + return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv) + } + return nil, nil +} + +func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) { + osv := ctx.Value(ContextOperationServerVariables) + if osv != nil { + if operationVariables, ok := osv.(map[string]map[string]string); !ok { + return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv) + } else { + variables, ok := operationVariables[endpoint] + if ok { + return variables, nil + } + } + } + return getServerVariables(ctx) +} + +// ServerURLWithContext returns a new server URL given an endpoint +func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) { + sc, ok := c.OperationServers[endpoint] + if !ok { + sc = c.Servers + } + + if ctx == nil { + return sc.URL(0, nil) + } + + index, err := getServerOperationIndex(ctx, endpoint) + if err != nil { + return "", err + } + + variables, err := getServerOperationVariables(ctx, endpoint) + if err != nil { + return "", err + } + + return sc.URL(index, variables) +} diff --git a/docs/DefaultAPI.md b/docs/DefaultAPI.md new file mode 100644 index 0000000..05ca7c4 --- /dev/null +++ b/docs/DefaultAPI.md @@ -0,0 +1,78 @@ +# \DefaultAPI + +All URIs are relative to *https://logbook.qrz.com/api* + +| Method | HTTP request | Description | +| -------------------------------------- | ------------ | -------------------------- | +| [**RootPost**](DefaultAPI.md#RootPost) | **Post** / | The do-everything endpoint | + +## RootPost + +> Response +> RootPost(ctx).KEY(kEY).ACTION(aCTION).ADIF(aDIF).OPTION(oPTION).LOGIDS(lOGIDS).Execute() + +The do-everything endpoint + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/k0swe/qrz-logbook" +) + +func main() { + kEY := "kEY_example" // string | A QRZ supplied logbook access key + aCTION := "aCTION_example" // string | Type of request, i.e. INSERT, DELETE, UPLOAD, etc. + aDIF := "aDIF_example" // string | ADIF formatted input data (optional) + oPTION := "oPTION_example" // string | Action-specific options (optional) + lOGIDS := "lOGIDS_example" // string | A comma separated list of integer logid values (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.DefaultAPI.RootPost(context.Background()).KEY(kEY).ACTION(aCTION).ADIF(aDIF).OPTION(oPTION).LOGIDS(lOGIDS).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `DefaultAPI.RootPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `RootPost`: Response + fmt.Fprintf(os.Stdout, "Response from `DefaultAPI.RootPost`: %v\n", resp) +} +``` + +### Path Parameters + +### Other Parameters + +Other parameters are passed through a pointer to a apiRootPostRequest struct via +the builder pattern + +| Name | Type | Description | Notes | +| ---------- | ---------- | -------------------------------------------------- | ----- | +| **kEY** | **string** | A QRZ supplied logbook access key | +| **aCTION** | **string** | Type of request, i.e. INSERT, DELETE, UPLOAD, etc. | +| **aDIF** | **string** | ADIF formatted input data | +| **oPTION** | **string** | Action-specific options | +| **lOGIDS** | **string** | A comma separated list of integer logid values | + +### Return type + +[**Response**](Response.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/x-www-form-urlencoded +- **Accept**: application/x-www-form-urlencoded + +[[Back to top]](#) +[[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) diff --git a/docs/DefaultApi.md b/docs/DefaultApi.md index a661aec..e69de29 100644 --- a/docs/DefaultApi.md +++ b/docs/DefaultApi.md @@ -1,51 +0,0 @@ -# \DefaultApi - -All URIs are relative to *https://logbook.qrz.com/api* - -| Method | HTTP request | Description | -| -------------------------------------- | ------------ | -------------------------- | -| [**RootPost**](DefaultApi.md#RootPost) | **Post** / | The do-everything endpoint | - -## RootPost - -> Response RootPost(ctx, kEY, aCTION, optional) - -The do-everything endpoint - -### Required Parameters - -| Name | Type | Description | Notes | -| ------------ | ------------------- | --------------------------------------------------------------------------- | -------------------- | -| **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. | -| **kEY** | **string** | A QRZ supplied logbook access key | -| **aCTION** | **string** | Type of request, i.e. INSERT, DELETE, UPLOAD, etc. | -| **optional** | **\*RootPostOpts** | optional parameters | nil if no parameters | - -### Optional Parameters - -Optional parameters are passed through a pointer to a RootPostOpts struct - -| Name | Type | Description | Notes | -| ---- | ---- | ----------- | ----- | - -**aDIF** | **optional.String**| ADIF formatted input data | **oPTION** | -**optional.String**| Action-specific options | **lOGIDS** | **optional.String**| -A comma separated list of integer logid values | - -### Return type - -[**Response**](Response.md) - -### Authorization - -No authorization required - -### HTTP request headers - -- **Content-Type**: application/x-www-form-urlencoded -- **Accept**: application/x-www-form-urlencoded - -[[Back to top]](#) -[[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) diff --git a/docs/Request.md b/docs/Request.md index 8522747..6956e07 100644 --- a/docs/Request.md +++ b/docs/Request.md @@ -2,13 +2,145 @@ ## Properties -| Name | Type | Description | Notes | -| ---------- | ---------- | -------------------------------------------------- | ---------- | -| **KEY** | **string** | A QRZ supplied logbook access key | -| **ACTION** | **string** | Type of request, i.e. INSERT, DELETE, UPLOAD, etc. | -| **ADIF** | **string** | ADIF formatted input data | [optional] | -| **OPTION** | **string** | Action-specific options | [optional] | -| **LOGIDS** | **string** | A comma separated list of integer logid values | [optional] | +| Name | Type | Description | Notes | +| ---------- | --------------------- | -------------------------------------------------- | ---------- | +| **KEY** | **string** | A QRZ supplied logbook access key | +| **ACTION** | **string** | Type of request, i.e. INSERT, DELETE, UPLOAD, etc. | +| **ADIF** | Pointer to **string** | ADIF formatted input data | [optional] | +| **OPTION** | Pointer to **string** | Action-specific options | [optional] | +| **LOGIDS** | Pointer to **string** | A comma separated list of integer logid values | [optional] | + +## Methods + +### NewRequest + +`func NewRequest(kEY string, aCTION string, ) *Request` + +NewRequest instantiates a new Request object This constructor will assign +default values to properties that have it defined, and makes sure properties +required by API are set, but the set of arguments will change when the set of +required properties is changed + +### NewRequestWithDefaults + +`func NewRequestWithDefaults() *Request` + +NewRequestWithDefaults instantiates a new Request object This constructor will +only assign default values to properties that have it defined, but it doesn't +guarantee that properties required by API are set + +### GetKEY + +`func (o *Request) GetKEY() string` + +GetKEY returns the KEY field if non-nil, zero value otherwise. + +### GetKEYOk + +`func (o *Request) GetKEYOk() (*string, bool)` + +GetKEYOk returns a tuple with the KEY field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetKEY + +`func (o *Request) SetKEY(v string)` + +SetKEY sets KEY field to given value. + +### GetACTION + +`func (o *Request) GetACTION() string` + +GetACTION returns the ACTION field if non-nil, zero value otherwise. + +### GetACTIONOk + +`func (o *Request) GetACTIONOk() (*string, bool)` + +GetACTIONOk returns a tuple with the ACTION field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetACTION + +`func (o *Request) SetACTION(v string)` + +SetACTION sets ACTION field to given value. + +### GetADIF + +`func (o *Request) GetADIF() string` + +GetADIF returns the ADIF field if non-nil, zero value otherwise. + +### GetADIFOk + +`func (o *Request) GetADIFOk() (*string, bool)` + +GetADIFOk returns a tuple with the ADIF field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetADIF + +`func (o *Request) SetADIF(v string)` + +SetADIF sets ADIF field to given value. + +### HasADIF + +`func (o *Request) HasADIF() bool` + +HasADIF returns a boolean if a field has been set. + +### GetOPTION + +`func (o *Request) GetOPTION() string` + +GetOPTION returns the OPTION field if non-nil, zero value otherwise. + +### GetOPTIONOk + +`func (o *Request) GetOPTIONOk() (*string, bool)` + +GetOPTIONOk returns a tuple with the OPTION field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetOPTION + +`func (o *Request) SetOPTION(v string)` + +SetOPTION sets OPTION field to given value. + +### HasOPTION + +`func (o *Request) HasOPTION() bool` + +HasOPTION returns a boolean if a field has been set. + +### GetLOGIDS + +`func (o *Request) GetLOGIDS() string` + +GetLOGIDS returns the LOGIDS field if non-nil, zero value otherwise. + +### GetLOGIDSOk + +`func (o *Request) GetLOGIDSOk() (*string, bool)` + +GetLOGIDSOk returns a tuple with the LOGIDS field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetLOGIDS + +`func (o *Request) SetLOGIDS(v string)` + +SetLOGIDS sets LOGIDS field to given value. + +### HasLOGIDS + +`func (o *Request) HasLOGIDS() bool` + +HasLOGIDS returns a boolean if a field has been set. [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) diff --git a/docs/Response.md b/docs/Response.md index 0288f1f..30d2fd3 100644 --- a/docs/Response.md +++ b/docs/Response.md @@ -2,14 +2,183 @@ ## Properties -| Name | Type | Description | Notes | -| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| **RESULT** | **string** | OK when the operation succeeds, FAIL when the operation failed, AUTH when API Access lacked sufficient privileges for the operation, or other action-specific codes | [optional] | -| **REASON** | **string** | Used with RESULT=FAIL to describe the specific reason for failure | [optional] | -| **LOGIDS** | **string** | A comma separated list of logid values that were affected by the action | [optional] | -| **LOGID** | **string** | The logid value of the record that was inserted or replaced. (Singular \"LOGID\" response only used by INSERT as it is a single record operation.) | [optional] | -| **COUNT** | **string** | The number of QSO records that were affected by the action | [optional] | -| **DATA** | **string** | Used for action-specific data such as status reports | [optional] | +| Name | Type | Description | Notes | +| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| **RESULT** | Pointer to **string** | OK when the operation succeeds, FAIL when the operation failed, AUTH when API Access lacked sufficient privileges for the operation, or other action-specific codes | [optional] | +| **REASON** | Pointer to **string** | Used with RESULT=FAIL to describe the specific reason for failure | [optional] | +| **LOGIDS** | Pointer to **string** | A comma separated list of logid values that were affected by the action | [optional] | +| **LOGID** | Pointer to **string** | The logid value of the record that was inserted or replaced. (Singular \"LOGID\" response only used by INSERT as it is a single record operation.) | [optional] | +| **COUNT** | Pointer to **string** | The number of QSO records that were affected by the action | [optional] | +| **DATA** | Pointer to **string** | Used for action-specific data such as status reports | [optional] | + +## Methods + +### NewResponse + +`func NewResponse() *Response` + +NewResponse instantiates a new Response object This constructor will assign +default values to properties that have it defined, and makes sure properties +required by API are set, but the set of arguments will change when the set of +required properties is changed + +### NewResponseWithDefaults + +`func NewResponseWithDefaults() *Response` + +NewResponseWithDefaults instantiates a new Response object This constructor will +only assign default values to properties that have it defined, but it doesn't +guarantee that properties required by API are set + +### GetRESULT + +`func (o *Response) GetRESULT() string` + +GetRESULT returns the RESULT field if non-nil, zero value otherwise. + +### GetRESULTOk + +`func (o *Response) GetRESULTOk() (*string, bool)` + +GetRESULTOk returns a tuple with the RESULT field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetRESULT + +`func (o *Response) SetRESULT(v string)` + +SetRESULT sets RESULT field to given value. + +### HasRESULT + +`func (o *Response) HasRESULT() bool` + +HasRESULT returns a boolean if a field has been set. + +### GetREASON + +`func (o *Response) GetREASON() string` + +GetREASON returns the REASON field if non-nil, zero value otherwise. + +### GetREASONOk + +`func (o *Response) GetREASONOk() (*string, bool)` + +GetREASONOk returns a tuple with the REASON field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetREASON + +`func (o *Response) SetREASON(v string)` + +SetREASON sets REASON field to given value. + +### HasREASON + +`func (o *Response) HasREASON() bool` + +HasREASON returns a boolean if a field has been set. + +### GetLOGIDS + +`func (o *Response) GetLOGIDS() string` + +GetLOGIDS returns the LOGIDS field if non-nil, zero value otherwise. + +### GetLOGIDSOk + +`func (o *Response) GetLOGIDSOk() (*string, bool)` + +GetLOGIDSOk returns a tuple with the LOGIDS field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetLOGIDS + +`func (o *Response) SetLOGIDS(v string)` + +SetLOGIDS sets LOGIDS field to given value. + +### HasLOGIDS + +`func (o *Response) HasLOGIDS() bool` + +HasLOGIDS returns a boolean if a field has been set. + +### GetLOGID + +`func (o *Response) GetLOGID() string` + +GetLOGID returns the LOGID field if non-nil, zero value otherwise. + +### GetLOGIDOk + +`func (o *Response) GetLOGIDOk() (*string, bool)` + +GetLOGIDOk returns a tuple with the LOGID field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetLOGID + +`func (o *Response) SetLOGID(v string)` + +SetLOGID sets LOGID field to given value. + +### HasLOGID + +`func (o *Response) HasLOGID() bool` + +HasLOGID returns a boolean if a field has been set. + +### GetCOUNT + +`func (o *Response) GetCOUNT() string` + +GetCOUNT returns the COUNT field if non-nil, zero value otherwise. + +### GetCOUNTOk + +`func (o *Response) GetCOUNTOk() (*string, bool)` + +GetCOUNTOk returns a tuple with the COUNT field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetCOUNT + +`func (o *Response) SetCOUNT(v string)` + +SetCOUNT sets COUNT field to given value. + +### HasCOUNT + +`func (o *Response) HasCOUNT() bool` + +HasCOUNT returns a boolean if a field has been set. + +### GetDATA + +`func (o *Response) GetDATA() string` + +GetDATA returns the DATA field if non-nil, zero value otherwise. + +### GetDATAOk + +`func (o *Response) GetDATAOk() (*string, bool)` + +GetDATAOk returns a tuple with the DATA field if it's non-nil, zero value +otherwise and a boolean to check if the value has been set. + +### SetDATA + +`func (o *Response) SetDATA(v string)` + +SetDATA sets DATA field to given value. + +### HasDATA + +`func (o *Response) HasDATA() bool` + +HasDATA returns a boolean if a field has been set. [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) diff --git a/go.mod b/go.mod index 8ca8338..9815784 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,11 @@ module github.com/k0swe/qrz-logbook -go 1.19 +go 1.18 + +require github.com/stretchr/testify v1.10.0 require ( - github.com/antihax/optional v1.0.0 - golang.org/x/oauth2 v0.25.0 + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index cdb2014..713a0b4 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,10 @@ -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/model_request.go b/model_request.go index b849273..558c2e9 100644 --- a/model_request.go +++ b/model_request.go @@ -1,16 +1,25 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. package qrzlog +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the Request type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Request{} + // Request struct for Request type Request struct { // A QRZ supplied logbook access key @@ -18,9 +27,272 @@ type Request struct { // Type of request, i.e. INSERT, DELETE, UPLOAD, etc. ACTION string `json:"ACTION"` // ADIF formatted input data - ADIF string `json:"ADIF,omitempty"` + ADIF *string `json:"ADIF,omitempty"` // Action-specific options - OPTION string `json:"OPTION,omitempty"` + OPTION *string `json:"OPTION,omitempty"` // A comma separated list of integer logid values - LOGIDS string `json:"LOGIDS,omitempty"` + LOGIDS *string `json:"LOGIDS,omitempty"` +} + +type _Request Request + +// NewRequest instantiates a new Request object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRequest(kEY string, aCTION string) *Request { + this := Request{} + this.KEY = kEY + this.ACTION = aCTION + return &this +} + +// NewRequestWithDefaults instantiates a new Request object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRequestWithDefaults() *Request { + this := Request{} + return &this +} + +// GetKEY returns the KEY field value +func (o *Request) GetKEY() string { + if o == nil { + var ret string + return ret + } + + return o.KEY +} + +// GetKEYOk returns a tuple with the KEY field value +// and a boolean to check if the value has been set. +func (o *Request) GetKEYOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.KEY, true +} + +// SetKEY sets field value +func (o *Request) SetKEY(v string) { + o.KEY = v +} + +// GetACTION returns the ACTION field value +func (o *Request) GetACTION() string { + if o == nil { + var ret string + return ret + } + + return o.ACTION +} + +// GetACTIONOk returns a tuple with the ACTION field value +// and a boolean to check if the value has been set. +func (o *Request) GetACTIONOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ACTION, true +} + +// SetACTION sets field value +func (o *Request) SetACTION(v string) { + o.ACTION = v +} + +// GetADIF returns the ADIF field value if set, zero value otherwise. +func (o *Request) GetADIF() string { + if o == nil || IsNil(o.ADIF) { + var ret string + return ret + } + return *o.ADIF +} + +// GetADIFOk returns a tuple with the ADIF field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Request) GetADIFOk() (*string, bool) { + if o == nil || IsNil(o.ADIF) { + return nil, false + } + return o.ADIF, true +} + +// HasADIF returns a boolean if a field has been set. +func (o *Request) HasADIF() bool { + if o != nil && !IsNil(o.ADIF) { + return true + } + + return false +} + +// SetADIF gets a reference to the given string and assigns it to the ADIF field. +func (o *Request) SetADIF(v string) { + o.ADIF = &v +} + +// GetOPTION returns the OPTION field value if set, zero value otherwise. +func (o *Request) GetOPTION() string { + if o == nil || IsNil(o.OPTION) { + var ret string + return ret + } + return *o.OPTION +} + +// GetOPTIONOk returns a tuple with the OPTION field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Request) GetOPTIONOk() (*string, bool) { + if o == nil || IsNil(o.OPTION) { + return nil, false + } + return o.OPTION, true +} + +// HasOPTION returns a boolean if a field has been set. +func (o *Request) HasOPTION() bool { + if o != nil && !IsNil(o.OPTION) { + return true + } + + return false +} + +// SetOPTION gets a reference to the given string and assigns it to the OPTION field. +func (o *Request) SetOPTION(v string) { + o.OPTION = &v +} + +// GetLOGIDS returns the LOGIDS field value if set, zero value otherwise. +func (o *Request) GetLOGIDS() string { + if o == nil || IsNil(o.LOGIDS) { + var ret string + return ret + } + return *o.LOGIDS +} + +// GetLOGIDSOk returns a tuple with the LOGIDS field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Request) GetLOGIDSOk() (*string, bool) { + if o == nil || IsNil(o.LOGIDS) { + return nil, false + } + return o.LOGIDS, true +} + +// HasLOGIDS returns a boolean if a field has been set. +func (o *Request) HasLOGIDS() bool { + if o != nil && !IsNil(o.LOGIDS) { + return true + } + + return false +} + +// SetLOGIDS gets a reference to the given string and assigns it to the LOGIDS field. +func (o *Request) SetLOGIDS(v string) { + o.LOGIDS = &v +} + +func (o Request) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Request) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["KEY"] = o.KEY + toSerialize["ACTION"] = o.ACTION + if !IsNil(o.ADIF) { + toSerialize["ADIF"] = o.ADIF + } + if !IsNil(o.OPTION) { + toSerialize["OPTION"] = o.OPTION + } + if !IsNil(o.LOGIDS) { + toSerialize["LOGIDS"] = o.LOGIDS + } + return toSerialize, nil +} + +func (o *Request) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "KEY", + "ACTION", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varRequest := _Request{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varRequest) + + if err != nil { + return err + } + + *o = Request(varRequest) + + return err +} + +type NullableRequest struct { + value *Request + isSet bool +} + +func (v NullableRequest) Get() *Request { + return v.value +} + +func (v *NullableRequest) Set(val *Request) { + v.value = val + v.isSet = true +} + +func (v NullableRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRequest(val *Request) *NullableRequest { + return &NullableRequest{value: val, isSet: true} +} + +func (v NullableRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) } diff --git a/model_response.go b/model_response.go index 5d2a37e..df90d26 100644 --- a/model_response.go +++ b/model_response.go @@ -1,28 +1,311 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. package qrzlog +import ( + "encoding/json" +) + +// checks if the Response type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Response{} + // Response struct for Response type Response struct { // OK when the operation succeeds, FAIL when the operation failed, AUTH when API Access lacked sufficient privileges for the operation, or other action-specific codes - RESULT string `json:"RESULT,omitempty"` + RESULT *string `json:"RESULT,omitempty"` // Used with RESULT=FAIL to describe the specific reason for failure - REASON string `json:"REASON,omitempty"` + REASON *string `json:"REASON,omitempty"` // A comma separated list of logid values that were affected by the action - LOGIDS string `json:"LOGIDS,omitempty"` + LOGIDS *string `json:"LOGIDS,omitempty"` // The logid value of the record that was inserted or replaced. (Singular \"LOGID\" response only used by INSERT as it is a single record operation.) - LOGID string `json:"LOGID,omitempty"` + LOGID *string `json:"LOGID,omitempty"` // The number of QSO records that were affected by the action - COUNT string `json:"COUNT,omitempty"` + COUNT *string `json:"COUNT,omitempty"` // Used for action-specific data such as status reports - DATA string `json:"DATA,omitempty"` + DATA *string `json:"DATA,omitempty"` +} + +// NewResponse instantiates a new Response object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewResponse() *Response { + this := Response{} + return &this +} + +// NewResponseWithDefaults instantiates a new Response object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewResponseWithDefaults() *Response { + this := Response{} + return &this +} + +// GetRESULT returns the RESULT field value if set, zero value otherwise. +func (o *Response) GetRESULT() string { + if o == nil || IsNil(o.RESULT) { + var ret string + return ret + } + return *o.RESULT +} + +// GetRESULTOk returns a tuple with the RESULT field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetRESULTOk() (*string, bool) { + if o == nil || IsNil(o.RESULT) { + return nil, false + } + return o.RESULT, true +} + +// HasRESULT returns a boolean if a field has been set. +func (o *Response) HasRESULT() bool { + if o != nil && !IsNil(o.RESULT) { + return true + } + + return false +} + +// SetRESULT gets a reference to the given string and assigns it to the RESULT field. +func (o *Response) SetRESULT(v string) { + o.RESULT = &v +} + +// GetREASON returns the REASON field value if set, zero value otherwise. +func (o *Response) GetREASON() string { + if o == nil || IsNil(o.REASON) { + var ret string + return ret + } + return *o.REASON +} + +// GetREASONOk returns a tuple with the REASON field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetREASONOk() (*string, bool) { + if o == nil || IsNil(o.REASON) { + return nil, false + } + return o.REASON, true +} + +// HasREASON returns a boolean if a field has been set. +func (o *Response) HasREASON() bool { + if o != nil && !IsNil(o.REASON) { + return true + } + + return false +} + +// SetREASON gets a reference to the given string and assigns it to the REASON field. +func (o *Response) SetREASON(v string) { + o.REASON = &v +} + +// GetLOGIDS returns the LOGIDS field value if set, zero value otherwise. +func (o *Response) GetLOGIDS() string { + if o == nil || IsNil(o.LOGIDS) { + var ret string + return ret + } + return *o.LOGIDS +} + +// GetLOGIDSOk returns a tuple with the LOGIDS field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetLOGIDSOk() (*string, bool) { + if o == nil || IsNil(o.LOGIDS) { + return nil, false + } + return o.LOGIDS, true +} + +// HasLOGIDS returns a boolean if a field has been set. +func (o *Response) HasLOGIDS() bool { + if o != nil && !IsNil(o.LOGIDS) { + return true + } + + return false +} + +// SetLOGIDS gets a reference to the given string and assigns it to the LOGIDS field. +func (o *Response) SetLOGIDS(v string) { + o.LOGIDS = &v +} + +// GetLOGID returns the LOGID field value if set, zero value otherwise. +func (o *Response) GetLOGID() string { + if o == nil || IsNil(o.LOGID) { + var ret string + return ret + } + return *o.LOGID +} + +// GetLOGIDOk returns a tuple with the LOGID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetLOGIDOk() (*string, bool) { + if o == nil || IsNil(o.LOGID) { + return nil, false + } + return o.LOGID, true +} + +// HasLOGID returns a boolean if a field has been set. +func (o *Response) HasLOGID() bool { + if o != nil && !IsNil(o.LOGID) { + return true + } + + return false +} + +// SetLOGID gets a reference to the given string and assigns it to the LOGID field. +func (o *Response) SetLOGID(v string) { + o.LOGID = &v +} + +// GetCOUNT returns the COUNT field value if set, zero value otherwise. +func (o *Response) GetCOUNT() string { + if o == nil || IsNil(o.COUNT) { + var ret string + return ret + } + return *o.COUNT +} + +// GetCOUNTOk returns a tuple with the COUNT field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetCOUNTOk() (*string, bool) { + if o == nil || IsNil(o.COUNT) { + return nil, false + } + return o.COUNT, true +} + +// HasCOUNT returns a boolean if a field has been set. +func (o *Response) HasCOUNT() bool { + if o != nil && !IsNil(o.COUNT) { + return true + } + + return false +} + +// SetCOUNT gets a reference to the given string and assigns it to the COUNT field. +func (o *Response) SetCOUNT(v string) { + o.COUNT = &v +} + +// GetDATA returns the DATA field value if set, zero value otherwise. +func (o *Response) GetDATA() string { + if o == nil || IsNil(o.DATA) { + var ret string + return ret + } + return *o.DATA +} + +// GetDATAOk returns a tuple with the DATA field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Response) GetDATAOk() (*string, bool) { + if o == nil || IsNil(o.DATA) { + return nil, false + } + return o.DATA, true +} + +// HasDATA returns a boolean if a field has been set. +func (o *Response) HasDATA() bool { + if o != nil && !IsNil(o.DATA) { + return true + } + + return false +} + +// SetDATA gets a reference to the given string and assigns it to the DATA field. +func (o *Response) SetDATA(v string) { + o.DATA = &v +} + +func (o Response) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Response) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.RESULT) { + toSerialize["RESULT"] = o.RESULT + } + if !IsNil(o.REASON) { + toSerialize["REASON"] = o.REASON + } + if !IsNil(o.LOGIDS) { + toSerialize["LOGIDS"] = o.LOGIDS + } + if !IsNil(o.LOGID) { + toSerialize["LOGID"] = o.LOGID + } + if !IsNil(o.COUNT) { + toSerialize["COUNT"] = o.COUNT + } + if !IsNil(o.DATA) { + toSerialize["DATA"] = o.DATA + } + return toSerialize, nil +} + +type NullableResponse struct { + value *Response + isSet bool +} + +func (v NullableResponse) Get() *Response { + return v.value +} + +func (v *NullableResponse) Set(val *Response) { + v.value = val + v.isSet = true +} + +func (v NullableResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableResponse(val *Response) *NullableResponse { + return &NullableResponse{value: val, isSet: true} +} + +func (v NullableResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) } diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000..f8d07ce --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.10.0" + } +} diff --git a/regenerate.sh b/regenerate.sh index 5602763..f6f5edc 100755 --- a/regenerate.sh +++ b/regenerate.sh @@ -1,2 +1,8 @@ #!/bin/bash -openapi-generator generate -i=api/openapi.yaml -g=go -c=api/openapi-config.yaml +npm install @openapitools/openapi-generator-cli prettier -g +openapi-generator-cli generate -i=api/openapi.yaml -g=go -c=api/openapi-config.yaml +find . -type f -exec sed -i 's/GIT_USER_ID\/GIT_REPO_ID/k0swe\/qrz\-logbook/g' {} + +go get -u +go mod tidy +go fmt ./... +prettier -w --prose-wrap always . diff --git a/response.go b/response.go index d519460..7528e35 100644 --- a/response.go +++ b/response.go @@ -1,11 +1,11 @@ /* - * QRZ Logbook API - * - * This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. - * - * API version: 1.0.0 - * Contact: flloyd@qrz.com - */ +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. @@ -33,7 +33,7 @@ type APIResponse struct { Payload []byte `json:"-"` } -// NewAPIResponse returns a new APIResonse object. +// NewAPIResponse returns a new APIResponse object. func NewAPIResponse(r *http.Response) *APIResponse { response := &APIResponse{Response: r} diff --git a/test/api_default_test.go b/test/api_default_test.go new file mode 100644 index 0000000..bc11713 --- /dev/null +++ b/test/api_default_test.go @@ -0,0 +1,37 @@ +/* +QRZ Logbook API + +Testing DefaultAPIService + +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); + +package qrzlog + +import ( + "context" + openapiclient "github.com/k0swe/qrz-logbook" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func Test_qrzlog_DefaultAPIService(t *testing.T) { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + + t.Run("Test DefaultAPIService RootPost", func(t *testing.T) { + + t.Skip("skip test") // remove to run test + + resp, httpRes, err := apiClient.DefaultAPI.RootPost(context.Background()).Execute() + + require.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, 200, httpRes.StatusCode) + + }) + +} diff --git a/unmarshal.go b/unmarshal.go index c8f9f76..2add735 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -1,29 +1,39 @@ package qrzlog import ( + "net/url" "regexp" "strings" ) -func unmarshalForm(payload []byte, v interface{}) error { - resp := v.(*Response) +func unmarshalForm(payload []byte, resp *Response) error { + if resp == nil { + resp = &Response{} + } s := string(payload) // QRZ's Logbook API returns something resembling application/x-www-form-urlencoded, but // the fields are not escaped so attempting to use url.ParseQuery() directly fails. - // TODO: This parser is a terrible hack and if you can think of something better, have at it. - findField(&s, regexp.MustCompile(`(^|&)RESULT=(\w*)`), &resp.RESULT) - findField(&s, regexp.MustCompile(`(^|&)REASON=(\w*)`), &resp.REASON) - findField(&s, regexp.MustCompile(`(^|&)LOGIDS=([\d,]*)`), &resp.LOGIDS) - findField(&s, regexp.MustCompile(`(^|&)LOGID=(\d*)`), &resp.LOGID) - findField(&s, regexp.MustCompile(`(^|&)COUNT=(\d*)`), &resp.COUNT) - resp.DATA = strings.Trim(s, "& \n") + values, err := url.ParseQuery(s) + if err != nil { + return err + } + + v1 := values.Get("RESULT") + resp.RESULT = &v1 + v2 := values.Get("REASON") + resp.REASON = &v2 + v3 := values.Get("LOGIDS") + resp.LOGIDS = &v3 + v4 := values.Get("LOGID") + resp.LOGID = &v4 + v5 := values.Get("COUNT") + resp.COUNT = &v5 + + trim := strings.Trim(s, "& \n") + resp.DATA = &trim return nil } -func findField(payload *string, regex *regexp.Regexp, field *string) { - submatch := regex.FindStringSubmatch(*payload) - if submatch != nil { - *field = submatch[2] - *payload = strings.Replace(*payload, submatch[0], "", -1) - } +func findField(data *string, compile *regexp.Regexp, s *string) { + } diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..8f6d5de --- /dev/null +++ b/utils.go @@ -0,0 +1,362 @@ +/* +QRZ Logbook API + +This API provides methods for external programs to interact with the QRZ Logbook using an HTTP REST interface. The QRZ Logbook is a combination free and paid subscription service of QRZ. Some advanced features require a valid subscription while the majority of operations are free to all QRZ members. All users of the QRZ Logbook, regardless of their subscription status, may access, edit, update, and view their complete logs online at the QRZ website. + +API version: 1.0.0 +Contact: flloyd@qrz.com +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package qrzlog + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "time" +) + +// PtrBool is a helper routine that returns a pointer to given boolean value. +func PtrBool(v bool) *bool { return &v } + +// PtrInt is a helper routine that returns a pointer to given integer value. +func PtrInt(v int) *int { return &v } + +// PtrInt32 is a helper routine that returns a pointer to given integer value. +func PtrInt32(v int32) *int32 { return &v } + +// PtrInt64 is a helper routine that returns a pointer to given integer value. +func PtrInt64(v int64) *int64 { return &v } + +// PtrFloat32 is a helper routine that returns a pointer to given float value. +func PtrFloat32(v float32) *float32 { return &v } + +// PtrFloat64 is a helper routine that returns a pointer to given float value. +func PtrFloat64(v float64) *float64 { return &v } + +// PtrString is a helper routine that returns a pointer to given string value. +func PtrString(v string) *string { return &v } + +// PtrTime is helper routine that returns a pointer to given Time value. +func PtrTime(v time.Time) *time.Time { return &v } + +type NullableBool struct { + value *bool + isSet bool +} + +func (v NullableBool) Get() *bool { + return v.value +} + +func (v *NullableBool) Set(val *bool) { + v.value = val + v.isSet = true +} + +func (v NullableBool) IsSet() bool { + return v.isSet +} + +func (v *NullableBool) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBool(val *bool) *NullableBool { + return &NullableBool{value: val, isSet: true} +} + +func (v NullableBool) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBool) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt struct { + value *int + isSet bool +} + +func (v NullableInt) Get() *int { + return v.value +} + +func (v *NullableInt) Set(val *int) { + v.value = val + v.isSet = true +} + +func (v NullableInt) IsSet() bool { + return v.isSet +} + +func (v *NullableInt) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt(val *int) *NullableInt { + return &NullableInt{value: val, isSet: true} +} + +func (v NullableInt) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt32 struct { + value *int32 + isSet bool +} + +func (v NullableInt32) Get() *int32 { + return v.value +} + +func (v *NullableInt32) Set(val *int32) { + v.value = val + v.isSet = true +} + +func (v NullableInt32) IsSet() bool { + return v.isSet +} + +func (v *NullableInt32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt32(val *int32) *NullableInt32 { + return &NullableInt32{value: val, isSet: true} +} + +func (v NullableInt32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt64 struct { + value *int64 + isSet bool +} + +func (v NullableInt64) Get() *int64 { + return v.value +} + +func (v *NullableInt64) Set(val *int64) { + v.value = val + v.isSet = true +} + +func (v NullableInt64) IsSet() bool { + return v.isSet +} + +func (v *NullableInt64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt64(val *int64) *NullableInt64 { + return &NullableInt64{value: val, isSet: true} +} + +func (v NullableInt64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat32 struct { + value *float32 + isSet bool +} + +func (v NullableFloat32) Get() *float32 { + return v.value +} + +func (v *NullableFloat32) Set(val *float32) { + v.value = val + v.isSet = true +} + +func (v NullableFloat32) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat32(val *float32) *NullableFloat32 { + return &NullableFloat32{value: val, isSet: true} +} + +func (v NullableFloat32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat64 struct { + value *float64 + isSet bool +} + +func (v NullableFloat64) Get() *float64 { + return v.value +} + +func (v *NullableFloat64) Set(val *float64) { + v.value = val + v.isSet = true +} + +func (v NullableFloat64) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat64(val *float64) *NullableFloat64 { + return &NullableFloat64{value: val, isSet: true} +} + +func (v NullableFloat64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableString struct { + value *string + isSet bool +} + +func (v NullableString) Get() *string { + return v.value +} + +func (v *NullableString) Set(val *string) { + v.value = val + v.isSet = true +} + +func (v NullableString) IsSet() bool { + return v.isSet +} + +func (v *NullableString) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableString(val *string) *NullableString { + return &NullableString{value: val, isSet: true} +} + +func (v NullableString) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableString) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableTime struct { + value *time.Time + isSet bool +} + +func (v NullableTime) Get() *time.Time { + return v.value +} + +func (v *NullableTime) Set(val *time.Time) { + v.value = val + v.isSet = true +} + +func (v NullableTime) IsSet() bool { + return v.isSet +} + +func (v *NullableTime) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTime(val *time.Time) *NullableTime { + return &NullableTime{value: val, isSet: true} +} + +func (v NullableTime) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTime) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +// IsNil checks if an input is nil +func IsNil(i interface{}) bool { + if i == nil { + return true + } + switch reflect.TypeOf(i).Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return reflect.ValueOf(i).IsNil() + case reflect.Array: + return reflect.ValueOf(i).IsZero() + } + return false +} + +type MappedNullable interface { + ToMap() (map[string]interface{}, error) +} + +// A wrapper for strict JSON decoding +func newStrictDecoder(data []byte) *json.Decoder { + dec := json.NewDecoder(bytes.NewBuffer(data)) + dec.DisallowUnknownFields() + return dec +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} diff --git a/wrapper.go b/wrapper.go index c420563..83d07c2 100644 --- a/wrapper.go +++ b/wrapper.go @@ -3,7 +3,6 @@ package qrzlog import ( "context" "errors" - "github.com/antihax/optional" "regexp" "strconv" "strings" @@ -19,23 +18,23 @@ type FetchResponse struct { func Fetch(ctx context.Context, key *string) (*FetchResponse, error) { client := newClient() - opts := RootPostOpts{} - apiResp, _, err := client.DefaultApi.RootPost(ctx, *key, "FETCH", &opts) + req := client.DefaultAPI.RootPost(ctx).KEY(*key).ACTION("FETCH") + apiResp, _, err := req.Execute() if err != nil { return nil, err } - count, _ := strconv.ParseUint(apiResp.COUNT, 10, 64) - adif := strings.Replace(apiResp.DATA, "ADIF=", "", -1) + count, _ := strconv.ParseUint(*apiResp.COUNT, 10, 64) + adif := strings.Replace(*apiResp.DATA, "ADIF=", "", -1) adif = strings.ReplaceAll(adif, "<", "<") adif = strings.ReplaceAll(adif, ">", ">") r := FetchResponse{ - Result: apiResp.RESULT, + Result: *apiResp.RESULT, Count: count, Adif: adif, } - if apiResp.RESULT == "FAIL" && apiResp.REASON != "" { + if *apiResp.RESULT == "FAIL" && *apiResp.REASON != "" { // having a logbook with 0 QSOs will always result in a FAIL - err = errors.New(apiResp.REASON) + err = errors.New(*apiResp.REASON) } return &r, err } @@ -56,34 +55,34 @@ type StatusResponse struct { func Status(ctx context.Context, key *string) (*StatusResponse, error) { client := newClient() - opts := RootPostOpts{} - apiResp, _, err := client.DefaultApi.RootPost(ctx, *key, "STATUS", &opts) + req := client.DefaultAPI.RootPost(ctx).KEY(*key).ACTION("STATUS") + apiResp, _, err := req.Execute() if err != nil { return nil, err } - count, _ := strconv.ParseUint(apiResp.COUNT, 10, 64) + count, _ := strconv.ParseUint(*apiResp.COUNT, 10, 64) r := StatusResponse{ - Result: apiResp.RESULT, + Result: *apiResp.RESULT, Count: count, } var confirmedStr, dxccCountStr string - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)CONFIRMED=([\d]*)`), &confirmedStr) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)CONFIRMED=([\d]*)`), &confirmedStr) r.Confirmed, _ = strconv.ParseUint(confirmedStr, 10, 64) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)DXCC_COUNT=(\d*)`), &dxccCountStr) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)DXCC_COUNT=(\d*)`), &dxccCountStr) r.DxccCount, _ = strconv.ParseUint(dxccCountStr, 10, 64) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)ACTION=(\w*)`), &r.Action) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)BOOKID=(\d*)`), &r.BookId) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)CALLSIGN=([\w-/]*)`), &r.Callsign) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)END_DATE=([\d-]*)`), &r.EndDate) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)OWNER=([\w-/]*)`), &r.Owner) - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)START_DATE=([\d-]*)`), &r.StartDate) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)ACTION=(\w*)`), &r.Action) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)BOOKID=(\d*)`), &r.BookId) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)CALLSIGN=([\w-/]*)`), &r.Callsign) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)END_DATE=([\d-]*)`), &r.EndDate) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)OWNER=([\w-/]*)`), &r.Owner) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)START_DATE=([\d-]*)`), &r.StartDate) // Put this at the end because it's the least strict regex - findField(&apiResp.DATA, regexp.MustCompile(`(^|&)BOOK_NAME=(.*)`), &r.BookName) - if apiResp.RESULT == "FAIL" && apiResp.REASON != "" { - err = errors.New(apiResp.REASON) + findField(apiResp.DATA, regexp.MustCompile(`(^|&)BOOK_NAME=(.*)`), &r.BookName) + if *apiResp.RESULT == "FAIL" && *apiResp.REASON != "" { + err = errors.New(*apiResp.REASON) } return &r, err } @@ -96,25 +95,25 @@ type InsertResponse struct { func Insert(ctx context.Context, key *string, adif string, replace bool) (*InsertResponse, error) { client := newClient() - opts := RootPostOpts{ - ADIF: optional.NewString(adif), - } + act := "INSERT" if replace { - opts.OPTION = optional.NewString("REPLACE") + act = "REPLACE" } - apiResp, _, err := client.DefaultApi.RootPost(ctx, *key, "INSERT", &opts) + req := client.DefaultAPI.RootPost(ctx).KEY(*key).ACTION(act) + req.ADIF(adif) + apiResp, _, err := req.Execute() if err != nil { return nil, err } - count, _ := strconv.ParseUint(apiResp.COUNT, 10, 64) + count, _ := strconv.ParseUint(*apiResp.COUNT, 10, 64) r := InsertResponse{ - Result: apiResp.RESULT, - LogId: apiResp.LOGID, + Result: *apiResp.RESULT, + LogId: *apiResp.LOGID, Count: count, } - if apiResp.RESULT == "FAIL" && apiResp.REASON != "" { - err = errors.New(apiResp.REASON) + if *apiResp.RESULT == "FAIL" && *apiResp.REASON != "" { + err = errors.New(*apiResp.REASON) } return &r, err } @@ -128,24 +127,22 @@ type DeleteResponse struct { func Delete(ctx context.Context, key *string, ids []string) (*DeleteResponse, error) { client := newClient() - idsSlice := strings.Join(ids, ",") - opts := RootPostOpts{ - LOGIDS: optional.NewString(idsSlice), - } - apiResp, _, err := client.DefaultApi.RootPost(ctx, *key, "DELETE", &opts) + req := client.DefaultAPI.RootPost(ctx).KEY(*key).ACTION("DELETE") + req.LOGIDS(strings.Join(ids, ",")) + apiResp, _, err := req.Execute() if err != nil { return nil, err } - count, _ := strconv.ParseUint(apiResp.COUNT, 10, 64) - notDeleted := strings.Split(apiResp.LOGIDS, ",") + count, _ := strconv.ParseUint(*apiResp.COUNT, 10, 64) + notDeleted := strings.Split(*apiResp.LOGIDS, ",") r := DeleteResponse{ - Result: apiResp.RESULT, + Result: *apiResp.RESULT, LogIds: notDeleted, Count: count, } - if apiResp.RESULT == "FAIL" && apiResp.REASON != "" { - err = errors.New(apiResp.REASON) + if *apiResp.RESULT == "FAIL" && *apiResp.REASON != "" { + err = errors.New(*apiResp.REASON) } return &r, err }