package photo import ( "net/http" "regexp" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/models" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" ) var UserPhotosRegexp = regexp.MustCompile(`^/photo/u/([^@]+?)$`) // UserPhotos controller (/photo/u/:username) to view a user's gallery or manage if it's yourself. func UserPhotos() http.HandlerFunc { tmpl := templates.Must("photo/gallery.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Query params. var ( viewStyle = r.FormValue("view") // cards (default), full ) if viewStyle != "full" { viewStyle = "cards" } // Parse the username out of the URL parameters. var username string m := UserPhotosRegexp.FindStringSubmatch(r.URL.Path) if m != nil { username = m[1] } // Find this user. user, err := models.FindUser(username) if err != nil { templates.NotFoundPage(w, r) return } // Load the current user in case they are viewing their own page. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Unexpected error: couldn't get CurrentUser") } var ( isOwnPhotos = currentUser.ID == user.ID isShy = currentUser.IsShy() isShyFrom = !isOwnPhotos && (currentUser.IsShyFrom(user) || (isShy && !models.AreFriends(currentUser.ID, user.ID))) ) // Bail early if we are shy from this user. if isShy && isShyFrom { var vars = map[string]interface{}{ "IsOwnPhotos": currentUser.ID == user.ID, "IsShyUser": isShy, "IsShyFrom": isShyFrom, // "IsMyPrivateUnlockedFor": isGranted, // have WE granted THIS USER to see our private pics? // "AreWeGrantedPrivate": isGrantee, // have THEY granted US private photo access. "User": user, "Photos": []*models.Photo{}, "PhotoCount": models.CountPhotos(user.ID), "Pager": &models.Pagination{}, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } return } // Is either one blocking? if models.IsBlocking(currentUser.ID, user.ID) && !currentUser.IsAdmin { templates.NotFoundPage(w, r) return } // Is this user private and we're not friends? var ( areFriends = models.AreFriends(user.ID, currentUser.ID) isPrivate = user.Visibility == models.UserVisibilityPrivate && !areFriends ) if isPrivate && !currentUser.IsAdmin && !isOwnPhotos { session.FlashError(w, r, "This user's profile page and photo gallery are private.") templates.Redirect(w, "/u/"+user.Username) return } // Has this user granted access to see their privates? var ( isGrantee = models.IsPrivateUnlocked(user.ID, currentUser.ID) // THEY have granted US access isGranted = models.IsPrivateUnlocked(currentUser.ID, user.ID) // WE have granted THEM access ) // What set of visibilities to query? visibility := []models.PhotoVisibility{models.PhotoPublic} if isOwnPhotos || isGrantee || currentUser.HasAdminScope(config.ScopePhotoModerator) { visibility = append(visibility, models.PhotoPrivate) } if isOwnPhotos || models.AreFriends(user.ID, currentUser.ID) || currentUser.HasAdminScope(config.ScopePhotoModerator) { visibility = append(visibility, models.PhotoFriends) } // Inner circle photos. if currentUser.IsInnerCircle() { visibility = append(visibility, models.PhotoInnerCircle) } // Explicit photo filter? explicit := currentUser.Explicit if isOwnPhotos { explicit = true } // Get the page of photos. pager := &models.Pagination{ Page: 1, PerPage: config.PageSizeUserGallery, Sort: "created_at desc", } pager.ParsePage(r) photos, err := models.PaginateUserPhotos(user.ID, visibility, explicit, pager) if err != nil { log.Error("PaginateUserPhotos(%s): %s", user.Username, err) } // Get the count of explicit photos if we are not viewing explicit photos. var explicitCount int64 if !explicit { explicitCount, _ = models.CountExplicitPhotos(user.ID, visibility) } // Get Likes information about these photos. var photoIDs = []uint64{} for _, p := range photos { photoIDs = append(photoIDs, p.ID) } likeMap := models.MapLikes(currentUser, "photos", photoIDs) commentMap := models.MapCommentCounts("photos", photoIDs) var vars = map[string]interface{}{ "IsOwnPhotos": currentUser.ID == user.ID, "IsShyUser": isShy, "IsShyFrom": isShyFrom, "IsMyPrivateUnlockedFor": isGranted, // have WE granted THIS USER to see our private pics? "AreWeGrantedPrivate": isGrantee, // have THEY granted US private photo access. "User": user, "Photos": photos, "PhotoCount": models.CountPhotosICanSee(user, currentUser), "NoteCount": models.CountNotesAboutUser(currentUser, user), "PublicPhotoCount": models.CountPublicPhotos(user.ID), "InnerCircleMinimumPublicPhotos": config.InnerCircleMinimumPublicPhotos, "Pager": pager, "LikeMap": likeMap, "CommentMap": commentMap, "ViewStyle": viewStyle, "ExplicitCount": explicitCount, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }