website/pkg/controller/api/orphaned_comment_photos.go
Noah 47f898561c Forum Photo Attachments
* Add support to upload a picture to forum posts and replies, in forums that
  have the PermitPhotos setting enabled.
* New DB table: CommentPhoto holds the association between a photo and a
  forum ID. Photos can be uploaded at preview time (before a CommentID is
  available) and get associated to the CommentID on save.
* Cron endpoint /v1/comment-photos/remove-orphaned can clean up orphaned
  photos without a CommentID older than 24 hours.
* Add "Photo Boards" as a default forum category for new boards.
2022-10-20 21:02:30 -07:00

94 lines
2.3 KiB
Go

package api
import (
"fmt"
"net/http"
"code.nonshy.com/nonshy/website/pkg/config"
"code.nonshy.com/nonshy/website/pkg/models"
"code.nonshy.com/nonshy/website/pkg/photo"
)
// RemoveOrphanedCommentPhotos API.
//
// URL: /v1/comment-photos/remove-orphaned
//
// Query parameters: ?apiKey={CronAPIKey}
//
// This endpoint looks for CommentPhotos having a blank CommentID that were created older
// than 24 hours ago and removes them. Configure the "CronAPIKey" in your settings.json
// and pass it as the query parameter.
func RemoveOrphanedCommentPhotos() http.HandlerFunc {
// Response JSON schema.
type Response struct {
OK bool `json:"OK"`
Error string `json:"error,omitempty"`
Total int64 `json:"total"`
Removed int `json:"removed"`
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
SendJSON(w, http.StatusNotAcceptable, Response{
Error: "GET method only",
})
return
}
// Get and validate the API key.
var (
apiKey = r.FormValue("apiKey")
compare = config.Current.CronAPIKey
)
if compare == "" {
SendJSON(w, http.StatusInternalServerError, Response{
OK: false,
Error: "app CronAPIKey is not configured",
})
return
} else if apiKey == "" || apiKey != compare {
SendJSON(w, http.StatusInternalServerError, Response{
OK: false,
Error: "invalid apiKey query parameter",
})
return
}
// Do the needful.
photos, total, err := models.GetOrphanedCommentPhotos()
if err != nil {
SendJSON(w, http.StatusInternalServerError, Response{
OK: false,
Error: fmt.Sprintf("GetOrphanedCommentPhotos: %s", err),
})
return
}
for _, row := range photos {
if err := photo.Delete(row.Filename); err != nil {
SendJSON(w, http.StatusInternalServerError, Response{
OK: false,
Error: fmt.Sprintf("Photo ID %d: removing file %s: %s", row.ID, row.Filename, err),
})
return
}
if err := row.Delete(); err != nil {
SendJSON(w, http.StatusInternalServerError, Response{
OK: false,
Error: fmt.Sprintf("DeleteOrphanedCommentPhotos(%d): %s", row.ID, err),
})
return
}
}
// Send success response.
SendJSON(w, http.StatusOK, Response{
OK: true,
Total: total,
Removed: len(photos),
})
})
}