Enhance some duration flags
parent
217ca81b17
commit
a3087047b6
35
cmd/tier.go
35
cmd/tier.go
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"heckel.io/ntfy/user"
|
"heckel.io/ntfy/user"
|
||||||
"heckel.io/ntfy/util"
|
"heckel.io/ntfy/util"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -17,12 +16,12 @@ func init() {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultMessageLimit = 5000
|
defaultMessageLimit = 5000
|
||||||
defaultMessageExpiryDuration = 12 * time.Hour
|
defaultMessageExpiryDuration = "12h"
|
||||||
defaultEmailLimit = 20
|
defaultEmailLimit = 20
|
||||||
defaultReservationLimit = 3
|
defaultReservationLimit = 3
|
||||||
defaultAttachmentFileSizeLimit = "15M"
|
defaultAttachmentFileSizeLimit = "15M"
|
||||||
defaultAttachmentTotalSizeLimit = "100M"
|
defaultAttachmentTotalSizeLimit = "100M"
|
||||||
defaultAttachmentExpiryDuration = 6 * time.Hour
|
defaultAttachmentExpiryDuration = "6h"
|
||||||
defaultAttachmentBandwidthLimit = "1G"
|
defaultAttachmentBandwidthLimit = "1G"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,12 +46,12 @@ var cmdTier = &cli.Command{
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "name", Usage: "tier name"},
|
&cli.StringFlag{Name: "name", Usage: "tier name"},
|
||||||
&cli.Int64Flag{Name: "message-limit", Value: defaultMessageLimit, Usage: "daily message limit"},
|
&cli.Int64Flag{Name: "message-limit", Value: defaultMessageLimit, Usage: "daily message limit"},
|
||||||
&cli.DurationFlag{Name: "message-expiry-duration", Value: defaultMessageExpiryDuration, Usage: "duration after which messages are deleted"},
|
&cli.StringFlag{Name: "message-expiry-duration", Value: defaultMessageExpiryDuration, Usage: "duration after which messages are deleted"},
|
||||||
&cli.Int64Flag{Name: "email-limit", Value: defaultEmailLimit, Usage: "daily email limit"},
|
&cli.Int64Flag{Name: "email-limit", Value: defaultEmailLimit, Usage: "daily email limit"},
|
||||||
&cli.Int64Flag{Name: "reservation-limit", Value: defaultReservationLimit, Usage: "topic reservation limit"},
|
&cli.Int64Flag{Name: "reservation-limit", Value: defaultReservationLimit, Usage: "topic reservation limit"},
|
||||||
&cli.StringFlag{Name: "attachment-file-size-limit", Value: defaultAttachmentFileSizeLimit, Usage: "per-attachment file size limit"},
|
&cli.StringFlag{Name: "attachment-file-size-limit", Value: defaultAttachmentFileSizeLimit, Usage: "per-attachment file size limit"},
|
||||||
&cli.StringFlag{Name: "attachment-total-size-limit", Value: defaultAttachmentTotalSizeLimit, Usage: "total size limit of attachments for the user"},
|
&cli.StringFlag{Name: "attachment-total-size-limit", Value: defaultAttachmentTotalSizeLimit, Usage: "total size limit of attachments for the user"},
|
||||||
&cli.DurationFlag{Name: "attachment-expiry-duration", Value: defaultAttachmentExpiryDuration, Usage: "duration after which attachments are deleted"},
|
&cli.StringFlag{Name: "attachment-expiry-duration", Value: defaultAttachmentExpiryDuration, Usage: "duration after which attachments are deleted"},
|
||||||
&cli.StringFlag{Name: "attachment-bandwidth-limit", Value: defaultAttachmentBandwidthLimit, Usage: "daily bandwidth limit for attachment uploads/downloads"},
|
&cli.StringFlag{Name: "attachment-bandwidth-limit", Value: defaultAttachmentBandwidthLimit, Usage: "daily bandwidth limit for attachment uploads/downloads"},
|
||||||
&cli.StringFlag{Name: "stripe-monthly-price-id", Usage: "Monthly Stripe price ID for paid tiers (e.g. price_12345)"},
|
&cli.StringFlag{Name: "stripe-monthly-price-id", Usage: "Monthly Stripe price ID for paid tiers (e.g. price_12345)"},
|
||||||
&cli.StringFlag{Name: "stripe-yearly-price-id", Usage: "Yearly Stripe price ID for paid tiers (e.g. price_12345)"},
|
&cli.StringFlag{Name: "stripe-yearly-price-id", Usage: "Yearly Stripe price ID for paid tiers (e.g. price_12345)"},
|
||||||
|
@ -90,12 +89,12 @@ Examples:
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "name", Usage: "tier name"},
|
&cli.StringFlag{Name: "name", Usage: "tier name"},
|
||||||
&cli.Int64Flag{Name: "message-limit", Usage: "daily message limit"},
|
&cli.Int64Flag{Name: "message-limit", Usage: "daily message limit"},
|
||||||
&cli.DurationFlag{Name: "message-expiry-duration", Usage: "duration after which messages are deleted"},
|
&cli.StringFlag{Name: "message-expiry-duration", Usage: "duration after which messages are deleted"},
|
||||||
&cli.Int64Flag{Name: "email-limit", Usage: "daily email limit"},
|
&cli.Int64Flag{Name: "email-limit", Usage: "daily email limit"},
|
||||||
&cli.Int64Flag{Name: "reservation-limit", Usage: "topic reservation limit"},
|
&cli.Int64Flag{Name: "reservation-limit", Usage: "topic reservation limit"},
|
||||||
&cli.StringFlag{Name: "attachment-file-size-limit", Usage: "per-attachment file size limit"},
|
&cli.StringFlag{Name: "attachment-file-size-limit", Usage: "per-attachment file size limit"},
|
||||||
&cli.StringFlag{Name: "attachment-total-size-limit", Usage: "total size limit of attachments for the user"},
|
&cli.StringFlag{Name: "attachment-total-size-limit", Usage: "total size limit of attachments for the user"},
|
||||||
&cli.DurationFlag{Name: "attachment-expiry-duration", Usage: "duration after which attachments are deleted"},
|
&cli.StringFlag{Name: "attachment-expiry-duration", Usage: "duration after which attachments are deleted"},
|
||||||
&cli.StringFlag{Name: "attachment-bandwidth-limit", Usage: "daily bandwidth limit for attachment uploads/downloads"},
|
&cli.StringFlag{Name: "attachment-bandwidth-limit", Usage: "daily bandwidth limit for attachment uploads/downloads"},
|
||||||
&cli.StringFlag{Name: "stripe-monthly-price-id", Usage: "Monthly Stripe price ID for paid tiers (e.g. price_12345)"},
|
&cli.StringFlag{Name: "stripe-monthly-price-id", Usage: "Monthly Stripe price ID for paid tiers (e.g. price_12345)"},
|
||||||
&cli.StringFlag{Name: "stripe-yearly-price-id", Usage: "Yearly Stripe price ID for paid tiers (e.g. price_12345)"},
|
&cli.StringFlag{Name: "stripe-yearly-price-id", Usage: "Yearly Stripe price ID for paid tiers (e.g. price_12345)"},
|
||||||
|
@ -189,6 +188,10 @@ func execTierAdd(c *cli.Context) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = code
|
name = code
|
||||||
}
|
}
|
||||||
|
messageExpiryDuration, err := util.ParseDuration(c.String("message-expiry-duration"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
attachmentFileSizeLimit, err := util.ParseSize(c.String("attachment-file-size-limit"))
|
attachmentFileSizeLimit, err := util.ParseSize(c.String("attachment-file-size-limit"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -201,17 +204,21 @@ func execTierAdd(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
attachmentExpiryDuration, err := util.ParseDuration(c.String("attachment-expiry-duration"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
tier := &user.Tier{
|
tier := &user.Tier{
|
||||||
ID: "", // Generated
|
ID: "", // Generated
|
||||||
Code: code,
|
Code: code,
|
||||||
Name: name,
|
Name: name,
|
||||||
MessageLimit: c.Int64("message-limit"),
|
MessageLimit: c.Int64("message-limit"),
|
||||||
MessageExpiryDuration: c.Duration("message-expiry-duration"),
|
MessageExpiryDuration: messageExpiryDuration,
|
||||||
EmailLimit: c.Int64("email-limit"),
|
EmailLimit: c.Int64("email-limit"),
|
||||||
ReservationLimit: c.Int64("reservation-limit"),
|
ReservationLimit: c.Int64("reservation-limit"),
|
||||||
AttachmentFileSizeLimit: attachmentFileSizeLimit,
|
AttachmentFileSizeLimit: attachmentFileSizeLimit,
|
||||||
AttachmentTotalSizeLimit: attachmentTotalSizeLimit,
|
AttachmentTotalSizeLimit: attachmentTotalSizeLimit,
|
||||||
AttachmentExpiryDuration: c.Duration("attachment-expiry-duration"),
|
AttachmentExpiryDuration: attachmentExpiryDuration,
|
||||||
AttachmentBandwidthLimit: attachmentBandwidthLimit,
|
AttachmentBandwidthLimit: attachmentBandwidthLimit,
|
||||||
StripeMonthlyPriceID: c.String("stripe-monthly-price-id"),
|
StripeMonthlyPriceID: c.String("stripe-monthly-price-id"),
|
||||||
StripeYearlyPriceID: c.String("stripe-yearly-price-id"),
|
StripeYearlyPriceID: c.String("stripe-yearly-price-id"),
|
||||||
|
@ -252,7 +259,10 @@ func execTierChange(c *cli.Context) error {
|
||||||
tier.MessageLimit = c.Int64("message-limit")
|
tier.MessageLimit = c.Int64("message-limit")
|
||||||
}
|
}
|
||||||
if c.IsSet("message-expiry-duration") {
|
if c.IsSet("message-expiry-duration") {
|
||||||
tier.MessageExpiryDuration = c.Duration("message-expiry-duration")
|
tier.MessageExpiryDuration, err = util.ParseDuration(c.String("message-expiry-duration"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if c.IsSet("email-limit") {
|
if c.IsSet("email-limit") {
|
||||||
tier.EmailLimit = c.Int64("email-limit")
|
tier.EmailLimit = c.Int64("email-limit")
|
||||||
|
@ -273,7 +283,10 @@ func execTierChange(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.IsSet("attachment-expiry-duration") {
|
if c.IsSet("attachment-expiry-duration") {
|
||||||
tier.AttachmentExpiryDuration = c.Duration("attachment-expiry-duration")
|
tier.AttachmentExpiryDuration, err = util.ParseDuration(c.String("attachment-expiry-duration"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if c.IsSet("attachment-bandwidth-limit") {
|
if c.IsSet("attachment-bandwidth-limit") {
|
||||||
tier.AttachmentBandwidthLimit, err = util.ParseSize(c.String("attachment-bandwidth-limit"))
|
tier.AttachmentBandwidthLimit, err = util.ParseSize(c.String("attachment-bandwidth-limit"))
|
||||||
|
|
|
@ -29,11 +29,11 @@ func TestCLI_Tier_AddListChangeDelete(t *testing.T) {
|
||||||
app, _, _, stderr = newTestApp()
|
app, _, _, stderr = newTestApp()
|
||||||
require.Nil(t, runTierCommand(app, conf, "change",
|
require.Nil(t, runTierCommand(app, conf, "change",
|
||||||
"--message-limit=999",
|
"--message-limit=999",
|
||||||
"--message-expiry-duration=99h",
|
"--message-expiry-duration=2d",
|
||||||
"--email-limit=91",
|
"--email-limit=91",
|
||||||
"--reservation-limit=98",
|
"--reservation-limit=98",
|
||||||
"--attachment-file-size-limit=100m",
|
"--attachment-file-size-limit=100m",
|
||||||
"--attachment-expiry-duration=7h",
|
"--attachment-expiry-duration=1d",
|
||||||
"--attachment-total-size-limit=10G",
|
"--attachment-total-size-limit=10G",
|
||||||
"--attachment-bandwidth-limit=100G",
|
"--attachment-bandwidth-limit=100G",
|
||||||
"--stripe-monthly-price-id=price_991",
|
"--stripe-monthly-price-id=price_991",
|
||||||
|
@ -41,11 +41,11 @@ func TestCLI_Tier_AddListChangeDelete(t *testing.T) {
|
||||||
"pro",
|
"pro",
|
||||||
))
|
))
|
||||||
require.Contains(t, stderr.String(), "- Message limit: 999")
|
require.Contains(t, stderr.String(), "- Message limit: 999")
|
||||||
require.Contains(t, stderr.String(), "- Message expiry duration: 99h")
|
require.Contains(t, stderr.String(), "- Message expiry duration: 48h")
|
||||||
require.Contains(t, stderr.String(), "- Email limit: 91")
|
require.Contains(t, stderr.String(), "- Email limit: 91")
|
||||||
require.Contains(t, stderr.String(), "- Reservation limit: 98")
|
require.Contains(t, stderr.String(), "- Reservation limit: 98")
|
||||||
require.Contains(t, stderr.String(), "- Attachment file size limit: 100.0 MB")
|
require.Contains(t, stderr.String(), "- Attachment file size limit: 100.0 MB")
|
||||||
require.Contains(t, stderr.String(), "- Attachment expiry duration: 7h")
|
require.Contains(t, stderr.String(), "- Attachment expiry duration: 24h")
|
||||||
require.Contains(t, stderr.String(), "- Attachment total size limit: 10.0 GB")
|
require.Contains(t, stderr.String(), "- Attachment total size limit: 10.0 GB")
|
||||||
require.Contains(t, stderr.String(), "- Stripe prices (monthly/yearly): price_991 / price_992")
|
require.Contains(t, stderr.String(), "- Stripe prices (monthly/yearly): price_991 / price_992")
|
||||||
|
|
||||||
|
|
20
util/time.go
20
util/time.go
|
@ -45,15 +45,9 @@ func ParseFutureTime(s string, now time.Time) (time.Time, error) {
|
||||||
return time.Time{}, errUnparsableTime
|
return time.Time{}, errUnparsableTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFromDuration(s string, now time.Time) (time.Time, error) {
|
// ParseDuration is like time.ParseDuration, except that it also understands days (d), which
|
||||||
d, err := parseDuration(s)
|
// translates to 24 hours, e.g. "2d" or "20h".
|
||||||
if err == nil {
|
func ParseDuration(s string) (time.Duration, error) {
|
||||||
return now.Add(d), nil
|
|
||||||
}
|
|
||||||
return time.Time{}, errUnparsableTime
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDuration(s string) (time.Duration, error) {
|
|
||||||
d, err := time.ParseDuration(s)
|
d, err := time.ParseDuration(s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return d, nil
|
return d, nil
|
||||||
|
@ -80,6 +74,14 @@ func parseDuration(s string) (time.Duration, error) {
|
||||||
return 0, errUnparsableTime
|
return 0, errUnparsableTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseFromDuration(s string, now time.Time) (time.Time, error) {
|
||||||
|
d, err := ParseDuration(s)
|
||||||
|
if err == nil {
|
||||||
|
return now.Add(d), nil
|
||||||
|
}
|
||||||
|
return time.Time{}, errUnparsableTime
|
||||||
|
}
|
||||||
|
|
||||||
func parseUnixTime(s string, now time.Time) (time.Time, error) {
|
func parseUnixTime(s string, now time.Time) (time.Time, error) {
|
||||||
t, err := strconv.Atoi(s)
|
t, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -78,3 +78,17 @@ func TestParseFutureTime_UnixTime(t *testing.T) {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, time.Date(2021, 12, 11, 0, 51, 51, 0, time.UTC), d)
|
require.Equal(t, time.Date(2021, 12, 11, 0, 51, 51, 0, time.UTC), d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseDuration(t *testing.T) {
|
||||||
|
d, err := ParseDuration("2d")
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, 48*time.Hour, d)
|
||||||
|
|
||||||
|
d, err = ParseDuration("2h")
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, 2*time.Hour, d)
|
||||||
|
|
||||||
|
d, err = ParseDuration("0")
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, time.Duration(0), d)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue