Skip to content

Commit

Permalink
Merge pull request #183 from disgoorg/feature/pagination-helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
sebm253 authored Sep 8, 2022
2 parents 15bdcc1 + 0fa0901 commit 1c504a9
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 2 deletions.
38 changes: 38 additions & 0 deletions _examples/pagination/examplebot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
_ "embed"
"os"

"github.com/disgoorg/disgo"
"github.com/disgoorg/disgo/rest"
"github.com/disgoorg/log"
)

var token = os.Getenv("disgo_token")

func main() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
log.SetLevel(log.LevelDebug)
log.Info("starting example...")
log.Info("bot version: ", disgo.Version)

client := rest.New(rest.NewClient(token))

page := client.GetMessagesPage(817327182111571989, 1016790288607498240, 3)

var i int
for page.Next() {
for _, m := range page.Items {
println(m.ID)
}
println("---")
i++
if i >= 3 {
break
}
}
if page.Err != nil {
log.Error(page.Err)
}
}
13 changes: 13 additions & 0 deletions rest/channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Channels interface {

GetMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) (*discord.Message, error)
GetMessages(channelID snowflake.ID, around snowflake.ID, before snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.Message, error)
GetMessagesPage(channelID snowflake.ID, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.Message]
CreateMessage(channelID snowflake.ID, messageCreate discord.MessageCreate, opts ...RequestOpt) (*discord.Message, error)
UpdateMessage(channelID snowflake.ID, messageID snowflake.ID, messageUpdate discord.MessageUpdate, opts ...RequestOpt) (*discord.Message, error)
DeleteMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error
Expand Down Expand Up @@ -128,6 +129,18 @@ func (s *channelImpl) GetMessages(channelID snowflake.ID, around snowflake.ID, b
return
}

func (s *channelImpl) GetMessagesPage(channelID snowflake.ID, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.Message] {
return Page[discord.Message]{
getItemsFunc: func(before snowflake.ID, after snowflake.ID) ([]discord.Message, error) {
return s.GetMessages(channelID, 0, before, after, limit, opts...)
},
getIDFunc: func(msg discord.Message) snowflake.ID {
return msg.ID
},
ID: startID,
}
}

