corso/src/pkg/backup/details/iteminfo.go
ryanfkeepers 14817de592 get details working (and other cleanup)
details wasn't properly listing backed up items.  This fixes
the details display, and contains some code clean-up that occurred
along the way.
2024-01-24 15:17:14 -07:00

191 lines
5.2 KiB
Go

package details
import (
"time"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/pkg/path"
)
type ItemType int
// ItemTypes are enumerated by service (hundredth digit) and data type (ones digit).
// Ex: exchange is 00x where x is the data type. Sharepoint is 10x, and etc.
// Every item info struct should get its own hundredth enumeration entry.
// Every item category for that service should get its own entry (even if differences
// between types aren't apparent on initial implementation, this future-proofs
// against breaking changes).
// Entries should not be rearranged.
// Additionally, any itemType directly assigned a number should not be altered.
// This applies to OneDriveItem and FolderItem
const (
UnknownType ItemType = 0
// Exchange (00x)
ExchangeContact ItemType = 1
ExchangeEvent ItemType = 2
ExchangeMail ItemType = 3
// SharePoint (10x)
SharePointLibrary ItemType = 101 // also used for groups
SharePointList ItemType = 102
SharePointPage ItemType = 103
// OneDrive (20x)
OneDriveItem ItemType = 205
// Folder Management(30x)
FolderItem ItemType = 306
// Groups/Teams(40x)
GroupsChannelMessage ItemType = 401
GroupsConversationPost ItemType = 402
// Teams Chat
TeamsChat ItemType = 501
)
func UpdateItem(item *ItemInfo, newLocPath *path.Builder) {
// Only OneDrive and SharePoint have information about parent folders
// contained in them.
// Can't switch based on infoType because that's been unstable.
if item.Exchange != nil {
item.Exchange.UpdateParentPath(newLocPath)
} else if item.SharePoint != nil {
// SharePoint used to store library items with the OneDriveItem ItemType.
// Start switching them over as we see them since there's no point in
// keeping the old format.
if item.SharePoint.ItemType == OneDriveItem {
item.SharePoint.ItemType = SharePointLibrary
}
item.SharePoint.UpdateParentPath(newLocPath)
} else if item.OneDrive != nil {
item.OneDrive.UpdateParentPath(newLocPath)
} else if item.Groups != nil {
item.Groups.UpdateParentPath(newLocPath)
}
}
// ItemInfo is a oneOf that contains service specific
// information about the item it tracks
type ItemInfo struct {
Folder *FolderInfo `json:"folder,omitempty"`
Exchange *ExchangeInfo `json:"exchange,omitempty"`
SharePoint *SharePointInfo `json:"sharePoint,omitempty"`
OneDrive *OneDriveInfo `json:"oneDrive,omitempty"`
Groups *GroupsInfo `json:"groups,omitempty"`
TeamsChats *TeamsChatsInfo `json:"teamsChats,omitempty"`
// Optional item extension data
Extension *ExtensionData `json:"extension,omitempty"`
}
// typedInfo should get embedded in each sesrvice type to track
// the type of item it stores for multi-item service support.
// infoType provides internal categorization for collecting like-typed ItemInfos.
// It should return the most granular value type (ex: "event" for an exchange
// calendar event).
func (i ItemInfo) infoType() ItemType {
switch {
case i.Folder != nil:
return i.Folder.ItemType
case i.Exchange != nil:
return i.Exchange.ItemType
case i.SharePoint != nil:
return i.SharePoint.ItemType
case i.OneDrive != nil:
return i.OneDrive.ItemType
case i.Groups != nil:
return i.Groups.ItemType
case i.TeamsChats != nil:
return i.TeamsChats.ItemType
}
return UnknownType
}
func (i ItemInfo) size() int64 {
switch {
case i.Exchange != nil:
return i.Exchange.Size
case i.OneDrive != nil:
return i.OneDrive.Size
case i.SharePoint != nil:
return i.SharePoint.Size
case i.Groups != nil:
return i.Groups.Size
case i.Folder != nil:
return i.Folder.Size
case i.TeamsChats != nil:
return int64(i.TeamsChats.Chat.MessageCount)
}
return 0
}
func (i ItemInfo) Modified() time.Time {
switch {
case i.Exchange != nil:
return i.Exchange.Modified
case i.OneDrive != nil:
return i.OneDrive.Modified
case i.SharePoint != nil:
return i.SharePoint.Modified
case i.Groups != nil:
return i.Groups.Modified
case i.Folder != nil:
return i.Folder.Modified
case i.TeamsChats != nil:
return i.TeamsChats.Modified
}
return time.Time{}
}
func (i ItemInfo) uniqueLocation(baseLoc *path.Builder) (*uniqueLoc, error) {
switch {
case i.Exchange != nil:
return i.Exchange.uniqueLocation(baseLoc)
case i.OneDrive != nil:
return i.OneDrive.uniqueLocation(baseLoc)
case i.SharePoint != nil:
return i.SharePoint.uniqueLocation(baseLoc)
case i.Groups != nil:
return i.Groups.uniqueLocation(baseLoc)
case i.TeamsChats != nil:
return i.TeamsChats.uniqueLocation(baseLoc)
default:
return nil, clues.New("unsupported type")
}
}
func (i ItemInfo) updateFolder(f *FolderInfo) error {
switch {
case i.Exchange != nil:
return i.Exchange.updateFolder(f)
case i.OneDrive != nil:
return i.OneDrive.updateFolder(f)
case i.SharePoint != nil:
return i.SharePoint.updateFolder(f)
case i.Groups != nil:
return i.Groups.updateFolder(f)
case i.TeamsChats != nil:
return i.TeamsChats.updateFolder(f)
default:
return clues.New("unsupported type")
}
}
// true if the info represents an item backed by the drive api.
func (i ItemInfo) isDriveItem() bool {
iit := i.infoType()
if !(iit == OneDriveItem || iit == SharePointLibrary) {
return false
}
return !(i.OneDrive == nil && i.SharePoint == nil && i.Groups == nil)
}