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

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)
}