premium

package
v1.24.19 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2021 License: MIT Imports: 34 Imported by: 0

README

Package premium provides functionality to give guilds premium status through various sources (patreon only atm).

It maintains a list of premium users and guilds and their slots in redis, compiled from each source.

Those redis lists/sets/hashes are updated at a certain interval from the sources, that means no matter how many sources you only have to check 1 key to see if a guild is premium, it also simplifies things as a whole.

Documentation

Index

Constants

View Source
const (
	NormalStateMaxMessages   = 1000
	NormalStateMaxMessageAge = time.Hour

	PremiumStateMaxMessags    = 10000
	PremiumStateMaxMessageAge = time.Hour * 12
)
View Source
const (
	// Hash
	// Key: guild id's
	// Value: the user id's providing the premium status
	RedisKeyPremiumGuilds          = "premium_activated_guilds"
	RedisKeyPremiumGuildsTmp       = "premium_activated_guilds_tmp"
	RedisKeyPremiumGuildLastActive = "premium_guild_last_active"
)

Variables

View Source
var (
	ErrCodeExpired  = errors.New("Code expired")
	ErrCodeNotFound = errors.New("Code not found")
)
View Source
var (
	PremiumSources []PremiumSource

	ErrSlotNotFound        = errors.New("premium slot not found")
	ErrGuildAlreadyPremium = errors.New("guild already assigned premium from another slot")
)
View Source
var DBSchemas = []string{`
CREATE TABLE IF NOT EXISTS premium_slots (
	id BIGSERIAL PRIMARY KEY,

	created_at TIMESTAMP WITH TIME ZONE NOT NULL,
	attached_at TIMESTAMP WITH TIME ZONE,

	user_id BIGINT NOT NULL,
	guild_id BIGINT,

	title TEXT NOT NULL,
	message TEXT NOT NULL,
	source TEXT NOT NULL,
	source_id BIGINT NOT NULL,

	full_duration BIGINT NOT NULL,
	permanent BOOLEAN NOT NULL,
	duration_remaining BIGINT NOT NULL
);
`, `
CREATE TABLE IF NOT EXISTS premium_codes (
	id BIGSERIAL PRIMARY KEY,

	code TEXT UNIQUE NOT NULL,
	message TEXT NOT NULL,

	created_at TIMESTAMP WITH TIME ZONE NOT NULL,
	used_at TIMESTAMP WITH TIME ZONE,
	slot_id BIGINT references premium_slots(id),

	user_id BIGINT,
	guild_id BIGINT,

	permanent BOOLEAN NOT NULL,
	duration BIGINT NOT NULL
);
`, `
CREATE INDEX IF NOT EXISTS premium_codes_code_idx ON premium_codes(code);
`}
View Source
var (
	ErrCodeCollision = errors.New("Code collision")
)

Functions

func AllGuildsOncePremium

func AllGuildsOncePremium() (map[int64]time.Time, error)

AllGuildsOncePremium returns all the guilds that have has premium once, and the last time that was active

func AttachSlotToGuild

func AttachSlotToGuild(ctx context.Context, slotID int64, userID int64, guildID int64) error

func ContextPremium

func ContextPremium(ctx context.Context) bool

func CreatePremiumSlot

func CreatePremiumSlot(ctx context.Context, exec boil.ContextExecutor, userID int64, source, title, message string, sourceSlotID int64, duration time.Duration) (*models.PremiumSlot, error)

func DetachSlotFromGuild

func DetachSlotFromGuild(ctx context.Context, slotID int64, userID int64) error

func GenerateCode

func GenerateCode(ctx context.Context, message string, duration time.Duration) (*models.PremiumCode, error)

GenerateCode generates a redeemable premium code with the specified duration (-1 for permanent) and message

func HandleGetPremiumMainPage

func HandleGetPremiumMainPage(w http.ResponseWriter, r *http.Request) (tmpl web.TemplateData, err error)

func HandlePostLookupCode

func HandlePostLookupCode(w http.ResponseWriter, r *http.Request) (tmpl web.TemplateData, err error)

func HandlePostRedeemCode

