mirror of
https://github.com/jimeh/ozu.io.git
synced 2026-02-19 08:06:39 +00:00
Initial commit
This commit is contained in:
29
main.go
Normal file
29
main.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/iris-contrib/middleware/logger"
|
||||
"github.com/kataras/iris"
|
||||
)
|
||||
|
||||
func main() {
|
||||
shortner := NewShortner()
|
||||
defer shortner.Close()
|
||||
|
||||
routes := Routes{Shortner: shortner}
|
||||
|
||||
iris.Use(logger.New(iris.Logger))
|
||||
iris.Get("/set/:key/:value", routes.Set)
|
||||
iris.Get("/get/:key", routes.Get)
|
||||
iris.Get("/shorten/:url", routes.Shorten)
|
||||
iris.Get("/lookup/:uid", routes.Lookup)
|
||||
iris.Get("/", routes.Root)
|
||||
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
|
||||
iris.Listen(":" + port)
|
||||
}
|
||||
54
routes.go
Normal file
54
routes.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package main
|
||||
|
||||
import "github.com/kataras/iris"
|
||||
|
||||
// Routes handles HTTP requests from iris.
|
||||
type Routes struct {
|
||||
Shortner *Shortner
|
||||
}
|
||||
|
||||
// Root returns the root.
|
||||
func (r *Routes) Root(c *iris.Context) {
|
||||
c.Write("hello world")
|
||||
}
|
||||
|
||||
// Get fetches a value for a given key.
|
||||
func (r *Routes) Get(c *iris.Context) {
|
||||
key := c.Param("key")
|
||||
value := r.Shortner.Get([]byte(key))
|
||||
c.Write(string(value))
|
||||
}
|
||||
|
||||
// Set writes a given value to the specified key.
|
||||
func (r *Routes) Set(c *iris.Context) {
|
||||
key := []byte(c.Param("key"))
|
||||
value := []byte(c.Param("value"))
|
||||
err := r.Shortner.Set(key, value)
|
||||
|
||||
if err == nil {
|
||||
c.Write("OK")
|
||||
} else {
|
||||
c.Log("ERROR: ", err.Error(), "\n")
|
||||
c.Write("Oops >_<")
|
||||
}
|
||||
}
|
||||
|
||||
// Shorten attempts to shorten a URL to a UID
|
||||
func (r *Routes) Shorten(c *iris.Context) {
|
||||
url := []byte(c.Param("url"))
|
||||
uid, err := r.Shortner.Shorten(url)
|
||||
|
||||
if err == nil {
|
||||
c.Write("Shortened: %s", uid)
|
||||
} else {
|
||||
c.Log("ERROR: ", err.Error(), "\n")
|
||||
c.Write("Oops >_<")
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup attempts to fetch previously shortened URLs based on UID
|
||||
func (r *Routes) Lookup(c *iris.Context) {
|
||||
uid := []byte(c.Param("uid"))
|
||||
url := r.Shortner.Lookup(uid)
|
||||
c.Write("URL: %s", url)
|
||||
}
|
||||
100
shortner.go
Normal file
100
shortner.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/jbenet/go-base58"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
// NewShortner returns a new Shortner.
|
||||
func NewShortner() *Shortner {
|
||||
db, err := leveldb.OpenFile("shortner.db", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return &Shortner{
|
||||
Db: db,
|
||||
KeyPrefix: []byte("url:"),
|
||||
}
|
||||
}
|
||||
|
||||
// Shortner shortens URLs.
|
||||
type Shortner struct {
|
||||
Db *leveldb.DB
|
||||
KeyPrefix []byte
|
||||
}
|
||||
|
||||
// Close calls Close() on the goleveldb.
|
||||
func (s *Shortner) Close() {
|
||||
err := s.Db.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get reads from the database.
|
||||
func (s *Shortner) Get(key []byte) []byte {
|
||||
value, _ := s.Db.Get(key, nil)
|
||||
return value
|
||||
}
|
||||
|
||||
// Set writes to the database.
|
||||
func (s *Shortner) Set(key []byte, value []byte) error {
|
||||
return s.Db.Put(key, value, nil)
|
||||
}
|
||||
|
||||
// Shorten shortens given URL
|
||||
func (s *Shortner) Shorten(url []byte) ([]byte, error) {
|
||||
uid, err := s.newUID()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
key := s.makeKey(uid)
|
||||
err = s.Set(key, url)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
return uid, nil
|
||||
}
|
||||
|
||||
// Lookup attempts to fetch the value for given UID
|
||||
func (s *Shortner) Lookup(uid []byte) []byte {
|
||||
return s.Get(s.makeKey(uid))
|
||||
}
|
||||
|
||||
func (s *Shortner) makeKey(uid []byte) []byte {
|
||||
return append(s.KeyPrefix, uid...)
|
||||
}
|
||||
|
||||
func (s *Shortner) newUID() ([]byte, error) {
|
||||
key := []byte("index")
|
||||
|
||||
tx, err := s.Db.OpenTransaction()
|
||||
defer tx.Commit()
|
||||
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
index, _ := tx.Get(key, nil)
|
||||
if index == nil {
|
||||
index = []byte("1")
|
||||
}
|
||||
|
||||
num, _ := strconv.Atoi(string(index))
|
||||
num++
|
||||
index = []byte(strconv.Itoa(num))
|
||||
|
||||
err = tx.Put(key, index, nil)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
uid := base58.Encode(index)
|
||||
return []byte(uid), nil
|
||||
}
|
||||
Reference in New Issue
Block a user