contented/Metadata.go

103 lines
1.9 KiB
Go

package contented
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/speps/go-hashids"
bolt "go.etcd.io/bbolt"
)
const (
hashIdSalt = "contented"
hashIdMinLength = 2
)
type Metadata struct {
FileHash string
FileSize int64
UploadTime time.Time
UploadIP string
Filename string
MimeType string
}
func (this *Server) Metadata(fileID string) (*Metadata, error) {
var m Metadata
err := this.db.View(func(tx *bolt.Tx) error {
content := tx.Bucket(this.metadataBucket).Get([]byte(fileID))
if len(content) == 0 {
return os.ErrNotExist
}
return json.Unmarshal(content, &m)
})
if err != nil {
return nil, err
}
return &m, nil
}
func idToString(v uint64) string {
hd := hashids.NewData()
hd.Salt = hashIdSalt
hd.MinLength = hashIdMinLength
h := hashids.NewWithData(hd)
s, _ := h.EncodeInt64([]int64{int64(v)})
return s
}
func (this *Server) AddMetadata(m Metadata) (string, error) {
jb, err := json.Marshal(m)
if err != nil {
return "", err
}
var shortRef string = ""
err = this.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket(this.metadataBucket)
seq, err := b.NextSequence()
if err != nil {
return fmt.Errorf("NextSequence: %w", err)
}
shortRef = idToString(seq)
if b.Get([]byte(shortRef)) != nil {
return fmt.Errorf("Next bucket sequence %d creates colliding ID %s", seq, shortRef)
}
return b.Put([]byte(shortRef), jb)
})
if err != nil {
return "", err
}
if shortRef == "" {
return "", errors.New("Invalid URL generated")
}
return shortRef, nil
}
func (this *Server) handleInformation(w http.ResponseWriter, fileID string) {
m, err := this.Metadata(fileID)
if err != nil {
if os.IsNotExist(err) {
http.Error(w, "Not found", 404)
return
}
log.Println(err.Error())
http.Error(w, "Internal error", 500)
return
}
this.serveJsonObject(w, m)
}