mirror of https://github.com/jlelse/GoBlog
Short URLs
This commit is contained in:
parent
75a960e975
commit
9da9e37f32
|
@ -97,6 +97,15 @@ func migrateDb() error {
|
|||
return err
|
||||
},
|
||||
},
|
||||
&migrator.Migration{
|
||||
Name: "00008",
|
||||
Func: func(tx *sql.Tx) error {
|
||||
_, err := tx.Exec(`
|
||||
create table shortpath (id integer primary key autoincrement, path text not null, unique(path));
|
||||
`)
|
||||
return err
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
|
|
3
http.go
3
http.go
|
@ -173,6 +173,9 @@ func buildHandler() (http.Handler, error) {
|
|||
r.With(cacheMiddleware).Get(path, serveAsset)
|
||||
}
|
||||
|
||||
// Short paths
|
||||
r.With(cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", redirectToLongPath)
|
||||
|
||||
paginationPath := "/page/{page:[0-9-]+}"
|
||||
feedPath := ".{feed:rss|json|atom}"
|
||||
|
||||
|
|
1
posts.go
1
posts.go
|
@ -51,6 +51,7 @@ func servePost(w http.ResponseWriter, r *http.Request) {
|
|||
if canonical == "" {
|
||||
canonical = p.fullURL()
|
||||
}
|
||||
w.Header().Add("Link", fmt.Sprintf("<%s>; rel=shortlink", p.shortURL()))
|
||||
render(w, templatePost, &renderData{
|
||||
blogString: p.Blog,
|
||||
Canonical: canonical,
|
||||
|
|
|
@ -12,6 +12,14 @@ func (p *post) fullURL() string {
|
|||
return appConfig.Server.PublicAddress + p.Path
|
||||
}
|
||||
|
||||
func (p *post) shortURL() string {
|
||||
s, err := shortenPath(p.Path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return appConfig.Server.PublicAddress + s
|
||||
}
|
||||
|
||||
func (p *post) firstParameter(parameter string) (result string) {
|
||||
if pp := p.Parameters[parameter]; len(pp) > 0 {
|
||||
result = pp[0]
|
||||
|
|
|
@ -85,6 +85,9 @@ func initRendering() error {
|
|||
})
|
||||
return mentions
|
||||
},
|
||||
"shorturl": func(p *post) string {
|
||||
return p.shortURL()
|
||||
},
|
||||
// Others
|
||||
"dateformat": func(date string, format string) string {
|
||||
d, err := dateparse.ParseLocal(date)
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
)
|
||||
|
||||
func shortenPath(p string) (string, error) {
|
||||
if p == "" {
|
||||
return "", errors.New("empty path")
|
||||
}
|
||||
id := getShortPathID(p)
|
||||
if id == -1 {
|
||||
_, err := appDbExec("insert or ignore into shortpath (path) values (@path)", sql.Named("path", p))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
id = getShortPathID(p)
|
||||
}
|
||||
if id == -1 {
|
||||
return "", errors.New("failed to retrieve short path for " + p)
|
||||
}
|
||||
return fmt.Sprintf("/s/%x", id), nil
|
||||
}
|
||||
|
||||
func getShortPathID(p string) (id int) {
|
||||
if p == "" {
|
||||
return -1
|
||||
}
|
||||
row, err := appDbQueryRow("select id from shortpath where path = @path", sql.Named("path", p))
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
err = row.Scan(&id)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func redirectToLongPath(rw http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(chi.URLParam(r, "id"), 16, 64)
|
||||
if err != nil {
|
||||
serve404(rw, r)
|
||||
return
|
||||
}
|
||||
row, err := appDbQueryRow("select path from shortpath where id = @id", sql.Named("id", id))
|
||||
if err != nil {
|
||||
serve404(rw, r)
|
||||
return
|
||||
}
|
||||
var path string
|
||||
err = row.Scan(&path)
|
||||
if err != nil {
|
||||
serve404(rw, r)
|
||||
return
|
||||
}
|
||||
http.Redirect(rw, r, path, http.StatusFound)
|
||||
}
|
|
@ -35,7 +35,7 @@ func (p *post) tgPost() {
|
|||
message.WriteString(title)
|
||||
message.WriteString("\n\n")
|
||||
}
|
||||
message.WriteString(p.fullURL())
|
||||
message.WriteString(p.shortURL())
|
||||
sendTelegramMessage(message.String(), tg.BotToken, tg.ChatID)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{{ define "title" }}
|
||||
<title>{{ with p .Data "title" }}{{ . }} - {{end}}{{ .Blog.Title }}</title>
|
||||
{{ include "postheadmeta" . }}
|
||||
{{ with shorturl .Data }}<link rel="shortlink" href="{{ . }}">{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
|
|
Loading…
Reference in New Issue