You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
package shrty
|
|
|
|
import (
|
|
"fmt"
|
|
"crypto/sha256"
|
|
"time"
|
|
"encoding/json"
|
|
)
|
|
|
|
type Data struct {
|
|
URL string `json:"url"`
|
|
URLFetched string `json:"url_fetched"`
|
|
CanonicalURL string `json:"canonical_url"`
|
|
OriginalURL string `json:"original_url"`
|
|
Domain string `json:"domain"`
|
|
Hash string `json:"hash"`
|
|
Token string `json:"token"`
|
|
Meta `json:"meta"`
|
|
FavIconLink string `json:"favicon_url"`
|
|
HTTPStatusCode string `json:"http_code"`
|
|
Category string `json:"category"`
|
|
Created string `json:"created_at"`
|
|
Clicks int64 `json:"clicks"`
|
|
}
|
|
|
|
type Meta struct{
|
|
Title string `json:"title"meta:"og:title"`
|
|
Image string `json:"image"meta:"og:image"`
|
|
Description string `json:"description"meta:"og:description"`
|
|
Type string `json:"type"meta:"og:type"`
|
|
}
|
|
|
|
func (s *Store) Short(URL string, value *string) error {
|
|
d := &Data{
|
|
URL: URL,
|
|
}
|
|
|
|
err := CheckURL(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create a sha256 Hash from the URL
|
|
d.Hash = fmt.Sprintf("%x", sha256.Sum256([]byte(d.OriginalURL)))
|
|
|
|
// Check if the URL already in the Storage
|
|
if ok := s.Exist(d); ok {
|
|
*value = d.Token
|
|
return nil
|
|
}
|
|
|
|
// Iterate to the length of the hash to get the shortest output
|
|
for hashShortestLen := 1; hashShortestLen <= 32; hashShortestLen++ {
|
|
// Test if the Token not exist and return the new generated token
|
|
if _, ok := s.Token[d.Hash[:hashShortestLen]]; !ok {
|
|
d.Token = d.Hash[:hashShortestLen]
|
|
d.Created = time.Now().String()
|
|
|
|
s.Token[d.Token] = d
|
|
s.Url[d.Hash] = d.Token
|
|
*value = d.Token
|
|
|
|
s.Save()
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return ErrCreateToken
|
|
}
|
|
|
|
// URL already Exist in the
|
|
func (s *Store) Exist(d *Data) bool {
|
|
if val, ok := s.Url[d.Hash]; ok {
|
|
d = s.Token[val]
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Returns the URL for the given token
|
|
func (s *Store) Redirect(token string) (string, bool) {
|
|
if shrt, ok := s.Token[token]; ok {
|
|
s.Token[token].Clicks += 1
|
|
s.Save()
|
|
return shrt.OriginalURL, true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
// Get Data for the given Token
|
|
func (s *Store) Get(token string, value *Data) bool {
|
|
if data, ok := s.Token[token]; ok {
|
|
*value = *data
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Get all entries
|
|
func (s *Store) GetAll() string {
|
|
b, err := json.Marshal(&s)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(b)
|
|
} |