Working download !!!

master
Chakib Benziane 5 years ago
parent 4985b3aea3
commit 44de8bc448

@ -7,11 +7,13 @@ import (
"net/http" "net/http"
"time" "time"
"git.sp4ke.com/sp4ke/bit4sat/db"
"git.sp4ke.com/sp4ke/bit4sat/ln" "git.sp4ke.com/sp4ke/bit4sat/ln"
"git.sp4ke.com/sp4ke/bit4sat/storage" "git.sp4ke.com/sp4ke/bit4sat/storage"
"git.sp4ke.com/sp4ke/bit4sat/utils" "git.sp4ke.com/sp4ke/bit4sat/utils"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/mediocregopher/radix/v3"
) )
func download(c *gin.Context) { func download(c *gin.Context) {
@ -26,6 +28,14 @@ func download(c *gin.Context) {
return 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
}
// Get the download session // Get the download session
session, err := SessionStore.Get(c.Request, DlSessionKey) session, err := SessionStore.Get(c.Request, DlSessionKey)
if err != nil { if err != nil {
@ -80,16 +90,6 @@ func download(c *gin.Context) {
return 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{ invoiceOpts := ln.InvoiceOpts{
Amount: up.AskAmount, Amount: up.AskAmount,
Curr: ln.CurrencyID[up.AskCurrency], Curr: ln.CurrencyID[up.AskCurrency],
@ -104,10 +104,20 @@ func download(c *gin.Context) {
return return
} }
// Store invoice // Store invoice_id ---> upload_id
key := fmt.Sprintf("invoice_id_%s_upload_id", invoice.RHash)
err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", key, upId))
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
// Store invoice_<invoice_id>
invoiceKey := fmt.Sprintf("invoice_%s", invoice.RHash)
err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", invoiceKey, invoice))
session.Values["session-id"] = sessId session.Values["session-id"] = sessId
session.Values["invoice"] = invoice session.Values["invoice-id"] = invoice.RHash
invoiceExpires := time.Time(invoice.ExpiresAt).Sub(time.Now()).Seconds() invoiceExpires := time.Time(invoice.ExpiresAt).Sub(time.Now()).Seconds()
@ -131,10 +141,9 @@ func download(c *gin.Context) {
} else { } else {
log.Printf("continue download session id: %s", dlSess) log.Printf("continue download session id: %s", dlSess)
invVal := session.Values["invoice"] // Get invoice-id linked to sessionId
var invoice = &ln.Invoice{} invIdVal := session.Values["invoice-id"]
if invoice, ok = invVal.(*ln.Invoice); !ok { if invIdVal == nil {
log.Printf("Could not find invoice in session %s", dlSess)
session.Options.MaxAge = -1 session.Options.MaxAge = -1
err = session.Save(c.Request, c.Writer) err = session.Save(c.Request, c.Writer)
@ -148,14 +157,9 @@ func download(c *gin.Context) {
return return
} }
//TODO: Check if invoice paid ?? var invoiceId string
if invoiceId, ok = invIdVal.(string); !ok {
//If paid return the files else return the invoice to pay log.Printf("Could not find invoice in session %s", dlSess)
filesVal := session.Values["files"]
var filesMeta = &[]storage.FileUpload{}
if filesMeta, ok = filesVal.(*[]storage.FileUpload); !ok {
// The cookie broke ???
session.Options.MaxAge = -1 session.Options.MaxAge = -1
err = session.Save(c.Request, c.Writer) err = session.Save(c.Request, c.Writer)
@ -165,13 +169,42 @@ func download(c *gin.Context) {
} }
utils.JSONErr(c, http.StatusExpectationFailed, utils.JSONErr(c, http.StatusExpectationFailed,
"start a new download session session") "invoice not found, start a new download session session")
return
}
// Get invoice from invoice_id
invoiceKey := fmt.Sprintf("invoice_%s", invoiceId)
invoice := ln.Invoice{}
err = db.DB.Redis.Do(radix.FlatCmd(&invoice, "GET", invoiceKey))
if err != nil {
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
}
// If invoice paid send the files
if invoice.Settled {
log.Println("dl invoice paid, sending")
// set response type to zip mime type
c.Header("Content-Type", "application/zip")
c.Header("Content-Disposition", "attachment; filename=download.zip")
err := storage.ZipFiles(upFilesMeta, c.Writer)
if err != nil {
log.Fatal(err)
}
//c.JSON(http.StatusOK, gin.H{
//"download": "ok",
//"invoice": invoice,
//})
return return
} }
c.JSON(http.StatusPaymentRequired, gin.H{ c.JSON(http.StatusPaymentRequired, gin.H{
"invoice": invoice, "invoice": invoice,
"files": filesMeta, "files": upFilesMeta,
}) })
} }

@ -7,7 +7,6 @@ import (
"git.sp4ke.com/sp4ke/bit4sat/db" "git.sp4ke.com/sp4ke/bit4sat/db"
"git.sp4ke.com/sp4ke/bit4sat/ln" "git.sp4ke.com/sp4ke/bit4sat/ln"
"git.sp4ke.com/sp4ke/bit4sat/lndrpc"
"git.sp4ke.com/sp4ke/bit4sat/storage" "git.sp4ke.com/sp4ke/bit4sat/storage"
"git.sp4ke.com/sp4ke/bit4sat/utils" "git.sp4ke.com/sp4ke/bit4sat/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -73,25 +72,63 @@ func pollInvoice(c *gin.Context) {
invoiceId := c.Param("rhash") invoiceId := c.Param("rhash")
// First check if already paid // First check if already paid
lnInv, err := lndrpc.LookupInvoiceRhashStr(invoiceId)
// Get the invoice from invoice_id
invoiceKey := fmt.Sprintf("invoice_%s", invoiceId)
invoice := ln.Invoice{}
err := db.DB.Redis.Do(radix.FlatCmd(&invoice, "GET", invoiceKey))
if err != nil { if err != nil {
log.Println(err) utils.JSONErrPriv(c, http.StatusInternalServerError, err)
utils.JSONErr(c, http.StatusNotFound,
"invoice not found !")
return return
} }
invoice := ln.InvoiceFromLndIn(lnInv)
res := gin.H{
"invoice": invoice,
}
// If paid return ok // If paid return ok
if lnInv.Settled { if invoice.Settled {
c.JSON(http.StatusOK, res) c.JSON(http.StatusOK, gin.H{
"invoice": invoice,
})
// Poll
} else { } else {
c.JSON(http.StatusPaymentRequired, res)
invoiceChan := make(chan *ln.Invoice)
errorChan := make(chan error)
log.Printf("starting invoice poll for %s", invoice.RHash)
// If waiting payment, wait until invoice is paid
go ln.PollPaidInvoice(invoice.RHash, invoiceChan, errorChan)
select {
case invoice := <-invoiceChan:
// if expired return with expired response
if invoice.Expired {
c.JSON(http.StatusGone, gin.H{
"invoice": invoice,
})
return
}
////////////////
///// Invoice was paid
////////////////
//
log.Println("POLL: invoice was paid")
c.JSON(http.StatusOK, gin.H{
"invoice": invoice,
})
case err := <-errorChan:
utils.JSONErrPriv(c, http.StatusInternalServerError, err)
}
// We stopped waiting for the invoice, it must have expired
c.JSON(http.StatusGone, gin.H{
"invoice": invoice,
})
} }
return return
@ -115,7 +152,7 @@ func invoiceCbHandler(c *gin.Context) {
// get upload id related to invoice // get upload id related to invoice
var uploadId string var uploadId string
invoiceUploadKey := fmt.Sprintf("invoice_%s_upload", invoice.RHash) invoiceUploadKey := fmt.Sprintf("invoice_%s_uploadid", invoice.RHash)
err := db.DB.Redis.Do(radix.FlatCmd(&uploadId, "GET", invoiceUploadKey)) err := db.DB.Redis.Do(radix.FlatCmd(&uploadId, "GET", invoiceUploadKey))
if err != nil { if err != nil {

@ -289,21 +289,6 @@ func (ctrl UploadCtrl) PollStatus(c *gin.Context) {
case invoice := <-invoiceChan: case invoice := <-invoiceChan:
log.Printf("poll: received invoice notif %s", invoice.RHash) log.Printf("poll: received invoice notif %s", invoice.RHash)
// if expired return with expired response
if invoice.Expired {
err := storage.SetUploadStatus(uploadId, storage.UpPayExpired)
if err != nil {
log.Printf("Redis error: %s", err)
}
c.JSON(http.StatusGone, gin.H{
"status": uploadStatus,
"invoice": invoice,
})
return
}
//////////////// ////////////////
///// Invoice was paid ///// Invoice was paid
//////////////// ////////////////
@ -368,8 +353,22 @@ func (ctrl UploadCtrl) PollStatus(c *gin.Context) {
case err := <-errorChan: case err := <-errorChan:
utils.JSONErrPriv(c, http.StatusInternalServerError, err) utils.JSONErrPriv(c, http.StatusInternalServerError, err)
return
} }
// We stopped waiting for the invoice, it must have expired
err := storage.SetUploadStatus(uploadId, storage.UpPayExpired)
if err != nil {
log.Printf("Redis error: %s", err)
}
c.JSON(http.StatusGone, gin.H{
"status": uploadStatus,
"invoice": invoice,
})
return
} else { } else {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"status": uploadStatus, "status": uploadStatus,

@ -0,0 +1,13 @@
package db
import (
"github.com/mediocregopher/radix/v3"
)
func GetFromKey(key string, target interface{}) error {
return DB.Redis.Do(radix.FlatCmd(target, "GET", key))
}
func SetKeyVal(key string, val interface{}) error {
return DB.Redis.Do(radix.FlatCmd(nil, "SET", key, val))
}

@ -180,3 +180,11 @@ func UpdateInvoiceFromLnd(storedIn *Invoice, newIn *lnrpc.Invoice) *Invoice {
return storedIn return storedIn
} }
func IsExpiredInvoice(creation, expiry int64) bool {
createdAt := time.Unix(int64(creation), 0)
expiresAt := createdAt.Add(time.Second * time.Duration(expiry))
return time.Now().After(expiresAt)
}

@ -56,10 +56,19 @@ const (
); );
` `
DBUploadPayments = `
CREATE TABLE IF NOT EXISTS upload_payments (
payment_id_rhash varchar(64) PRIMARY KEY,
upload_id text NOT NULL references uploads(upload_id),
msat_amount real NOT NULL,
created timestamp DEFAULT now()
);
`
//TODO: store all invoices from redis to local sqldb
DBInvoicesSchema = ` DBInvoicesSchema = `
CREATE TABLE IF NOT EXISTS invoices ( CREATE TABLE IF NOT EXISTS invoices (
rhash varchar(64) PRIMARY KEY, rhash varchar(64) PRIMARY KEY
payload text DEFAULT ''
); );
` `
@ -256,6 +265,16 @@ func (u *FileUpload) UnmarshalBinary(b []byte) error {
//func SyncUploadStatusToDB(){ //func SyncUploadStatusToDB(){
//} //}
//
func AddPaymentToUpload(uploadId string, rhash string, msatAmount float64) error {
query := `INSERT INTO
upload_payments (payment_id_rhash, upload_id, msat_amount)
VALUES ($1, $2, $3)
`
_, err := DB.Sql.Exec(query, rhash, uploadId, msatAmount)
return err
}
func GetDownloadId(uploadId string) (string, error) { func GetDownloadId(uploadId string) (string, error) {
key := fmt.Sprintf("download_for_upload_%s", uploadId) key := fmt.Sprintf("download_for_upload_%s", uploadId)
@ -285,9 +304,9 @@ func GetDownloadId(uploadId string) (string, error) {
} }
// Store it back on redis cache // Store it back on redis cache
err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, downloadId)) err = db.SetKeyVal(key, downloadId)
} else { } else {
err = DB.Redis.Do(radix.FlatCmd(&downloadId, "GET", key)) err = db.GetFromKey(key, &downloadId)
} }
return downloadId, err return downloadId, err
@ -321,9 +340,9 @@ func GetUploadIdForDlId(dlId string) (string, error) {
} }
// Store it back on redis cache // Store it back on redis cache
err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, upId)) err = db.SetKeyVal(key, upId)
} else { } else {
err = DB.Redis.Do(radix.FlatCmd(&upId, "GET", key)) err = db.GetFromKey(key, &upId)
} }
return upId, err return upId, err
@ -334,11 +353,13 @@ func GetUploadInvoice(uploadId string) (*ln.Invoice, error) {
uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId) uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId)
err := DB.Redis.Do(radix.FlatCmd(&invoice, "GET", uploadInvoiceKey)) err := db.GetFromKey(uploadInvoiceKey, &invoice)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Printf("GetUploadInvoice returned %#v")
return &invoice, nil return &invoice, nil
} }
@ -394,11 +415,11 @@ func GetUploadById(id string) (*Upload, error) {
} }
// Sotre it back on redis // Sotre it back on redis
err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, up)) err = db.SetKeyVal(key, up)
// Get it from redis // Get it from redis
} else { } else {
err = DB.Redis.Do(radix.FlatCmd(&up, "GET", key)) err = db.GetFromKey(key, &up)
} }
return &up, err return &up, err
@ -447,14 +468,14 @@ func GetUploadStatus(id string) (status UpStatus, err error) {
key := fmt.Sprintf("upload_status_%s", id) key := fmt.Sprintf("upload_status_%s", id)
err = DB.Redis.Do(radix.FlatCmd(&status, "GET", key)) err = db.GetFromKey(key, &status)
return return
} }
func SetUploadAdminToken(uploadId, token string) error { func SetUploadAdminToken(uploadId, token string) error {
key := fmt.Sprintf("upload_admin_%s", uploadId) key := fmt.Sprintf("upload_admin_%s", uploadId)
err := DB.Redis.Do(radix.FlatCmd(nil, "SET", key, token)) err := db.SetKeyVal(key, token)
if err != nil { if err != nil {
return err return err
} }
@ -467,26 +488,21 @@ func SetUploadAdminToken(uploadId, token string) error {
func GetUploadAdminToken(uploadId string) (string, error) { func GetUploadAdminToken(uploadId string) (string, error) {
var token string var token string
key := fmt.Sprintf("upload_admin_%s", uploadId) key := fmt.Sprintf("upload_admin_%s", uploadId)
err := DB.Redis.Do(radix.FlatCmd(&token, "GET", key)) err := db.GetFromKey(key, &token)
return token, err return token, err
} }
func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error { func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error {
uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId) uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId)
invoiceJson, err := json.Marshal(invoice) err := db.SetKeyVal(uploadInvoiceKey, invoice)
if err != nil {
return err
}
err = DB.Redis.Do(radix.FlatCmd(nil, "SET", uploadInvoiceKey, invoiceJson))
if err != nil { if err != nil {
return err return err
} }
// Set inverse relation // Set inverse relation
invoiceUploadKey := fmt.Sprintf("invoice_%s_upload", invoice.RHash) invoiceUploadKey := fmt.Sprintf("invoice_%s_upload_id", invoice.RHash)
err = DB.Redis.Do(radix.FlatCmd(nil, "SET", invoiceUploadKey, uploadId)) err = db.SetKeyVal(invoiceUploadKey, uploadId)
if err != nil { if err != nil {
return err return err
} }
@ -498,11 +514,11 @@ func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error {
} }
// Add invoice to invoices table // Add invoice to invoices table
query := `INSERT INTO invoices(rhash, payload) query := `INSERT INTO invoices(rhash)
VALUES($1,$2) VALUES($1)
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
` `
_, err = tx.Exec(query, invoice.RHash, invoiceJson) _, err = tx.Exec(query, invoice.RHash)
if err != nil { if err != nil {
return err return err
} }
@ -518,9 +534,9 @@ func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error {
} }
func GetUploadIdForInvoice(invoiceId string) (string, error) { func GetUploadIdForInvoice(invoiceId string) (string, error) {
key := fmt.Sprintf("invoice_%s_upload", invoiceId) key := fmt.Sprintf("invoice_%s_upload_id", invoiceId)
err := DB.Redis.Do(radix.FlatCmd(&invoiceId, "GET", key)) err := db.GetFromKey(key, &invoiceId)
return invoiceId, err return invoiceId, err
} }

@ -0,0 +1,57 @@
package storage
import (
"archive/zip"
"io"
"os"
)
func ZipFiles(files []FileUpload, w io.Writer) error {
zipWriter := zip.NewWriter(w)
defer zipWriter.Close()
// Add files to zip
for _, file := range files {
if err := AddFileToZip(zipWriter, file); err != nil {
return err
}
}
return nil
}
// https://golangcode.com/create-zip-files-in-go/
func AddFileToZip(zipWriter *zip.Writer, file FileUpload) error {
fileToZip, err := os.Open(GetStoreDestination(file.SHA256 + file.FileExt))
if err != nil {
return err
}
defer fileToZip.Close()
// get file info
info, err := fileToZip.Stat()
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
// Reset original file name
header.Name = file.FileName
// Change to deflate for better compression
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, fileToZip)
return nil
}

