2026-02-17 17:29:15 +00:00
|
|
|
package sync
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2026-02-24 15:34:53 +00:00
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strconv"
|
2026-02-17 17:29:15 +00:00
|
|
|
|
2026-02-24 17:22:20 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/config"
|
2026-02-24 15:34:53 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/db"
|
2026-02-17 17:29:15 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
2026-02-24 15:34:53 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform"
|
|
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/userfile"
|
|
|
|
|
"github.com/go-chi/chi/v5"
|
2026-02-17 17:29:15 +00:00
|
|
|
)
|
|
|
|
|
|
2026-02-24 16:14:35 +00:00
|
|
|
type contentUploadList struct {
|
|
|
|
|
RecentUploads []platform.UploadSummary
|
|
|
|
|
}
|
2026-02-17 17:29:15 +00:00
|
|
|
type contentUploadPlaceholder struct{}
|
|
|
|
|
|
2026-02-24 16:14:35 +00:00
|
|
|
func getUploadList(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentUploadList], *errorWithStatus) {
|
|
|
|
|
rows, err := platform.UploadSummaryList(ctx, org)
|
|
|
|
|
return newResponse("sync/upload-list.html", contentUploadList{
|
|
|
|
|
RecentUploads: rows,
|
|
|
|
|
}), newErrorMaybe("get upload list: %w", err)
|
2026-02-24 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-24 17:22:20 +00:00
|
|
|
type contentUploadURL struct {
|
|
|
|
|
Discard string // URL for discarding the upload
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newContentUploadURL(id int32) contentUploadURL {
|
|
|
|
|
id_str := strconv.FormatInt(int64(id), 10)
|
|
|
|
|
return contentUploadURL{
|
|
|
|
|
Discard: config.MakeURLNidus("/upload/%s/discard", id_str),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type contentUploadDetail struct {
|
2026-02-24 15:34:53 +00:00
|
|
|
CSVFileID int32
|
|
|
|
|
Organization *models.Organization
|
|
|
|
|
Upload platform.UploadPoolDetail
|
2026-02-24 17:22:20 +00:00
|
|
|
URL contentUploadURL
|
2026-02-24 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
type contentUploadPoolList struct {
|
|
|
|
|
Uploads []platform.PoolUpload
|
|
|
|
|
}
|
|
|
|
|
type contentUploadPoolCreate struct{}
|
|
|
|
|
|
|
|
|
|
func getUploadPoolList(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolList], *errorWithStatus) {
|
|
|
|
|
uploads, err := platform.PoolUploadList(ctx, u.OrganizationID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, newError("Failed to get uploads: %w", err)
|
|
|
|
|
}
|
|
|
|
|
data := contentUploadPoolList{
|
|
|
|
|
Uploads: uploads,
|
|
|
|
|
}
|
|
|
|
|
return newResponse("sync/pool-list.html", data), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getUploadPoolCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolCreate], *errorWithStatus) {
|
|
|
|
|
data := contentUploadPoolCreate{}
|
|
|
|
|
return newResponse("sync/pool-csv-upload.html", data), nil
|
|
|
|
|
}
|
2026-02-24 17:22:20 +00:00
|
|
|
func getUploadByID(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadDetail], *errorWithStatus) {
|
2026-02-24 15:34:53 +00:00
|
|
|
org, err := u.Organization().One(ctx, db.PGInstance.BobDB)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, newError("Failed to get organization: %w", err)
|
|
|
|
|
}
|
|
|
|
|
file_id_str := chi.URLParam(r, "id")
|
2026-02-24 17:22:20 +00:00
|
|
|
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
|
2026-02-24 15:34:53 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, newError("Failed to parse file_id: %w", err)
|
|
|
|
|
}
|
2026-02-24 17:22:20 +00:00
|
|
|
file_id := int32(file_id_)
|
|
|
|
|
detail, err := platform.GetUploadPoolDetail(ctx, u.OrganizationID, file_id)
|
2026-02-24 15:34:53 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, newError("Failed to get pool: %w", err)
|
|
|
|
|
}
|
2026-02-24 17:22:20 +00:00
|
|
|
data := contentUploadDetail{
|
|
|
|
|
CSVFileID: file_id,
|
2026-02-24 15:34:53 +00:00
|
|
|
Organization: org,
|
|
|
|
|
Upload: detail,
|
2026-02-24 17:22:20 +00:00
|
|
|
URL: newContentUploadURL(file_id),
|
2026-02-24 15:34:53 +00:00
|
|
|
}
|
2026-02-24 17:10:54 +00:00
|
|
|
return newResponse("sync/upload-by-id.html", data), nil
|
2026-02-24 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type FormUploadPool struct{}
|
|
|
|
|
|
|
|
|
|
func postUploadPoolCreate(ctx context.Context, r *http.Request, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
|
|
|
|
|
uploads, err := userfile.SaveFileUpload(r, "csvfile", userfile.CollectionCSV)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", newError("Failed to extract image uploads: %s", err)
|
|
|
|
|
}
|
|
|
|
|
if len(uploads) == 0 {
|
|
|
|
|
return "", newErrorStatus(http.StatusBadRequest, "No upload found")
|
|
|
|
|
}
|
|
|
|
|
if len(uploads) != 1 {
|
|
|
|
|
return "", newErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
|
|
|
|
}
|
|
|
|
|
upload := uploads[0]
|
|
|
|
|
pool_upload, err := platform.NewPoolUpload(r.Context(), u, upload)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", newError("Failed to create new pool: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("/pool/upload/%d", pool_upload.ID), nil
|
2026-02-17 17:29:15 +00:00
|
|
|
}
|