Private pastes, systemd unit file, design updates.
It is now possible to create private pastes, just check approriate checkbox. Added systemd unit file. Don't forget to fix it for your needs! Updated design for pastes viewing, now paste information shows in table. Improves mobile experience at least :).
This commit is contained in:
@@ -53,7 +53,7 @@ var (
|
||||
regexInts = regexp.MustCompile("[0-9]+")
|
||||
)
|
||||
|
||||
// GET for "/paste/PASTE_ID".
|
||||
// GET for "/paste/PASTE_ID" and "/paste/PASTE_ID/TIMESTAMP" (private pastes).
|
||||
func pasteGET(ec echo.Context) error {
|
||||
errhtml, err := static.ReadFile("error.html")
|
||||
if err != nil {
|
||||
@@ -74,6 +74,23 @@ func pasteGET(ec echo.Context) error {
|
||||
return ec.HTML(http.StatusBadRequest, errhtmlAsString)
|
||||
}
|
||||
|
||||
// Check if we have a private paste and it's parameters are correct.
|
||||
if paste.Private {
|
||||
tsProvidedStr := ec.Param("timestamp")
|
||||
tsProvided, err2 := strconv.ParseInt(tsProvidedStr, 10, 64)
|
||||
if err2 != nil {
|
||||
c.Logger.Error().Msgf("Invalid timestamp '%s' provided for getting private paste #%d: %s", tsProvidedStr, pasteID, err2.Error())
|
||||
errhtmlAsString := strings.Replace(string(errhtml), "{error}", "Paste #"+strconv.Itoa(pasteID)+" not found", 1)
|
||||
return ec.HTML(http.StatusBadRequest, errhtmlAsString)
|
||||
}
|
||||
pasteTs := paste.CreatedAt.Unix()
|
||||
if tsProvided != pasteTs {
|
||||
c.Logger.Error().Msgf("Incorrect timestamp '%v' provided for private paste #%d, waiting for %v", tsProvidedStr, pasteID, strconv.FormatInt(pasteTs, 10))
|
||||
errhtmlAsString := strings.Replace(string(errhtml), "{error}", "Paste #"+strconv.Itoa(pasteID)+" not found", 1)
|
||||
return ec.HTML(http.StatusBadRequest, errhtmlAsString)
|
||||
}
|
||||
}
|
||||
|
||||
pasteHTML, err2 := static.ReadFile("paste.html")
|
||||
if err2 != nil {
|
||||
return ec.String(http.StatusNotFound, "parse.html wasn't found!")
|
||||
@@ -85,6 +102,12 @@ func pasteGET(ec echo.Context) error {
|
||||
pasteHTMLAsString = strings.Replace(pasteHTMLAsString, "{pasteDate}", paste.CreatedAt.Format("2006-01-02 @ 15:04:05"), 1)
|
||||
pasteHTMLAsString = strings.Replace(pasteHTMLAsString, "{pasteLanguage}", paste.Language, 1)
|
||||
|
||||
if paste.Private {
|
||||
pasteHTMLAsString = strings.Replace(pasteHTMLAsString, "{privateMode}", "Private", 1)
|
||||
} else {
|
||||
pasteHTMLAsString = strings.Replace(pasteHTMLAsString, "{privateMode}", "Public", 1)
|
||||
}
|
||||
|
||||
// Highlight.
|
||||
// Get lexer.
|
||||
lexer := lexers.Get(paste.Language)
|
||||
@@ -193,6 +216,12 @@ func pastePOST(ec echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Private paste?
|
||||
paste.Private = false
|
||||
if params["paste-private"][0] == "on" {
|
||||
paste.Private = true
|
||||
}
|
||||
|
||||
id, err2 := Save(paste)
|
||||
if err2 != nil {
|
||||
c.Logger.Debug().Msgf("Failed to save paste: %s", err2.Error())
|
||||
@@ -202,6 +231,12 @@ func pastePOST(ec echo.Context) error {
|
||||
|
||||
newPasteIDAsString := strconv.FormatInt(id, 10)
|
||||
c.Logger.Debug().Msgf("Paste saved, URL: /paste/" + newPasteIDAsString)
|
||||
|
||||
// Private pastes have it's timestamp in URL.
|
||||
if paste.Private {
|
||||
return ec.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString+"/"+strconv.FormatInt(paste.CreatedAt.Unix(), 10))
|
||||
}
|
||||
|
||||
return ec.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString)
|
||||
}
|
||||
|
||||
|
@@ -41,11 +41,16 @@ func New(cc *context.Context) {
|
||||
// New paste.
|
||||
c.Echo.POST("/paste/", pastePOST)
|
||||
|
||||
// Show paste.
|
||||
// Show public paste.
|
||||
c.Echo.GET("/paste/:id", pasteGET)
|
||||
// Show RAW.
|
||||
// Show RAW representation of public paste.
|
||||
c.Echo.GET("/paste/:id/raw", pasteRawGET)
|
||||
|
||||
// Show private paste.
|
||||
c.Echo.GET("/paste/:id/:timestamp", pasteGET)
|
||||
// Show RAW representation of private paste.
|
||||
c.Echo.GET("/paste/:id/:timestamp/raw", pasteRawGET)
|
||||
|
||||
// Pastes list.
|
||||
c.Echo.GET("/pastes/", pastesGET)
|
||||
c.Echo.GET("/pastes/:page", pastesGET)
|
||||
|
@@ -56,6 +56,5 @@ type Paste struct {
|
||||
KeepFor int `db:"keep_for"`
|
||||
KeepForUnitType int `db:"keep_for_unit_type"`
|
||||
Language string `db:"language"`
|
||||
Private bool `db:"private"`
|
||||
}
|
||||
|
||||
func (p *Paste) Highlight() {}
|
||||
|
@@ -52,7 +52,7 @@ func GetPagedPastes(page int) ([]Paste, error) {
|
||||
startPagination = (page - 1) * PAGINATION
|
||||
}
|
||||
|
||||
err := dbConn.Select(&pastes, dbConn.Rebind("SELECT * FROM `pastes` ORDER BY id DESC LIMIT ? OFFSET ?"), PAGINATION, startPagination)
|
||||
err := dbConn.Select(&pastes, dbConn.Rebind("SELECT * FROM `pastes` WHERE private != true ORDER BY id DESC LIMIT ? OFFSET ?"), PAGINATION, startPagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func GetPastesPages() int {
|
||||
// Save saves paste to database and returns it's ID.
|
||||
func Save(p *Paste) (int64, error) {
|
||||
dbConn := c.Database.GetDatabaseConnection()
|
||||
result, err := dbConn.NamedExec("INSERT INTO `pastes` (title, data, created_at, keep_for, keep_for_unit_type, language) VALUES (:title, :data, :created_at, :keep_for, :keep_for_unit_type, :language)", p)
|
||||
result, err := dbConn.NamedExec("INSERT INTO `pastes` (title, data, created_at, keep_for, keep_for_unit_type, language, private) VALUES (:title, :data, :created_at, :keep_for, :keep_for_unit_type, :language, :private)", p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user