package main import ( "fmt" "os" "slices" ) 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 var importProfile bool = false var importFollows bool = false var importPreferences bool = false i := 1 for { if i >= len(os.Args) { break } if os.Args[i][0] != '-' { fmt.Fprintf(os.Stderr, "unrecognised argument `%s`.\n", os.Args[i]) os.Exit(1) } 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 case "profile": importProfile = true case "follows": importFollows = true case "preferences": importPreferences = true } i += 1 } if fromUser == "" { fmt.Fprintf(os.Stderr, "missing required argument -from.\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 -pass.\n") os.Exit(1) } if pdsUrl == "" { fmt.Fprintf(os.Stderr, "missing required argument -pds.\n") os.Exit(1) } if fromPdsUrl == "" { fromPdsUrl = pdsUrl } if !(importProfile || importFollows || importPreferences) { fmt.Fprintf(os.Stderr, "no action was specified.\n") os.Exit(1) } var fromSession *AtprotoSession if !(fromPassword == "" || fromPdsUrl == "") { var err error 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 importProfile { err := ImportProfile(toSession, pdsUrl, fromUser, dryrun, verbose) if err != nil { fmt.Fprintf(os.Stderr, "failed to import profile: %v\n", err) os.Exit(1) } } if importPreferences { if fromSession == nil { fmt.Fprintf(os.Stderr, "-frompass and -frompds must be provided for a preferences import.\n") os.Exit(1) } err := ImportPreferences(fromSession, toSession, pdsUrl, dryrun, verbose) if err != nil { fmt.Fprintf(os.Stderr, "failed to import preferences: %v\n", err) os.Exit(1) } } if importFollows { err := ImportFollows(toSession, pdsUrl, fromUser, 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 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. imports (at least one required): -profile: imports the account profile, including avatar, banner, display name, and description. -follows: imports the following list of the account. 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], ) }