~artemis/paste

daa62cb8de0bee9e69588f6a3eb677efb4a0f294 — Diane 3 years ago 125ade9
finished changing routing
5 files changed, 64 insertions(+), 54 deletions(-)

M handlers.go
M templates/markdown.html
M templates/partials.html
M templates/show.html
M todo.txt
M handlers.go => handlers.go +53 -43
@@ 19,19 19,30 @@ import (
type Handlers struct {
	BackendService storage.Backend
	Templates      *template.Template
	Renderers      map[string]Renderer
}

// Content is the response data structure
type Content struct {
	Error string
	Value string
	// Those following string fields are the paste in its different view modes (raw, view, markdown, etc.)
	// on a URL-prefix-basis, e.g. View may contain `/s/<code>`, raw would contain `/r/<code>`,
	// and md would contain `/md/<code>`
	Error           string
	Value           string
	ViewMode        ViewMode
	Code            string
	OriginalCommand PasteSubmitCommand
}

type ViewMode struct {
	Value string
}

func (v ViewMode) Is(value string) bool {
	return v.Value == value
}

func mode(viewMode string) ViewMode {
	return ViewMode{Value: viewMode}
}

// PasteSubmitCommand is the paste upload command
type PasteSubmitCommand struct {
	Paste          string


@@ 64,6 75,12 @@ var genericErrors = map[int]GenericError{
// GetRouter builds a HTTP router based on Gorilla/Mux, to handle
// HTTP traffic
func (h Handlers) GetRouter() *mux.Router {
	h.Renderers = map[string]Renderer{
		"show":     h.viewAsCode,
		"raw":      h.viewAsRaw,
		"markdown": h.viewAsMarkdown,
	}

	r := mux.NewRouter()
	r.Use(LogRequest)



@@ 76,11 93,7 @@ func (h Handlers) GetRouter() *mux.Router {

	r.HandleFunc("/about", h.handleAbout).Methods(http.MethodGet)
	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))

	// TODO add format filters
	r.HandleFunc("/s/{key}", h.handleShowPaste).Methods(http.MethodGet)
	r.HandleFunc("/r/{key}", h.handleShowRaw).Methods(http.MethodGet)
	r.HandleFunc("/md/{key}", h.HandleShowMarkdown).Methods(http.MethodGet)
	r.HandleFunc("/-/{key}", h.handlePasteRetrieval).Methods(http.MethodGet)

	return r
}


@@ 187,56 200,53 @@ func (h Handlers) handleNewPaste(w http.ResponseWriter, req *http.Request) {
		return
	}

	http.Redirect(w, req, "/s/"+key, http.StatusFound)
	http.Redirect(w, req, "/-/"+key, http.StatusFound)
	_, err = fmt.Fprint(w, key)
	ErrIf(err)
}

func (h Handlers) handlePasteRetrieval(w http.ResponseWriter, req *http.Request, key string) (bool, string) {
func (h Handlers) handlePasteRetrieval(w http.ResponseWriter, req *http.Request) {
	key := mux.Vars(req)["key"]
	res, err := h.BackendService.Retrieve(key)

	if nil != err {
	viewMode := req.URL.Query().Get("view")
	if "" == viewMode {
		viewMode = "show"
	}

	if (!rules.Choice{Choices: []string{"show", "raw", "markdown"}}.Validate(viewMode)) {
		h.GenericHTTPError(400, fmt.Sprintf("Unknown view mode %s", viewMode))(w, req)
	} else if nil != err {
		h.GenericHTTPError(500, err.Error())(w, req)
		return false, ""
	} else if res == "" {
		h.GenericHTTPError(404, nil)(w, req)
		return false, ""
	} else {
		ErrIf(h.Renderers[viewMode](w, key, res))
	}

	return true, res
}

func (h Handlers) handleShowPaste(w http.ResponseWriter, req *http.Request) {
	key := mux.Vars(req)["key"]
type Renderer func(w http.ResponseWriter, key string, value string) error

	if ok, res := h.handlePasteRetrieval(w, req, key); ok {
		ErrIf(h.Templates.ExecuteTemplate(w, "show", &Content{
			Value: res,
			Code:  key,
		}))
	}
func (h Handlers) viewAsCode(w http.ResponseWriter, key string, value string) error {
	return h.Templates.ExecuteTemplate(w, "show", &Content{
		Value:    value,
		Code:     key,
		ViewMode: mode("show"),
	})
}

func (h Handlers) handleShowRaw(w http.ResponseWriter, req *http.Request) {
	key := mux.Vars(req)["key"]

	if ok, res := h.handlePasteRetrieval(w, req, key); ok {
		w.Header().Set("Content-Type", "text/plain; charset=utf8")
		_, err := fmt.Fprint(w, res)
		ErrIf(err)
	}
func (h Handlers) viewAsMarkdown(w http.ResponseWriter, key string, value string) error {
	return h.Templates.ExecuteTemplate(w, "markdown", &Content{
		Value:    value,
		Code:     key,
		ViewMode: mode("markdown"),
	})
}

// HandleShowMarkdown renders document with blackfriday.v2 and returns a HTML page
func (h Handlers) HandleShowMarkdown(w http.ResponseWriter, req *http.Request) {
	key := mux.Vars(req)["key"]

	if ok, res := h.handlePasteRetrieval(w, req, key); ok {
		ErrIf(h.Templates.ExecuteTemplate(w, "markdown", &Content{
			Value: res,
			Code:  key,
		}))
	}
func (h Handlers) viewAsRaw(w http.ResponseWriter, key string, value string) error {
	w.Header().Set("Content-Type", "text/plain; charset=utf8")
	_, err := fmt.Fprint(w, value)
	return err
}

// endregion

M templates/markdown.html => templates/markdown.html +1 -1
@@ 11,7 11,7 @@
	<body>
	{{template "header"}}

	{{template "view-mode"}}
	{{template "view-mode" .ViewMode}}

	<main>
		{{.Value|markdown}}

M templates/partials.html => templates/partials.html +6 -6
@@ 22,12 22,12 @@
	<header class="spaced mid-aligned">
		<div></div>

		<form action="/change-mode">
			<label for="">View mode: </label>
			<select name="" id="">
				<option value="">Source-code</option>
				<option value="">Markdown</option>
				<option value="">Raw</option>
		<form>
			<label for="view">View mode: </label>
			<select name="view" id="view">
				<option value="show" {{if .Is "show"}}selected{{end}}>Source-code</option>
				<option value="markdown" {{if .Is "markdown"}}selected{{end}}>Markdown</option>
				<option value="raw">Raw</option>
			</select>

			<button type="submit">Change view</button>

M templates/show.html => templates/show.html +1 -1
@@ 10,7 10,7 @@
	<body>
	{{template "header"}}

	{{template "view-mode"}}
	{{template "view-mode" .ViewMode}}

	<main>
		<pre class="code">

M todo.txt => todo.txt +3 -3
@@ 1,5 1,5 @@
text trimming on paste
uniformized 404 error page
uniformized error pages
server-side syntaxic coloration
mode changer
change routing system to use GET parameters and - as prefix
x 2020-06-21 mode changer
x 2020-06-21 change routing system to use GET parameters and - as prefix