You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bit4sat/api/download.go

203 lines
4.6 KiB
Go

package api
import (
"encoding/gob"
"fmt"
"log"
"net/http"
"time"
"git.sp4ke.com/sp4ke/bit4sat/ln"
"git.sp4ke.com/sp4ke/bit4sat/storage"
"git.sp4ke.com/sp4ke/bit4sat/utils"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
func download(c *gin.Context) {
var ok bool
dlId := c.Param("dlId")
// Get upload id for dl id
upId, err := storage.GetUploadIdForDlId(dlId)
if err != nil {
utils.JSONErr(c, http.StatusNotFound, "this file does not exist anymore")
return
}
// Get the download session
session, err := SessionStore.Get(c.Request, DlSessionKey)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
dlSess := session.Values["session-id"]
dlIdVal := session.Values["dlId"]
var sessDlId string
// If no dlId was stored before than this is a new download
if dlIdVal == nil {
sessDlId = dlId
} else {
if sessDlId, ok = dlIdVal.(string); !ok {
log.Printf("cannot cast sessDlId value")
utils.JSONErr(c, http.StatusExpectationFailed,
"start a new download session session")
return
}
}
// Test if we are alread in a download session
// If the stored dlId is different than the
// current dl id it means we're downloading a different
// file
if dlSess == nil || (sessDlId != dlId) {
// This is a new download session
log.Println("new download session")
session.Values["dlId"] = dlId
// Create a unique session id for this download session
sessId, err := storage.GetShortId()
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
log.Printf("going to generate invoice for %s", upId)
//TODO: use fee asked by uploader
//
// Get upload data asked by uploader
up, err := storage.GetUploadById(upId)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
// Get files metadata for upload
var upFilesMeta []storage.FileUpload
upFilesMeta, err = storage.GetUploadFilesMeta(upId)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
session.Values["files"] = upFilesMeta
invoiceOpts := ln.InvoiceOpts{
Amount: up.AskAmount,
Curr: ln.CurrencyID[up.AskCurrency],
Memo: fmt.Sprintf("bit4sat download: %s", sessId),
}
log.Printf("invoice opts %#v", invoiceOpts)
invoice, err := ln.NewInvoice(invoiceOpts)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
// Store invoice
session.Values["session-id"] = sessId
session.Values["invoice"] = invoice
invoiceExpires := time.Time(invoice.ExpiresAt).Sub(time.Now()).Seconds()
//TODO: this session can be reused during this hour
session.Options.MaxAge = int(invoiceExpires)
//log.Printf("session: %#v", session.Values)
err = session.Save(c.Request, c.Writer)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
c.JSON(http.StatusPaymentRequired, gin.H{
"invoice": invoice,
"files": upFilesMeta,
})
// This is a returning download session to pay the invoice
} else {
log.Printf("continue download session id: %s", dlSess)
invVal := session.Values["invoice"]
var invoice = &ln.Invoice{}
if invoice, ok = invVal.(*ln.Invoice); !ok {
log.Printf("Could not find invoice in session %s", dlSess)
session.Options.MaxAge = -1
err = session.Save(c.Request, c.Writer)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
utils.JSONErr(c, http.StatusExpectationFailed,
"invoice not found, start a new download session session")
return
}
//TODO: Check if invoice paid ??
//If paid return the files else return the invoice to pay
filesVal := session.Values["files"]
var filesMeta = &[]storage.FileUpload{}
if filesMeta, ok = filesVal.(*[]storage.FileUpload); !ok {
// The cookie broke ???
session.Options.MaxAge = -1
err = session.Save(c.Request, c.Writer)
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
utils.JSONErr(c, http.StatusExpectationFailed,
"start a new download session session")
return
}
c.JSON(http.StatusPaymentRequired, gin.H{
"invoice": invoice,
"files": filesMeta,
})
}
return
}
func TestDownHandler(c *gin.Context) {
sess := sessions.Default(c)
test := sess.Get("test")
log.Printf("%#v", test)
if test != nil {
sess.Clear()
sess.Save()
c.String(http.StatusOK, "I remember you")
} else {
sess.Set("test", 1)
sess.Save()
c.String(http.StatusOK, "i dont remember you")
}
return
}
func init() {
gob.Register(&ln.Invoice{})
gob.Register(&[]storage.FileUpload{})
}