scotty/cmd/loves.go
Philipp Wolfer 117014a977
Change project license to GPLv3
Individual files, mainly the models and the HTTP clients stay under MIT
2023-11-22 08:05:23 +01:00

129 lines
4.2 KiB
Go

/*
Copyright © 2023 Philipp Wolfer <phw@uploadedlobster.com>
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 <https://www.gnu.org/licenses/>.
*/
package cmd
import (
"fmt"
"sync"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uploadedlobster.com/scotty/backends"
"go.uploadedlobster.com/scotty/models"
"go.uploadedlobster.com/scotty/storage"
)
// lovesCmd represents the loves command
var lovesCmd = &cobra.Command{
Use: "loves",
Short: "Transfer loves between two services",
Long: `Transfers loves between two configured services.`,
Run: func(cmd *cobra.Command, args []string) {
sourceName, sourceConfig := getConfigFromFlag(cmd, "from")
targetName, targetConfig := getConfigFromFlag(cmd, "to")
fmt.Printf("Transferring loves from %s to %s...\n", sourceName, targetName)
// Setup database
db, err := storage.New(viper.GetString("database"))
cobra.CheckErr(err)
// Initialize backends
exportBackend, err := backends.ResolveBackend[models.LovesExport](sourceConfig)
cobra.CheckErr(err)
importBackend, err := backends.ResolveBackend[models.LovesImport](targetConfig)
cobra.CheckErr(err)
// Authenticate backends, if needed
token, err := db.GetOAuth2Token(sourceName)
cobra.CheckErr(err)
auth, err := backends.Authenticate(exportBackend, token, viper.GetViper())
cobra.CheckErr(err)
if auth {
db.SetOAuth2Token(sourceName, token)
}
token, err = db.GetOAuth2Token(targetName)
cobra.CheckErr(err)
auth, err = backends.Authenticate(importBackend, token, viper.GetViper())
cobra.CheckErr(err)
if auth {
defer db.SetOAuth2Token(targetName, token)
}
// Read timestamp
timestamp := time.Unix(getInt64FromFlag(cmd, "timestamp"), 0)
if timestamp == time.Unix(0, 0) {
timestamp, err = db.GetImportTimestamp(sourceName, targetName, "loves")
cobra.CheckErr(err)
}
fmt.Printf("From timestamp: %v (%v)\n", timestamp, timestamp.Unix())
// Prepare progress bars
exportProgress := make(chan models.Progress)
importProgress := make(chan models.Progress)
var wg sync.WaitGroup
progress := progressBar(&wg, exportProgress, importProgress)
// Export from source
lovesChan := make(chan models.LovesResult, 1000)
go exportBackend.ExportLoves(timestamp, lovesChan, exportProgress)
// Import into target
resultChan := make(chan models.ImportResult)
go backends.ProcessLovesImports(importBackend, lovesChan, resultChan, importProgress)
result := <-resultChan
wg.Wait()
progress.Wait()
if result.Error != nil {
fmt.Printf("Import failed, last reported timestamp was %v (%v)\n", result.LastTimestamp, result.LastTimestamp.Unix())
cobra.CheckErr(result.Error)
}
fmt.Printf("Imported %v of %v loves into %v.\n",
result.ImportCount, result.TotalCount, targetName)
// Update timestamp
if result.LastTimestamp.Unix() < timestamp.Unix() {
result.LastTimestamp = timestamp
}
fmt.Printf("Latest timestamp: %v (%v)\n", result.LastTimestamp, result.LastTimestamp.Unix())
err = db.SetImportTimestamp(sourceName, targetName, "loves", result.LastTimestamp)
cobra.CheckErr(err)
// Print errors
if len(result.ImportErrors) > 0 {
fmt.Printf("\nDuring the import the following errors occurred:\n")
for _, err := range result.ImportErrors {
fmt.Printf("Error: %v\n", err)
}
}
},
}
func init() {
beamCmd.AddCommand(lovesCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// lovesCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// lovesCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}