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
|
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 {
|
if err != nil {
|
||||||
|
|
3
http.go
3
http.go
|
@ -173,6 +173,9 @@ func buildHandler() (http.Handler, error) {
|
||||||
r.With(cacheMiddleware).Get(path, serveAsset)
|
r.With(cacheMiddleware).Get(path, serveAsset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Short paths
|
||||||
|
r.With(cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", redirectToLongPath)
|
||||||
|
|
||||||
paginationPath := "/page/{page:[0-9-]+}"
|
paginationPath := "/page/{page:[0-9-]+}"
|
||||||
feedPath := ".{feed:rss|json|atom}"
|
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 == "" {
|
if canonical == "" {
|
||||||
canonical = p.fullURL()
|
canonical = p.fullURL()
|
||||||
}
|
}
|
||||||
|
w.Header().Add("Link", fmt.Sprintf("<%s>; rel=shortlink", p.shortURL()))
|
||||||
render(w, templatePost, &renderData{
|
render(w, templatePost, &renderData{
|
||||||
blogString: p.Blog,
|
blogString: p.Blog,
|
||||||
Canonical: canonical,
|
Canonical: canonical,
|
||||||
|
|
|
@ -12,6 +12,14 @@ func (p *post) fullURL() string {
|
||||||
return appConfig.Server.PublicAddress + p.Path
|
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) {
|
func (p *post) firstParameter(parameter string) (result string) {
|
||||||
if pp := p.Parameters[parameter]; len(pp) > 0 {
|
if pp := p.Parameters[parameter]; len(pp) > 0 {
|
||||||
result = pp[0]
|
result = pp[0]
|
||||||
|
|
|
@ -85,6 +85,9 @@ func initRendering() error {
|
||||||
})
|
})
|
||||||
return mentions
|
return mentions
|
||||||
},
|
},
|
||||||
|
"shorturl": func(p *post) string {
|
||||||
|
return p.shortURL()
|
||||||
|
},
|
||||||
// Others
|
// Others
|
||||||
"dateformat": func(date string, format string) string {
|
"dateformat": func(date string, format string) string {
|
||||||
d, err := dateparse.ParseLocal(date)
|
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(title)
|
||||||
message.WriteString("\n\n")
|
message.WriteString("\n\n")
|
||||||
}
|
}
|
||||||
message.WriteString(p.fullURL())
|
message.WriteString(p.shortURL())
|
||||||
sendTelegramMessage(message.String(), tg.BotToken, tg.ChatID)
|
sendTelegramMessage(message.String(), tg.BotToken, tg.ChatID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{{ define "title" }}
|
{{ define "title" }}
|
||||||
<title>{{ with p .Data "title" }}{{ . }} - {{end}}{{ .Blog.Title }}</title>
|
<title>{{ with p .Data "title" }}{{ . }} - {{end}}{{ .Blog.Title }}</title>
|
||||||
{{ include "postheadmeta" . }}
|
{{ include "postheadmeta" . }}
|
||||||
|
{{ with shorturl .Data }}<link rel="shortlink" href="{{ . }}">{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
|
|
Loading…
Reference in New Issue