fork of indigo with slightly nicer lexgen
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 162 lines 4.4 kB view raw
1package main 2 3import ( 4 "errors" 5 "fmt" 6 7 comatproto "github.com/bluesky-social/indigo/api/atproto" 8 "github.com/bluesky-social/indigo/atproto/identity" 9 "github.com/bluesky-social/indigo/cmd/relay/relay" 10 "github.com/bluesky-social/indigo/cmd/relay/relay/models" 11 "github.com/bluesky-social/indigo/util/cliutil" 12 "github.com/bluesky-social/indigo/xrpc" 13 14 "github.com/urfave/cli/v2" 15) 16 17var cmdPullHosts = &cli.Command{ 18 Name: "pull-hosts", 19 Usage: "initializes or updates host list from an existing relay (public API)", 20 Action: runPullHosts, 21 Flags: []cli.Flag{ 22 &cli.StringFlag{ 23 Name: "relay-host", 24 Usage: "method, hostname, and port of relay to pull from", 25 Value: "https://bsky.network", 26 EnvVars: []string{"RELAY_HOST"}, 27 }, 28 &cli.StringFlag{ 29 Name: "db-url", 30 Usage: "database connection string for relay database", 31 Value: "sqlite://data/relay/relay.sqlite", 32 EnvVars: []string{"DATABASE_URL"}, 33 }, 34 &cli.IntFlag{ 35 Name: "default-account-limit", 36 Value: 100, 37 Usage: "max number of active accounts for new upstream hosts", 38 EnvVars: []string{"RELAY_DEFAULT_ACCOUNT_LIMIT", "RELAY_DEFAULT_REPO_LIMIT"}, 39 }, 40 &cli.IntFlag{ 41 Name: "batch-size", 42 Value: 500, 43 Usage: "host many hosts to pull at a time", 44 EnvVars: []string{"RELAY_PULL_HOSTS_BATCH_SIZE"}, 45 }, 46 &cli.StringSliceFlag{ 47 Name: "trusted-domains", 48 Usage: "domain names which mark trusted hosts; use wildcard prefix to match suffixes", 49 Value: cli.NewStringSlice("*.host.bsky.network"), 50 EnvVars: []string{"RELAY_TRUSTED_DOMAINS"}, 51 }, 52 &cli.BoolFlag{ 53 Name: "skip-host-checks", 54 Usage: "don't run describeServer requests to see if host is a PDS before adding", 55 EnvVars: []string{"RELAY_SKIP_HOST_CHECKS"}, 56 }, 57 }, 58} 59 60func runPullHosts(cctx *cli.Context) error { 61 ctx := cctx.Context 62 63 if cctx.Args().Len() > 0 { 64 return fmt.Errorf("unexpected arguments") 65 } 66 67 client := xrpc.Client{ 68 Host: cctx.String("relay-host"), 69 } 70 71 skipHostChecks := cctx.Bool("skip-host-checks") 72 73 dir := identity.DefaultDirectory() 74 75 dburl := cctx.String("db-url") 76 db, err := cliutil.SetupDatabase(dburl, 10) 77 if err != nil { 78 return err 79 } 80 81 relayConfig := relay.DefaultRelayConfig() 82 relayConfig.DefaultRepoLimit = cctx.Int64("default-account-limit") 83 relayConfig.TrustedDomains = cctx.StringSlice("trusted-domains") 84 85 // NOTE: setting evtmgr to nil 86 r, err := relay.NewRelay(db, nil, dir, relayConfig) 87 if err != nil { 88 return err 89 } 90 91 checker := relay.NewHostClient(relayConfig.UserAgent) 92 93 cursor := "" 94 size := cctx.Int64("batch-size") 95 for { 96 resp, err := comatproto.SyncListHosts(ctx, &client, cursor, size) 97 if err != nil { 98 return err 99 } 100 for _, h := range resp.Hosts { 101 if h.Status == nil { 102 fmt.Printf("%s: status=unknown\n", h.Hostname) 103 continue 104 } 105 if !(models.HostStatus(*h.Status) == models.HostStatusActive || models.HostStatus(*h.Status) == models.HostStatusIdle) { 106 fmt.Printf("%s: status=%s\n", h.Hostname, *h.Status) 107 continue 108 } 109 if h.Seq == nil || *h.Seq <= 0 { 110 fmt.Printf("%s: no-cursor\n", h.Hostname) 111 continue 112 } 113 existing, err := r.GetHost(ctx, h.Hostname) 114 if err != nil && !errors.Is(err, relay.ErrHostNotFound) { 115 return err 116 } 117 if existing != nil { 118 fmt.Printf("%s: exists\n", h.Hostname) 119 continue 120 } 121 hostname, noSSL, err := relay.ParseHostname(h.Hostname) 122 if err != nil { 123 return fmt.Errorf("%w: %s", err, h.Hostname) 124 } 125 if noSSL { 126 // skip "localhost" and non-SSL hosts (this is for public PDS instances) 127 fmt.Printf("%s: non-public\n", h.Hostname) 128 continue 129 } 130 131 accountLimit := r.Config.DefaultRepoLimit 132 trusted := relay.IsTrustedHostname(hostname, r.Config.TrustedDomains) 133 if trusted { 134 accountLimit = r.Config.TrustedRepoLimit 135 } 136 137 if !skipHostChecks { 138 if err := checker.CheckHost(ctx, "https://"+hostname); err != nil { 139 fmt.Printf("%s: checking host: %s\n", h.Hostname, err) 140 continue 141 } 142 } 143 144 host := models.Host{ 145 Hostname: hostname, 146 NoSSL: noSSL, 147 Status: models.HostStatusActive, 148 Trusted: trusted, 149 AccountLimit: accountLimit, 150 } 151 if err := db.Create(&host).Error; err != nil { 152 return err 153 } 154 fmt.Printf("%s: added\n", h.Hostname) 155 } 156 if resp.Cursor == nil || *resp.Cursor == "" { 157 break 158 } 159 cursor = *resp.Cursor 160 } 161 return nil 162}