use-redis
Chakib Benziane 5 years ago
commit e449299304

@ -0,0 +1,14 @@
TARGET := bit4sat
GOINSTALL := GO111MODULE=on go install -v
GOBUILD := GO111MODULE=on go build -v
.PHONY: all build install
all: build
build:
$(GOBUILD) -o $(TARGET)
install:
$(GOINSTALL)

@ -0,0 +1,33 @@
package main
import (
"git.sp4ke.com/sp4ke/bit4sat-server.git/storage"
"github.com/gin-gonic/gin"
)
var (
UploadCtrl = storage.UploadCtrl{}
)
type API struct {
router *gin.Engine
}
func (api *API) Run() {
uploadRoute := api.router.Group("/upload")
{
uploadRoute.POST("/", UploadCtrl.New)
uploadRoute.PUT("/:id", UploadCtrl.Upload)
}
api.router.Run(":8880")
}
func NewAPI() *API {
return &API{
router: gin.Default(),
}
}

@ -0,0 +1,74 @@
package db
import (
"fmt"
"log"
"net/url"
"os"
"path/filepath"
"git.sp4ke.com/sp4ke/bit4sat-server.git/utils"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
)
const (
DBName = "bit4sat.sqlite"
DBPath = "db-storage"
DBPathEnv = "BIT4SAT_DB_PATH"
DBPragma = ` PRAGMA foreign_keys = ON; `
)
var (
DBOptions = map[string]string{
"_journal_mode": "WAL",
}
DB *Database
)
type Database struct {
Handle *sqlx.DB
}
func (d *Database) Open() error {
dsnOptions := &url.Values{}
for k, v := range DBOptions {
dsnOptions.Set(k, v)
}
// Get db base path
path, set := os.LookupEnv(DBPathEnv)
if !set {
path = DBPath
}
// Create path if not exists
err := utils.Mkdir(path)
if err != nil {
log.Fatal(err)
}
path = filepath.Join(path, DBName)
//path = fmt.Sprintf("%s/%s", path, DBName)
dsn := fmt.Sprintf("file:%s?%s", path, dsnOptions.Encode())
log.Printf("Opening sqlite db %s\n", dsn)
d.Handle, err = sqlx.Open("sqlite3", dsn)
if err != nil {
log.Fatal(err)
}
// Execute Pragmas
d.Handle.MustExec(DBPragma)
return nil
}
func init() {
DB = &Database{}
DB.Open()
}

@ -0,0 +1,16 @@
module git.sp4ke.com/sp4ke/bit4sat-server.git
go 1.12
require (
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/golang/protobuf v1.3.1 // indirect
github.com/jmoiron/sqlx v1.2.0
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/mattn/go-sqlite3 v1.10.0
github.com/segmentio/ksuid v1.0.2
github.com/ugorji/go/codec v0.0.0-20190315113641-a70535d8491c // indirect
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)

@ -0,0 +1,28 @@
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc=
github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU=
github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go/codec v0.0.0-20190315113641-a70535d8491c h1:20Yyqg0mvFOyG3m7ejVqHEa03CBa3hTttx9jiYLkjYU=
github.com/ugorji/go/codec v0.0.0-20190315113641-a70535d8491c/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -0,0 +1,11 @@
package main
import "git.sp4ke.com/sp4ke/bit4sat-server.git/db"
func main() {
defer db.DB.Handle.Close()
api := NewAPI()
api.Run()
}

@ -0,0 +1,26 @@
package storage
import (
"log"
"os"
"git.sp4ke.com/sp4ke/bit4sat-server.git/utils"
)
const (
StoragePath = "storage"
StoragePathEnv = "BIT4SAT_STORAGE_PATH"
)
func init() {
path, set := os.LookupEnv(StoragePathEnv)
if !set {
path = StoragePath
}
err := utils.Mkdir(path)
if err != nil {
log.Fatal(err)
}
}

@ -0,0 +1,70 @@
package storage
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/segmentio/ksuid"
)
type UploadCtrl struct{}
func (ctrl UploadCtrl) New(c *gin.Context) {
uploadForm := UploadForm{}
up := &Upload{}
if err := c.ShouldBindJSON(&uploadForm); err != nil {
c.JSON(http.StatusNotAcceptable, gin.H{
"status": http.StatusNotAcceptable,
"error": err,
})
}
// Create unique id
id := ksuid.New()
up.ID = id.String()
// Save new upload
err := up.Write()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": http.StatusInternalServerError,
"error": "could not start new upload",
"msg": err.Error(),
})
c.Abort()
return
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"result": gin.H{
"id": up.ID,
},
})
}
func (ctrl UploadCtrl) Upload(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.JSON(http.StatusNotAcceptable, gin.H{
"status": http.StatusNotAcceptable,
"error": err.Error(),
})
c.Abort()
return
}
files := form.File["upload[]"]
for _, file := range files {
fmt.Println(file.Filename)
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"result": fmt.Sprintf("%d files uploaded uploaded !", len(files)),
})
}

@ -0,0 +1,16 @@
package storage
import "time"
type File struct {
Name string
SHA256 string
Size int64
}
type UploadForm struct {
Files []File `form:"files" binding:"required"`
// Default time.RFC3339
TimeStamp time.Time `form:"timestamp"`
}

@ -0,0 +1,55 @@
package storage
import (
"errors"
"log"
"git.sp4ke.com/sp4ke/bit4sat-server.git/db"
"github.com/mattn/go-sqlite3"
)
var DB = db.DB
const (
DBUploadSchema = `
CREATE TABLE IF NOT EXISTS "upload" (
"upload_id" TEXT NOT NULL,
"path" TEXT DEFAULT '',
PRIMARY KEY("upload_id")
);
`
QNewUpload = `INSERT INTO upload (upload_id) VALUES (:upload_id)`
)
var (
ErrDoesNotExist = errors.New("does not exist")
ErrAlreadyExists = errors.New("already exists")
)
type Upload struct {
ID string `db:"upload_id"`
Path string
}
func (u *Upload) Write() error {
_, err := DB.Handle.NamedExec(QNewUpload, u)
sqlErr, isSqlErr := err.(sqlite3.Error)
if isSqlErr && sqlErr.Code == sqlite3.ErrConstraint {
return ErrAlreadyExists
}
if err != nil {
return err
}
return nil
}
func init() {
_, err := DB.Handle.Exec(DBUploadSchema)
if err != nil {
log.Fatal(err)
}
}

@ -0,0 +1,16 @@
package utils
import (
"os"
"path/filepath"
)
const (
MkdirMode = 0770
)
func Mkdir(path ...string) error {
joined := filepath.Join(path...)
return os.MkdirAll(joined, MkdirMode)
}
Loading…
Cancel
Save