Files
primal bd76ea1108 Trim shortener.go - keep only URL creation, remove click tracking
Click tracking now handled by tracker service.
Reduced from 250 to 79 lines.
2026-02-02 13:28:10 -05:00

80 lines
2.1 KiB
Go

package main
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"strings"
"time"
)
// generateShortCode creates a short code from a URL
// Uses first 6 characters of base64-encoded SHA256 hash
func generateShortCode(url string) string {
hash := sha256.Sum256([]byte(url))
encoded := base64.URLEncoding.EncodeToString(hash[:])
// Take first 6 chars, replace URL-unsafe chars
code := encoded[:6]
code = strings.ReplaceAll(code, "-", "x")
code = strings.ReplaceAll(code, "_", "y")
return code
}
// CreateShortURL creates or retrieves a short URL for the given original URL
func (c *Crawler) CreateShortURL(originalURL string, itemGUID, feedURL string) (string, error) {
// Check if we already have this URL
var existingCode string
err := c.db.QueryRow(`
SELECT code FROM short_urls WHERE original_url = $1
`, originalURL).Scan(&existingCode)
if err == nil {
return existingCode, nil
}
// Generate new short code
code := generateShortCode(originalURL)
// Handle collision by appending counter
baseCode := code
for i := 0; i < 100; i++ {
if i > 0 {
code = fmt.Sprintf("%s%d", baseCode, i)
}
var existingURL string
err := c.db.QueryRow("SELECT original_url FROM short_urls WHERE code = $1", code).Scan(&existingURL)
if err != nil {
// Code doesn't exist, use it
break
}
if existingURL == originalURL {
// Same URL, return existing
return code, nil
}
// Collision with different URL, try next
}
// Insert new short URL
_, err = c.db.Exec(`
INSERT INTO short_urls (code, original_url, item_guid, feed_url, created_at, click_count)
VALUES ($1, $2, $3, $4, $5, 0)
`, code, originalURL, NullableString(itemGUID), NullableString(feedURL), time.Now())
if err != nil {
return "", fmt.Errorf("failed to create short URL: %v", err)
}
return code, nil
}
// GetShortURLForPost returns the short URL string for use in posts
// Format: https://news.1440.news/{code}
func (c *Crawler) GetShortURLForPost(originalURL, itemGUID, feedURL string) (string, error) {
code, err := c.CreateShortURL(originalURL, itemGUID, feedURL)
if err != nil {
return "", err
}
return fmt.Sprintf("https://news.1440.news/%s", code), nil
}