From 352315b041ce408d66a1bbe5ae8e50d0d18848e1 Mon Sep 17 00:00:00 2001 From: Joren Date: Wed, 11 Mar 2026 17:37:18 +0100 Subject: [PATCH] Add files only mode --- cmd/canvasarchiver/main.go | 10 ++++++++-- internal/canvas/client.go | 33 ++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cmd/canvasarchiver/main.go b/cmd/canvasarchiver/main.go index 9eea08a..8749031 100644 --- a/cmd/canvasarchiver/main.go +++ b/cmd/canvasarchiver/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "net/http" "os" @@ -12,6 +13,9 @@ import ( ) func main() { + filesOnly := flag.Bool("fo", false, "Files only mode - download all files to a single directory without module structure") + flag.Parse() + httpClient := &http.Client{} authenticator := auth.NewAuthenticator(httpClient) @@ -25,7 +29,7 @@ func main() { fmt.Print("Enter Course ID: ") fmt.Scanln(&courseID) - canvasClient := canvas.NewClient(httpClient, accessToken, courseID) + canvasClient := canvas.NewClient(httpClient, accessToken, courseID, *filesOnly) if err := canvasClient.GetCourseInfo(); err != nil { fmt.Printf("Error: %v\n", err) @@ -40,5 +44,7 @@ func main() { canvasClient.DownloadModules(courseRoot) - panopto.DownloadMainRecordings(httpClient, accessToken, courseID, courseRoot) + if !*filesOnly { + panopto.DownloadMainRecordings(httpClient, accessToken, courseID, courseRoot) + } } diff --git a/internal/canvas/client.go b/internal/canvas/client.go index 2b2220e..c460422 100644 --- a/internal/canvas/client.go +++ b/internal/canvas/client.go @@ -21,13 +21,15 @@ type Client struct { AccessToken string CourseID string CourseName string + FilesOnly bool } -func NewClient(httpClient *http.Client, accessToken, courseID string) *Client { +func NewClient(httpClient *http.Client, accessToken, courseID string, filesOnly bool) *Client { return &Client{ HTTPClient: httpClient, AccessToken: accessToken, CourseID: courseID, + FilesOnly: filesOnly, } } @@ -83,7 +85,10 @@ func (c *Client) DownloadCourseFiles(root string) { rawFolderPath := folderMap[file.FolderID] safeFolderPath := utils.SanitizePath(rawFolderPath) - subDir := filepath.Join(root, "Course Files", safeFolderPath) + subDir := root + if !c.FilesOnly { + subDir = filepath.Join(root, "Course Files", safeFolderPath) + } os.MkdirAll(subDir, 0o755) path := filepath.Join(subDir, utils.Sanitize(file.DisplayName)) @@ -125,9 +130,15 @@ func (c *Client) DownloadModules(courseRoot string) { resp.Body.Close() for _, mod := range modules { - modBaseDir := filepath.Join(courseRoot, "Modules", utils.Sanitize(mod.Name)) + modBaseDir := courseRoot + if !c.FilesOnly { + modBaseDir = filepath.Join(courseRoot, "Modules", utils.Sanitize(mod.Name)) + } os.MkdirAll(modBaseDir, 0o755) - fmt.Printf("\n[Module] %s\n", mod.Name) + + if !c.FilesOnly { + fmt.Printf("\n[Module] %s\n", mod.Name) + } subHeaderStack := []string{} lastIndent := 0 @@ -135,13 +146,16 @@ func (c *Client) DownloadModules(courseRoot string) { for _, item := range mod.Items { targetDir := modBaseDir - if len(subHeaderStack) > 0 { + if len(subHeaderStack) > 0 && !c.FilesOnly { targetDir = filepath.Join(modBaseDir, filepath.Join(subHeaderStack...)) } os.MkdirAll(targetDir, 0o755) switch item.Type { case "SubHeader": + if c.FilesOnly { + continue + } currentIndent := item.Indent if currentIndent <= lastIndent && len(subHeaderStack) > 0 { levelsToKeep := currentIndent @@ -162,11 +176,17 @@ func (c *Client) DownloadModules(courseRoot string) { c.downloadModuleFile(item, targetDir) case "ExternalTool": + if c.FilesOnly { + continue + } indent := strings.Repeat(" ", len(subHeaderStack)+1) fmt.Printf("%s- Found video tool: %s\n", indent, item.Title) panopto.DownloadVideo(c.HTTPClient, c.AccessToken, c.CourseID, targetDir, item.URL, item.Title) case "ExternalUrl": + if c.FilesOnly { + continue + } if strings.Contains(item.ExternalURL, "panopto.eu") { indent := strings.Repeat(" ", len(subHeaderStack)+1) fmt.Printf("%s- Found direct video link: %s\n", indent, item.Title) @@ -175,6 +195,9 @@ func (c *Client) DownloadModules(courseRoot string) { } case "Page": + if c.FilesOnly { + continue + } c.searchPageForVideos(item, targetDir) } } -- 2.49.1