✨ Pay for upload
This commit is contained in:
@ -32,8 +32,8 @@ func createAttachmentDirectly(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !user.HasPermNode("CreateAttachments", file.Size) {
|
||||
return fiber.NewError(fiber.StatusForbidden, "you are not permitted to create attachments like this large")
|
||||
if !user.HasPermNode("CreateAttachments", true) {
|
||||
return fiber.NewError(fiber.StatusForbidden, "you are not permitted to create attachments")
|
||||
} else if pool.Config.Data().MaxFileSize != nil && file.Size > *pool.Config.Data().MaxFileSize {
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("attachment pool %s doesn't allow file larger than %d", pool.Alias, *pool.Config.Data().MaxFileSize))
|
||||
}
|
||||
@ -62,6 +62,13 @@ func createAttachmentDirectly(c *fiber.Ctx) error {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
// If pool has no belongs to, it means it is shared pool, apply shared attachment discount
|
||||
withDiscount := pool.AccountID == nil
|
||||
if err := services.PlaceOrder(user.ID, file.Size, withDiscount); err != nil {
|
||||
tx.Rollback()
|
||||
return fiber.NewError(fiber.StatusPaymentRequired, err.Error())
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
metadata.Pool = &pool
|
||||
|
@ -41,13 +41,15 @@ func createAttachmentFragment(c *fiber.Ctx) error {
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to get attachment pool info: %v", err))
|
||||
}
|
||||
|
||||
if !user.HasPermNode("CreateAttachments", data.Size) {
|
||||
return fiber.NewError(fiber.StatusForbidden, "you are not permitted to create attachments like this large")
|
||||
if !user.HasPermNode("CreateAttachments", true) {
|
||||
return fiber.NewError(fiber.StatusForbidden, "you are not permitted to create attachments")
|
||||
} else if pool.Config.Data().MaxFileSize != nil && *pool.Config.Data().MaxFileSize > data.Size {
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("attachment pool %s doesn't allow file larger than %d", pool.Alias, *pool.Config.Data().MaxFileSize))
|
||||
}
|
||||
|
||||
metadata, err := services.NewAttachmentFragment(database.C, user, models.AttachmentFragment{
|
||||
tx := database.C.Begin()
|
||||
|
||||
metadata, err := services.NewAttachmentFragment(tx, user, models.AttachmentFragment{
|
||||
Name: data.FileName,
|
||||
Size: data.Size,
|
||||
Alternative: data.Alternative,
|
||||
@ -63,6 +65,15 @@ func createAttachmentFragment(c *fiber.Ctx) error {
|
||||
metadata.FileChunksMissing = services.FindFragmentMissingChunks(metadata)
|
||||
}
|
||||
|
||||
// If pool has no belongs to, it means it is shared pool, apply shared attachment discount
|
||||
withDiscount := pool.AccountID == nil
|
||||
if err := services.PlaceOrder(user.ID, data.Size, withDiscount); err != nil {
|
||||
tx.Rollback()
|
||||
return fiber.NewError(fiber.StatusPaymentRequired, err.Error())
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"chunk_size": viper.GetInt64("performance.file_chunk_size"),
|
||||
"chunk_count": len(metadata.FileChunks),
|
||||
|
60
pkg/internal/services/payment.go
Normal file
60
pkg/internal/services/payment.go
Normal file
@ -0,0 +1,60 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.solsynth.dev/hypernet/paperclip/pkg/internal/gap"
|
||||
wproto "git.solsynth.dev/hypernet/wallet/pkg/proto"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
const DiscountFileSize = 52428800 // 50 MiB
|
||||
|
||||
// PlaceOrder create a transaction if needed for user
|
||||
// Pricing according here: https://kb.solsynth.dev/solar-network/wallet#file-uploads
|
||||
func PlaceOrder(user uint, filesize int64, withDiscount bool) error {
|
||||
if filesize <= DiscountFileSize && withDiscount {
|
||||
// Discount included
|
||||
return nil
|
||||
}
|
||||
|
||||
var amount float64
|
||||
if withDiscount {
|
||||
billableSize := filesize - DiscountFileSize
|
||||
amount = float64(billableSize) / 1024 / 1024 * 1
|
||||
} else if filesize > DiscountFileSize {
|
||||
amount = 50 + float64(filesize-DiscountFileSize)/1024/1024*5
|
||||
} else {
|
||||
amount = float64(filesize) / 1024 / 1024 * 1
|
||||
}
|
||||
|
||||
if !withDiscount {
|
||||
amount += 10 // Service fee
|
||||
}
|
||||
|
||||
conn, err := gap.Nx.GetClientGrpcConn("wa")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to connect wallet: %v", err)
|
||||
}
|
||||
|
||||
wc := wproto.NewPaymentServiceClient(conn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||
defer cancel()
|
||||
resp, err := wc.MakeTransactionWithAccount(ctx, &wproto.MakeTransactionWithAccountRequest{
|
||||
PayerAccountId: lo.ToPtr(uint64(user)),
|
||||
Amount: amount,
|
||||
Remark: "File Uploading Fee",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Uint64("transaction", resp.Id).Float64("amount", amount).Bool("discount", withDiscount).
|
||||
Msg("Order placed for charge file uploading fee...")
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user