Auto generate short links if empty

This commit is contained in:
Ian Gulliver
2024-11-26 22:20:10 -06:00
parent 640e04f356
commit d9057f2aaa
4 changed files with 53 additions and 5 deletions

9
go.mod
View File

@@ -1,5 +1,10 @@
module github.com/gopatchy/shortlinks
go 1.22
go 1.22.0
require github.com/lib/pq v1.10.9
toolchain go1.23.3
require (
github.com/lib/pq v1.10.9
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
)

2
go.sum
View File

@@ -1,2 +1,4 @@
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=

36
main.go
View File

@@ -7,14 +7,17 @@ import (
"log"
"net/http"
"os"
"time"
_ "github.com/lib/pq"
"golang.org/x/exp/rand"
)
type ShortLinks struct {
tmpl *template.Template
mux *http.ServeMux
db *sql.DB
r *rand.Rand
}
type response struct {
@@ -33,6 +36,7 @@ func NewShortLinks(db *sql.DB) (*ShortLinks, error) {
tmpl: tmpl,
mux: http.NewServeMux(),
db: db,
r: rand.New(rand.NewSource(uint64(time.Now().UnixNano()))),
}
sl.mux.HandleFunc("GET /{$}", sl.serveRoot)
@@ -88,6 +92,14 @@ func (sl *ShortLinks) serveSet(w http.ResponseWriter, r *http.Request) {
short := r.Form.Get("short")
if short == "" {
short, err = sl.genShort()
if err != nil {
sendError(w, http.StatusInternalServerError, "genShort: %s", err)
return
}
}
long := r.Form.Get("long")
if long == "" {
sendError(w, http.StatusBadRequest, "long= param required")
@@ -110,6 +122,30 @@ DO UPDATE SET long = $2;
})
}
func (sl *ShortLinks) genShort() (string, error) {
for chars := 3; chars <= 10; chars++ {
b := make([]byte, chars)
for i := range b {
b[i] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[sl.r.Intn(62)]
}
short := string(b)
exists := false
err := sl.db.QueryRow("SELECT EXISTS(SELECT 1 FROM links WHERE short = $1)", short).Scan(&exists)
if err != nil {
return "", fmt.Errorf("check exists: %w", err)
}
if !exists {
return short, nil
}
}
return "", fmt.Errorf("no available short link found")
}
func main() {
port := os.Getenv("PORT")
if port == "" {

View File

@@ -87,7 +87,10 @@ async function set() {
document.getElementById('short-icon').setAttribute('name', 'check-square-fill');
document.getElementById('long-icon').setAttribute('name', 'check-square-fill');
if (short != '') {
setShortItem(short, 'check-square-fill');
}
const params = new URLSearchParams();
params.set('short', short);
@@ -98,14 +101,16 @@ async function set() {
});
if (resp.status !== 200) {
error('Failed to set', await resp.text());
error('Failed to set', (await resp.json()).message);
return;
}
const newShort = (await resp.json()).short;
if (document.getElementById('short').value == short && document.getElementById('long').value == long) {
document.getElementById('short-icon').setAttribute('name', 'check-square');
document.getElementById('long-icon').setAttribute('name', 'check-square');
setShortItem(short, 'check-square');
setShortItem(newShort, 'check-square');
}
}