Yōten: A social tracker for your language learning journey built on the atproto.

feat(handlers/study-session): use slogger

Signed-off-by: brookjeynes <me@brookjeynes.dev>

+58 -47
+58 -47
internal/server/handlers/study-session.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 - "log" 7 6 "net/http" 8 7 "strconv" 9 8 "time" ··· 117 116 } 118 117 119 118 func (h *Handler) HandleStudySessionFeed(w http.ResponseWriter, r *http.Request) { 119 + l := h.Logger.With("handler", "HandleStudySessionFeed") 120 + 120 121 isFriends, err := strconv.ParseBool(r.URL.Query().Get("friends")) 121 122 if err != nil { 122 - log.Println("failed to parse friends value:", err) 123 + l.Error("failed to parse friends value", "err", err) 123 124 isFriends = false 124 125 } 125 126 ··· 129 130 } 130 131 page, err := strconv.ParseInt(pageStr, 10, 64) 131 132 if err != nil { 132 - log.Println("failed to parse page value:", err) 133 + l.Error("failed to parse page value", "err", err) 133 134 page = 1 134 135 } 135 136 if page == 0 { ··· 148 149 if !isFriends { 149 150 feed, err = db.GetStudySessionFeed(h.Db, pageSize+1, int(offset)) 150 151 if err != nil { 151 - log.Println("failed to get global feed:", err) 152 + l.Error("failed to get global feed", "err", err) 152 153 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 153 154 return 154 155 } 155 156 err = h.GetBskyProfileHydratedSessionFeed(feed) 156 157 if err != nil { 157 - log.Println("failed to hydrate bsky profiles:", err) 158 + l.Error("failed to hydrate bsky profiles", "err", err) 158 159 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 159 160 return 160 161 } 161 162 } else { 162 163 if fetchUserError != nil { 163 - log.Println("failed to get logged-in user:", err) 164 + l.Error("failed to get logged-in user", "err", err) 164 165 htmx.HxRedirect(w, "/login") 165 166 return 166 167 } 167 168 168 169 feed, err = db.GetFriendsStudySessionFeed(h.Db, user.Did, pageSize+1, int(offset)) 169 170 if err != nil { 170 - log.Println("failed to get global feed:", err) 171 + l.Error("failed to get global feed", "err", err) 171 172 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 172 173 return 173 174 } 174 175 err = h.GetBskyProfileHydratedSessionFeed(feed) 175 176 if err != nil { 176 - log.Println("failed to hydrate bsky profiles:", err) 177 + l.Error("failed to hydrate bsky profiles", "err", err) 177 178 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 178 179 return 179 180 } ··· 181 182 182 183 feed, err = ApplyPendingChanges(h, w, r, feed, PendingStudySessionCreation, PendingStudySessionUpdates, PendingStudySessionDeletion) 183 184 if err != nil { 184 - log.Printf("failed to save yoten-session after processing pending changes: %v", err) 185 + l.Error("failed to save yoten-session after processing pending changes", "err", err) 185 186 } 186 187 187 188 nextPage := 0 ··· 200 201 } 201 202 202 203 func (h *Handler) HandleEditStudySessionPage(w http.ResponseWriter, r *http.Request) { 204 + l := h.Logger.With("handler", "HandleEditStudySessionPage") 205 + 203 206 client, err := h.Oauth.AuthorizedClient(r) 204 207 if err != nil { 205 - log.Println("failed to get authorized client:", err) 208 + l.Error("failed to get authorized client", "err", err) 206 209 htmx.HxRedirect(w, "/login") 207 210 return 208 211 } 209 212 210 213 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 211 214 if err != nil { 212 - log.Println("failed to get logged-in user:", err) 215 + l.Error("failed to get logged-in user", "err", err) 213 216 htmx.HxRedirect(w, "/login") 214 217 return 215 218 } ··· 217 220 rkey := chi.URLParam(r, "rkey") 218 221 studySession, err := db.GetStudySessionByRkey(h.Db, user.Did, rkey) 219 222 if err != nil { 220 - log.Println("failed to get study session from db:", err) 223 + l.Error("failed to get study session from db", "err", err) 221 224 htmx.HxError(w, http.StatusInternalServerError, "Failed to update study session, try again later.") 222 225 return 223 226 } 224 227 225 228 if user.Did != studySession.Did { 226 - log.Printf("user '%s' does not own record '%s'", user.Did, studySession.Rkey) 229 + l.Error("user does not own record", "did", user.Did, "sessionDid", studySession.Did) 227 230 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this study session.") 228 231 return 229 232 } ··· 232 235 case http.MethodGet: 233 236 userDefinedActivities, err := db.GetActivitiesByDid(h.Db, user.Did) 234 237 if err != nil { 235 - log.Println("failed to get user-defined activities:", err) 238 + l.Error("failed to get user-defined activities", "err", err) 236 239 } 237 240 238 241 resources, err := db.GetResourcesByDid(h.Db, user.Did) 239 242 if err != nil { 240 - log.Println("failed to get user-defined resources:", err) 243 + l.Error("failed to get user-defined resources", "err", err) 241 244 } 242 245 243 246 preDefinedActivities, err := db.GetPredefinedActivities(h.Db) 244 247 if err != nil { 245 - log.Println("failed to get pre-defined activities:", err) 248 + l.Error("failed to get pre-defined activities", "err", err) 246 249 } 247 250 248 251 currentResource := studySession.Resource ··· 267 270 268 271 languages, err := db.GetProfileLanguages(h.Db, user.Did) 269 272 if err != nil { 270 - log.Println("failed to fetch profile languages:", err) 273 + l.Error("failed to fetch profile languages", "err", err) 271 274 } 272 275 273 276 views.EditStudySessionPage(views.EditStudySessionPageParams{ ··· 280 283 case http.MethodPost: 281 284 updatedStudySession, err := h.parseStudySessionForm(r) 282 285 if err != nil { 283 - log.Println("invalid study session form:", err) 286 + l.Error("invalid study session form", "err", err) 284 287 htmx.HxError(w, http.StatusBadRequest, "Failed to update study session, ensure all data is valid.") 285 288 return 286 289 } ··· 289 292 updatedStudySession.CreatedAt = studySession.CreatedAt 290 293 291 294 if err := db.ValidateStudySession(updatedStudySession); err != nil { 292 - log.Println("invalid study session:", err) 295 + l.Error("invalid study session", "err", err) 293 296 switch { 294 297 case errors.Is(err, db.ErrSessionDescriptionTooLong): 295 298 htmx.HxError(w, http.StatusBadRequest, "Study session description cannot be more than 256 characters.") ··· 358 361 SwapRecord: cid, 359 362 }) 360 363 if err != nil { 361 - log.Println("failed to update study session record:", err) 364 + l.Error("failed to update study session record", "err", err) 362 365 htmx.HxError(w, http.StatusInternalServerError, "Failed to update study session, try again later.") 363 366 return 364 367 } 365 368 366 369 err = SavePendingUpdate(h, w, r, PendingStudySessionUpdates, updatedStudySession) 367 370 if err != nil { 368 - log.Printf("failed to save yoten-session to add pending study session updates: %v", err) 371 + l.Error("failed to save yoten-session to add pending study session updates", "err", err) 369 372 } 370 373 371 374 if !h.Config.Core.Dev { ··· 377 380 Set("rkey", rkey), 378 381 }) 379 382 if err != nil { 380 - log.Println("failed to enqueue posthog event:", err) 383 + l.Error("failed to enqueue posthog event", "err", err) 381 384 } 382 385 } 383 386 ··· 386 389 } 387 390 388 391 func (h *Handler) HandleNewStudySessionPage(w http.ResponseWriter, r *http.Request) { 392 + l := h.Logger.With("handler", "HandleNewStudySessionPage") 393 + 389 394 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 390 395 if err != nil { 391 - log.Println("failed to get logged-in user:", err) 396 + l.Error("failed to get logged-in user", "err", err) 392 397 htmx.HxRedirect(w, "/login") 393 398 return 394 399 } 395 400 396 401 client, err := h.Oauth.AuthorizedClient(r) 397 402 if err != nil { 398 - log.Println("failed to get authorized client:", err) 403 + l.Error("failed to get authorized client", "err", err) 399 404 htmx.HxRedirect(w, "/login") 400 405 return 401 406 } ··· 404 409 case http.MethodGet: 405 410 profile, err := db.GetProfile(h.Db, user.Did) 406 411 if err != nil { 407 - log.Printf("failed to find %s in db: %s", user.Did, err) 412 + l.Error("failed to find user in db", "did", user.Did, "err", err) 408 413 htmx.HxError(w, http.StatusNotFound, "Failed to find user.") 409 414 return 410 415 } 411 416 412 417 userDefinedActivities, err := db.GetActivitiesByDid(h.Db, user.Did) 413 418 if err != nil { 414 - log.Println("failed to get user-defined activities:", err) 419 + l.Error("failed to get user-defined activities", "err", err) 415 420 } 416 421 preDefinedActivities, err := db.GetPredefinedActivities(h.Db) 417 422 if err != nil { 418 - log.Println("failed to get pre-defined activities:", err) 423 + l.Error("failed to get pre-defined activities", "err", err) 419 424 } 420 425 activeActivities := utils.Filter(userDefinedActivities, func(activity db.Activity) bool { 421 426 return activity.Status != db.Deleted ··· 424 429 425 430 resources, err := db.GetResourcesByDid(h.Db, user.Did) 426 431 if err != nil { 427 - log.Println("failed to get user-defined resources:", err) 432 + l.Error("failed to get user-defined resources", "err", err) 428 433 } 429 434 activeResources := utils.Filter(resources, func(resource db.Resource) bool { 430 435 return resource.Status != db.Deleted ··· 440 445 case http.MethodPost: 441 446 newStudySession, err := h.parseStudySessionForm(r) 442 447 if err != nil { 443 - log.Println("invalid study session form:", err) 448 + l.Error("invalid study session form", "err", err) 444 449 htmx.HxError(w, http.StatusBadRequest, "Failed to update study session, ensure all data is valid.") 445 450 return 446 451 } ··· 459 464 } 460 465 461 466 if err := db.ValidateStudySession(newStudySession); err != nil { 462 - log.Println("invalid study session:", err) 467 + l.Error("invalid study session", "err", err) 463 468 switch { 464 469 case errors.Is(err, db.ErrSessionDescriptionTooLong): 465 470 htmx.HxError(w, http.StatusBadRequest, "Study session description cannot be more than 256 characters.") ··· 521 526 }, 522 527 }) 523 528 if err != nil { 524 - log.Println("failed to create study session record:", err) 529 + l.Error("failed to create study session record", "err", err) 525 530 htmx.HxError(w, http.StatusInternalServerError, "Failed to create study session, try again later.") 526 531 return 527 532 } 528 533 529 534 err = SavePendingCreate(h, w, r, PendingStudySessionCreation, newStudySession) 530 535 if err != nil { 531 - log.Printf("failed to save yoten-session to add pending study session creation: %v", err) 536 + l.Error("failed to save yoten-session to add pending study session creation", "err", err) 532 537 } 533 538 534 539 if !h.Config.Core.Dev { ··· 545 550 Set("date_is_today", newStudySession.Date.Truncate(24*time.Hour).Equal(time.Now().UTC().In(loc).Truncate(24*time.Hour))), 546 551 }) 547 552 if err != nil { 548 - log.Println("failed to enqueue posthog event:", err) 553 + l.Error("failed to enqueue posthog event", "err", err) 549 554 } 550 555 } 551 556 ··· 554 559 } 555 560 556 561 func (h *Handler) HandleDeleteStudySession(w http.ResponseWriter, r *http.Request) { 562 + l := h.Logger.With("handler", "HandleDeleteStudySession") 563 + 557 564 user := h.Oauth.GetUser(r) 558 565 if user == nil { 559 - log.Println("failed to get logged-in user") 566 + l.Error("failed to get logged-in user") 560 567 htmx.HxRedirect(w, "/login") 561 568 return 562 569 } 563 570 564 571 client, err := h.Oauth.AuthorizedClient(r) 565 572 if err != nil { 566 - log.Println("failed to get authorized client:", err) 573 + l.Error("failed to get authorized client", "err", err) 567 574 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete study session, try again later.") 568 575 return 569 576 } ··· 572 579 case http.MethodDelete: 573 580 err := r.ParseForm() 574 581 if err != nil { 575 - log.Println("failed to parse study session delete form:", err) 582 + l.Error("failed to parse study session delete form", "err", err) 576 583 htmx.HxError(w, http.StatusBadRequest, "Failed to delete study session, try again later.") 577 584 return 578 585 } ··· 580 587 rkey := chi.URLParam(r, "rkey") 581 588 studySession, err := db.GetStudySessionByRkey(h.Db, user.Did, rkey) 582 589 if err != nil { 583 - log.Println("failed to get study session from db:", err) 590 + l.Error("failed to get study session from db", "err", err) 584 591 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete study session, try again later.") 585 592 return 586 593 } 587 594 588 595 if user.Did != studySession.Did { 589 - log.Println("failed to delete study session: user does not own record") 596 + l.Error("user does not own record", "did", user.Did, "sessionDid", studySession.Did) 590 597 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete study session, try again later.") 591 598 return 592 599 } ··· 597 604 Rkey: rkey, 598 605 }) 599 606 if err != nil { 600 - log.Println("failed to delete study session from PDS:", err) 607 + l.Error("failed to delete study session from PDS", "err", err) 601 608 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete study session, try again later.") 602 609 return 603 610 } 604 611 605 612 err = SavePendingDelete(h, w, r, PendingStudySessionDeletion, studySession) 606 613 if err != nil { 607 - log.Printf("failed to save yoten-session to add pending study session deletion: %v", err) 614 + l.Error("failed to save yoten-session to add pending study session deletion", "err", err) 608 615 } 609 616 610 617 if !h.Config.Core.Dev { ··· 617 624 Set("session_age_seconds", time.Since(studySession.CreatedAt).Seconds()), 618 625 }) 619 626 if err != nil { 620 - log.Println("failed to enqueue posthog event:", err) 627 + l.Error("failed to enqueue posthog event", "err", err) 621 628 } 622 629 } 623 630 ··· 644 651 } 645 652 646 653 func (h *Handler) HandleStudySessionPage(w http.ResponseWriter, r *http.Request) { 654 + l := h.Logger.With("handler", "HandleStudySessionPage") 655 + 647 656 user, _ := bsky.GetUserWithBskyProfile(h.Oauth, r) 648 657 didOrHandle := chi.URLParam(r, "user") 649 658 if didOrHandle == "" { ··· 661 670 662 671 studySession, err := db.GetStudySessionByRkey(h.Db, ident.DID.String(), rkey) 663 672 if err != nil { 664 - log.Println("failed to retrieve study session:", err) 673 + l.Error("failed to retrieve study session", "err", err) 665 674 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve study session, try again later.") 666 675 return 667 676 } 668 677 669 678 bskyProfile, err := bsky.GetBskyProfile(ident.DID.String()) 670 679 if err != nil { 671 - log.Println("failed to retrieve bsky profile for study session:", err) 680 + l.Error("failed to retrieve bsky profile for study session", "err", err) 672 681 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve bsky profile, try again later.") 673 682 return 674 683 } 675 684 676 685 profile, err := db.GetProfile(h.Db, ident.DID.String()) 677 686 if err != nil { 678 - log.Println("failed to retrieve profile for study session:", err) 687 + l.Error("failed to retrieve profile for study session", "err", err) 679 688 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve profile, try again later.") 680 689 return 681 690 } ··· 698 707 } 699 708 700 709 func (h *Handler) HandleStudySessionPageCommentFeed(w http.ResponseWriter, r *http.Request) { 710 + l := h.Logger.With("handler", "HandleStudySessionPageCommentFeed") 711 + 701 712 user, _ := bsky.GetUserWithBskyProfile(h.Oauth, r) 702 713 703 714 didOrHandle := chi.URLParam(r, "user") ··· 721 732 } 722 733 page, err := strconv.ParseInt(pageStr, 10, 64) 723 734 if err != nil { 724 - log.Println("failed to parse page value:", err) 735 + l.Error("failed to parse page value", "err", err) 725 736 page = 1 726 737 } 727 738 if page == 0 { ··· 733 744 734 745 commentFeed, err := db.GetCommentsForSession(h.Db, studySessionUri.String(), pageSize+1, int(offset)) 735 746 if err != nil { 736 - log.Println("failed to get comment feed:", err) 747 + l.Error("failed to get comment feed", "err", err) 737 748 htmx.HxError(w, http.StatusInternalServerError, "Failed to get comment feed, try again later.") 738 749 return 739 750 } ··· 769 780 770 781 populatedCommentFeed, err := h.BuildCommentFeed(finalFeed) 771 782 if err != nil { 772 - log.Println("failed to populate comment feed:", err) 783 + l.Error("failed to populate comment feed", "err", err) 773 784 htmx.HxError(w, http.StatusInternalServerError, "Failed to get comment feed, try again later.") 774 785 return 775 786 }