diff --git a/api/job/ent_job.go b/api/job/ent_job.go new file mode 100644 index 0000000..f6e8437 --- /dev/null +++ b/api/job/ent_job.go @@ -0,0 +1,56 @@ +package job + +// GetJobResponse defines get job response +type GetJobResponse struct { + TranslationJobUID string + JobName string +} + +// FindFirstJobByName finds the first job by name from the list of jobs +func FindFirstJobByName(jobs []GetJobResponse, name string) (GetJobResponse, bool) { + for _, job := range jobs { + if job.JobName == name { + return job, true + } + } + return GetJobResponse{}, false +} + +type getJobResponse struct { + Response struct { + Code string `json:"code"` + Data struct { + JobName string `json:"jobName"` + TranslationJobUID string `json:"translationJobUid"` + } `json:"data"` + } `json:"response"` +} +type getJobsResponse struct { + Response struct { + Code string `json:"code"` + Data struct { + Items []struct { + JobName string `json:"jobName"` + TranslationJobUID string `json:"translationJobUid"` + } `json:"items"` + } `json:"data"` + } `json:"response"` +} + +func toGetJobResponse(r getJobResponse) GetJobResponse { + return GetJobResponse{ + TranslationJobUID: r.Response.Data.TranslationJobUID, + JobName: r.Response.Data.JobName, + } +} + +func toGetJobsResponse(r getJobsResponse) []GetJobResponse { + res := make([]GetJobResponse, len(r.Response.Data.Items)) + for i, job := range r.Response.Data.Items { + res[i] = GetJobResponse{ + TranslationJobUID: job.TranslationJobUID, + JobName: job.JobName, + } + } + return res +} diff --git a/api/job/ent_job_progress.go b/api/job/ent_job_progress.go new file mode 100644 index 0000000..350737a --- /dev/null +++ b/api/job/ent_job_progress.go @@ -0,0 +1,66 @@ +package job + +import ( + "encoding/json" + "fmt" +) + +// GetJobProgressResponse defines get job progress response +type GetJobProgressResponse struct { + TranslationJobUID string + TotalWordCount uint32 + PercentComplete uint32 + Json []byte +} +type getJobProgressResponse struct { + Response struct { + Code string `json:"code"` + Data struct { + ContentProgressReport []struct { + Progress struct { + PercentComplete int `json:"percentComplete"` + TotalWordCount int `json:"totalWordCount"` + } `json:"progress"` + TargetLocaleDescription string `json:"targetLocaleDescription"` + TargetLocaleId string `json:"targetLocaleId"` + UnauthorizedProgressReport struct { + StringCount int `json:"stringCount"` + WordCount int `json:"wordCount"` + } `json:"unauthorizedProgressReport"` + WorkflowProgressReportList []struct { + WorkflowName string `json:"workflowName"` + WorkflowStepSummaryReportItemList []struct { + StringCount int `json:"stringCount"` + WordCount int `json:"wordCount"` + WorkflowStepName string `json:"workflowStepName"` + WorkflowStepType string `json:"workflowStepType"` + WorkflowStepUid string `json:"workflowStepUid"` + } `json:"workflowStepSummaryReportItemList"` + WorkflowUid string `json:"workflowUid"` + } `json:"workflowProgressReportList"` + } `json:"contentProgressReport"` + Progress struct { + PercentComplete int `json:"percentComplete"` + TotalWordCount int `json:"totalWordCount"` + } `json:"progress"` + SummaryReport []struct { + StringCount int `json:"stringCount"` + WordCount int `json:"wordCount"` + WorkflowStepName string `json:"workflowStepName"` + } `json:"summaryReport"` + } `json:"data"` + } `json:"response"` +} + +func toGetJobProgressResponse(r getJobProgressResponse, translationJobUID string) (GetJobProgressResponse, error) { + data, err := json.Marshal(r.Response.Data) + if err != nil { + return GetJobProgressResponse{}, fmt.Errorf("failed to marshal job progress response: %w", err) + } + return GetJobProgressResponse{ + TranslationJobUID: translationJobUID, + TotalWordCount: uint32(r.Response.Data.Progress.TotalWordCount), + PercentComplete: uint32(r.Response.Data.Progress.PercentComplete), + Json: data, + }, nil +} diff --git a/api/job/job.go b/api/job/job.go index f71dbcb..23455dc 100644 --- a/api/job/job.go +++ b/api/job/job.go @@ -4,15 +4,18 @@ import ( "encoding/json" "fmt" "io" + "net/url" smclient "github.com/Smartling/api-sdk-go/helpers/sm_client" ) -const jobBasePath = "/job-batches-api/v2/projects/" +const jobBasePath = "/jobs-api/v3/projects/" // Job defines the job behaviour type Job interface { - GetJob(projectID string, translationJobUID string) (GetJobResponse, error) + Get(projectID string, translationJobUID string) (GetJobResponse, error) + GetAllByName(projectID, name string) (jobs []GetJobResponse, err error) + Progress(projectID string, translationJobUID string) (GetJobProgressResponse, error) } // NewJob returns new Job implementation @@ -29,27 +32,89 @@ func newHttpJob(client *smclient.Client) httpJob { return httpJob{client: client} } -// GetJob gets a job related info -func (h httpJob) GetJob(projectID string, translationJobUID string) (GetJobResponse, error) { +// Get gets a job related info +func (h httpJob) Get(projectID string, translationJobUID string) (GetJobResponse, error) { url := jobBasePath + projectID + "/jobs/" + translationJobUID var response getJobResponse rawMessage, code, err := h.client.Get(url, nil) if err != nil { return GetJobResponse{}, err } + defer func() { + if err := rawMessage.Close(); err != nil { + h.client.Logger.Debugf("failed to close response body: %v", err) + } + }() + body, err := io.ReadAll(rawMessage) + if err != nil { + return GetJobResponse{}, fmt.Errorf("failed to read response body: %w", err) + } if code != 200 { - body, _ := io.ReadAll(rawMessage) h.client.Logger.Debugf("response body: %s\n", body) return GetJobResponse{}, fmt.Errorf("unexpected response code: %d", code) } + if err := json.Unmarshal(body, &response); err != nil { + return GetJobResponse{}, fmt.Errorf("failed to unmarshal response: %w", err) + } + return toGetJobResponse(response), nil +} + +// GetAllByName gets all jobs of a project by name +func (h httpJob) GetAllByName(projectID, name string) ([]GetJobResponse, error) { + reqURL := jobBasePath + projectID + "/jobs" + + params := url.Values{} + params.Set("jobName", name) + + rawMessage, code, err := h.client.Get(reqURL, params) + if err != nil { + return nil, err + } + defer func() { + if err := rawMessage.Close(); err != nil { + h.client.Logger.Debugf("failed to close response body: %v", err) + } + }() body, err := io.ReadAll(rawMessage) if err != nil { - body, _ := io.ReadAll(rawMessage) + return nil, fmt.Errorf("failed to read response body: %w", err) + } + if code != 200 { h.client.Logger.Debugf("response body: %s\n", body) - return GetJobResponse{}, err + return nil, fmt.Errorf("unexpected response code: %d", code) + } + var res getJobsResponse + if err := json.Unmarshal(body, &res); err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + jobs := toGetJobsResponse(res) + + return jobs, nil +} + +// Progress returns a job related progress +func (h httpJob) Progress(projectID string, translationJobUID string) (GetJobProgressResponse, error) { + url := jobBasePath + projectID + "/jobs/" + translationJobUID + "/progress" + var response getJobProgressResponse + rawMessage, code, err := h.client.Get(url, nil) + if err != nil { + return GetJobProgressResponse{}, err + } + defer func() { + if err := rawMessage.Close(); err != nil { + h.client.Logger.Debugf("failed to close response body: %v", err) + } + }() + body, err := io.ReadAll(rawMessage) + if err != nil { + return GetJobProgressResponse{}, fmt.Errorf("failed to read response body: %w", err) + } + if code != 200 { + h.client.Logger.Debugf("response body: %s\n", body) + return GetJobProgressResponse{}, fmt.Errorf("unexpected response code: %d", code) } if err := json.Unmarshal(body, &response); err != nil { - return GetJobResponse{}, fmt.Errorf("failed to unmarshal response: %w", err) + return GetJobProgressResponse{}, fmt.Errorf("failed to unmarshal response: %w", err) } - return toGetJobResponse(response), nil + return toGetJobProgressResponse(response, translationJobUID) } diff --git a/api/job/job_ent.go b/api/job/job_ent.go deleted file mode 100644 index 9d3d84d..0000000 --- a/api/job/job_ent.go +++ /dev/null @@ -1,23 +0,0 @@ -package job - -// GetJobResponse defines get job response -type GetJobResponse struct { - TranslationJobUID string - JobName string -} -type getJobResponse struct { - Response struct { - Code string `json:"code"` - Data struct { - JobName string `json:"jobName"` - TranslationJobUID string `json:"translationJobUid"` - } `json:"data"` - } `json:"response"` -} - -func toGetJobResponse(r getJobResponse) GetJobResponse { - return GetJobResponse{ - TranslationJobUID: r.Response.Data.TranslationJobUID, - JobName: r.Response.Data.JobName, - } -} diff --git a/download_file_request.go b/download_file_request.go index 8ffe7f3..7cb71b7 100644 --- a/download_file_request.go +++ b/download_file_request.go @@ -21,8 +21,9 @@ package smartling import ( "fmt" - "github.com/Smartling/api-sdk-go/helpers/sm_file" "net/url" + + "github.com/Smartling/api-sdk-go/helpers/sm_file" ) // RetrievalType describes type of file download. diff --git a/helpers/sm_file/file_last_modified_request.go b/helpers/sm_file/file_last_modified_request.go index 4fde406..6505a0c 100644 --- a/helpers/sm_file/file_last_modified_request.go +++ b/helpers/sm_file/file_last_modified_request.go @@ -32,13 +32,11 @@ type FileLastModifiedRequest struct { func (request *FileLastModifiedRequest) GetForm() (*sm_form.Form, error) { form, err := request.FileURIRequest.GetForm() - if err != nil { return nil, err } err = form.Writer.WriteField("lastModifiedAfter", request.LastModifiedAfter.String()) - if err != nil { return nil, err } diff --git a/helpers/sm_file/files_list_request.go b/helpers/sm_file/files_list_request.go index 9587deb..b23c46e 100644 --- a/helpers/sm_file/files_list_request.go +++ b/helpers/sm_file/files_list_request.go @@ -21,8 +21,9 @@ package smfile import ( "fmt" - "github.com/Smartling/api-sdk-go/helpers/utc" "net/url" + + "github.com/Smartling/api-sdk-go/helpers/utc" ) // FilesListRequest represents request used to filter files returned by diff --git a/helpers/sm_file/get_file_type_by_extension.go b/helpers/sm_file/get_file_type_by_extension.go index 2d46a08..cf8948a 100644 --- a/helpers/sm_file/get_file_type_by_extension.go +++ b/helpers/sm_file/get_file_type_by_extension.go @@ -23,33 +23,31 @@ import ( "strings" ) -var ( - extensions = map[string]FileType{ - "yml": FileTypeYAML, - "yaml": FileTypeYAML, - "html": FileTypeHTML, - "htm": FileTypeHTML, - "xlf": FileTypeXLIFF, - "xliff": FileTypeXLIFF, - "json": FileTypeJSON, - "docx": FileTypeDOCX, - "pptx": FileTypePPTX, - "xlsx": FileTypeXLSX, - "txt": FileTypePlaintext, - "ts": FileTypeQt, - "idml": FileTypeIDML, - "resx": FileTypeResx, - "resw": FileTypeResx, - "csv": FileTypeCSV, - "stringsdict": FileTypeStringsdict, - "strings": FileTypeIOS, - "po": FileTypeGettext, - "pot": FileTypeGettext, - "xml": FileTypeXML, - "properties": FileTypeJavaProperties, - "": FileTypeUnknown, - } -) +var extensions = map[string]FileType{ + "yml": FileTypeYAML, + "yaml": FileTypeYAML, + "html": FileTypeHTML, + "htm": FileTypeHTML, + "xlf": FileTypeXLIFF, + "xliff": FileTypeXLIFF, + "json": FileTypeJSON, + "docx": FileTypeDOCX, + "pptx": FileTypePPTX, + "xlsx": FileTypeXLSX, + "txt": FileTypePlaintext, + "ts": FileTypeQt, + "idml": FileTypeIDML, + "resx": FileTypeResx, + "resw": FileTypeResx, + "csv": FileTypeCSV, + "stringsdict": FileTypeStringsdict, + "strings": FileTypeIOS, + "po": FileTypeGettext, + "pot": FileTypeGettext, + "xml": FileTypeXML, + "properties": FileTypeJavaProperties, + "": FileTypeUnknown, +} func GetFileTypeByExtension(ext string) FileType { return extensions[strings.TrimPrefix(ext, ".")]