A fork of https://github.com/teal-fm/piper

Merge pull request #30 from fatfingers23/bugfix/ClearClearClearClear

Bugfix: Resolves #29 and keeps a local state if a play status has been clearned

authored by

natalie and committed by
GitHub
d732dadf eff5d1c2

+51 -11
+2 -1
.gitignore
··· 4 4 jwk*.json 5 5 **.bak 6 6 .idea 7 - AM_AUTHKEY.p8 7 + AM_AUTHKEY.p8 8 + .DS_Store
+3
models/constants.go
··· 1 + package models 2 + 3 + const SubmissionAgent = "piper/v0.0.3"
+1 -1
service/atproto/submission.go
··· 99 99 // Get submission client agent 100 100 submissionAgent := viper.GetString("app.submission_agent") 101 101 if submissionAgent == "" { 102 - submissionAgent = "piper/v0.0.1" 102 + submissionAgent = models.SubmissionAgent 103 103 } 104 104 105 105 playRecord := &teal.AlphaFeedPlay{
+45 -9
service/playingnow/playingnow.go
··· 6 6 "log" 7 7 "os" 8 8 "strconv" 9 + "sync" 9 10 "time" 10 11 11 12 "github.com/bluesky-social/indigo/atproto/client" ··· 24 25 db *db.DB 25 26 atprotoService *atprotoauth.ATprotoAuthService 26 27 logger *log.Logger 28 + mu sync.RWMutex 29 + clearedStatus map[int64]bool // tracks if a user's status has been cleared on their repo 27 30 } 28 31 29 32 // NewPlayingNowService creates a new playing now service ··· 34 37 db: database, 35 38 atprotoService: atprotoService, 36 39 logger: logger, 40 + clearedStatus: make(map[int64]bool), 37 41 } 38 42 } 39 43 ··· 75 79 Item: playView, 76 80 } 77 81 78 - var swapRecord *string 82 + var swapRecord *comatproto.RepoGetRecord_Output 79 83 swapRecord, err = p.getStatusSwapRecord(ctx, atProtoClient) 80 84 if err != nil { 81 85 return err 82 86 } 83 87 88 + var swapCid *string 89 + if swapRecord != nil { 90 + swapCid = swapRecord.Cid 91 + } 92 + 93 + p.logger.Printf("Publishing playing now status for user %d (DID: %s): %s - %s", userID, did, track.Artist[0].Name, track.Name) 94 + 84 95 // Create the record input 85 96 input := comatproto.RepoPutRecord_Input{ 86 97 Collection: "fm.teal.alpha.actor.status", 87 98 Repo: atProtoClient.AccountDID.String(), 88 99 Rkey: "self", // Use "self" as the record key for current status 89 100 Record: &lexutil.LexiconTypeDecoder{Val: status}, 90 - SwapRecord: swapRecord, 101 + SwapRecord: swapCid, 91 102 } 92 103 93 104 // Submit to PDS ··· 96 107 return fmt.Errorf("failed to create playing now status for DID %s: %w", did, err) 97 108 } 98 109 99 - p.logger.Printf("Successfully published playing now status for user %d (DID: %s): %s - %s", 100 - userID, did, track.Artist[0].Name, track.Name) 110 + // Resets clear to false since there is a song playing. The publish playing state is kept in the services from 111 + // if a song has changed/stamped 112 + p.mu.Lock() 113 + p.clearedStatus[userID] = false 114 + p.mu.Unlock() 101 115 102 116 return nil 103 117 } 104 118 105 119 // ClearPlayingNow removes the current playing status by setting an expired status 106 120 func (p *PlayingNowService) ClearPlayingNow(ctx context.Context, userID int64) error { 121 + // Check if status is already cleared to avoid clearing on the users repo over and over 122 + p.mu.RLock() 123 + alreadyCleared := p.clearedStatus[userID] 124 + p.mu.RUnlock() 125 + 126 + if alreadyCleared { 127 + return nil 128 + } 129 + 107 130 // Get user information 108 131 user, err := p.db.GetUserByID(userID) 109 132 if err != nil { ··· 140 163 Item: emptyPlayView, 141 164 } 142 165 143 - var swapRecord *string 166 + var swapRecord *comatproto.RepoGetRecord_Output 144 167 swapRecord, err = p.getStatusSwapRecord(ctx, atProtoClient) 168 + 145 169 if err != nil { 146 170 return err 147 171 } 148 172 173 + var swapCid *string 174 + if swapRecord != nil { 175 + swapCid = swapRecord.Cid 176 + } 177 + 149 178 // Update the record 150 179 input := comatproto.RepoPutRecord_Input{ 151 180 Collection: "fm.teal.alpha.actor.status", 152 181 Repo: atProtoClient.AccountDID.String(), 153 182 Rkey: "self", 154 183 Record: &lexutil.LexiconTypeDecoder{Val: status}, 155 - SwapRecord: swapRecord, 184 + SwapRecord: swapCid, 156 185 } 157 186 158 187 if _, err := comatproto.RepoPutRecord(ctx, atProtoClient, &input); err != nil { ··· 161 190 } 162 191 163 192 p.logger.Printf("Successfully cleared playing now status for user %d (DID: %s)", userID, did) 193 + 194 + // Mark status as cleared so we don't clear again until user starts playing a song again 195 + p.mu.Lock() 196 + p.clearedStatus[userID] = true 197 + p.mu.Unlock() 198 + 164 199 return nil 165 200 } 166 201 ··· 216 251 // Get submission client agent 217 252 submissionAgent := viper.GetString("app.submission_agent") 218 253 if submissionAgent == "" { 219 - submissionAgent = "piper/v0.0.2" 254 + submissionAgent = models.SubmissionAgent 220 255 } 221 256 222 257 playView := &teal.AlphaFeedDefs_PlayView{ ··· 238 273 239 274 // getStatusSwapRecord retrieves the current swap record (CID) for the actor status record. 240 275 // Returns (nil, nil) if the record does not exist yet. 241 - func (p *PlayingNowService) getStatusSwapRecord(ctx context.Context, atApiClient *client.APIClient) (*string, error) { 276 + func (p *PlayingNowService) getStatusSwapRecord(ctx context.Context, atApiClient *client.APIClient) (*comatproto.RepoGetRecord_Output, error) { 242 277 result, err := comatproto.RepoGetRecord(ctx, atApiClient, "", "fm.teal.alpha.actor.status", atApiClient.AccountDID.String(), "self") 243 278 244 279 if err != nil { ··· 253 288 return nil, fmt.Errorf("error getting the record: %w", err) 254 289 255 290 } 256 - return result.Cid, nil 291 + 292 + return result, nil 257 293 }