package photo import ( "fmt" "net/http" "strconv" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/models" pphoto "code.nonshy.com/nonshy/website/pkg/photo" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" ) // Edit controller (/photo/edit?id=N) to change properties about your picture. func Edit() http.HandlerFunc { // Reuse the upload page but with an EditPhoto variable. tmpl := templates.Must("photo/upload.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Query params. photoID, err := strconv.Atoi(r.FormValue("id")) if err != nil { session.FlashError(w, r, "Photo 'id' parameter required.") templates.Redirect(w, "/") return } // Find this photo by ID. photo, err := models.GetPhoto(uint64(photoID)) if err != nil { templates.NotFoundPage(w, r) return } // Load the current user. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Unexpected error: couldn't get CurrentUser") templates.Redirect(w, "/") return } // Do we have permission for this photo? if photo.UserID != currentUser.ID && !currentUser.IsAdmin { templates.ForbiddenPage(w, r) return } // Are we saving the changes? if r.Method == http.MethodPost { var ( caption = r.FormValue("caption") isExplicit = r.FormValue("explicit") == "true" isGallery = r.FormValue("gallery") == "true" visibility = models.PhotoVisibility(r.FormValue("visibility")) // Profile pic fields setProfilePic = r.FormValue("intent") == "profile-pic" crop = pphoto.ParseCropCoords(r.FormValue("crop")) // Are we GOING private? goingPrivate = visibility == models.PhotoPrivate && visibility != photo.Visibility ) photo.Caption = caption photo.Explicit = isExplicit photo.Gallery = isGallery photo.Visibility = visibility // Are we cropping ourselves a new profile pic? log.Error("Profile pic? %+v and crop is: %+v", setProfilePic, crop) if setProfilePic && crop != nil && len(crop) >= 4 { cropFilename, err := pphoto.ReCrop(photo.Filename, crop[0], crop[1], crop[2], crop[3]) log.Error("ReCrop got: %s, %s", cropFilename, err) if err != nil { session.FlashError(w, r, "Couldn't re-crop for profile picture: %s", err) } else { // If there was an old profile pic, remove it from disk. if photo.CroppedFilename != "" { pphoto.Delete(photo.CroppedFilename) } photo.CroppedFilename = cropFilename log.Warn("HERE WE SET (%s) ON PHOTO (%+v)", cropFilename, photo) } } log.Error("SAVING PHOTO: %+v", photo) if err := photo.Save(); err != nil { session.FlashError(w, r, "Couldn't save photo: %s", err) } // Set their profile pic to this one. if setProfilePic { currentUser.ProfilePhoto = *photo log.Error("Set user ProfilePhotoID=%d", photo.ID) if err := currentUser.Save(); err != nil { session.FlashError(w, r, "Couldn't save user: %s", err) } } // Flash success. session.Flash(w, r, "Photo settings updated!") // If this picture has moved to Private, revoke any notification we gave about it before. if goingPrivate { log.Info("The picture is GOING PRIVATE, revoke any notifications about it") models.RemoveNotification("photos", photo.ID) } // Whose photo gallery to redirect to? if admin editing a user's photo, // go back to the owner's gallery instead of our own. if photo.UserID != currentUser.ID { if owner, err := models.GetUser(photo.UserID); err == nil { templates.Redirect(w, "/photo/u/"+owner.Username) return } } // Return the user to their gallery. templates.Redirect(w, "/photo/u/"+currentUser.Username) return } var vars = map[string]interface{}{ "EditPhoto": photo, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) } // Delete controller (/photo/Delete?id=N) to change properties about your picture. func Delete() http.HandlerFunc { // Reuse the upload page but with an EditPhoto variable. tmpl := templates.Must("photo/delete.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Query params. photoID, err := strconv.Atoi(r.FormValue("id")) if err != nil { log.Error("photo.Delete: failed to parse `id` param (%s) as int: %s", r.FormValue("id"), err) session.FlashError(w, r, "Photo 'id' parameter required.") templates.Redirect(w, "/") return } // Page to redirect to in case of errors. redirect := fmt.Sprintf("%s?id=%d", r.URL.Path, photoID) // Find this photo by ID. photo, err := models.GetPhoto(uint64(photoID)) if err != nil { templates.NotFoundPage(w, r) return } // Load the current user. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Unexpected error: couldn't get CurrentUser") templates.Redirect(w, "/") return } // Do we have permission for this photo? if photo.UserID != currentUser.ID && !currentUser.IsAdmin { templates.ForbiddenPage(w, r) return } // Confirm deletion? if r.Method == http.MethodPost { confirm := r.PostFormValue("confirm") == "true" if !confirm { session.FlashError(w, r, "Confirm you want to delete this photo.") templates.Redirect(w, redirect) return } // Was this our profile picture? if currentUser.ProfilePhotoID != nil && *currentUser.ProfilePhotoID == photo.ID { log.Debug("Delete Photo: was the user's profile photo, unset ProfilePhotoID") if err := currentUser.RemoveProfilePhoto(); err != nil { session.FlashError(w, r, "Error unsetting your current profile photo: %s", err) templates.Redirect(w, redirect) return } } // Remove the images from disk. for _, filename := range []string{ photo.Filename, photo.CroppedFilename, } { if len(filename) > 0 { if err := pphoto.Delete(filename); err != nil { log.Error("Delete Photo: couldn't remove file from disk: %s: %s", filename, err) } } } if err := photo.Delete(); err != nil { session.FlashError(w, r, "Couldn't delete photo: %s", err) templates.Redirect(w, redirect) return } session.Flash(w, r, "Photo deleted!") // Whose photo gallery to redirect to? if admin editing a user's photo, // go back to the owner's gallery instead of our own. if photo.UserID != currentUser.ID { if owner, err := models.GetUser(photo.UserID); err == nil { templates.Redirect(w, "/photo/u/"+owner.Username) return } } // Return the user to their gallery. templates.Redirect(w, "/photo/u/"+currentUser.Username) } var vars = map[string]interface{}{ "Photo": photo, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }