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.
		
		
		
		
		
			
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
| package shrt
 | |
| 
 | |
| import (
 | |
|   "fmt"
 | |
|   "crypto/sha256"
 | |
|   "errors"
 | |
|   "encoding/json"
 | |
|   "net/url"
 | |
|   "os"
 | |
|   "io"
 | |
|   "bytes"
 | |
| )
 | |
| 
 | |
| type Storage struct  {
 | |
|   Token map[string]*shrt
 | |
|   Url map[string]string
 | |
| }
 | |
| 
 | |
| type shrt struct {
 | |
|   URL string
 | |
|   Datum string
 | |
|   Count int64
 | |
| }
 | |
| 
 | |
| var (
 | |
|   ErrNotFound = errors.New("Url not Found")
 | |
|   ErrCreateToken = errors.New("There are some problems while creating Token")
 | |
|   ErrNoUrl = errors.New("String is no Url!")
 | |
| )
 | |
| 
 | |
| func Open() (*Storage, error){
 | |
|   s := Storage{Token: make(map[string]*shrt), Url: make(map[string]string)}
 | |
|   // Open db ore create if not exist!
 | |
|   if db, err := os.OpenFile("./test.db", os.O_RDWR|os.O_CREATE, 0644); err == nil {
 | |
|     json.Unmarshal(StreamToByte(db), &s)
 | |
|     db.Close()
 | |
|     return &s, nil
 | |
|   } else {
 | |
|     return &s, err
 | |
|   }
 | |
| }
 | |
| 
 | |
| func (s *Storage) Add(URL string, value interface{}) (string, error) {
 | |
|   // Check if it is a valide Url found on:
 | |
|   // http://stackoverflow.com/questions/31480710/validate-url-with-standard-package-in-go
 | |
|   _, err := url.ParseRequestURI(URL)
 | |
|   if err != nil {
 | |
|     return "", ErrNoUrl
 | |
|   }
 | |
| 
 | |
|   // Create a sha256 Hash from the URL
 | |
|   hash := fmt.Sprintf("%x", sha256.Sum256([]byte(URL)))
 | |
| 
 | |
|   // Test if the URL alraedy exist and return the key
 | |
|   if val, ok := s.Url[hash]; ok {
 | |
|     return val, nil
 | |
|   }
 | |
|   // Iterate to the length of 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[hash[:hashShortestLen]]; !ok {
 | |
|       token := hash[:hashShortestLen]
 | |
|       s.Token[token] = &shrt{URL: URL}
 | |
|       s.Url[hash] = token
 | |
|       value = s.Url[hash]
 | |
|       s.Save()
 | |
|       return token, nil
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  return "", ErrCreateToken
 | |
| }
 | |
| 
 | |
| func (s *Storage) Remove(URL string) error {
 | |
|   return nil
 | |
| }
 | |
| 
 | |
| // Get returns the URL for the given token
 | |
| func (s *Storage) Get(token string) (string, bool) {
 | |
|   if shrt, ok := s.Token[token]; ok {
 | |
|     fmt.Printf("Url mit dem Token %s gefunden: %s \n", token, shrt.URL)
 | |
|     s.Token[token].Count += 1
 | |
|     s.Save()
 | |
|     return shrt.URL, true
 | |
|   }
 | |
|   return "", false
 | |
| }
 | |
| 
 | |
| func (s *Storage) All() (string) {
 | |
|   b, err := json.Marshal(&s)
 | |
|   if err != nil {
 | |
|     return ""
 | |
|   }
 | |
|   return string(b)
 | |
| }
 | |
| 
 | |
| func (s *Storage) Save() error {
 | |
|   if db, err := os.OpenFile("./test.db", os.O_RDWR|os.O_CREATE, 0644); err == nil {
 | |
|     b, err := json.Marshal(&s)
 | |
|     db.Write(b)
 | |
|     db.Close()
 | |
|     return err
 | |
|   } else {
 | |
|     return err
 | |
|   }
 | |
| }
 | |
| 
 | |
| func StreamToByte(stream io.Reader) []byte {
 | |
|   buf := new(bytes.Buffer)
 | |
|   buf.ReadFrom(stream)
 | |
|   return buf.Bytes()
 | |
| }
 |