migratesky/main.go

161 lines
3.8 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"os"
"slices"
)
func main() {
if len(os.Args) == 1 || slices.Contains(os.Args, "-help") {
printHelp()
os.Exit(0)
}
2025-06-22 19:16:17 +01:00
var fromUser string
var fromPassword string
var toUser string
var toPassword string
var pdsUrl string
2025-06-22 19:16:17 +01:00
var fromPdsUrl string
var dryrun bool = false
var verbose bool = false
var importProfile bool = false
var importFollows bool = false
2025-06-22 19:16:17 +01:00
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":
2025-06-22 19:16:17 +01:00
i, fromUser = getValue(i)
case "frompass":
i, fromPassword = getValue(i)
case "to":
2025-06-22 19:16:17 +01:00
i, toUser = getValue(i)
case "topass":
i, toPassword = getValue(i)
case "pds":
i, pdsUrl = getValue(i)
2025-06-22 19:16:17 +01:00
case "frompds":
i, fromPdsUrl = getValue(i)
case "dryrun":
dryrun = true
case "v":
verbose = true
case "profile":
importProfile = true
case "follows":
importFollows = true
2025-06-22 19:16:17 +01:00
case "preferences":
importPreferences = true
}
i += 1
}
2025-06-22 19:16:17 +01:00
if fromUser == "" {
fmt.Fprintf(os.Stderr, "missing required argument -from.\n")
os.Exit(1)
}
2025-06-22 19:16:17 +01:00
if toUser == "" {
fmt.Fprintf(os.Stderr, "missing required argument -to.\n")
os.Exit(1)
}
2025-06-22 19:16:17 +01:00
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)
}
2025-06-22 19:16:17 +01:00
if fromPdsUrl == "" { fromPdsUrl = pdsUrl }
2025-06-22 19:16:17 +01:00
if !(importProfile || importFollows || importPreferences) {
fmt.Fprintf(os.Stderr, "no action was specified.\n")
os.Exit(1)
}
2025-06-22 19:16:17 +01:00
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 {
2025-06-22 19:16:17 +01:00
fmt.Fprintf(os.Stderr, "failed to create session for destination account: %v\n", err)
os.Exit(1)
}
if importProfile {
2025-06-22 19:16:17 +01:00
err := ImportProfile(toSession, pdsUrl, fromUser, dryrun, verbose)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to import profile: %v\n", err)
os.Exit(1)
}
}
2025-06-22 19:16:17 +01:00
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 {
2025-06-22 19:16:17 +01:00
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 <arguments...> <imports...>
required arguments:
2025-06-22 19:16:17 +01:00
-from <identifier>: the source account handle or DID.
-frompass <password>: the source account password.
-to <identifier>: the destination account handle or DID.
-topass <password>: the destination account password.
-pds <pds-url>: 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:
2025-06-22 19:16:17 +01:00
-frompds <pds-url>: 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],
)
}