summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/gotosocial/action/admin/media/list.go168
-rw-r--r--cmd/gotosocial/admin.go22
2 files changed, 150 insertions, 40 deletions
diff --git a/cmd/gotosocial/action/admin/media/list.go b/cmd/gotosocial/action/admin/media/list.go
index 5b6108b11..0a2e60ede 100644
--- a/cmd/gotosocial/action/admin/media/list.go
+++ b/cmd/gotosocial/action/admin/media/list.go
@@ -20,6 +20,7 @@ package media
import (
"bufio"
"context"
+ "errors"
"fmt"
"os"
"path"
@@ -34,14 +35,17 @@ import (
)
type list struct {
- dbService db.DB
- state *state.State
- maxID string
- limit int
- out *bufio.Writer
+ dbService db.DB
+ state *state.State
+ maxID string
+ limit int
+ localOnly bool
+ remoteOnly bool
+ out *bufio.Writer
}
-func (l *list) GetAllMediaPaths(ctx context.Context, filter func(*gtsmodel.MediaAttachment) string) ([]string, error) {
+// Get a list of attachment using a custom filter
+func (l *list) GetAllAttachmentPaths(ctx context.Context, filter func(*gtsmodel.MediaAttachment) string) ([]string, error) {
res := make([]string, 0, 100)
for {
attachments, err := l.dbService.GetAttachments(ctx, l.maxID, l.limit)
@@ -72,8 +76,52 @@ func (l *list) GetAllMediaPaths(ctx context.Context, filter func(*gtsmodel.Media
return res, nil
}
+// Get a list of emojis using a custom filter
+func (l *list) GetAllEmojisPaths(ctx context.Context, filter func(*gtsmodel.Emoji) string) ([]string, error) {
+ res := make([]string, 0, 100)
+ for {
+ attachments, err := l.dbService.GetEmojis(ctx, l.maxID, l.limit)
+ if err != nil {
+ return nil, fmt.Errorf("failed to retrieve media metadata from database: %w", err)
+ }
+
+ for _, a := range attachments {
+ v := filter(a)
+ if v != "" {
+ res = append(res, v)
+ }
+ }
+
+ // If we got less results than our limit, we've reached the
+ // last page to retrieve and we can break the loop. If the
+ // last batch happens to contain exactly the same amount of
+ // items as the limit we'll end up doing one extra query.
+ if len(attachments) < l.limit {
+ break
+ }
+
+ // Grab the last ID from the batch and set it as the maxID
+ // that'll be used in the next iteration so we don't get items
+ // we've already seen.
+ l.maxID = attachments[len(attachments)-1].ID
+ }
+ return res, nil
+}
+
func setupList(ctx context.Context) (*list, error) {
- var state state.State
+ var (
+ localOnly = config.GetAdminMediaListLocalOnly()
+ remoteOnly = config.GetAdminMediaListRemoteOnly()
+ state state.State
+ )
+
+ // Validate flags.
+ if localOnly && remoteOnly {
+ return nil, errors.New(
+ "local-only and remote-only flags cannot be true at the same time; " +
+ "choose one or the other, or set neither to list all media",
+ )
+ }
state.Caches.Init()
state.Caches.Start()
@@ -87,11 +135,13 @@ func setupList(ctx context.Context) (*list, error) {
state.DB = dbService
return &list{
- dbService: dbService,
- state: &state,
- limit: 200,
- maxID: "",
- out: bufio.NewWriter(os.Stdout),
+ dbService: dbService,
+ state: &state,
+ limit: 200,
+ maxID: "",
+ localOnly: localOnly,
+ remoteOnly: remoteOnly,
+ out: bufio.NewWriter(os.Stdout),
}, nil
}
@@ -103,7 +153,8 @@ func (l *list) shutdown() error {
return err
}
-var ListLocal action.GTSAction = func(ctx context.Context) error {
+// ListAttachments lists local, remote, or all attachment paths.
+var ListAttachments action.GTSAction = func(ctx context.Context) error {
list, err := setupList(ctx)
if err != nil {
return err
@@ -116,26 +167,53 @@ var ListLocal action.GTSAction = func(ctx context.Context) error {
}
}()
- mediaPath := config.GetStorageLocalBasePath()
- media, err := list.GetAllMediaPaths(
- ctx,
- func(m *gtsmodel.MediaAttachment) string {
+ var (
+ mediaPath = config.GetStorageLocalBasePath()
+ filter func(*gtsmodel.MediaAttachment) string
+ )
+
+ switch {
+ case list.localOnly:
+ filter = func(m *gtsmodel.MediaAttachment) string {
+ if m.RemoteURL != "" {
+ // Remote, not
+ // interested.
+ return ""
+ }
+
+ return path.Join(mediaPath, m.File.Path)
+ }
+
+ case list.remoteOnly:
+ filter = func(m *gtsmodel.MediaAttachment) string {
if m.RemoteURL == "" {
- return path.Join(mediaPath, m.File.Path)
+ // Local, not
+ // interested.
+ return ""
}
- return ""
- })
+
+ return path.Join(mediaPath, m.File.Path)
+ }
+
+ default:
+ filter = func(m *gtsmodel.MediaAttachment) string {
+ return path.Join(mediaPath, m.File.Path)
+ }
+ }
+
+ attachments, err := list.GetAllAttachmentPaths(ctx, filter)
if err != nil {
return err
}
- for _, m := range media {
- _, _ = list.out.WriteString(m + "\n")
+ for _, a := range attachments {
+ _, _ = list.out.WriteString(a + "\n")
}
return nil
}
-var ListRemote action.GTSAction = func(ctx context.Context) error {
+// ListEmojis lists local, remote, or all emoji filepaths.
+var ListEmojis action.GTSAction = func(ctx context.Context) error {
list, err := setupList(ctx)
if err != nil {
return err
@@ -148,17 +226,47 @@ var ListRemote action.GTSAction = func(ctx context.Context) error {
}
}()
- media, err := list.GetAllMediaPaths(
- ctx,
- func(m *gtsmodel.MediaAttachment) string {
- return m.RemoteURL
- })
+ var (
+ mediaPath = config.GetStorageLocalBasePath()
+ filter func(*gtsmodel.Emoji) string
+ )
+
+ switch {
+ case list.localOnly:
+ filter = func(e *gtsmodel.Emoji) string {
+ if e.ImageRemoteURL != "" {
+ // Remote, not
+ // interested.
+ return ""
+ }
+
+ return path.Join(mediaPath, e.ImagePath)
+ }
+
+ case list.remoteOnly:
+ filter = func(e *gtsmodel.Emoji) string {
+ if e.ImageRemoteURL == "" {
+ // Local, not
+ // interested.
+ return ""
+ }
+
+ return path.Join(mediaPath, e.ImagePath)
+ }
+
+ default:
+ filter = func(e *gtsmodel.Emoji) string {
+ return path.Join(mediaPath, e.ImagePath)
+ }
+ }
+
+ emojis, err := list.GetAllEmojisPaths(ctx, filter)
if err != nil {
return err
}
- for _, m := range media {
- _, _ = list.out.WriteString(m + "\n")
+ for _, e := range emojis {
+ _, _ = list.out.WriteString(e + "\n")
}
return nil
}
diff --git a/cmd/gotosocial/admin.go b/cmd/gotosocial/admin.go
index a8aab810e..3b2ea69e3 100644
--- a/cmd/gotosocial/admin.go
+++ b/cmd/gotosocial/admin.go
@@ -178,29 +178,31 @@ func adminCommands() *cobra.Command {
ADMIN MEDIA LIST COMMANDS
*/
- adminMediaListLocalCmd := &cobra.Command{
- Use: "list-local",
- Short: "admin command to list media on local storage",
+ adminMediaListAttachmentsCmd := &cobra.Command{
+ Use: "list-attachments",
+ Short: "list local, remote, or all attachments",
PreRunE: func(cmd *cobra.Command, args []string) error {
return preRun(preRunArgs{cmd: cmd})
},
RunE: func(cmd *cobra.Command, args []string) error {
- return run(cmd.Context(), media.ListLocal)
+ return run(cmd.Context(), media.ListAttachments)
},
}
+ config.AddAdminMediaList(adminMediaListAttachmentsCmd)
+ adminMediaCmd.AddCommand(adminMediaListAttachmentsCmd)
- adminMediaListRemoteCmd := &cobra.Command{
- Use: "list-remote",
- Short: "admin command to list remote media cached on this instance",
+ adminMediaListEmojisLocalCmd := &cobra.Command{
+ Use: "list-emojis",
+ Short: "list local, remote, or all emojis",
PreRunE: func(cmd *cobra.Command, args []string) error {
return preRun(preRunArgs{cmd: cmd})
},
RunE: func(cmd *cobra.Command, args []string) error {
- return run(cmd.Context(), media.ListRemote)
+ return run(cmd.Context(), media.ListEmojis)
},
}
-
- adminMediaCmd.AddCommand(adminMediaListLocalCmd, adminMediaListRemoteCmd)
+ config.AddAdminMediaList(adminMediaListEmojisLocalCmd)
+ adminMediaCmd.AddCommand(adminMediaListEmojisLocalCmd)
/*
ADMIN MEDIA PRUNE COMMANDS