initial commit; working state

This commit is contained in:
Vikas
2024-06-02 10:33:54 +05:30
commit a124c1b0be
24 changed files with 1082 additions and 0 deletions

78
web/handlers.go Normal file
View File

@@ -0,0 +1,78 @@
package web
import (
"context"
"fmt"
"net/http"
"github.com/v1k45/paste/db"
"github.com/v1k45/paste/views"
)
type Handler struct {
DB *db.DB
}
func NewHandler(db *db.DB) *Handler {
return &Handler{DB: db}
}
func (h *Handler) Index(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
component := views.Index()
component.Render(context.Background(), w)
}
func (h *Handler) Paste(w http.ResponseWriter, r *http.Request) {
pastedText := r.FormValue("text")
if pastedText == "" {
errorResponse(w, http.StatusBadRequest, "Invalid Data", "Paste content is required.")
return
}
expiresAt, err := getExpiresAt(r.FormValue("expiration"))
if err != nil {
errorResponse(w, http.StatusBadRequest, "Invalid Data", "Invalid expiration time.")
return
}
paste, err := h.DB.NewPaste(pastedText, expiresAt)
if err != nil {
errorResponse(w, http.StatusInternalServerError, "Internal Server Error", "Failed to create paste, please try again later.")
return
}
var scheme string
if r.TLS == nil {
scheme = "http"
} else {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/p/%s/%s", scheme, r.Host, paste.ID, paste.Key)
component := views.PasteSuccess(url)
component.Render(context.Background(), w)
}
func (h *Handler) View(w http.ResponseWriter, r *http.Request) {
if _, err := h.DB.Get(r.PathValue("id")); err != nil {
errorResponse(w, http.StatusNotFound, "Not Found", "The paste you are looking for is either expired or does not exist.")
return
}
component := views.View()
component.Render(context.Background(), w)
}
func (h *Handler) Decrypt(w http.ResponseWriter, r *http.Request) {
decryptedText, err := h.DB.Decrypt(r.PathValue("id"), r.PathValue("key"))
if err != nil {
errorResponse(
w, http.StatusInternalServerError,
"Internal Server Error", "The paste you are looking for is either expired, corrputed or does not exist.")
return
}
component := views.Decrypt(decryptedText)
component.Render(context.Background(), w)
}

12
web/routes.go Normal file
View File

@@ -0,0 +1,12 @@
package web
import "net/http"
func (h *Handler) Router() http.Handler {
router := http.NewServeMux()
router.HandleFunc("GET /", h.Index)
router.HandleFunc("POST /", h.Paste)
router.HandleFunc("GET /p/{id}/{key}", h.View)
router.HandleFunc("POST /p/{id}/{key}", h.Decrypt)
return router
}

35
web/utils.go Normal file
View File

@@ -0,0 +1,35 @@
package web
import (
"context"
"errors"
"net/http"
"time"
"github.com/v1k45/paste/views"
)
var (
expirationTimes = map[string]time.Duration{
"1h": time.Hour,
"1d": 24 * time.Hour,
"1w": 7 * 24 * time.Hour,
"2w": 2 * 7 * 24 * time.Hour,
"4w": 4 * 7 * 24 * time.Hour,
}
)
func getExpiresAt(expiresAt string) (time.Time, error) {
expiresDuration, found := expirationTimes[expiresAt]
if !found {
return time.Time{}, errors.New("invalid expiration time")
}
return time.Now().Add(expiresDuration), nil
}
func errorResponse(w http.ResponseWriter, status int, title, message string) {
w.WriteHeader(status)
component := views.Error(title, message)
component.Render(context.Background(), w)
}