func (s *channelImpl) CreateMessage(channelID snowflake.ID, messageCreate discord.MessageCreate, opts ...RequestOpt) (message *discord.Message, err error) {
body, err := messageCreate.ToBody()
if err != nil {
Expand Down
17 changes: 15 additions & 2 deletions rest/guild_scheduled_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type GuildScheduledEvents interface {
UpdateGuildScheduledEvent(guildID snowflake.ID, guildScheduledEventID snowflake.ID, guildScheduledEventUpdate discord.GuildScheduledEventUpdate, opts ...RequestOpt) (*discord.GuildScheduledEvent, error)
DeleteGuildScheduledEvent(guildID snowflake.ID, guildScheduledEventID snowflake.ID, opts ...RequestOpt) error

GetGuildScheduledEventUsers(guildID snowflake.ID, guildScheduledEventID snowflake.ID, limit int, withMember bool, before snowflake.ID, after snowflake.ID, opts ...RequestOpt) ([]discord.GuildScheduledEventUser, error)
GetGuildScheduledEventUsers(guildID snowflake.ID, guildScheduledEventID snowflake.ID, withMember bool, before snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.GuildScheduledEventUser, error)
GetGuildScheduledEventUsersPage(guildID snowflake.ID, guildScheduledEventID snowflake.ID, withMember bool, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.GuildScheduledEventUser]
}

type guildScheduledEventImpl struct {
Expand Down Expand Up @@ -57,7 +58,7 @@ func (s *guildScheduledEventImpl) DeleteGuildScheduledEvent(guildID snowflake.ID
return s.client.Do(DeleteGuildScheduledEvent.Compile(nil, guildID, guildScheduledEventID), nil, nil, opts...)
}

func (s *guildScheduledEventImpl) GetGuildScheduledEventUsers(guildID snowflake.ID, guildScheduledEventID snowflake.ID, limit int, withMember bool, before snowflake.ID, after snowflake.ID, opts ...RequestOpt) (guildScheduledEventUsers []discord.GuildScheduledEventUser, err error) {
func (s *guildScheduledEventImpl) GetGuildScheduledEventUsers(guildID snowflake.ID, guildScheduledEventID snowflake.ID, withMember bool, before snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) (guildScheduledEventUsers []discord.GuildScheduledEventUser, err error) {
queryValues := discord.QueryValues{}
if limit > 0 {
queryValues["limit"] = limit
Expand All @@ -74,3 +75,15 @@ func (s *guildScheduledEventImpl) GetGuildScheduledEventUsers(guildID snowflake.
err = s.client.Do(GetGuildScheduledEventUsers.Compile(nil, guildID, guildScheduledEventID), nil, &guildScheduledEventUsers, opts...)
return
}

func (s *guildScheduledEventImpl) GetGuildScheduledEventUsersPage(guildID snowflake.ID, guildScheduledEventID snowflake.ID, withMember bool, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.GuildScheduledEventUser] {
return Page[discord.GuildScheduledEventUser]{
getItemsFunc: func(before snowflake.ID, after snowflake.ID) ([]discord.GuildScheduledEventUser, error) {
return s.GetGuildScheduledEventUsers(guildID, guildScheduledEventID, withMember, before, after, limit, opts...)
},
getIDFunc: func(user discord.GuildScheduledEventUser) snowflake.ID {
return user.User.ID
},
ID: startID,
}
}
28 changes: 28 additions & 0 deletions rest/guilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Guilds interface {
DeleteRole(guildID snowflake.ID, roleID snowflake.ID, opts ...RequestOpt) error

GetBans(guildID snowflake.ID, before snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.Ban, error)
GetBansPage(guildID snowflake.ID, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.Ban]
GetBan(guildID snowflake.ID, userID snowflake.ID, opts ...RequestOpt) (*discord.Ban, error)
AddBan(guildID snowflake.ID, userID snowflake.ID, deleteMessageDuration time.Duration, opts ...RequestOpt) error
DeleteBan(guildID snowflake.ID, userID snowflake.ID, opts ...RequestOpt) error
Expand All @@ -42,6 +43,7 @@ type Guilds interface {
GetAllWebhooks(guildID snowflake.ID, opts ...RequestOpt) ([]discord.Webhook, error)

GetAuditLog(guildID snowflake.ID, userID snowflake.ID, actionType discord.AuditLogEvent, before snowflake.ID, limit int, opts ...RequestOpt) (*discord.AuditLog, error)
GetAuditLogPage(guildID snowflake.ID, userID snowflake.ID, actionType discord.AuditLogEvent, startID snowflake.ID, limit int, opts ...RequestOpt) AuditLogPage
}

type guildImpl struct {
Expand Down Expand Up @@ -144,6 +146,18 @@ func (s *guildImpl) GetBans(guildID snowflake.ID, before snowflake.ID, after sno
return
}

func (s *guildImpl) GetBansPage(guildID snowflake.ID, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.Ban] {
return Page[discord.Ban]{
getItemsFunc: func(before snowflake.ID, after snowflake.ID) (bans []discord.Ban, err error) {
return s.GetBans(guildID, before, after, limit, opts...)
},
getIDFunc: func(ban discord.Ban) snowflake.ID {
return ban.User.ID
},
ID: startID,
}
}

func (s *guildImpl) GetBan(guildID snowflake.ID, userID snowflake.ID, opts ...RequestOpt) (ban *discord.Ban, err error) {
err = s.client.Do(GetBan.Compile(nil, guildID, userID), nil, &ban, opts...)
return
Expand Down Expand Up @@ -193,3 +207,17 @@ func (s *guildImpl) GetAuditLog(guildID snowflake.ID, userID snowflake.ID, actio
err = s.client.Do(GetAuditLogs.Compile(values, guildID), nil, &auditLog, opts...)
return
}

func (s *guildImpl) GetAuditLogPage(guildID snowflake.ID, userID snowflake.ID, actionType discord.AuditLogEvent, startID snowflake.ID, limit int, opts ...RequestOpt) AuditLogPage {
return AuditLogPage{
getItems: func(before snowflake.ID) (discord.AuditLog, error) {
log, err := s.GetAuditLog(guildID, userID, actionType, before, limit, opts...)
var finalLog discord.AuditLog
if log != nil {
finalLog = *log
}
return finalLog, err
},
ID: startID,
}
}
13 changes: 13 additions & 0 deletions rest/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type OAuth2 interface {
GetCurrentUser(bearerToken string, opts ...RequestOpt) (*discord.OAuth2User, error)
GetCurrentMember(bearerToken string, guildID snowflake.ID, opts ...RequestOpt) (*discord.Member, error)
GetCurrentUserGuilds(bearerToken string, before snowflake.ID, after snowflake.ID, limit int, opts ...RequestOpt) ([]discord.OAuth2Guild, error)
GetCurrentUserGuildsPage(bearerToken string, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.OAuth2Guild]
GetCurrentUserConnections(bearerToken string, opts ...RequestOpt) ([]discord.Connection, error)

SetGuildCommandPermissions(bearerToken string, applicationID snowflake.ID, guildID snowflake.ID, commandID snowflake.ID, commandPermissions []discord.ApplicationCommandPermission, opts ...RequestOpt) (*discord.ApplicationCommandPermissions, error)
Expand Down Expand Up @@ -74,6 +75,18 @@ func (s *oAuth2Impl) GetCurrentUserGuilds(bearerToken string, before snowflake.I
return
}

func (s *oAuth2Impl) GetCurrentUserGuildsPage(bearerToken string, startID snowflake.ID, limit int, opts ...RequestOpt) Page[discord.OAuth2Guild] {
return Page[discord.OAuth2Guild]{
getItemsFunc: func(before snowflake.ID, after snowflake.ID) ([]discord.OAuth2Guild, error) {
return s.GetCurrentUserGuilds(bearerToken, before, after, limit, opts...)
},
getIDFunc: func(guild discord.OAuth2Guild) snowflake.ID {
return guild.ID
},
ID: startID,
}
}

func (s *oAuth2Impl) GetCurrentUserConnections(bearerToken string, opts ...RequestOpt) (connections []discord.Connection, err error) {
err = s.client.Do(GetCurrentUserConnections.Compile(nil), nil, &connections, withBearerToken(bearerToken, opts)...)
return
Expand Down
77 changes: 77 additions & 0 deletions rest/page.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package rest

import (
"errors"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/snowflake/v2"
)

var ErrNoMorePages = errors.New("no more pages")

type Page[T any] struct {
getItemsFunc func(before snowflake.ID, after snowflake.ID) ([]T, error)
getIDFunc func(t T) snowflake.ID

Items []T
Err error

ID snowflake.ID
}

func (p *Page[T]) Next() bool {
if p.Err != nil {
return false
}

if len(p.Items) > 0 {
p.ID = p.getIDFunc(p.Items[0])
}

p.Items, p.Err = p.getItemsFunc(0, p.ID)
if p.Err == nil && len(p.Items) == 0 {
p.Err = ErrNoMorePages
}
return p.Err == nil
}

func (p *Page[T]) Previous() bool {
if p.Err != nil {
return false
}

if len(p.Items) > 0 {
p.ID = p.getIDFunc(p.Items[len(p.Items)-1])
}

p.Items, p.Err = p.getItemsFunc(p.ID, 0)
if p.Err == nil && len(p.Items) == 0 {
p.Err = ErrNoMorePages
}
return p.Err == nil
}

type AuditLogPage struct {
getItems func(before snowflake.ID) (discord.AuditLog, error)

discord.AuditLog
Err error

ID snowflake.ID
}

func (p *AuditLogPage) Previous() bool {
if p.Err != nil {
return false
}

if len(p.AuditLogEntries) > 0 {
p.ID = p.AuditLogEntries[len(p.AuditLogEntries)-1].ID
}

p.AuditLog, p.Err = p.getItems(p.ID)
if p.Err == nil && len(p.AuditLogEntries) == 0 {
p.Err = ErrNoMorePages
}
return p.Err == nil
}

0 comments on commit 1c504a9

Please sign in to comment.