-
Notifications
You must be signed in to change notification settings - Fork 18
/
delete.go
132 lines (123 loc) · 4.47 KB
/
delete.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package delete
import (
"fmt"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/sagan/ptool/client"
"github.com/sagan/ptool/cmd"
"github.com/sagan/ptool/util"
"github.com/sagan/ptool/util/helper"
)
var command = &cobra.Command{
Use: "delete {client} [--category category] [--tag tag] [--filter filter] [infoHash]...",
Annotations: map[string]string{"cobra-prompt-dynamic-suggestions": "delete"},
Aliases: []string{"rm"},
Short: "Delete torrents from client.",
Long: `Delete torrents from client.
[infoHash]...: infoHash list of torrents to delete. It's possible to use state filter to target multiple torrents:
_all, _active, _done, _undone, _downloading, _seeding, _paused, _completed, _error.
Specially, use a single "-" as args to read infoHash list from stdin, delimited by blanks.
It will ask for confirmation of deletion, unless --force flag is set.`,
Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.OnlyValidArgs),
RunE: delete,
}
var (
preserve = false
force = false
filter = ""
category = ""
tag = ""
tracker = ""
minTorrentSizeStr = ""
maxTorrentSizeStr = ""
)
func init() {
command.Flags().BoolVarP(&preserve, "preserve", "p", false,
"Preserve (don't delete) torrent content files on the disk")
command.Flags().BoolVarP(&force, "force", "", false, "Force deletion. Do NOT prompt for confirm")
command.Flags().StringVarP(&filter, "filter", "", "", "Filter torrents by name")
command.Flags().StringVarP(&category, "category", "", "", "Filter torrents by category")
command.Flags().StringVarP(&tag, "tag", "", "",
"Filter torrents by tag. Comma-separated list. Torrent which tags contain any one in the list matches")
command.Flags().StringVarP(&tracker, "tracker", "", "", "Filter torrents by tracker domain")
command.Flags().StringVarP(&minTorrentSizeStr, "min-torrent-size", "", "-1",
"Skip torrent with size smaller than (<) this value. -1 == no limit")
command.Flags().StringVarP(&maxTorrentSizeStr, "max-torrent-size", "", "-1",
"Skip torrent with size larger than (>) this value. -1 == no limit")
cmd.RootCmd.AddCommand(command)
}
func delete(cmd *cobra.Command, args []string) error {
clientName := args[0]
infoHashes := args[1:]
clientInstance, err := client.CreateClient(clientName)
if err != nil {
return fmt.Errorf("failed to create client: %v", err)
}
minTorrentSize, _ := util.RAMInBytes(minTorrentSizeStr)
maxTorrentSize, _ := util.RAMInBytes(maxTorrentSizeStr)
infohashesOnly := true
if category != "" || tag != "" || filter != "" || tracker != "" || minTorrentSize >= 0 || maxTorrentSize >= 0 {
infohashesOnly = false
} else {
// special case. read info hashes from stdin
if len(infoHashes) == 1 && infoHashes[0] == "-" {
if data, err := helper.ReadArgsFromStdin(); err != nil {
return fmt.Errorf("failed to parse stdin to info hashes: %v", err)
} else if len(data) == 0 {
return nil
} else {
infoHashes = data
}
}
for _, infoHash := range infoHashes {
if !client.IsValidInfoHash(infoHash) {
infohashesOnly = false
break
}
}
}
if infohashesOnly {
if len(infoHashes) == 0 {
return fmt.Errorf("no torrent to delete")
}
if force {
if err = clientInstance.DeleteTorrents(infoHashes, !preserve); err != nil {
return fmt.Errorf("failed to delete torrents: %v", err)
}
return nil
}
}
torrents, err := client.QueryTorrents(clientInstance, category, tag, filter, infoHashes...)
if err != nil {
return fmt.Errorf("failed to fetch client torrents: %v", err)
}
if tracker != "" || minTorrentSize >= 0 || maxTorrentSize >= 0 {
torrents = util.Filter(torrents, func(t client.Torrent) bool {
if tracker != "" && t.TrackerDomain != tracker ||
minTorrentSize >= 0 && t.Size < minTorrentSize ||
maxTorrentSize >= 0 && t.Size > maxTorrentSize {
return false
}
return true
})
}
if len(torrents) == 0 {
log.Infof("No matched torrents found")
return nil
}
if !force {
client.PrintTorrents(torrents, "", 1, false)
fmt.Printf("\n")
if !util.AskYesNoConfirm(fmt.Sprintf("Above %d torrents will be deteled (Preserve disk files = %t)",
len(torrents), preserve)) {
return fmt.Errorf("abort")
}
}
infoHashes = util.Map(torrents, func(t client.Torrent) string { return t.InfoHash })
err = clientInstance.DeleteTorrents(infoHashes, !preserve)
if err != nil {
return fmt.Errorf("failed to delete torrents: %v", err)
}
fmt.Printf("%d torrents deleted.\n", len(torrents))
return nil
}