95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
package api
|
|
|
|
import (
|
|
"TheAdversary/config"
|
|
"TheAdversary/database"
|
|
"TheAdversary/schema"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/gomarkdown/markdown"
|
|
"go.uber.org/zap"
|
|
"net/http"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type uploadPayload struct {
|
|
Title string `json:"title"`
|
|
Summary string `json:"summary"`
|
|
Authors []int `json:"authors"`
|
|
Image string `json:"image"`
|
|
Tags []string `json:"tags"`
|
|
Link string `json:"link"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
func Upload(w http.ResponseWriter, r *http.Request) {
|
|
authorId, ok := authorizedSession(r)
|
|
if !ok {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
var payload uploadPayload
|
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
InvalidJson.Send(w)
|
|
return
|
|
}
|
|
|
|
rawMarkdown, err := base64.StdEncoding.DecodeString(payload.Content)
|
|
if err != nil {
|
|
zap.S().Warnf("Cannot decode base64")
|
|
ApiError{Message: "invalid base64 content", Code: http.StatusUnprocessableEntity}.Send(w)
|
|
return
|
|
}
|
|
|
|
var notFound []string
|
|
database.GetDB().Select("* FROM ? EXCEPT ?", payload.Authors, database.GetDB().Table("author").Select("id")).Find(¬Found)
|
|
if len(notFound) > 0 {
|
|
ApiError{fmt.Sprintf("no authors with the id(s) %s were found", strings.Join(notFound, ", ")), http.StatusUnprocessableEntity}.Send(w)
|
|
return
|
|
}
|
|
|
|
a := article{
|
|
Title: payload.Title,
|
|
Summary: payload.Summary,
|
|
Image: payload.Image,
|
|
Created: time.Now().Unix(),
|
|
Modified: time.Unix(0, 0).Unix(),
|
|
Link: "/" + path.Join(config.Prefix, "article", payload.Link),
|
|
Markdown: string(rawMarkdown),
|
|
Html: string(markdown.ToHTML(rawMarkdown, nil, nil)),
|
|
}
|
|
database.GetDB().Table("article").Create(&a)
|
|
var authors []map[string]interface{}
|
|
for _, author := range append([]int{authorId}, payload.Authors...) {
|
|
authors = append(authors, map[string]interface{}{
|
|
"article_id": a.ID,
|
|
"author_id": author,
|
|
})
|
|
}
|
|
database.GetDB().Table("article_author").Create(&authors)
|
|
var tags []map[string]interface{}
|
|
for _, tag := range payload.Tags {
|
|
authors = append(authors, map[string]interface{}{
|
|
"article_id": a.ID,
|
|
"tag": tag,
|
|
})
|
|
}
|
|
database.GetDB().Table("article_tag").Create(&tags)
|
|
|
|
var articleSummary schema.ArticleSummary
|
|
database.GetDB().Table("article").Find(&articleSummary, &a.ID)
|
|
database.GetDB().Table("author").Where("id IN (?)", database.GetDB().Table("article_author").Select("author_id").Where("article_id = ?", a.ID)).Find(&articleSummary.Authors)
|
|
if payload.Tags != nil {
|
|
articleSummary.Tags = payload.Tags
|
|
} else {
|
|
articleSummary.Tags = []string{}
|
|
}
|
|
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(articleSummary)
|
|
}
|