FILE / Unmei/Backend
v1/novels_routes.go
Исходный файл и его история в репозитории.
240 lines
5.5 KiB
Go
240 lines
5.5 KiB
Go
package v1
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
func RegisterNovelsRoutes(r *mux.Router) {
|
|
r.HandleFunc("/novels", resolveNovels).Methods("GET", "OPTIONS", "POST")
|
|
r.HandleFunc("/novels/{novelId:[0-9]+}", resolveNovel).Methods("GET", "OPTIONS", "PUT", "DELETE")
|
|
r.HandleFunc("/novels/{novelId:[0-9]+}/cover", uploadNovelCover).Methods("POST", "OPTIONS")
|
|
r.HandleFunc("/novels/{novelId:[0-9]+}/comments", resolveNovelComments).Methods("GET", "OPTIONS", "POST")
|
|
r.HandleFunc("/novels/{novelId:[0-9]+}/characters", resolveNovelCharacters).Methods("GET", "OPTIONS")
|
|
r.HandleFunc("/novels/{novelId:[0-9]+}/genres", resolveNovelGenres).Methods("GET", "OPTIONS")
|
|
}
|
|
|
|
func resolveNovels(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodGet {
|
|
sortBy, ok := r.URL.Query()["sort"]
|
|
|
|
if !ok || len(sortBy) <= 0 {
|
|
sortBy = append(sortBy, "rating")
|
|
}
|
|
|
|
query, ok := r.URL.Query()["q"]
|
|
if ok {
|
|
novels, err := SearchNovels(query[0])
|
|
Response(w, err, novels)
|
|
return
|
|
}
|
|
|
|
novels, err := FetchNovels(sortBy[0])
|
|
Response(w, err, &novels)
|
|
} else if r.Method == http.MethodPost {
|
|
body, err := ReadBody(r)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
var novel Novel
|
|
err = json.Unmarshal(body, &novel)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
novel, err = CreateNovel(&novel)
|
|
if err == nil {
|
|
w.WriteHeader(http.StatusCreated)
|
|
w.Header().Add("Location", fmt.Sprintf("https://%v%v/%v", r.Host, r.URL, novel.ID))
|
|
}
|
|
Response(w, err, &novel)
|
|
}
|
|
}
|
|
|
|
func resolveNovelGenres(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
id, _ := strconv.Atoi(vars["novelId"])
|
|
|
|
genres, err := FetchNovelGenres(int32(id))
|
|
Response(w, err, genres)
|
|
}
|
|
|
|
func resolveNovelCharacters(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
novelId, _ := strconv.Atoi(vars["novelId"])
|
|
|
|
characters, err := FetchNovelCharacters(novelId)
|
|
Response(w, err, characters)
|
|
}
|
|
|
|
func resolveNovel(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
novelId, _ := strconv.Atoi(vars["novelId"])
|
|
|
|
if r.Method == http.MethodGet {
|
|
novel, err := FetchNovel(novelId)
|
|
Response(w, err, novel)
|
|
} else if r.Method == http.MethodPut {
|
|
body, err := ReadBody(r)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
novel, err := FetchNovel(novelId)
|
|
if err != nil {
|
|
Response(w, err, nil)
|
|
return
|
|
}
|
|
err = json.Unmarshal(body, novel)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
novel, err = UpdateNovel(novel)
|
|
Response(w, err, novel)
|
|
} else if r.Method == http.MethodDelete {
|
|
_, err := FetchNovel(novelId)
|
|
if err == sql.ErrNoRows {
|
|
NotFound.Ferror(w)
|
|
return
|
|
}
|
|
|
|
err = DeleteNovel(novelId)
|
|
if err != nil {
|
|
w.WriteHeader(500)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
JSON(w, "")
|
|
}
|
|
}
|
|
|
|
func uploadNovelCover(w http.ResponseWriter, r *http.Request) {
|
|
user, err := FetchCurrentUser(r)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
if !hasPermission(user, "novel") {
|
|
NoAccess.Ferror(w)
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
novelId, _ := strconv.Atoi(vars["novelId"])
|
|
|
|
err = r.ParseMultipartForm(1024 * 1024 * 2)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
file, handler, err := r.FormFile("cover")
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
if !strings.HasPrefix(handler.Header["Content-Type"][0], "image") {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
RawError(w, "Wrong document type!")
|
|
return
|
|
}
|
|
|
|
fileBytes, err := ioutil.ReadAll(file)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
err = file.Close()
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
ext := strings.Split(handler.Header["Content-Type"][0], "/")[1]
|
|
path := filepath.Join(config.CDNPath, "novels", "logo", fmt.Sprintf("%v.%v", novelId, ext))
|
|
|
|
err = ioutil.WriteFile(path, fileBytes, 0644)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
Error(w, err)
|
|
return
|
|
}
|
|
coverPath := fmt.Sprintf("%v/novels/logo/%v.%v", config.CDNUrl, novelId, ext)
|
|
err = UpdateNovelCover(novelId, coverPath)
|
|
Response(w, err, coverPath)
|
|
}
|
|
|
|
func resolveNovelComments(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
novelId, _ := strconv.Atoi(vars["novelId"])
|
|
|
|
if r.Method == http.MethodGet {
|
|
offsetParam, ok := r.URL.Query()["offset"]
|
|
if !ok || len(offsetParam) <= 0 {
|
|
offsetParam = append(offsetParam, "0")
|
|
}
|
|
|
|
countParam, ok := r.URL.Query()["count"]
|
|
if !ok || len(countParam) <= 0 {
|
|
countParam = append(countParam, "5")
|
|
}
|
|
|
|
offset, _ := strconv.Atoi(offsetParam[0])
|
|
count, _ := strconv.Atoi(countParam[0])
|
|
|
|
var response = make(map[string]interface{}, 2)
|
|
comments, err := FetchNovelComments(novelId)
|
|
response["count"] = len(comments)
|
|
|
|
if offset+count > len(comments) {
|
|
comments = comments[offset:]
|
|
} else {
|
|
comments = comments[offset : offset+count]
|
|
}
|
|
response["comments"] = comments
|
|
Response(w, err, response)
|
|
} else if r.Method == http.MethodPost {
|
|
user, err := FetchCurrentUser(r)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
body, err := ReadBody(r)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
commentData := CommentNovel{NovelID: int16(novelId), UserID: user.ID}
|
|
err = json.Unmarshal(body, &commentData)
|
|
if err != nil {
|
|
Error(w, err)
|
|
return
|
|
}
|
|
|
|
comment, err := AddNovelComment(commentData)
|
|
Response(w, err, comment)
|
|
}
|
|
}
|