Compare commits
29 Commits
main
...
ImplementP
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75fe8ee78b | ||
|
|
9d87b30e0c | ||
|
|
1a6b867956 | ||
|
|
e0465585ce | ||
|
|
fbd62c8b0c | ||
|
|
202c796896 | ||
|
|
6ae0baff43 | ||
|
|
89edc583a3 | ||
|
|
a9372af65c | ||
|
|
397526c4c8 | ||
|
|
84440ade4d | ||
|
|
79ef5a56fc | ||
|
|
39006d2cef | ||
|
|
0d811278b7 | ||
|
|
deacf812ca | ||
|
|
0dfb1b1d4d | ||
|
|
5fffb5cfb8 | ||
|
|
21d8ec9d4a | ||
|
|
93607f5cd5 | ||
|
|
07e772ee0e | ||
|
|
63080485a8 | ||
|
|
27990e6174 | ||
|
|
7de04b98ab | ||
|
|
aef4c688ac | ||
|
|
54d5e05950 | ||
|
|
5fbc37fbc1 | ||
|
|
d1f0d683af | ||
|
|
fa1a432a87 | ||
|
|
8d4277b1c7 |
@ -61,25 +61,51 @@ func CreateCollections(
|
||||
// conversations as well.
|
||||
// Also, this should be produced by the Handler.
|
||||
// chanPager := handler.NewChannelsPager(qp.ProtectedResource.ID())
|
||||
// TODO(neha): enumerate channels
|
||||
channels := []graph.Displayable{}
|
||||
|
||||
collections, err := populateCollections(
|
||||
ctx,
|
||||
qp,
|
||||
handler,
|
||||
su,
|
||||
channels,
|
||||
scope,
|
||||
// dps,
|
||||
bpc.Options,
|
||||
errs)
|
||||
if err != nil {
|
||||
return nil, clues.Wrap(err, "filling collections")
|
||||
}
|
||||
// enumerating channels
|
||||
pager := handler.NewChannelsPager(qp.ProtectedResource.ID())
|
||||
|
||||
for _, coll := range collections {
|
||||
allCollections = append(allCollections, coll)
|
||||
// Loop through all pages returned by Graph API.
|
||||
for {
|
||||
var (
|
||||
err error
|
||||
page api.PageLinker
|
||||
)
|
||||
|
||||
page, err = pager.GetPage(graph.ConsumeNTokens(ctx, graph.SingleGetOrDeltaLC))
|
||||
if err != nil {
|
||||
return nil, graph.Wrap(ctx, err, "retrieving drives")
|
||||
}
|
||||
|
||||
channels, err := pager.ValuesIn(page)
|
||||
if err != nil {
|
||||
return nil, graph.Wrap(ctx, err, "extracting drives from response")
|
||||
}
|
||||
|
||||
collections, err := populateCollections(
|
||||
ctx,
|
||||
qp,
|
||||
handler,
|
||||
su,
|
||||
channels,
|
||||
scope,
|
||||
// dps,
|
||||
bpc.Options,
|
||||
errs)
|
||||
if err != nil {
|
||||
return nil, clues.Wrap(err, "filling collections")
|
||||
}
|
||||
|
||||
for _, coll := range collections {
|
||||
allCollections = append(allCollections, coll)
|
||||
}
|
||||
|
||||
nextLink := ptr.Val(page.GetOdataNextLink())
|
||||
if len(nextLink) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
pager.SetNext(nextLink)
|
||||
}
|
||||
|
||||
return allCollections, nil
|
||||
@ -90,7 +116,7 @@ func populateCollections(
|
||||
qp graph.QueryParams,
|
||||
bh BackupHandler,
|
||||
statusUpdater support.StatusUpdater,
|
||||
channels []graph.Displayable,
|
||||
channels []models.Channelable,
|
||||
scope selectors.GroupsScope,
|
||||
// dps DeltaPaths,
|
||||
ctrlOpts control.Options,
|
||||
@ -127,7 +153,9 @@ func populateCollections(
|
||||
// prevDelta = dp.Delta
|
||||
// prevPathStr = dp.Path // do not log: pii; log prevPath instead
|
||||
// prevPath path.Path
|
||||
ictx = clues.Add(
|
||||
// TODO: update this path
|
||||
previousPath string
|
||||
ictx = clues.Add(
|
||||
ctx,
|
||||
"channel_id", cID)
|
||||
// "previous_delta", pii.SafeURL{
|
||||
@ -153,11 +181,10 @@ func populateCollections(
|
||||
// }
|
||||
|
||||
// ictx = clues.Add(ictx, "previous_path", prevPath)
|
||||
|
||||
// TODO: the handler should provide this implementation.
|
||||
items, err := collectItems(
|
||||
ctx,
|
||||
bh.NewMessagePager(qp.ProtectedResource.ID(), ptr.Val(c.GetId())))
|
||||
bh.NewMessagePager(qp.ProtectedResource.ID(), ptr.Val(c.GetId()), previousPath))
|
||||
if err != nil {
|
||||
el.AddRecoverable(ctx, clues.Stack(err))
|
||||
continue
|
||||
@ -306,7 +333,7 @@ func includeContainer(
|
||||
directory := ptr.Val(gd.GetDisplayName())
|
||||
|
||||
// TODO(keepers): awaiting parent branch to update to main
|
||||
ok := scope.Matches(selectors.GroupsCategoryUnknown, directory)
|
||||
ok := scope.Matches(selectors.GroupsChannelMessage, directory)
|
||||
|
||||
logger.Ctx(ctx).With(
|
||||
"included", ok,
|
||||
|
||||
59
src/internal/m365/collection/groups/channels_handler.go
Normal file
59
src/internal/m365/collection/groups/channels_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package groups
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/microsoft/kiota-abstractions-go/serialization"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
var _ BackupHandler = &groupBackupHandler{}
|
||||
|
||||
type groupBackupHandler struct {
|
||||
ac api.Channels
|
||||
groupID string
|
||||
}
|
||||
|
||||
func NewGroupBackupHandler(groupID string, ac api.Channels, scope selectors.GroupsScope) groupBackupHandler {
|
||||
return groupBackupHandler{
|
||||
ac: ac,
|
||||
groupID: groupID,
|
||||
}
|
||||
}
|
||||
|
||||
func (gHandler groupBackupHandler) GetChannelByID(
|
||||
ctx context.Context,
|
||||
teamID, channelID string,
|
||||
) (models.Channelable, error) {
|
||||
return gHandler.ac.Client.Channels().GetChannel(ctx, teamID, channelID)
|
||||
}
|
||||
|
||||
func (gHandler groupBackupHandler) NewChannelsPager(
|
||||
teamID string,
|
||||
) api.Pager[models.Channelable] {
|
||||
return gHandler.ac.NewChannelPager(teamID)
|
||||
}
|
||||
|
||||
func (gHandler groupBackupHandler) GetMessageByID(
|
||||
ctx context.Context,
|
||||
teamID, channelID, itemID string,
|
||||
) (models.ChatMessageable, error) {
|
||||
chatMessage, _, err := gHandler.ac.GetMessage(ctx, teamID, channelID, itemID)
|
||||
return chatMessage, err
|
||||
}
|
||||
|
||||
func (gHandler groupBackupHandler) NewMessagePager(
|
||||
teamID, channelID, prevDelta string,
|
||||
) api.DeltaPager[models.ChatMessageable] {
|
||||
return gHandler.ac.NewChannelMessageDeltaPager(teamID, channelID, prevDelta)
|
||||
}
|
||||
|
||||
func (gHandler groupBackupHandler) GetMessageReplies(
|
||||
ctx context.Context,
|
||||
teamID, channelID, messageID string,
|
||||
) (serialization.Parsable, error) {
|
||||
return gHandler.ac.GetReplies(ctx, teamID, channelID, messageID)
|
||||
}
|
||||
@ -23,7 +23,7 @@ type BackupHandler interface {
|
||||
teamID, channelID, itemID string,
|
||||
) (models.ChatMessageable, error)
|
||||
NewMessagePager(
|
||||
teamID, channelID string,
|
||||
teamID, channelID, prevDelta string,
|
||||
) api.DeltaPager[models.ChatMessageable]
|
||||
|
||||
GetMessageReplies(
|
||||
@ -31,10 +31,3 @@ type BackupHandler interface {
|
||||
teamID, channelID, messageID string,
|
||||
) (serialization.Parsable, error)
|
||||
}
|
||||
|
||||
type BackupMessagesHandler interface {
|
||||
GetMessage(ctx context.Context, teamID, channelID, itemID string) (models.ChatMessageable, error)
|
||||
NewMessagePager(teamID, channelID string) api.DeltaPager[models.ChatMessageable]
|
||||
GetChannel(ctx context.Context, teamID, channelID string) (models.Channelable, error)
|
||||
GetReply(ctx context.Context, teamID, channelID, messageID string) (serialization.Parsable, error)
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/groups"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/site"
|
||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||
"github.com/alcionai/corso/src/internal/m365/support"
|
||||
@ -94,6 +95,20 @@ func ProduceBackupCollections(
|
||||
el.AddRecoverable(ctx, err)
|
||||
continue
|
||||
}
|
||||
|
||||
case path.ChannelMessagesCategory:
|
||||
dbcs, err = groups.CreateCollections(
|
||||
ctx,
|
||||
bpc,
|
||||
groups.NewGroupBackupHandler(bpc.ProtectedResource.ID(), ac.Channels(), scope),
|
||||
creds.AzureTenantID,
|
||||
scope,
|
||||
su,
|
||||
errs)
|
||||
if err != nil {
|
||||
el.AddRecoverable(ctx, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
collections = append(collections, dbcs...)
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
)
|
||||
|
||||
@ -108,8 +107,7 @@ func (c Channels) GetChannelByName(
|
||||
func (c Channels) GetMessage(
|
||||
ctx context.Context,
|
||||
teamID, channelID, itemID string,
|
||||
errs *fault.Bus,
|
||||
) (serialization.Parsable, *details.GroupsInfo, error) {
|
||||
) (models.ChatMessageable, *details.GroupsInfo, error) {
|
||||
var size int64
|
||||
|
||||
message, err := c.Stable.
|
||||
|
||||
@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/teams"
|
||||
|
||||
@ -79,6 +80,79 @@ func (c Channels) NewChannelMessageDeltaPager(
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// non delta channel message pager
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type MessageItemIDType struct {
|
||||
ItemID string
|
||||
}
|
||||
|
||||
type channelMessagePageCtrl struct {
|
||||
gs graph.Servicer
|
||||
builder *teams.ItemChannelsItemMessagesRequestBuilder
|
||||
options *teams.ItemChannelsItemMessagesRequestBuilderGetRequestConfiguration
|
||||
}
|
||||
|
||||
func (c Channels) GetItemIDsInContainer(
|
||||
ctx context.Context,
|
||||
teamID, channelID string,
|
||||
) (map[string]struct{}, error) {
|
||||
ctx = clues.Add(ctx, "channel_id", channelID)
|
||||
pager := c.NewChannelItemPager(teamID, channelID)
|
||||
|
||||
items, err := enumerateItems(ctx, pager)
|
||||
if err != nil {
|
||||
return nil, graph.Wrap(ctx, err, "enumerating contacts")
|
||||
}
|
||||
|
||||
m := map[string]struct{}{}
|
||||
|
||||
for _, item := range items {
|
||||
m[ptr.Val(item.GetId())] = struct{}{}
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c Channels) NewChannelItemPager(
|
||||
teamID, containerID string,
|
||||
selectProps ...string,
|
||||
) itemPager[models.ChatMessageable] {
|
||||
options := &teams.ItemChannelsItemMessagesRequestBuilderGetRequestConfiguration{
|
||||
QueryParameters: &teams.ItemChannelsItemMessagesRequestBuilderGetQueryParameters{},
|
||||
}
|
||||
|
||||
if len(selectProps) > 0 {
|
||||
options.QueryParameters.Select = selectProps
|
||||
}
|
||||
|
||||
builder := c.Stable.
|
||||
Client().
|
||||
Teams().
|
||||
ByTeamId(teamID).
|
||||
Channels().
|
||||
ByChannelId(containerID).
|
||||
Messages()
|
||||
|
||||
return &channelMessagePageCtrl{c.Stable, builder, options}
|
||||
}
|
||||
|
||||
//lint:ignore U1000 False Positive
|
||||
func (p *channelMessagePageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.ChatMessageable], error) {
|
||||
page, err := p.builder.Get(ctx, p.options)
|
||||
if err != nil {
|
||||
return nil, graph.Stack(ctx, err)
|
||||
}
|
||||
|
||||
return EmptyDeltaLinker[models.ChatMessageable]{PageLinkValuer: page}, nil
|
||||
}
|
||||
|
||||
//lint:ignore U1000 False Positive
|
||||
func (p *channelMessagePageCtrl) setNext(nextLink string) {
|
||||
p.builder = teams.NewItemChannelsItemMessagesRequestBuilder(nextLink, p.gs.Adapter())
|
||||
}
|
||||
|
||||
// GetChannelMessagesDelta fetches a delta of all messages in the channel.
|
||||
func (c Channels) GetChannelMessagesDelta(
|
||||
ctx context.Context,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user