Fix orphaned comment photo worker
This commit is contained in:
parent
40b1f2f57a
commit
5c5367c557
23
README.md
23
README.md
|
@ -126,26 +126,15 @@ the web app by using the admin controls on their profile page.
|
||||||
templates, issue redirects, error pages, ...
|
templates, issue redirects, error pages, ...
|
||||||
* `pkg/utility`: miscellaneous useful functions for the app.
|
* `pkg/utility`: miscellaneous useful functions for the app.
|
||||||
|
|
||||||
## Cron API Endpoints
|
## Cron workers
|
||||||
|
|
||||||
In settings.json get or configure the CronAPIKey (a UUID4 value is good and
|
You can schedule the `nonshy vacuum` command in your crontab. This command
|
||||||
the app generates a fresh one by default). The following are the cron API
|
will check and clean up the database for things such as: orphaned comment
|
||||||
endpoints that you may want to configure to run periodic maintenance tasks
|
photos (where somebody uploaded a photo to post on the forum, but then didn't
|
||||||
on the app, such as to remove orphaned comment photos.
|
finish creating their post).
|
||||||
|
|
||||||
### GET /v1/comment-photos/remove-orphaned
|
|
||||||
|
|
||||||
Query parameters: `apiKey` which is the CronAPIKey.
|
|
||||||
|
|
||||||
This endpoint removes orphaned CommentPhotos (photo attachments to forum
|
|
||||||
posts). An orphaned photo is one that has no CommentID and was uploaded
|
|
||||||
older than 24 hours ago; e.g. a user uploaded a picture but then did not
|
|
||||||
complete the posting of their comment.
|
|
||||||
|
|
||||||
Suggested crontab:
|
|
||||||
|
|
||||||
```cron
|
```cron
|
||||||
0 2 * * * curl "http://localhost:8080/v1/comment-photos/remove-orphaned?apiKey=X"
|
0 2 * * * cd /home/nonshy/git/website && ./nonshy vacuum
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/config"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/worker"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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 int64 `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.
|
|
||||||
total, err := worker.VacuumOrphanedCommentPhotos(false)
|
|
||||||
if err != nil {
|
|
||||||
SendJSON(w, http.StatusInternalServerError, Response{
|
|
||||||
Error: err.Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send success response.
|
|
||||||
SendJSON(w, http.StatusOK, Response{
|
|
||||||
OK: true,
|
|
||||||
Total: total,
|
|
||||||
Removed: total,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -134,7 +134,15 @@ func GetOrphanedCommentPhotos() ([]*CommentPhoto, int64, error) {
|
||||||
ps = []*CommentPhoto{}
|
ps = []*CommentPhoto{}
|
||||||
)
|
)
|
||||||
|
|
||||||
query := DB.Model(&CommentPhoto{}).Where("comment_id = 0 AND created_at < ?", cutoff)
|
query := DB.Model(&CommentPhoto{}).Where(`
|
||||||
|
(comment_id <> 0 AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM comments
|
||||||
|
WHERE comments.id = comment_photos.comment_id
|
||||||
|
))
|
||||||
|
OR
|
||||||
|
(comment_id = 0 AND created_at < ?)`,
|
||||||
|
cutoff,
|
||||||
|
)
|
||||||
query.Count(&count)
|
query.Count(&count)
|
||||||
res := query.Limit(500).Find(&ps)
|
res := query.Limit(500).Find(&ps)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
|
|
|
@ -121,7 +121,6 @@ func New() http.Handler {
|
||||||
mux.Handle("POST /v1/notifications/read", middleware.LoginRequired(api.ReadNotification()))
|
mux.Handle("POST /v1/notifications/read", middleware.LoginRequired(api.ReadNotification()))
|
||||||
mux.Handle("POST /v1/notifications/delete", middleware.LoginRequired(api.ClearNotification()))
|
mux.Handle("POST /v1/notifications/delete", middleware.LoginRequired(api.ClearNotification()))
|
||||||
mux.Handle("POST /v1/photos/mark-explicit", middleware.LoginRequired(api.MarkPhotoExplicit()))
|
mux.Handle("POST /v1/photos/mark-explicit", middleware.LoginRequired(api.MarkPhotoExplicit()))
|
||||||
mux.Handle("GET /v1/comment-photos/remove-orphaned", api.RemoveOrphanedCommentPhotos())
|
|
||||||
mux.Handle("POST /v1/barertc/report", barertc.Report())
|
mux.Handle("POST /v1/barertc/report", barertc.Report())
|
||||||
mux.Handle("POST /v1/barertc/profile", barertc.Profile())
|
mux.Handle("POST /v1/barertc/profile", barertc.Profile())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user