First version with Storage and Counter

master
kreativmonkey 8 years ago
parent 6c4196cb91
commit 315dd5e62f

@ -1,81 +0,0 @@
package shrt
import (
//"github.com/asaskevich/govalidator"
"fmt"
"crypto/sha256"
"errors"
"io"
"bytes"
)
type Storage struct {
Token map[string]string `json: tokens`
Url map[string]shrt `json: urls`
}
type shrt struct {
URL string
Token string
count int
}
var (
ErrNotFound = errors.New("Url not Found")
ErrCreateToken = errors.New("There are some problems while creating Token")
)
func Open() (*Storage, error){
// Open db ore create if not exist!
s := Storage{Token: make(map[string]string), Url: make(map[string]shrt)}
return &s, nil
}
func StreamToByte(stream io.Reader) []byte {
buf := new(bytes.Buffer)
buf.ReadFrom(stream)
return buf.Bytes()
}
func (s *Storage) Add(URL string, value interface{}) (string, error) {
// if the URL a valid URL?
/*if !govalidator.IsURL(URL) {
return "", errors.New("invalid url")
} */
// 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.Token, 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] = hash
s.Url[hash] = shrt{URL: URL, Token: token}
value = s.Url[hash]
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, value interface{}) bool {
if hash, ok := s.Token[token]; ok {
fmt.Printf("Url gefunden %s mit Hash: %v \n", s.Url[hash].URL, hash)
value = s.Url[hash].URL
fmt.Printf("Value: %V \n", value)
return true
}
return false
}

@ -3,9 +3,10 @@ package main
import (
"net/http"
"fmt"
"text/template"
"github.com/kreativmonkey/shrt/short"
"log"
"html/template"
"github.com/kreativmonkey/shrt/lib"
)
type Page struct {
@ -30,25 +31,21 @@ func index(w http.ResponseWriter, r *http.Request) {
fmt.Println("Path: ", r.URL.Path[1:])
switch r.Method {
case "GET":
var redirect string
if ok := short.Get(r.URL.Path[1:], &redirect); ok{
P := Page{Title: ToString(r.URL.Path[1:]), Body: redirect}
fmt.Printf("Redirect: %s \n", redirect)
t, _ := template.ParseFiles("template/index.gohtml")
t.Execute(w, P)
fmt.Println("Url by Token:", P)
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 {
P := Page{Title: "All: ", Body: short.All ()}
t, _ := template.ParseFiles("template/index.gohtml")
t.Execute(w, nil)
t.Execute(w, P)
}
case "POST":
r.ParseForm()
var test string
token, err := short.Add(ToString(r.Form["url"]), &test)
token, err := short.Add(r.FormValue("url"), &test)
if err != nil {
panic(err)
}
P := Page{Title: ToString(r.Form["url"]), Body: token}
P := Page{Title: r.FormValue("url"), Body: token}
t, _ := template.ParseFiles("template/index.gohtml")
t.Execute(w, P)
fmt.Println("Token by Url:", P)
@ -56,10 +53,6 @@ func index(w http.ResponseWriter, r *http.Request) {
}
func handelPost(w http.ResponseWriter, r *http.Request){
}
func main() {
http.HandleFunc("/", index) // setting router rule
err := http.ListenAndServe(":9090", nil) // setting listening port
@ -67,9 +60,3 @@ func main() {
log.Fatal("ListenAndServe: ", err)
}
}
// ToString convert the input to a string.
func ToString(obj interface{}) string {
res := fmt.Sprintf("%s", obj)
return string(res)
}

@ -0,0 +1,112 @@
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()
}

@ -2,14 +2,57 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<title>Shrt</title>
<style>
#main {
width: 1170px;
margin: 0 auto;
text-align: center;
}
h1 {
font-size: 67px;
line-height: 1;
margin: 21px 0 10px 0;
}
form {
display: block;
margin-top: 0em;
}
form input {
padding: 7px;
font-size: 12px;
display: block;
width: 100%;
margin-bottom: 10px;
}
form button {
display: inline-block;
margin-bottom: 0;
font-size: 15px;
font-weight: normal;
line-height: 1.428571429;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-image: none;
border: 1px solid transparent;
border-radius: 0;
color: #fff;
padding: 14px 28px;
background-color: #39b3d7;
border-color: #269abc;
}
</style>
</head>
<body>
<div id="main">
<h1>Shrt</h1>
<form id="shorten" action="./" method="post">
<input type="text" name="url" placeholder="Url to shorten!" required="">
<input type="url" name="url" pattern="^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?" placeholder="Url to shorten!" required="" autofocus>
<button class="button" type="submit" name="submit" value="short">Kürzen</button>
</form>
</div>
<p>Current URL: {{.}}</p>
</body>

Loading…
Cancel
Save