chore(router,service): remove editor and projects endpoint and services
They will be reimplemented later
This commit is contained in:
283
router/editor.go
283
router/editor.go
@@ -1,283 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/internals/randstr"
|
||||
"forge.capytal.company/capytalcode/project-comicverse/service"
|
||||
"forge.capytal.company/loreddev/x/smalltrip/exception"
|
||||
)
|
||||
|
||||
func (router *router) pages(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
|
||||
// TODO: Check if project exists
|
||||
id := r.PathValue("ID")
|
||||
if id == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "ID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
pageID := r.PathValue("PageID")
|
||||
|
||||
switch getMethod(r) {
|
||||
case http.MethodGet, http.MethodHead:
|
||||
if pageID == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "PageID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
router.getPage(w, r)
|
||||
|
||||
case http.MethodPost:
|
||||
router.addPage(w, r)
|
||||
|
||||
case http.MethodDelete:
|
||||
if pageID == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "PageID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
router.deletePage(w, r)
|
||||
|
||||
default:
|
||||
exception.
|
||||
MethodNotAllowed([]string{
|
||||
http.MethodGet,
|
||||
http.MethodHead,
|
||||
http.MethodPost,
|
||||
http.MethodDelete,
|
||||
}).
|
||||
ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) addPage(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
id := r.PathValue("ID")
|
||||
router.assert.NotZero(id, "This method should be used after the path values are checked")
|
||||
|
||||
img, _, err := r.FormFile("image")
|
||||
if err != nil {
|
||||
// TODO: Handle if the file is bigger than allowed by ParseForm (10mb)
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
err = router.service.AddPage(id, img)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/projects/%s/", id), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (router *router) getPage(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
id := r.PathValue("ID")
|
||||
router.assert.NotZero(id, "This method should be used after the path values are checked")
|
||||
|
||||
pageID := r.PathValue("PageID")
|
||||
router.assert.NotZero(pageID, "This method should be used after the path values are checked")
|
||||
|
||||
page, err := router.service.GetPage(id, pageID)
|
||||
if errors.Is(err, service.ErrPageNotExists) {
|
||||
exception.NotFound(exception.WithError(err)).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if i, ok := page.Image.(io.WriterTo); ok {
|
||||
_, err = i.WriteTo(w)
|
||||
} else {
|
||||
_, err = io.Copy(w, page.Image)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) deletePage(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
id := r.PathValue("ID")
|
||||
router.assert.NotZero(id, "This method should be used after the path values are checked")
|
||||
|
||||
pageID := r.PathValue("PageID")
|
||||
router.assert.NotZero(pageID, "This method should be used after the path values are checked")
|
||||
|
||||
err := router.service.DeletePage(id, pageID)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/projects/%s/", id), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (router *router) interactions(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
|
||||
// TODO: Check if the project exists
|
||||
id := r.PathValue("ID")
|
||||
if id == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "ID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Check if page exists
|
||||
pageID := r.PathValue("PageID")
|
||||
if pageID == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "PageID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
interactionID := r.PathValue("InteractionID")
|
||||
|
||||
switch getMethod(r) {
|
||||
case http.MethodPost:
|
||||
router.addInteraction(w, r)
|
||||
|
||||
case http.MethodDelete:
|
||||
if interactionID == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "InteractionID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
router.deleteInteraction(w, r)
|
||||
|
||||
default:
|
||||
exception.
|
||||
MethodNotAllowed([]string{
|
||||
http.MethodPost,
|
||||
http.MethodDelete,
|
||||
}).
|
||||
ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) addInteraction(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
id := r.PathValue("ID")
|
||||
router.assert.NotZero(id, "This method should be used after the path values are checked")
|
||||
|
||||
pageID := r.PathValue("PageID")
|
||||
router.assert.NotZero(pageID, "This method should be used after the path values are checked")
|
||||
|
||||
// TODO: Methods to manipulate interactions, instead of router need to do this logic
|
||||
page, err := router.service.GetPage(id, pageID)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
page.Image = nil // HACK: Prevent image update on S3
|
||||
|
||||
x, err := strconv.ParseUint(r.FormValue("x"), 10, 0)
|
||||
if err != nil {
|
||||
exception.
|
||||
BadRequest(errors.Join(errors.New(`value "x" should be a valid non-negative integer`), err)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
y, err := strconv.ParseUint(r.FormValue("y"), 10, 0)
|
||||
if err != nil {
|
||||
exception.
|
||||
BadRequest(errors.Join(errors.New(`value "y" should be a valid non-negative integer`), err)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
link := r.FormValue("link")
|
||||
if link == "" {
|
||||
exception.BadRequest(errors.New(`missing parameter "link" in request`)).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
intID, err := randstr.NewHex(6)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
page.Interactions[intID] = service.PageInteraction{
|
||||
X: uint16(x),
|
||||
Y: uint16(y),
|
||||
URL: link,
|
||||
}
|
||||
|
||||
err = router.service.UpdatePage(id, page)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/projects/%s/", id), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (router *router) deleteInteraction(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
id := r.PathValue("ID")
|
||||
router.assert.NotZero(id, "This method should be used after the path values are checked")
|
||||
|
||||
pageID := r.PathValue("PageID")
|
||||
router.assert.NotZero(pageID, "This method should be used after the path values are checked")
|
||||
|
||||
interactionID := r.PathValue("InteractionID")
|
||||
router.assert.NotZero(interactionID, "This method should be used after the path values are checked")
|
||||
|
||||
// TODO: Methods to manipulate interactions, instead of router need to do this logic
|
||||
page, err := router.service.GetPage(id, pageID)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
page.Image = nil // HACK: Prevent image update on S3
|
||||
|
||||
delete(page.Interactions, interactionID)
|
||||
|
||||
err = router.service.UpdatePage(id, page)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/projects/%s/", id), http.StatusSeeOther)
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/service"
|
||||
"forge.capytal.company/loreddev/x/smalltrip/exception"
|
||||
)
|
||||
|
||||
func (router *router) projects(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
|
||||
switch getMethod(r) {
|
||||
case http.MethodGet, http.MethodHead:
|
||||
if id := r.PathValue("ID"); id != "" {
|
||||
router.getProject(w, r)
|
||||
} else {
|
||||
router.listProjects(w, r)
|
||||
}
|
||||
|
||||
case http.MethodPost:
|
||||
router.createProject(w, r)
|
||||
|
||||
case http.MethodDelete:
|
||||
if id := r.PathValue("ID"); id != "" {
|
||||
router.deleteProject(w, r)
|
||||
} else {
|
||||
exception.
|
||||
BadRequest(errors.New(`missing "ID" path value`)).
|
||||
ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
default:
|
||||
exception.MethodNotAllowed([]string{
|
||||
http.MethodHead,
|
||||
http.MethodGet,
|
||||
http.MethodPost,
|
||||
http.MethodDelete,
|
||||
}).ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) createProject(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
|
||||
if getMethod(r) != http.MethodPost {
|
||||
exception.
|
||||
MethodNotAllowed([]string{http.MethodPost}).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
p, err := router.service.CreateProject()
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
router.assert.NotZero(p.ID)
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("%s/", path.Join(r.URL.Path, p.ID)), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (router *router) getProject(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
router.assert.NotNil(router.templates)
|
||||
|
||||
if getMethod(r) != http.MethodGet && getMethod(r) != http.MethodHead {
|
||||
exception.
|
||||
MethodNotAllowed([]string{http.MethodGet, http.MethodHead}).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
id := r.PathValue("ID")
|
||||
if id == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "ID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
p, err := router.service.GetProject(id)
|
||||
switch {
|
||||
case errors.Is(err, service.ErrProjectNotExists):
|
||||
exception.NotFound().ServeHTTP(w, r)
|
||||
return
|
||||
|
||||
case err != nil:
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
err = router.templates.ExecuteTemplate(w, "project", p)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) listProjects(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
router.assert.NotNil(router.templates)
|
||||
|
||||
if getMethod(r) != http.MethodGet && getMethod(r) != http.MethodHead {
|
||||
exception.
|
||||
MethodNotAllowed([]string{http.MethodGet, http.MethodHead}).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
ps, err := router.service.ListProjects()
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
b, err := json.Marshal(ps)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err = w.Write(b)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (router *router) deleteProject(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
router.assert.NotNil(router.service)
|
||||
router.assert.NotNil(router.templates)
|
||||
|
||||
if getMethod(r) != http.MethodDelete {
|
||||
exception.
|
||||
MethodNotAllowed([]string{http.MethodDelete}).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
id := r.PathValue("ID")
|
||||
if id == "" {
|
||||
exception.
|
||||
BadRequest(fmt.Errorf(`a valid path value of "ID" must be provided`)).
|
||||
ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
err := router.service.DeleteProject(id)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
err = router.templates.ExecuteTemplate(w, "partials-status", map[string]any{
|
||||
"StatusCode": http.StatusOK,
|
||||
"Message": fmt.Sprintf("Project %q successfully deleted", id),
|
||||
"Redirect": "/dashboard/",
|
||||
"RedirectMessage": "Go back to dashboard",
|
||||
})
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/service"
|
||||
"forge.capytal.company/capytalcode/project-comicverse/templates"
|
||||
@@ -95,44 +94,6 @@ func (router *router) setup() http.Handler {
|
||||
|
||||
r.HandleFunc("/dashboard/", router.dashboard)
|
||||
|
||||
r.HandleFunc("/projects/{$}", router.projects)
|
||||
r.HandleFunc("/projects/{ID}/", router.projects)
|
||||
r.HandleFunc("/projects/{ID}/pages/{$}", router.pages)
|
||||
r.HandleFunc("/projects/{ID}/pages/{PageID}", router.pages)
|
||||
r.HandleFunc("/projects/{ID}/pages/{PageID}/interactions/{$}", router.interactions)
|
||||
r.HandleFunc("/projects/{ID}/pages/{PageID}/interactions/{InteractionID}", router.interactions)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (router *router) dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
router.assert.NotNil(router.templates)
|
||||
router.assert.NotNil(router.service)
|
||||
router.assert.NotNil(w)
|
||||
router.assert.NotNil(r)
|
||||
|
||||
p, err := router.service.ListProjects()
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
err = router.templates.ExecuteTemplate(w, "dashboard", p)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func getMethod(r *http.Request) string {
|
||||
if r.Method == http.MethodGet || r.Method == http.MethodHead {
|
||||
return r.Method
|
||||
}
|
||||
|
||||
m := r.FormValue("x-method")
|
||||
if m == "" {
|
||||
return r.Method
|
||||
}
|
||||
|
||||
return strings.ToUpper(m)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user