Add custom drive item

This commit is contained in:
Abhishek Pandey 2023-12-01 02:10:29 -08:00
parent 05dee79560
commit 7a7802e271
9 changed files with 214 additions and 240 deletions

View File

@ -51,7 +51,7 @@ type Collection struct {
// represents // represents
folderPath path.Path folderPath path.Path
// M365 IDs of file items within this collection // M365 IDs of file items within this collection
driveItems map[string]CorsoDriveItemable driveItems map[string]LiteDriveItemable
// Primary M365 ID of the drive this collection was created from // Primary M365 ID of the drive this collection was created from
driveID string driveID string
@ -91,7 +91,7 @@ type Collection struct {
counter *count.Bus counter *count.Bus
} }
func (c *Collection) GetDriveItemsMap() map[string]CorsoDriveItemable { func (c *Collection) GetDriveItemsMap() map[string]LiteDriveItemable {
return c.driveItems return c.driveItems
} }
@ -175,7 +175,7 @@ func newColl(
protectedResource: resource, protectedResource: resource,
folderPath: currPath, folderPath: currPath,
prevPath: prevPath, prevPath: prevPath,
driveItems: map[string]CorsoDriveItemable{}, driveItems: map[string]LiteDriveItemable{},
driveID: driveID, driveID: driveID,
data: dataCh, data: dataCh,
statusUpdater: statusUpdater, statusUpdater: statusUpdater,
@ -193,11 +193,11 @@ func newColl(
// Adds an itemID to the collection. This will make it eligible to be // Adds an itemID to the collection. This will make it eligible to be
// populated. The return values denotes if the item was previously // populated. The return values denotes if the item was previously
// present or is new one. // present or is new one.
func (oc *Collection) Add(cdi CorsoDriveItemable) bool { func (oc *Collection) Add(cdi LiteDriveItemable) bool {
// _, found := oc.driveItems[ptr.Val(item.GetId())] // _, found := oc.driveItems[ptr.Val(item.GetId())]
// oc.driveItems[ptr.Val(item.GetId())] = item // oc.driveItems[ptr.Val(item.GetId())] = item
//cdi := ToCorsoDriveItemable(item) //cdi := ToLiteDriveItemable(item)
_, found := oc.driveItems[ptr.Val(cdi.GetId())] _, found := oc.driveItems[ptr.Val(cdi.GetId())]
oc.driveItems[ptr.Val(cdi.GetId())] = cdi oc.driveItems[ptr.Val(cdi.GetId())] = cdi
@ -268,7 +268,7 @@ func (oc Collection) DoNotMergeItems() bool {
func (oc *Collection) getDriveItemContent( func (oc *Collection) getDriveItemContent(
ctx context.Context, ctx context.Context,
driveID string, driveID string,
item CorsoDriveItemable, item LiteDriveItemable,
errs *fault.Bus, errs *fault.Bus,
) (io.ReadCloser, error) { ) (io.ReadCloser, error) {
// var ( // var (
@ -351,7 +351,7 @@ func downloadContent(
ctx context.Context, ctx context.Context,
iaag itemAndAPIGetter, iaag itemAndAPIGetter,
uc getItemPropertyer, uc getItemPropertyer,
item CorsoDriveItemable, item LiteDriveItemable,
driveID string, driveID string,
counter *count.Bus, counter *count.Bus,
) (io.ReadCloser, error) { ) (io.ReadCloser, error) {
@ -386,7 +386,7 @@ func downloadContent(
return nil, clues.Wrap(err, "retrieving expired item") return nil, clues.Wrap(err, "retrieving expired item")
} }
cdi := ToCorsoDriveItemable(di) cdi := ToLiteDriveItemable(di)
content, err = downloadItem(ctx, iaag, cdi) content, err = downloadItem(ctx, iaag, cdi)
if err != nil { if err != nil {
@ -482,7 +482,7 @@ func (oc *Collection) streamItems(ctx context.Context, errs *fault.Bus) {
wg.Add(1) wg.Add(1)
go func(item CorsoDriveItemable) { go func(item LiteDriveItemable) {
defer wg.Done() defer wg.Done()
defer func() { <-semaphoreCh }() defer func() { <-semaphoreCh }()
@ -506,14 +506,14 @@ func (oc *Collection) streamItems(ctx context.Context, errs *fault.Bus) {
type lazyItemGetter struct { type lazyItemGetter struct {
info *details.ItemInfo info *details.ItemInfo
item CorsoDriveItemable item LiteDriveItemable
driveID string driveID string
suffix string suffix string
itemExtensionFactory []extensions.CreateItemExtensioner itemExtensionFactory []extensions.CreateItemExtensioner
contentGetter func( contentGetter func(
ctx context.Context, ctx context.Context,
driveID string, driveID string,
item CorsoDriveItemable, item LiteDriveItemable,
errs *fault.Bus) (io.ReadCloser, error) errs *fault.Bus) (io.ReadCloser, error)
} }
@ -554,7 +554,7 @@ func (lig *lazyItemGetter) GetData(
func (oc *Collection) streamDriveItem( func (oc *Collection) streamDriveItem(
ctx context.Context, ctx context.Context,
parentPath *path.Builder, parentPath *path.Builder,
item CorsoDriveItemable, item LiteDriveItemable,
stats *driveStats, stats *driveStats,
itemExtensionFactory []extensions.CreateItemExtensioner, itemExtensionFactory []extensions.CreateItemExtensioner,
errs *fault.Bus, errs *fault.Bus,

View File

@ -696,7 +696,7 @@ func (c *Collections) handleDelete(
func (c *Collections) getCollectionPath( func (c *Collections) getCollectionPath(
driveID string, driveID string,
item CorsoDriveItemable, item LiteDriveItemable,
) (path.Path, error) { ) (path.Path, error) {
var ( var (
pb = odConsts.DriveFolderPrefixBuilder(driveID) pb = odConsts.DriveFolderPrefixBuilder(driveID)
@ -855,7 +855,7 @@ func (c *Collections) processItem(
counter *count.Bus, counter *count.Bus,
skipper fault.AddSkipper, skipper fault.AddSkipper,
) error { ) error {
item := ToCorsoDriveItemable(di) item := ToLiteDriveItemable(di)
var ( var (
itemID = ptr.Val(item.GetId()) itemID = ptr.Val(item.GetId())

View File

@ -1,112 +1,183 @@
// Disable revive linter since any structs in this file will expose the same
// funcs as the original structs in the msgraph-sdk-go package, which do not
// follow some of the golint rules.
//
//nolint:revive
package drive package drive
import ( import (
"strings" "strings"
"time" "time"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/common/str" "github.com/alcionai/corso/src/internal/common/str"
"github.com/microsoftgraph/msgraph-sdk-go/models"
) )
// Replica of models.DriveItemable // Replica of models.DriveItemable
type CorsoDriveItemable interface { type LiteDriveItemable interface {
GetId() *string GetId() *string
GetName() *string GetName() *string
GetSize() *int64 GetSize() *int64
GetFile() fileDriveItemable // TODO(pandeyabs): replace with any
GetFolder() folderDriveItemable GetFolder() interface{}
GetPackageEscaped() packageDriveItemable GetPackageEscaped() interface{}
GetShared() interface{}
GetMalware() interface{}
GetDeleted() interface{}
GetRoot() interface{}
GetFile() fileItemable
GetParentReference() parentReferenceable GetParentReference() parentReferenceable
GetAdditionalData() map[string]interface{}
SetParentReference(parentReferenceable) SetParentReference(parentReferenceable)
GetShared() itemSharedable
GetCreatedBy() itemIdentitySetable GetCreatedBy() itemIdentitySetable
GetCreatedDateTime() *time.Time GetCreatedDateTime() *time.Time
GetLastModifiedDateTime() *time.Time GetLastModifiedDateTime() *time.Time
GetMalware() malwareable
GetDeleted() deletedable
GetRoot() itemRootable
}
type fileDriveItemable interface {
GetMimeType() *string
}
type folderDriveItemable interface{}
type packageDriveItemable interface{}
type parentReferenceable interface {
GetPath() *string
GetId() *string
GetName() *string
GetDriveId() *string
}
type itemSharedable interface{}
type malwareable interface{}
type deletedable interface{}
type itemRootable interface{}
type itemIdentitySetable interface {
GetUser() itemUserable
}
type itemUserable interface {
GetAdditionalData() map[string]interface{} GetAdditionalData() map[string]interface{}
} }
// Concrete implementations var _ LiteDriveItemable = &driveItema{}
type folderDriveItem struct {
isFolder bool type driveItema struct {
id string
name string
size int64
folder interface{}
pkg interface{}
shared interface{}
malware interface{}
deleted interface{}
root interface{}
file fileItemable
parentRef parentReferenceable
createdBy itemIdentitySetable
createdDateTime time.Time
lastModifiedDateTime time.Time
additionalData map[string]interface{}
} }
type fileDriveItem struct { // nolint
isFile bool func (c *driveItema) GetId() *string {
return &c.id
}
func (c *driveItema) GetName() *string {
return &c.name
}
func (c *driveItema) GetSize() *int64 {
return &c.size
}
func (c *driveItema) GetFolder() interface{} {
return c.folder
}
func (c *driveItema) GetPackageEscaped() interface{} {
return c.pkg
}
func (c *driveItema) GetShared() interface{} {
return c.shared
}
func (c *driveItema) GetMalware() interface{} {
return c.malware
}
func (c *driveItema) GetDeleted() interface{} {
return c.deleted
}
func (c *driveItema) GetRoot() interface{} {
return c.root
}
func (c *driveItema) GetFile() fileItemable {
return c.file
}
func (c *driveItema) GetParentReference() parentReferenceable {
return c.parentRef
}
// TODO(pandeyabs): Should we only support GETs?
func (c *driveItema) SetParentReference(parent parentReferenceable) {
c.parentRef = parent
}
func (c *driveItema) GetCreatedBy() itemIdentitySetable {
return c.createdBy
}
func (c *driveItema) GetCreatedDateTime() *time.Time {
return &c.createdDateTime
}
func (c *driveItema) GetLastModifiedDateTime() *time.Time {
return &c.lastModifiedDateTime
}
func (c *driveItema) GetAdditionalData() map[string]interface{} {
return c.additionalData
}
type (
fileItemable interface {
GetMimeType() *string
}
parentReferenceable interface {
GetPath() *string
GetId() *string
GetName() *string
GetDriveId() *string
}
itemIdentitySetable interface {
GetUser() itemUserable
}
itemUserable interface {
GetAdditionalData() map[string]interface{}
}
)
// Concrete implementations
var _ fileItemable = &fileItem{}
type fileItem struct {
mimeType string mimeType string
} }
func (fdi *fileDriveItem) GetMimeType() *string { func (f *fileItem) GetMimeType() *string {
return &fdi.mimeType return &f.mimeType
} }
type packageDriveItem struct { var _ parentReferenceable = &parentRef{}
isPackage bool
}
type parentReference struct { type parentRef struct {
path string path string
id string id string
name string name string
driveId string driveID string
} }
func (pr *parentReference) GetPath() *string { func (pr *parentRef) GetPath() *string {
return &pr.path return &pr.path
} }
func (pr *parentReference) GetId() *string { func (pr *parentRef) GetId() *string {
return &pr.id return &pr.id
} }
func (pr *parentReference) GetName() *string { func (pr *parentRef) GetName() *string {
return &pr.name return &pr.name
} }
func (pr *parentReference) GetDriveId() *string { func (pr *parentRef) GetDriveId() *string {
return &pr.driveId return &pr.driveID
} }
type itemShared struct { var _ itemIdentitySetable = &itemIdentitySet{}
isShared bool
}
type itemMalware struct {
isMalware bool
}
type itemDeleted struct {
isDeleted bool
}
type itemRoot struct {
isRoot bool
}
type itemIdentitySet struct { type itemIdentitySet struct {
user itemUserable user itemUserable
@ -116,6 +187,8 @@ func (iis *itemIdentitySet) GetUser() itemUserable {
return iis.user return iis.user
} }
var _ itemUserable = &itemUser{}
type itemUser struct { type itemUser struct {
additionalData map[string]interface{} additionalData map[string]interface{}
} }
@ -124,97 +197,70 @@ func (iu *itemUser) GetAdditionalData() map[string]interface{} {
return iu.additionalData return iu.additionalData
} }
type CorsoDriveItem struct { func ToLiteDriveItemable(item models.DriveItemable) LiteDriveItemable {
ID string cdi := &driveItema{
Name string id: strings.Clone(ptr.Val(item.GetId())),
Size int64 name: strings.Clone(ptr.Val(item.GetName())),
File fileDriveItemable size: ptr.Val(item.GetSize()),
Folder folderDriveItemable createdDateTime: ptr.Val(item.GetCreatedDateTime()),
Package packageDriveItemable lastModifiedDateTime: ptr.Val(item.GetLastModifiedDateTime()),
AdditionalData map[string]interface{} }
ParentReference parentReferenceable
Shared itemSharedable
CreatedBy itemIdentitySetable
CreatedDateTime time.Time
LastModifiedDateTime time.Time
Malware malwareable
Deleted deletedable
Root itemRootable
}
func (c *CorsoDriveItem) GetId() *string { if item.GetFolder() != nil {
return &c.ID cdi.folder = &struct{}{}
} } else if item.GetFile() != nil {
cdi.file = &fileItem{
mimeType: strings.Clone(ptr.Val(item.GetFile().GetMimeType())),
}
} else if item.GetPackageEscaped() != nil {
cdi.pkg = &struct{}{}
}
func (c *CorsoDriveItem) GetName() *string { if item.GetParentReference() != nil {
return &c.Name cdi.parentRef = &parentRef{
} id: strings.Clone(ptr.Val(item.GetParentReference().GetId())),
path: strings.Clone(ptr.Val(item.GetParentReference().GetPath())),
name: strings.Clone(ptr.Val(item.GetParentReference().GetName())),
driveID: strings.Clone(ptr.Val(item.GetParentReference().GetDriveId())),
}
}
func (c *CorsoDriveItem) GetSize() *int64 { if item.GetShared() != nil {
return &c.Size cdi.shared = &struct{}{}
} }
func (c *CorsoDriveItem) GetFile() fileDriveItemable { if item.GetMalware() != nil {
return c.File cdi.malware = &struct{}{}
} }
func (c *CorsoDriveItem) GetFolder() folderDriveItemable { if item.GetDeleted() != nil {
return c.Folder cdi.deleted = &struct{}{}
} }
func (c *CorsoDriveItem) GetPackageEscaped() packageDriveItemable { if item.GetRoot() != nil {
return c.Package cdi.root = &struct{}{}
} }
func (c *CorsoDriveItem) GetParentReference() parentReferenceable { if item.GetCreatedBy() != nil && item.GetCreatedBy().GetUser() != nil {
return c.ParentReference additionalData := item.GetCreatedBy().GetUser().GetAdditionalData()
} ad := make(map[string]interface{})
// TODO: Should we only support GETs? var s string
func (c *CorsoDriveItem) SetParentReference(parent parentReferenceable) {
c.ParentReference = parent
}
func (c *CorsoDriveItem) GetAdditionalData() map[string]interface{} { ed, ok := additionalData["email"]
return c.AdditionalData if ok {
} s = strings.Clone(ptr.Val(ed.(*string)))
ad["email"] = &s
} else if ed, ok = additionalData["displayName"]; ok {
s = strings.Clone(ptr.Val(ed.(*string)))
ad["displayName"] = &s
}
func (c *CorsoDriveItem) GetShared() itemSharedable { cdi.createdBy = &itemIdentitySet{
return c.Shared user: &itemUser{
} additionalData: ad,
},
func (c *CorsoDriveItem) GetCreatedBy() itemIdentitySetable { }
return c.CreatedBy
}
func (c *CorsoDriveItem) GetCreatedDateTime() *time.Time {
return &c.CreatedDateTime
}
func (c *CorsoDriveItem) GetLastModifiedDateTime() *time.Time {
return &c.LastModifiedDateTime
}
func (c *CorsoDriveItem) GetMalware() malwareable {
return c.Malware
}
func (c *CorsoDriveItem) GetDeleted() deletedable {
return c.Deleted
}
func (c *CorsoDriveItem) GetRoot() itemRootable {
return c.Root
}
// models.DriveItemable to CorsoDriveItemable
func ToCorsoDriveItemable(item models.DriveItemable) CorsoDriveItemable {
cdi := &CorsoDriveItem{
ID: strings.Clone(ptr.Val(item.GetId())),
Name: strings.Clone(ptr.Val(item.GetName())),
Size: ptr.Val(item.GetSize()),
CreatedDateTime: ptr.Val(item.GetCreatedDateTime()),
LastModifiedDateTime: ptr.Val(item.GetLastModifiedDateTime()),
} }
// Hacky way to cache the download url. Thats all we use from additional data // Hacky way to cache the download url. Thats all we use from additional data
@ -222,6 +268,7 @@ func ToCorsoDriveItemable(item models.DriveItemable) CorsoDriveItemable {
// lot more memory. // lot more memory.
if item.GetFile() != nil { if item.GetFile() != nil {
ad := make(map[string]interface{}) ad := make(map[string]interface{})
for _, key := range downloadURLKeys { for _, key := range downloadURLKeys {
if v, err := str.AnyValueToString(key, item.GetAdditionalData()); err == nil { if v, err := str.AnyValueToString(key, item.GetAdditionalData()); err == nil {
ad[key] = strings.Clone(v) ad[key] = strings.Clone(v)
@ -229,80 +276,7 @@ func ToCorsoDriveItemable(item models.DriveItemable) CorsoDriveItemable {
} }
} }
cdi.AdditionalData = ad cdi.additionalData = ad
}
if item.GetFolder() != nil {
cdi.Folder = &folderDriveItem{
isFolder: true,
}
}
if item.GetFile() != nil {
cdi.File = &fileDriveItem{
isFile: true,
mimeType: strings.Clone(ptr.Val(item.GetFile().GetMimeType())),
}
}
if item.GetPackageEscaped() != nil {
cdi.Package = &packageDriveItem{
isPackage: true,
}
}
if item.GetParentReference() != nil {
cdi.ParentReference = &parentReference{
id: strings.Clone(ptr.Val(item.GetParentReference().GetId())),
path: strings.Clone(ptr.Val(item.GetParentReference().GetPath())),
name: strings.Clone(ptr.Val(item.GetParentReference().GetName())),
driveId: strings.Clone(ptr.Val(item.GetParentReference().GetDriveId())),
}
}
if item.GetShared() != nil {
cdi.Shared = &itemShared{
isShared: true,
}
}
if item.GetMalware() != nil {
cdi.Malware = &itemMalware{
isMalware: true,
}
}
if item.GetDeleted() != nil {
cdi.Deleted = &itemDeleted{
isDeleted: true,
}
}
if item.GetRoot() != nil {
cdi.Root = &itemRoot{
isRoot: true,
}
}
if item.GetCreatedBy() != nil && item.GetCreatedBy().GetUser() != nil {
additionalData := item.GetCreatedBy().GetUser().GetAdditionalData()
ad := make(map[string]interface{})
var str string
ed, ok := additionalData["email"]
if ok {
str = strings.Clone(ptr.Val(ed.(*string)))
ad["email"] = &str
} else if ed, ok = additionalData["displayName"]; ok {
str = strings.Clone(ptr.Val(ed.(*string)))
ad["displayName"] = &str
}
cdi.CreatedBy = &itemIdentitySet{
user: &itemUser{
additionalData: ad,
},
}
} }
return cdi return cdi

View File

@ -104,7 +104,7 @@ func (h groupBackupHandler) SitePathPrefix(tenantID string) (path.Path, error) {
func (h groupBackupHandler) AugmentItemInfo( func (h groupBackupHandler) AugmentItemInfo(
dii details.ItemInfo, dii details.ItemInfo,
resource idname.Provider, resource idname.Provider,
item CorsoDriveItemable, item LiteDriveItemable,
size int64, size int64,
parentPath *path.Builder, parentPath *path.Builder,
) details.ItemInfo { ) details.ItemInfo {

View File

@ -6,7 +6,7 @@ import (
"github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/internal/common/ptr"
) )
func getItemCreator(item CorsoDriveItemable) string { func getItemCreator(item LiteDriveItemable) string {
if item.GetCreatedBy() == nil || item.GetCreatedBy().GetUser() == nil { if item.GetCreatedBy() == nil || item.GetCreatedBy().GetUser() == nil {
return "" return ""
} }
@ -28,7 +28,7 @@ func getItemCreator(item CorsoDriveItemable) string {
return *ed.(*string) return *ed.(*string)
} }
func getItemDriveInfo(item CorsoDriveItemable) (string, string) { func getItemDriveInfo(item LiteDriveItemable) (string, string) {
if item.GetParentReference() == nil { if item.GetParentReference() == nil {
return "", "" return "", ""
} }

View File

@ -23,7 +23,7 @@ type ItemInfoAugmenter interface {
AugmentItemInfo( AugmentItemInfo(
dii details.ItemInfo, dii details.ItemInfo,
resource idname.Provider, resource idname.Provider,
item CorsoDriveItemable, item LiteDriveItemable,
size int64, size int64,
parentPath *path.Builder, parentPath *path.Builder,
) details.ItemInfo ) details.ItemInfo

View File

@ -34,7 +34,7 @@ var downloadURLKeys = []string{
func downloadItem( func downloadItem(
ctx context.Context, ctx context.Context,
ag api.Getter, ag api.Getter,
item CorsoDriveItemable, item LiteDriveItemable,
) (io.ReadCloser, error) { ) (io.ReadCloser, error) {
if item == nil { if item == nil {
return nil, clues.New("nil item") return nil, clues.New("nil item")
@ -152,7 +152,7 @@ func downloadItemMeta(
ctx context.Context, ctx context.Context,
getter GetItemPermissioner, getter GetItemPermissioner,
driveID string, driveID string,
item CorsoDriveItemable, item LiteDriveItemable,
) (io.ReadCloser, int, error) { ) (io.ReadCloser, int, error) {
meta := metadata.Metadata{ meta := metadata.Metadata{
FileName: ptr.Val(item.GetName()), FileName: ptr.Val(item.GetName()),

View File

@ -33,7 +33,7 @@ func (h baseSiteHandler) NewDrivePager(
func (h baseSiteHandler) AugmentItemInfo( func (h baseSiteHandler) AugmentItemInfo(
dii details.ItemInfo, dii details.ItemInfo,
resource idname.Provider, resource idname.Provider,
item CorsoDriveItemable, item LiteDriveItemable,
size int64, size int64,
parentPath *path.Builder, parentPath *path.Builder,
) details.ItemInfo { ) details.ItemInfo {

View File

@ -42,7 +42,7 @@ func (h baseUserDriveHandler) NewDrivePager(
func (h baseUserDriveHandler) AugmentItemInfo( func (h baseUserDriveHandler) AugmentItemInfo(
dii details.ItemInfo, dii details.ItemInfo,
resource idname.Provider, resource idname.Provider,
item CorsoDriveItemable, item LiteDriveItemable,
size int64, size int64,
parentPath *path.Builder, parentPath *path.Builder,
) details.ItemInfo { ) details.ItemInfo {