package main import ( "fmt" "os" "slices" "strings" ) func main() { if len(os.Args) == 1 || slices.Contains(os.Args, "-help") { printHelp() os.Exit(0) } var fromUser string var fromPassword string var toUser string var toPassword string var pdsUrl string var fromPdsUrl string var dryrun bool = false var verbose bool = false collections := []string{} i := 1 for { if i >= len(os.Args) { break } if os.Args[i][0] != '-' { collections = append(collections, os.Args[i]) } getValue := func(i int) (int, string) { if i + 1 >= len(os.Args) { fmt.Fprintf(os.Stderr, "-%s requires a value.\n", os.Args[i]) os.Exit(1) } return i + 1, os.Args[i + 1] } switch os.Args[i][1:] { case "from": i, fromUser = getValue(i) case "frompass": i, fromPassword = getValue(i) case "to": i, toUser = getValue(i) case "topass": i, toPassword = getValue(i) case "pds": i, pdsUrl = getValue(i) case "frompds": i, fromPdsUrl = getValue(i) case "dryrun": dryrun = true case "v": verbose = true } i += 1 } if fromUser == "" { fmt.Fprintf(os.Stderr, "missing required argument -from.\n") os.Exit(1) } if fromPassword == "" { fmt.Fprintf(os.Stderr, "missing required argument -frompass.\n") os.Exit(1) } if toUser == "" { fmt.Fprintf(os.Stderr, "missing required argument -to.\n") os.Exit(1) } if toPassword == "" { fmt.Fprintf(os.Stderr, "missing required argument -topass.\n") os.Exit(1) } if pdsUrl == "" { fmt.Fprintf(os.Stderr, "missing required argument -pds.\n") os.Exit(1) } if fromPdsUrl == "" { fromPdsUrl = pdsUrl } if len(collections) == 0 { fmt.Fprintf(os.Stderr, "no action was specified.\n") os.Exit(1) } fromSession, err := CreateSession(fromPdsUrl, fromUser, fromPassword) if err != nil { fmt.Fprintf(os.Stderr, "failed to create session for source account: %v\n", err) os.Exit(1) } toSession, err := CreateSession(pdsUrl, toUser, toPassword) if err != nil { fmt.Fprintf(os.Stderr, "failed to create session for destination account: %v\n", err) os.Exit(1) } if slices.Contains(collections, "profile") { err := ImportProfile(fromSession, toSession, dryrun, verbose) if err != nil { fmt.Fprintf(os.Stderr, "failed to import profile: %v\n", err) os.Exit(1) } } if slices.Contains(collections, "preferences") { err := ImportPreferences(fromSession, toSession, dryrun, verbose) if err != nil { fmt.Fprintf(os.Stderr, "failed to import preferences: %v\n", err) os.Exit(1) } } if slices.Contains(collections, "follows") { err := ImportFollows(fromSession, toSession, dryrun, verbose) if err != nil { fmt.Fprintf(os.Stderr, "failed to import follows: %v\n", err) os.Exit(1) } } } func printHelp() { fmt.Printf( `usage: %s <-from > <-frompass > <-to > <-topass > <-pds > [collections...] required arguments: -from : the source account handle or DID. -frompass : the source account password. -to : the destination account handle or DID. -topass : the destination account password. -pds : the full https:// url of the destination account's PDS. collections: profile: imports account profile, including avatar, banner, display name, and description. follows: imports all following accounts. preferences: imports account preferences; including feeds, labeller settings, and content filters. optional arguments: -frompds : the source account's PDS url (defaults to the value of -pds). -dryrun: does not import follow records; good for sanity testing! -v: verbose output -help: shows this help message. `, os.Args[0][strings.LastIndex(os.Args[0], "/") + 1:], ) }