@ -2,12 +2,10 @@ package watchers
import ( import (
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"
"regexp" "regexp"
"time"
"git.sp4ke.com/sp4ke/bit4sat/bus" "git.sp4ke.com/sp4ke/bit4sat/bus"
"git.sp4ke.com/sp4ke/bit4sat/db" "git.sp4ke.com/sp4ke/bit4sat/db"
@ -83,51 +81,11 @@ func WatchInvoice() {
continue continue
} }
// Invoice expired
if expiredInvoice(invoice.CreationDate, invoice.Expiry) {
handleExpiredInvoice(invoice)
}
// Invoice was paid, we handle it // Invoice was paid, we handle it
handleSettledInvoice(invoice) handleSettledInvoice(invoice)
} }
} }
//TODO
func handleExpiredInvoice(invoice *lnrpc.Invoice) {
matchUp, err := regexp.MatchString(ReUploadInvoice, invoice.Memo)
if err != nil {
log.Printf("Error regex match: %s", err)
}
if matchUp {
// Update upload status to "expired"
uploadId, err := storage.GetUploadIdForInvoice(hex.EncodeToString(invoice.RHash))
if err != nil {
log.Fatal(fmt.Errorf("handleExpiredInvoice: %s", err))
}
err = storage.SetUploadStatus(uploadId, storage.UpPayExpired)
if err != nil {
log.Fatal(fmt.Errorf("handleExpiredInvoice %s", err))
}
}
// No need to store the invoice
// TODO
// TODO: flush all invoices and uploads
// TODO
}
func expiredInvoice(creation, expiry int64) bool {
createdAt := time.Unix(int64(creation), 0)
expiresAt := createdAt.Add(time.Second * time.Duration(expiry))
return time.Now().After(expiresAt)
}
func handleSettledInvoice(invoice *lnrpc.Invoice) { func handleSettledInvoice(invoice *lnrpc.Invoice) {
// we need to save it and also notify the pubsub channel // we need to save it and also notify the pubsub channel
@ -140,51 +98,100 @@ func handleSettledInvoice(invoice *lnrpc.Invoice) {
log.Printf("Error regex match: %s", err) log.Printf("Error regex match: %s", err)
} }
matchDown, err := regexp.MatchString(ReDownInvoice, invoice.Memo)
if err != nil {
log.Printf("Error regex match: %s", err)
}
// Handle upload related invoices // Handle upload related invoices
if matchUp { if matchUp {
// Update upload status to "paid" // Update upload status to "paid"
uploadId, err := storage.GetUploadIdForInvoice(hex.EncodeToString(invoice.RHash)) uploadId, err := storage.GetUploadIdForInvoice(hex.EncodeToString(invoice.RHash))
log.Printf("watcher: found upload id %s for invoice %s", uploadId,
hex.EncodeToString(invoice.RHash))
if err != nil { if err != nil {
log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) log.Printf("error handleSettledInvoice: %s", err)
return
} }
err = storage.SetUploadStatus(uploadId, storage.UpPaid) err = storage.SetUploadStatus(uploadId, storage.UpPaid)
if err != nil { if err != nil {
log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) log.Printf("error handleSettledInvoice: %s", err)
return
} }
// Get stored invoice for upload // Get stored invoice for upload
storedInvoice, err := storage.GetUploadInvoice(uploadId) storedInvoice, err := storage.GetUploadInvoice(uploadId)
if err != nil { if err != nil {
log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) log.Printf("error handleSettledInvoice: %s", err)
return
} }
log.Printf("stored invoice %#v", storedInvoice)
// Update stored invoice fields // Update stored invoice fields
newInvoice := ln.UpdateInvoiceFromLnd(storedInvoice, invoice) newInvoice := ln.UpdateInvoiceFromLnd(storedInvoice, invoice)
log.Printf("new invoice %#v", newInvoice)
// Set invoice for upload // Set invoice for upload
err = storage.SetUploadInvoice(uploadId, newInvoice) err = storage.SetUploadInvoice(uploadId, newInvoice)
if err != nil { if err != nil {
log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) log.Printf("error handleSettledInvoice: %s", err)
} return
newInvoiceJson, err := json.Marshal(newInvoice)
if err != nil {
log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err))
} }
log.Printf("Notifying invoice paid %s", uploadId) log.Printf("Notifying invoice paid for upload %s", uploadId)
// publish invoice was updated to upload_id_paid channel // publish invoice was updated to upload_id_paid channel
key := fmt.Sprintf("%s:%s", bus.InvoicePaidChannelPrefix, key := fmt.Sprintf("%s:%s", bus.InvoicePaidChannelPrefix,
newInvoice.RHash) newInvoice.RHash)
err = db.DB.Redis.Do(radix.FlatCmd(nil, "PUBLISH", err = db.DB.Redis.Do(radix.FlatCmd(nil, "PUBLISH",
key, newInvoiceJson)) key, newInvoice))
}
// This is a download invoice
if matchDown {
// Store the full invoice
key := fmt.Sprintf("invoice_%s", hex.EncodeToString(invoice.RHash))
storedInvoice := ln.InvoiceFromLndIn(invoice)
err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", key, storedInvoice))
if err != nil {
log.Printf("error handleSettledInvoice: %s", err)
return
}
// Get upload_id related to this invoice
key = fmt.Sprintf("invoice_id_%s_upload_id", storedInvoice.RHash)
log.Printf("looking for %s", key)
var uploadId string
err := db.DB.Redis.Do(radix.FlatCmd(&uploadId, "GET", key))
if err != nil {
log.Printf("error handleSettledInvoice: %s", err)
return
}
// Add payment to the corresponding upload_id (user account)
log.Printf("updating payment for upload %s", uploadId)
err = storage.AddPaymentToUpload(uploadId, storedInvoice.RHash,
storedInvoice.Msatoshi)
if err != nil {
log.Printf("error handleSettledInvoice: %s", err)
return
}
log.Printf("Notifying invoice paid for download")
key = fmt.Sprintf("%s:%s", bus.InvoicePaidChannelPrefix,
storedInvoice.RHash)
err = db.DB.Redis.Do(radix.FlatCmd(nil, "PUBLISH",
key, storedInvoice))
} }
if err != nil { if err != nil {
panic(err) log.Printf("error handleSettledInvoice: %s", err)
return
} }
} }

