cmd/media.go
author rjp <zimpenfish@gmail.com>
Mon, 23 Jan 2023 16:39:02 +0000
changeset 267 5b91a65ba95a
parent 239 605a00e9d1ab
child 268 4dd196a4ee7c
permissions -rw-r--r--
Update to handle non-int64 IDs Pleroma/Akkoma and GotoSocial use opaque IDs rather than `int64`s like Mastodon which means that `madon` can't talk to either of those. This commit updates everything that can be an ID to `madon.ActivityID` which is an alias for `string` - can't create a specific type for it since there's more than a few places where they're concatenated directly to strings for URLs, etc. Which means it could just as easily be a direct `string` type itself but I find that having distinct types can often make the code more readable and understandable. One extra bit is that `statusOpts` has grown a `_hasReplyTo` boolean to indicate whether the `--in-reply-to` flag was given or not because we can't distinguish because "empty because default" or "empty because given and empty". Another way around this would be to set the default to some theoretically impossible or unlikely string but you never know when someone might spin up an instance where, e.g., admin posts have negative integer IDs.

// Copyright © 2017-2018 Mikael Berthe <mikael@lilotux.net>
//
// Licensed under the MIT license.
// Please see the LICENSE file is this directory.

package cmd

import (
	"os"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	flag "github.com/spf13/pflag"

	"github.com/McKael/madon/v2"
)

var mediaFlags *flag.FlagSet

var mediaOpts struct {
	mediaID     madon.ActivityID
	filePath    string
	description string
	focus       string
}

// mediaCmd represents the media command
var mediaCmd = &cobra.Command{
	Use:     "media --file FILENAME",
	Aliases: []string{"upload"},
	Short:   "Upload or update a media attachment",
	Long: `Upload or update a media attachment

This command can be used to upload media that will be attached to
a status later.

A media description or focal point (focus) can be updated
as long as it is not yet attached to a status, with the '--update MEDIA_ID'
option.`,
	Example: `  madonctl upload --file FILENAME
  madonctl media --file FILENAME --description "My screenshot"
  madonctl media --update 3217821 --focus "0.5,-0.7"
  madonctl media --update 2468123 --description "Winter Snow"`,
	RunE: mediaRunE,
}

func init() {
	RootCmd.AddCommand(mediaCmd)

	mediaCmd.Flags().StringVar(&mediaOpts.filePath, "file", "", "Path of the media file")
	mediaCmd.Flags().StringVar(&mediaOpts.mediaID, "update", "", "Media to update (ID)")

	mediaCmd.Flags().StringVar(&mediaOpts.description, "description", "", "Plain text description")
	mediaCmd.Flags().StringVar(&mediaOpts.focus, "focus", "", "Focal point")

	// This will be used to check if the options were explicitly set or not
	mediaFlags = mediaCmd.Flags()
}

func mediaRunE(cmd *cobra.Command, args []string) error {
	opt := mediaOpts

	if opt.filePath == "" {
		if opt.mediaID == "" {
			return errors.New("no media file name provided")
		}
	} else if opt.mediaID != "" {
		return errors.New("cannot use both --file and --update")
	}

	if err := madonInit(true); err != nil {
		return err
	}

	var attachment *madon.Attachment
	var err error

	if opt.filePath != "" {
		attachment, err = gClient.UploadMedia(opt.filePath, opt.description, opt.focus)
	} else {
		// Update
		var desc, foc *string
		if mediaFlags.Lookup("description").Changed {
			desc = &opt.description
		}
		if mediaFlags.Lookup("focus").Changed {
			foc = &opt.focus
		}
		attachment, err = gClient.UpdateMedia(opt.mediaID, desc, foc)
	}
	if err != nil {
		errPrint("Error: %s", err.Error())
		os.Exit(1)
	}

	p, err := getPrinter()
	if err != nil {
		errPrint("Error: %s", err.Error())
		os.Exit(1)
	}
	return p.printObj(attachment)
}

// uploadFile uploads a media file and returns the attachment ID
func uploadFile(filePath string) (madon.ActivityID, error) {
	attachment, err := gClient.UploadMedia(filePath, "", "")
	if err != nil {
		return "", err
	}
	if attachment == nil {
		return "", nil
	}
	return attachment.ID, nil
}