func HandlePostRedeemCode(w http.ResponseWriter, r *http.Request) (tmpl web.TemplateData, err error)

func HandlePostUpdateSlot

func HandlePostUpdateSlot(w http.ResponseWriter, r *http.Request) (tmpl web.TemplateData, err error)

func IsGuildPremium

func IsGuildPremium(guildID int64) (bool, error)

IsGuildPremium return true if the provided guild has the premium status provided to it by a user

func IsGuildPremiumCached

func IsGuildPremiumCached(guildID int64) (bool, error)

IsGuildPremium return true if the provided guild has the premium status provided to it by a user

func LookupCode

func LookupCode(ctx context.Context, code string) (*models.PremiumCode, error)

func PremiumGuildMW

func PremiumGuildMW(inner http.Handler) http.Handler

Add in a template var wether the guild is premium or not

func PremiumProvidedBy

func PremiumProvidedBy(guildID int64) (int64, error)

func RedeemCode

func RedeemCode(ctx context.Context, code string, userID int64) error

func RegisterPlugin

func RegisterPlugin()

func RegisterPremiumSource

func RegisterPremiumSource(source PremiumSource)

func RemovePremiumSlots

func RemovePremiumSlots(ctx context.Context, exec boil.ContextExecutor, userID int64, slotsToRemove []int64) error

RemovePremiumSlots removes the specifues premium slots and attempts to migrate to other permanent available ones THIS SHOULD BE USED INSIDE A TRANSACTION ONLY, AS OTHERWISE RACE CONDITIONS BE UPON THEE

func SlotDurationLeft

func SlotDurationLeft(slot *models.PremiumSlot) (duration time.Duration)

func SlotExpired

func SlotExpired(ctx context.Context, slot *models.PremiumSlot) error

func TryRetryGenerateCode

func TryRetryGenerateCode(ctx context.Context, message string, duration time.Duration) (*models.PremiumCode, error)

TryRetryGenerateCode attempts to generate codes, if it enocunters a key collision it retries, returns on all other cases

func UserPremiumSlots

func UserPremiumSlots(ctx context.Context, userID int64) (slots []*models.PremiumSlot, err error)

UserPremiumSlots returns all slots for a user

Types

type CacheKey

type CacheKey int
const CacheKeyIsPremium CacheKey = 1

type CodePremiumSource

type CodePremiumSource struct{}

func (*CodePremiumSource) Init

func (ps *CodePremiumSource) Init()

func (*CodePremiumSource) Names

func (ps *CodePremiumSource) Names() (human string, idname string)

type CtxKey

type CtxKey int
var CtxKeyIsPremium CtxKey = 1

type NewPremiumGuildListener added in v1.24.19

type NewPremiumGuildListener interface {
	OnNewPremiumGuild(guildID int64) error
}

type Plugin

type Plugin struct {
}

func (*Plugin) AddCommands

func (p *Plugin) AddCommands()

func (*Plugin) BotInit

func (p *Plugin) BotInit()

func (*Plugin) InitWeb

func (p *Plugin) InitWeb()

func (*Plugin) LoadServerHomeWidget

func (p *Plugin) LoadServerHomeWidget(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)

func (*Plugin) MessageLimits

func (p *Plugin) MessageLimits(gs *dstate.GuildState) (maxMessages int, maxMessageAge time.Duration)

func (*Plugin) PluginInfo

func (p *Plugin) PluginInfo() *common.PluginInfo

func (*Plugin) RunBackgroundWorker

func (p *Plugin) RunBackgroundWorker()

func (*Plugin) ServerHomeWidgetOrder

func (p *Plugin) ServerHomeWidgetOrder() int

func (*Plugin) StopBackgroundWorker

func (p *Plugin) StopBackgroundWorker(wg *sync.WaitGroup)

type PremiumSource

type PremiumSource interface {
	Init()
	Names() (human string, idname string)
}

func FindSource

func FindSource(sourceID string) PremiumSource

type RemovedPremiumGuildListener added in v1.24.19

type RemovedPremiumGuildListener interface {
	OnRemovedPremiumGuild(guildID int64) error
}

type UpdateData

type UpdateData struct {
	GuildID int64
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL