## Description This contains the following changes: - Support functions to enumerate a users drives and the files within it. - `driveItemReader` method that that reads a drive item - Integration tests for the above ## Type of change Please check the type of change your PR introduces: - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 🐹 Trivial/Minor ## Issue(s) - #388 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package onedrive
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/alcionai/corso/internal/connector/graph"
|
|
"github.com/alcionai/corso/pkg/logger"
|
|
)
|
|
|
|
const (
|
|
// downloadUrlKey is used to find the download URL in a
|
|
// DriveItem response
|
|
downloadURLKey = "@microsoft.graph.downloadUrl"
|
|
)
|
|
|
|
// itemReader will return a io.ReadCloser for the specified item
|
|
// It crafts this by querying M365 for a download URL for the item
|
|
// and using a http client to initialize a reader
|
|
func driveItemReader(
|
|
ctx context.Context,
|
|
service graph.Service,
|
|
driveID, itemID string,
|
|
) (string, io.ReadCloser, error) {
|
|
logger.Ctx(ctx).Debugf("Reading Item %s at %s", itemID, time.Now())
|
|
|
|
item, err := service.Client().DrivesById(driveID).ItemsById(itemID).Get()
|
|
if err != nil {
|
|
return "", nil, errors.Wrapf(err, "failed to get item %s", itemID)
|
|
}
|
|
|
|
// Get the download URL - https://docs.microsoft.com/en-us/graph/api/driveitem-get-content
|
|
// These URLs are pre-authenticated and can be used to download the data using the standard
|
|
// http client
|
|
if _, found := item.GetAdditionalData()[downloadURLKey]; !found {
|
|
return "", nil, errors.Errorf("file does not have a download URL. ID: %s, %#v",
|
|
itemID, item.GetAdditionalData())
|
|
}
|
|
downloadURL := item.GetAdditionalData()[downloadURLKey].(*string)
|
|
|
|
// TODO: We should use the `msgraphgocore` http client which has the right
|
|
// middleware/options configured
|
|
resp, err := http.Get(*downloadURL)
|
|
if err != nil {
|
|
return "", nil, errors.Wrapf(err, "failed to download file from %s", *downloadURL)
|
|
}
|
|
|
|
return *item.GetName(), resp.Body, nil
|
|
}
|