diff --git a/internal/executor/show.go b/internal/executor/show.go index eeb23ce..ea84c83 100644 --- a/internal/executor/show.go +++ b/internal/executor/show.go @@ -5,7 +5,6 @@ package executor import ( - "errors" "flag" "fmt" "path/filepath" @@ -34,10 +33,10 @@ type ShowExecutor struct { listID string tag string pollID string - attachmentID string fromResourceType string imageViewer string limit int + attachmentIDs MultiStringFlagValue } func NewShowExecutor(printer *printer.Printer, configDir, cacheRoot, imageViewer, name, summary string) *ShowExecutor { @@ -61,7 +60,7 @@ func NewShowExecutor(printer *printer.Printer, configDir, cacheRoot, imageViewer showExe.StringVar(&showExe.listID, flagListID, "", "Specify the ID of the list to display") showExe.StringVar(&showExe.tag, flagTag, "", "Specify the name of the tag to use") showExe.StringVar(&showExe.pollID, flagPollID, "", "Specify the ID of the poll to display") - showExe.StringVar(&showExe.attachmentID, flagAttachmentID, "", "Specify the ID of the media attachment to display") + showExe.Var(&showExe.attachmentIDs, flagAttachmentID, "Specify the ID of the media attachment to display") showExe.StringVar(&showExe.fromResourceType, flagFrom, "", "Specify the resource type to view the target resource from (e.g. status for viewing media from, etc)") showExe.IntVar(&showExe.limit, flagLimit, 20, "Specify the limit of items to display") @@ -417,11 +416,18 @@ func (s *ShowExecutor) showMutedAccounts(gtsClient *client.Client) error { } func (s *ShowExecutor) showMediaAttachment(gtsClient *client.Client) error { - if s.attachmentID == "" { + if len(s.attachmentIDs) == 0 { return FlagNotSetError{flagText: flagAttachmentID} } - attachment, err := gtsClient.GetMediaAttachment(s.attachmentID) + if len(s.attachmentIDs) != 1 { + return fmt.Errorf( + "unexpected number of attachment IDs received: want 1, got %d", + len(s.attachmentIDs), + ) + } + + attachment, err := gtsClient.GetMediaAttachment(s.attachmentIDs[0]) if err != nil { return fmt.Errorf("unable to retrieve the media attachment: %w", err) } @@ -449,7 +455,7 @@ func (s *ShowExecutor) showMedia(gtsClient *client.Client) error { } func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error { - if s.attachmentID == "" { + if len(s.attachmentIDs) == 0 { return FlagNotSetError{flagText: flagAttachmentID} } @@ -457,31 +463,11 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error { return FlagNotSetError{flagText: flagStatusID} } - status, err := gtsClient.GetStatus(s.statusID) if err != nil { return fmt.Errorf("unable to retrieve the status: %w", err) } - attachmentExists := false - mediaURL := "" - mediaFilename := "" - - for _, attachment := range status.MediaAttachments { - if attachment.ID == s.attachmentID { - mediaURL = attachment.URL - split := strings.Split(attachment.URL, "/") - mediaFilename = split[len(split)-1] - attachmentExists = true - - break - } - } - - if !attachmentExists { - return errors.New("this media is not attached to this status") - } - cacheDir := filepath.Join( utilities.CalculateCacheDir(s.cacheRoot, utilities.GetFQDN(gtsClient.Authentication.Instance)), "media", @@ -491,20 +477,42 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error { return fmt.Errorf("unable to ensure the existence of the directory %q: %w", cacheDir, err) } - mediaFilePath := filepath.Join(cacheDir, mediaFilename) + attachmentsHashMap := make(map[string]string) + filepaths := make([]string, len(s.attachmentIDs)) - fileExists, err := utilities.FileExists(mediaFilePath) - if err != nil { - return fmt.Errorf("unable to check if the media file is already downloaded: %w", err) + for _, statusAttachment := range status.MediaAttachments { + attachmentsHashMap[statusAttachment.ID] = statusAttachment.URL } - if !fileExists { - if err := gtsClient.DownloadMedia(mediaURL, mediaFilePath); err != nil { - return fmt.Errorf("unable to download the media attachment: %w", err) + for ind, attachmentID := range s.attachmentIDs { + mediaURL, ok := attachmentsHashMap[attachmentID] + if !ok { + return fmt.Errorf("unknown media attachment: %s", attachmentID) } + + split := strings.Split(mediaURL, "/") + filename := split[len(split)-1] + filePath := filepath.Join(cacheDir, filename) + + fileExists, err := utilities.FileExists(filePath) + if err != nil { + return fmt.Errorf( + "unable to check if the media file is already downloaded for %s: %w", + attachmentID, + err, + ) + } + + if !fileExists { + if err := gtsClient.DownloadMedia(mediaURL, filePath); err != nil { + return fmt.Errorf("unable to download the media attachment for %s: %w", attachmentID, err) + } + } + + filepaths[ind] = filePath } - if err := utilities.OpenMedia(s.imageViewer, mediaFilePath); err != nil { + if err := utilities.OpenMedia(s.imageViewer, filepaths); err != nil { return fmt.Errorf("unable to open the image viewer: %w", err) } diff --git a/internal/utilities/utilities.go b/internal/utilities/utilities.go index c078f10..5e71636 100644 --- a/internal/utilities/utilities.go +++ b/internal/utilities/utilities.go @@ -17,12 +17,12 @@ func GetFQDN(url string) string { return r.ReplaceAllString(url, "") } -func OpenMedia(viewer, path string) error { +func OpenMedia(viewer string, paths []string) error { if viewer == "" { return errors.New("the image viewer is not specified") } - command := exec.Command(viewer, path) + command := exec.Command(viewer, paths...) if err := command.Start(); err != nil { return fmt.Errorf("received an error after starting the image viewer: %w", err)