Interactively go through your bluesky follow graph and decide to keep or remove follow records
0
fork

Configure Feed

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

Replace resume from cursor with resume with handle/DID

yemou bf93f18f 4e7d7971

+23 -15
+23 -15
main.go
··· 79 79 log.Fatal("Expected to be running inside of a terminal emulator") 80 80 } 81 81 82 - fetchLen := flag.Int64("f", 50, "Number of records to fetch at a time (>= 1 and <= 100)") 83 82 handle := flag.String("h", "", "Account handle to use") 84 - lastCursor := flag.String("c", "", "Cursor to resume from") 83 + resumeSubject := flag.String("r", "", "Resume from handle or DID") 85 84 flag.Parse() 86 85 87 - if *fetchLen < 1 || *fetchLen > 100 { 88 - log.Fatal("The fetch size should be between 1 and 100 (inclusive)") 89 - } 90 - 91 86 if *handle == "" { 92 87 log.Fatal("Missing an atproto (bluesky) handle") 93 88 } 94 89 95 90 ctx := context.Background() 96 91 92 + resume := false 93 + resumeDID := "" 94 + if *resumeSubject != "" { 95 + identityDirectory := identity.DefaultDirectory() 96 + doc, err := identityDirectory.Lookup(ctx, syntax.AtIdentifier(*resumeSubject)) 97 + 98 + if err != nil { 99 + log.Fatal("Couldn't verify handle or DID for resuming:", err) 100 + } 101 + 102 + resumeDID = string(doc.DID) 103 + resume = true 104 + } 105 + 97 106 oauthClient, sessionData, err := authenticate(ctx, handle) 98 107 if err != nil { 99 108 log.Fatal("Failed to authenticate:", err) ··· 121 130 fmt.Printf("\x1b[?1049h") 122 131 defer fmt.Printf("\x1b[?1049l") 123 132 124 - cursor := *lastCursor 133 + cursor := "" 125 134 for { 126 135 records, err := atproto.RepoListRecords(ctx, apiClient, 127 136 "app.bsky.graph.follow", 128 137 cursor, 129 - *fetchLen, 138 + 50, 130 139 sessionData.AccountDID.String(), 131 140 false, 132 141 ) ··· 139 148 break 140 149 } 141 150 142 - prevCursor := cursor 143 151 cursor = *records.Cursor 144 152 145 153 for _, record := range records.Records { ··· 148 156 fmt.Printf("\x1b[H") 149 157 150 158 followRecord := record.Value.Val.(*bsky.GraphFollow) 159 + 160 + if resume && followRecord.Subject != resumeDID { 161 + continue 162 + } 163 + resume = false 164 + 151 165 handle, displayName, description, avatar := getProfileInformation( 152 166 ctx, apiClient, 153 167 followRecord, ··· 171 185 172 186 if description != "" { 173 187 fmt.Printf("Description:\n%s\n\n", description) 174 - } 175 - 176 - // TODO: Figure out a better way to display/save the previous cursor 177 - // I'd like to display the cursor after quiting 178 - if prevCursor != "" { 179 - fmt.Println("Last Cursor:", prevCursor) 180 188 } 181 189 182 190 user_input: