diff --git a/cmd/listens.go b/cmd/listens.go index c18bace..9093dbc 100644 --- a/cmd/listens.go +++ b/cmd/listens.go @@ -70,12 +70,15 @@ var listensCmd = &cobra.Command{ progress := progressBar(&wg, exportProgress, importProgress) // Export from source - listensChan := make(chan models.ListensResult, 1000) - go exportBackend.ExportListens(timestamp, listensChan, exportProgress) + exportChan := make(chan models.ListensResult, 1000) + go exportBackend.ExportListens(timestamp, exportChan, exportProgress) // Import into target resultChan := make(chan models.ImportResult) - go backends.ProcessListensImports(importBackend, listensChan, resultChan, importProgress) + var processor = backends.ListensImportProcessor{ + Backend: importBackend, + } + go processor.Process(exportChan, resultChan, importProgress) result := <-resultChan close(exportProgress) wg.Wait() diff --git a/cmd/loves.go b/cmd/loves.go index 941290f..623b477 100644 --- a/cmd/loves.go +++ b/cmd/loves.go @@ -70,12 +70,15 @@ var lovesCmd = &cobra.Command{ progress := progressBar(&wg, exportProgress, importProgress) // Export from source - lovesChan := make(chan models.LovesResult, 1000) - go exportBackend.ExportLoves(timestamp, lovesChan, exportProgress) + exportChan := make(chan models.LovesResult, 1000) + go exportBackend.ExportLoves(timestamp, exportChan, exportProgress) // Import into target resultChan := make(chan models.ImportResult) - go backends.ProcessLovesImports(importBackend, lovesChan, resultChan, importProgress) + var processor = backends.LovesImportProcessor{ + Backend: importBackend, + } + go processor.Process(exportChan, resultChan, importProgress) result := <-resultChan close(exportProgress) wg.Wait() diff --git a/internal/backends/import.go b/internal/backends/import.go new file mode 100644 index 0000000..cd47960 --- /dev/null +++ b/internal/backends/import.go @@ -0,0 +1,121 @@ +/* +Copyright © 2023 Philipp Wolfer + +This file is part of Scotty. + +Scotty is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later version. + +Scotty is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +Scotty. If not, see . +*/ + +package backends + +import "go.uploadedlobster.com/scotty/internal/models" + +type ImportProcessor[T models.ListensResult | models.LovesResult] interface { + ImportBackend() models.ImportBackend + Process(results chan T, out chan models.ImportResult, progress chan models.Progress) + Import(export T, result models.ImportResult, out chan models.ImportResult, progress chan models.Progress) models.ImportResult +} + +type ListensImportProcessor struct { + Backend models.ListensImport +} + +func (p ListensImportProcessor) ImportBackend() models.ImportBackend { + return p.Backend +} + +func (p ListensImportProcessor) Process(results chan models.ListensResult, out chan models.ImportResult, progress chan models.Progress) { + process(p, results, out, progress) +} + +func (p ListensImportProcessor) Import(export models.ListensResult, result models.ImportResult, out chan models.ImportResult, progress chan models.Progress) models.ImportResult { + if export.Error != nil { + handleError(result, export.Error, out, progress) + return result + } + + if export.Total > 0 { + result.TotalCount = export.Total + } else { + result.TotalCount += len(export.Items) + } + importResult, err := p.Backend.ImportListens(export, result, progress) + if err != nil { + handleError(importResult, err, out, progress) + return result + } + return importResult +} + +type LovesImportProcessor struct { + Backend models.LovesImport +} + +func (p LovesImportProcessor) ImportBackend() models.ImportBackend { + return p.Backend +} + +func (p LovesImportProcessor) Process(results chan models.LovesResult, out chan models.ImportResult, progress chan models.Progress) { + process(p, results, out, progress) +} + +func (p LovesImportProcessor) Import(export models.LovesResult, result models.ImportResult, out chan models.ImportResult, progress chan models.Progress) models.ImportResult { + if export.Error != nil { + handleError(result, export.Error, out, progress) + return result + } + + if export.Total > 0 { + result.TotalCount = export.Total + } else { + result.TotalCount += len(export.Items) + } + importResult, err := p.Backend.ImportLoves(export, result, progress) + if err != nil { + handleError(importResult, err, out, progress) + return result + } + return importResult +} + +func process[R models.LovesResult | models.ListensResult, P ImportProcessor[R]](processor P, results chan R, out chan models.ImportResult, progress chan models.Progress) { + defer close(out) + defer close(progress) + result := models.ImportResult{} + + err := processor.ImportBackend().StartImport() + if err != nil { + handleError(result, err, out, progress) + return + } + + for exportResult := range results { + importResult := processor.Import(exportResult, result, out, progress) + result.Update(importResult) + progress <- models.Progress{}.FromImportResult(result) + } + + err = processor.ImportBackend().FinishImport() + if err != nil { + handleError(result, err, out, progress) + return + } + + progress <- models.Progress{}.FromImportResult(result).Complete() + out <- result +} + +func handleError(result models.ImportResult, err error, out chan models.ImportResult, progress chan models.Progress) { + result.Error = err + progress <- models.Progress{}.FromImportResult(result).Complete() + out <- result +} diff --git a/internal/backends/process.go b/internal/backends/process.go deleted file mode 100644 index 2e8cb2e..0000000 --- a/internal/backends/process.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright © 2023 Philipp Wolfer - -This file is part of Scotty. - -Scotty is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later version. - -Scotty is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -Scotty. If not, see . -*/ - -package backends - -import "go.uploadedlobster.com/scotty/internal/models" - -func ProcessListensImports(importer models.ListensImport, results chan models.ListensResult, out chan models.ImportResult, progress chan models.Progress) { - defer close(out) - defer close(progress) - result := models.ImportResult{} - - err := importer.StartImport() - if err != nil { - handleError(result, err, out, progress) - return - } - - for exportResult := range results { - if exportResult.Error != nil { - handleError(result, exportResult.Error, out, progress) - return - } - - if exportResult.Total > 0 { - result.TotalCount = exportResult.Total - } else { - result.TotalCount += len(exportResult.Items) - } - importResult, err := importer.ImportListens(exportResult, result, progress) - if err != nil { - handleError(importResult, err, out, progress) - return - } - - result.Update(importResult) - progress <- models.Progress{}.FromImportResult(result) - } - - err = importer.FinishImport() - if err != nil { - handleError(result, err, out, progress) - return - } - - progress <- models.Progress{}.FromImportResult(result).Complete() - out <- result -} - -func ProcessLovesImports(importer models.LovesImport, results chan models.LovesResult, out chan models.ImportResult, progress chan models.Progress) { - defer close(out) - defer close(progress) - result := models.ImportResult{} - - err := importer.StartImport() - if err != nil { - handleError(result, err, out, progress) - return - } - - for exportResult := range results { - if exportResult.Error != nil { - handleError(result, exportResult.Error, out, progress) - return - } - - if exportResult.Total > 0 { - result.TotalCount = exportResult.Total - } else { - result.TotalCount += len(exportResult.Items) - } - importResult, err := importer.ImportLoves(exportResult, result, progress) - if err != nil { - handleError(importResult, err, out, progress) - return - } - - result.Update(importResult) - progress <- models.Progress{}.FromImportResult(result) - } - - err = importer.FinishImport() - if err != nil { - handleError(result, err, out, progress) - return - } - - progress <- models.Progress{}.FromImportResult(result).Complete() - out <- result -} - -func handleError(result models.ImportResult, err error, out chan models.ImportResult, progress chan models.Progress) { - result.Error = err - progress <- models.Progress{}.FromImportResult(result).Complete() - out <- result -}