@ -1,9 +1,11 @@
<template> <template>
<div id="download"> <div id="download">
<pay v-if="!error" :objectId="dlId" :invoice="invoice"></pay> <pay v-if="!error && !showDl" :objectId="dlId" :invoice="invoice"></pay>
<div v-if="error" class="f4 mv5 light-red ttu">{{errorMsg}}</div> <div v-if="error" class="f4 mv5 light-red ttu">{{errorMsg}}</div>
<upload v-if="error"></upload> <upload v-if="error"></upload>
<a v-if="showDl" :href="dlLink" download="download.zip">download file</a>
</div> </div>
</template> </template>
@ -20,6 +22,8 @@ export default {
props: ['dlId'], props: ['dlId'],
data(){ data(){
return { return {
dlLink: "if",
showDl: false,
error: false, error: false,
errorMsg: "", errorMsg: "",
} }
@ -37,15 +41,39 @@ export default {
// ask payment // ask payment
} else if ( res.status === 402) { } else if ( res.status === 402) {
res.json() return res.json()
.then((data)=>{ .then((data)=>{
this.$store.commit('setInvoice', data.invoice) this.$store.commit('setInvoice', data.invoice)
this.$store.commit('setFiles', data.files) this.$store.commit('setFiles', data.files)
Api.pollInvoice(data.invoice.rhash)
.then((res)=>{
// invoice paid we can try again to download
if(res.ok){
//Api.download(self.dlId)
console.log("calling set download")
self.setDownload()
}
})
}) })
.catch((e)=>{console.log(e)}) .catch((e)=>{console.log(e)})
// download
} else {
console.log("calling set download")
self.setDownload()
} }
}) })
}, },
methods: {
setDownload(){
this.showDl = true;
this.dlLink = Api.endPoints.download + '/' + this.dlId
}
},
computed: { computed: {
...mapState({ ...mapState({

@ -7,9 +7,10 @@ const endPoints = {
upload: '/api/v1/u', upload: '/api/v1/u',
session: '/api/v1/session', session: '/api/v1/session',
pollstatus: '/api/v1/u/poll', pollupstatus: '/api/v1/u/poll',
checkstatus: '/api/v1/u/check', checkstatus: '/api/v1/u/check',
download: '/api/v1/d' download: '/api/v1/d',
pollinvoice: '/api/v1/pollinvoice'
} }
@ -50,11 +51,21 @@ export async function checkUploadStatus(uploadId){
return fetch(req).catch((e)=>{console.error(e)}) return fetch(req).catch((e)=>{console.error(e)})
} }
export function pollInvoice(invoiceId){
let req = new Request(endPoints.pollinvoice + '/' + invoiceId,{
method: 'GET',
credentials: 'same-origin'
})
return fetch(req).catch((e)=>{console.error(e)})
}
export async function pollUploadStatus(uploadId){ export async function pollUploadStatus(uploadId){
//console.log('polling upload status') //console.log('polling upload status')
let req = new Request(endPoints.pollstatus + '/' + uploadId,{ let req = new Request(endPoints.pollupstatus + '/' + uploadId,{
method: 'GET', method: 'GET',
credentials: 'same-origin' credentials: 'same-origin'
}) })
@ -132,4 +143,5 @@ export default {
pollUploadStatus: pollUploadStatus, pollUploadStatus: pollUploadStatus,
checkUploadStatus: checkUploadStatus, checkUploadStatus: checkUploadStatus,
download: download, download: download,
pollInvoice: pollInvoice,
} }

Loading…
Cancel
Save