From 9d4d1cae6d2bd230107bf9446c37fad30f27f622 Mon Sep 17 00:00:00 2001 From: kreativmonkey Date: Fri, 12 May 2017 22:55:42 +0200 Subject: [PATCH] constance --- main.go | 79 +++++++++++++++++++++++++-------------------------- short/shrt.go | 62 +++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 51 deletions(-) diff --git a/main.go b/main.go index 93a8246..b0a9539 100644 --- a/main.go +++ b/main.go @@ -2,65 +2,62 @@ package main import ( "net/http" - "fmt" - "text/template" - "github.com/kreativmonkey/shrt/short" + //"github.com/spf13/viper" + shorty "github.com/kreativmonkey/shrt/short" "log" + "fmt" ) -type Page struct { - Host string - Title string - Body string -} +const version = "0.01" +const port = "9090" +const db = "./test.db" var ( - short *shrt.Storage + short *shorty.Storage ) func init() { var err error - short, err = shrt.Open() + short, err = shorty.Open(db) if err != nil { panic(err) } + /* + viper.SetDefault("ContentDir", "content") + viper.SetDefault("Token", map[string]string{"url": "url", "token": "token"}) + + viper.SetConfigName("config") // name of config file (without expression) + viper.AddConfigPath("/etc/appname/") // path to look for the config file in + viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths + viper.AddConfigPath(".") // optionally look for config in the working directory + err = viper.ReadInConfig() // Find and read the config file + if err != nil { // Handle errors reading the config file + panic(fmt.Errorf("Fatal error config file: %s \n", err)) + }*/ } -func index(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case "GET": - if redirect, ok := short.Get(r.URL.Path[1:]); ok{ - http.Redirect(w, r, string(redirect), 301) - fmt.Printf("Token: %s Redirect to: %s \n", string(r.URL.Path[1:]), redirect) - } else { - t, _ := template.ParseFiles("template/index.gohtml") - t.Execute(w, Page{Title: "Shrt"}) - } - case "POST": - var test string - token, err := short.Add(r.FormValue("url"), &test) - if err != nil { - panic(err) - } - P := Page{Title: "Url:", Body: r.Host + "/" + token} - t, _ := template.ParseFiles("template/index.gohtml") - t.Execute(w, P) - } - -} - -func all(w http.ResponseWriter, r *http.Request) { - t, _ := template.New("all").Parse("{{.}}") - t.Execute(w, short.All()) +type shrt struct { + Token string `bson:"token" json:"token"` + URL string `bson:"url" json:"url"` + Date string `bson:"url_ending" json:"url_ending"` + Count int64 `bson:"click" json:"click"` } func main() { - http.HandleFunc("/", index) // setting router rule - http.HandleFunc("/all", all) // setting router rule - http.HandleFunc("/put", index) // setting router rule - err := http.ListenAndServe(":9090", nil) // setting listening port + http.HandleFunc("/", index) // render form for Input + http.HandleFunc("/{token}", redirect) // request token for redirect URL + http.HandleFunc("/shorten", shorten) // render Page for shorten URL + http.HandleFunc("/all", all) // render all in a json + http.HandleFunc("/api/action/shorten", shortenJSON) // setting router rule + http.HandleFunc("/api/action/lookup", lookup) // setting router rule + + http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("template/css")))) + http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("template/img")))) + err := http.ListenAndServe(":"+port, nil) // setting listening port if err != nil { log.Fatal("ListenAndServe: ", err) } -} \ No newline at end of file + fmt.Printf("Shrt %s started on Port: %s", version, port) +} + diff --git a/short/shrt.go b/short/shrt.go index 86663b2..9e5c0ab 100644 --- a/short/shrt.go +++ b/short/shrt.go @@ -9,17 +9,18 @@ import ( "os" "io" "bytes" + "time" ) type Storage struct { - Token map[string]*shrt - Url map[string]string + Token map[string]*shrt `json:"token"` + Url map[string]string `json:"url"` } type shrt struct { - URL string - Datum string - Count int64 + URL string `json:"url"` + Datum string `json:"datum"` + Count int64 `json:"count"` } var ( @@ -28,10 +29,11 @@ var ( ErrNoUrl = errors.New("String is no Url!") ) -func Open() (*Storage, error){ +// Open up +func Open(path string) (*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 { + if db, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644); err == nil { json.Unmarshal(StreamToByte(db), &s) db.Close() return &s, nil @@ -40,7 +42,42 @@ func Open() (*Storage, error){ } } -func (s *Storage) Add(URL string, value interface{}) (string, error) { +func (s *Storage) Short(URL string, value *string) (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] + t := time.Now() + s.Token[token] = &shrt{ + URL: URL, + Datum: t.String(), + } + s.Url[hash] = token + *value = s.Url[hash] + s.Save() + return token, nil + } + } + + return "", ErrCreateToken +} + +func (s *Storage) Add(URL string, value *string) (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) @@ -60,9 +97,13 @@ func (s *Storage) Add(URL string, value interface{}) (string, error) { // 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} + t := time.Now() + s.Token[token] = &shrt{ + URL: URL, + Datum: t.String(), + } s.Url[hash] = token - value = s.Url[hash] + *value = s.Url[hash] s.Save() return token, nil } @@ -86,6 +127,7 @@ func (s *Storage) Get(token string) (string, bool) { return "", false } +// Get all entries func (s *Storage) All() (string) { b, err := json.Marshal(&s) if err != nil {