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:
2018-05-01 22:56:45 +05:00
parent 64c2d62a49
commit c926a58276
16 changed files with 183 additions and 26 deletions

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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() {}

View File

@@ -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
}