Skip to content

Commit

Permalink
improve search cmd; update to go 1.22
Browse files Browse the repository at this point in the history
  • Loading branch information
sagan committed Feb 29, 2024
1 parent 283c58c commit 53013c2
Show file tree
Hide file tree
Showing 20 changed files with 153 additions and 121 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
ptool.toml
ptool.yaml
ptool.lock
ptool-global.lock
ptool_history
ptool_stats.txt
iyuu.db
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ ptool batchdl <site> --action add --add-client local
- --free : 只下载免费种子。
- --no-hr : 跳过存在 HR 的种子。
- --no-paid : 跳过"付费"的种子。(部分站点存在"付费"种子,第一次下载或汇报时扣除积分)
- --base-url : 手动指定种子列表页 URL,例如:"special.php"、"adult.php"、"torrents.php?cat=100"。
- --base-url : 手动指定种子列表页 URL,例如:"special.php"、"torrents.php?cat=100"。

### 显示种子文件信息 (parsetorrent)

Expand Down
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ type TorrentTracker struct {
type TorrentTrackers []TorrentTracker

type TorrentOption struct {
Name string
Name string // if not empty, set name of torrent in client to this value
Category string
SavePath string
Tags []string
Expand Down
17 changes: 3 additions & 14 deletions cmd/add/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ as a special case, it also supports directly reading .torrent file contents from
* [size] : Torrent size
* [id] : Torrent id in site
* [site] : Torrent site
* [filename] : Original torrent filename, with ".torrent" extension removed
* [filename] : Original torrent filename without ".torrent" extension
* [name] : Torrent name`,
Args: cobra.MatchAll(cobra.MinimumNArgs(2), cobra.OnlyValidArgs),
RunE: add,
Expand Down Expand Up @@ -131,13 +131,11 @@ func add(cmd *cobra.Command, args []string) error {
var err error
var hr bool
isLocal := forceLocal || torrent == "-" || !util.IsUrl(torrent) && strings.HasSuffix(torrent, ".torrent")

if !isLocal {
// site torrent
siteName = defaultSite
if !util.IsUrl(torrent) {
i := strings.Index(torrent, ".")
if i != -1 && i < len(torrent)-1 {
if i := strings.Index(torrent, "."); i != -1 {
siteName = torrent[:i]
}
} else {
Expand Down Expand Up @@ -227,16 +225,7 @@ func add(cmd *cobra.Command, args []string) error {
}
option.Tags = append(option.Tags, fixedTags...)
if rename != "" {
basename := filename
if i := strings.LastIndex(basename, "."); i != -1 {
basename = basename[:i]
}
option.Name = rename
option.Name = strings.ReplaceAll(option.Name, "[size]", util.BytesSize(float64(tinfo.Size)))
option.Name = strings.ReplaceAll(option.Name, "[id]", id)
option.Name = strings.ReplaceAll(option.Name, "[site]", siteName)
option.Name = strings.ReplaceAll(option.Name, "[filename]", basename)
option.Name = strings.ReplaceAll(option.Name, "[name]", tinfo.Info.Name)
option.Name = torrentutil.RenameTorrent(rename, siteName, id, filename, tinfo)
}
err = clientInstance.AddTorrent(content, option, nil)
if err != nil {
Expand Down
52 changes: 40 additions & 12 deletions cmd/batchdl/batchdl.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,28 @@ import (
"github.com/sagan/ptool/config"
"github.com/sagan/ptool/site"
"github.com/sagan/ptool/util"
"github.com/sagan/ptool/util/torrentutil"
)

var command = &cobra.Command{
Use: "batchdl {site} [--action add|download|...] [--base-url torrents_page_url]",
Annotations: map[string]string{"cobra-prompt-dynamic-suggestions": "batchdl"},
Aliases: []string{"ebookgod"},
Short: "Batch download the smallest (or by any other order) torrents from a site.",
Long: `Batch download the smallest (or by any other order) torrents from a site.`,
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: batchdl,
Long: `Batch download the smallest (or by any other order) torrents from a site.
--rename <name> flag supports the following variable placeholders:
* [size] : Torrent size
* [id] : Torrent id in site
* [site] : Torrent site
* [filename] : Original torrent filename without ".torrent" extension
* [name] : Torrent name`,
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: batchdl,
}

var (
downloadAll = false
onePage = false
addPaused = false
dense = false
Expand All @@ -51,7 +60,6 @@ var (
addClient = ""
addTags = ""
filter = ""
includes = []string{}
excludes = ""
savePath = ""
minTorrentSizeStr = ""
Expand All @@ -62,12 +70,16 @@ var (
downloadDir = ""
exportFile = ""
baseUrl = ""
action string
sortFlag string
orderFlag string
rename = ""
action = ""
sortFlag = ""
orderFlag = ""
includes = []string{}
)

func init() {
command.Flags().BoolVarP(&downloadAll, "all", "a", false,
`Download all torrents. Equivalent to "--include-downloaded --min-seeders -1"`)
command.Flags().BoolVarP(&onePage, "one-page", "", false, "Only fetch one page torrents")
command.Flags().BoolVarP(&addPaused, "add-paused", "", false, "Add torrents to client in paused state")
command.Flags().BoolVarP(&dense, "dense", "d", false, "Dense mode: show full torrent title & subtitle")
Expand All @@ -76,9 +88,9 @@ func init() {
command.Flags().BoolVarP(&noNeutral, "no-neutral", "", false,
"Skip neutral (do not count uploading & downloading & seeding bonus) torrent")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false,
`Sort site torrents by size in desc order. Equivalent with "--sort size --order desc"`)
`Sort site torrents by size in desc order. Equivalent to "--sort size --order desc"`)
command.Flags().BoolVarP(&newestFlag, "newest", "n", false,
`Download newest torrents of site. Equivalent with "--sort time --order desc --one-page"`)
`Download newest torrents of site. Equivalent to "--sort time --order desc --one-page"`)
command.Flags().BoolVarP(&addRespectNoadd, "add-respect-noadd", "", false,
`Used with "--action add". Check and respect _noadd flag in client`)
command.Flags().BoolVarP(&nohr, "no-hr", "", false,
Expand Down Expand Up @@ -125,7 +137,8 @@ func init() {
command.Flags().StringVarP(&exportFile, "export-file", "", "",
`Used with "--action export|printid". Set the output file. (If not set, will use stdout)`)
command.Flags().StringVarP(&baseUrl, "base-url", "", "",
`Manually set the base url of torrents list page. e.g.: "special.php", "adult.php", "torrents.php?cat=100"`)
`Manually set the base url of torrents list page. e.g.: "special.php", "torrents.php?cat=100"`)
command.Flags().StringVarP(&rename, "rename", "", "", "Rename downloaded or added torrents (supports variables)")
cmd.AddEnumFlagP(command, &action, "action", "", ActionEnumFlag)
cmd.AddEnumFlagP(command, &sortFlag, "sort", "", common.SiteTorrentSortFlag)
cmd.AddEnumFlagP(command, &orderFlag, "order", "", common.OrderFlag)
Expand All @@ -140,6 +153,10 @@ func batchdl(command *cobra.Command, args []string) error {
if err != nil {
return err
}
if downloadAll {
includeDownloaded = true
minSeeders = -1
}
if largestFlag && newestFlag {
return fmt.Errorf("--largest and --newest flags are NOT compatible")
}
Expand Down Expand Up @@ -376,14 +393,22 @@ mainloop:
}
if err != nil {
fmt.Printf("torrent %s (%s): failed to download: %v\n", torrent.Id, torrent.Name, err)
} else if tinfo, err := torrentutil.ParseTorrent(torrentContent, 99); err != nil {
fmt.Printf("torrent %s (%s): failed to parse: %v\n", torrent.Id, torrent.Name, err)
} else {
if action == "download" {
err = os.WriteFile(downloadDir+"/"+filename, torrentContent, 0666)
fileName := ""
if rename == "" {
fileName = filename
} else {
fileName = torrentutil.RenameTorrent(rename, sitename, torrent.Id, filename, tinfo)
}
err = os.WriteFile(downloadDir+"/"+fileName, torrentContent, 0666)
if err != nil {
fmt.Printf("torrent %s: failed to write to %s/file %s: %v\n", torrent.Id, downloadDir, filename, err)
} else {
fmt.Printf("torrent %s - %s (%s): downloaded to %s/%s\n", torrent.Id, torrent.Name,
util.BytesSize(float64(torrent.Size)), downloadDir, filename)
util.BytesSize(float64(torrent.Size)), downloadDir, fileName)
}
} else if action == "add" {
tags := []string{}
Expand All @@ -397,6 +422,9 @@ mainloop:
} else {
clientAddTorrentOption.Category = addCategory
}
if rename != "" {
clientAddTorrentOption.Name = torrentutil.RenameTorrent(rename, sitename, torrent.Id, filename, tinfo)
}
err = clientInstance.AddTorrent(torrentContent, clientAddTorrentOption, nil)
if err != nil {
fmt.Printf("torrent %s (%s): failed to add to client: %v\n", torrent.Id, torrent.Name, err)
Expand Down
5 changes: 2 additions & 3 deletions cmd/brush/strategy/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ func Decide(clientStatus *client.Status, clientTorrents []client.Torrent, siteTo
cntDownloadingTorrents := int64(0)
freespace := clientStatus.FreeSpaceOnDisk
freespaceChange := int64(0)
freespaceTarget := util.Min(clientOption.MinDiskSpace*2,
clientOption.MinDiskSpace+DELETE_TORRENTS_FREE_DISK_SPACE_TIER)
freespaceTarget := min(clientOption.MinDiskSpace*2, clientOption.MinDiskSpace+DELETE_TORRENTS_FREE_DISK_SPACE_TIER)
estimateUploadSpeed := clientStatus.UploadSpeed

var candidateTorrents []candidateTorrentStruct
Expand Down Expand Up @@ -420,7 +419,7 @@ func Decide(clientStatus *client.Status, clientTorrents []client.Torrent, siteTo
}

// mark torrents as resume
if freespace+freespaceChange >= util.Max(clientOption.MinDiskSpace, RESUME_TORRENTS_FREE_DISK_SPACE_TIER) {
if freespace+freespaceChange >= max(clientOption.MinDiskSpace, RESUME_TORRENTS_FREE_DISK_SPACE_TIER) {
for _, torrent := range clientTorrents {
if torrent.State != "error" || torrent.UploadSpeed < clientOption.SlowUploadSpeedTier*4 ||
isTorrentStalled(&torrent) || clientTorrentsMap[torrent.InfoHash].ResumeFlag {
Expand Down
10 changes: 10 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -69,6 +70,12 @@ func Execute() {
log.Debugf("ptool start: %v", os.Args)
log.Debugf("tty=%t, width=%d, height=%d", isTty, width, height)
log.Infof("config file: %s/%s", config.ConfigDir, config.ConfigFile)
if config.GlobalLock {
if config.LockFile != "" {
log.Fatalf("--lock and --global-lock flags are NOT compatible")
}
config.LockFile = path.Join(config.ConfigDir, config.GLOBAL_LOCK_FILE)
}
if config.LockFile != "" {
log.Debugf("Locking file: %s", config.LockFile)
lock := flock.New(config.LockFile)
Expand Down Expand Up @@ -134,6 +141,9 @@ func init() {
"It only works on Linux platform")
RootCmd.PersistentFlags().BoolVarP(&config.LockOrExit, "lock-or-exit", "", false,
"Used with --lock flag. If failed to acquire lock, exit 1 immediately instead of waiting")
RootCmd.PersistentFlags().BoolVarP(&config.GlobalLock, "global-lock", "", false,
"Similar to --lock but does NOT require a filename. "+
"All ptool instances which use the same config file share the lock")
RootCmd.PersistentFlags().StringVarP(&config.ConfigFile, "config", "", config.DefaultConfigFile,
"Config file ([ptool.toml])")
RootCmd.PersistentFlags().StringVarP(&config.LockFile, "lock", "", "",
Expand Down
5 changes: 5 additions & 0 deletions cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package delete
import (
"fmt"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/sagan/ptool/client"
Expand Down Expand Up @@ -112,6 +113,10 @@ func delete(cmd *cobra.Command, args []string) error {
return true
})
}
if len(torrents) == 0 {
log.Infof("No matched torrents found")
return nil
}
if !force {
client.PrintTorrents(torrents, "", 1, false)
fmt.Printf("\n")
Expand Down
22 changes: 6 additions & 16 deletions cmd/dltorrent/dltorrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,26 @@ var command = &cobra.Command{
Short: "Download site torrents to local.",
Long: `Download site torrents to local.
--filename <name> flag supports the following variable placeholders:
--rename <name> flag supports the following variable placeholders:
* [size] : Torrent size
* [id] : Torrent id in site
* [site] : Torrent site
* [filename] : Original torrent filename, with ".torrent" extension removed
* [filename] : Original torrent filename without ".torrent" extension
* [name] : Torrent name`,
Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.OnlyValidArgs),
RunE: dltorrent,
}

var (
downloadDir = ""
savename = ""
rename = ""
defaultSite = ""
)

func init() {
command.Flags().StringVarP(&defaultSite, "site", "", "", "Set default site of torrents")
command.Flags().StringVarP(&downloadDir, "dir", "", ".", `Set the dir of downloaded torrents`)
command.Flags().StringVarP(&savename, "filename", "", "",
"Set the filename of downloaded torrents (supports variables)")
command.Flags().StringVarP(&rename, "rename", "", "", "Rename downloaded torrents (supports variables)")
cmd.RootCmd.AddCommand(command)
}

Expand Down Expand Up @@ -107,19 +106,10 @@ func dltorrent(cmd *cobra.Command, args []string) error {
continue
}
fileName := ""
if savename == "" {
if rename == "" {
fileName = filename
} else {
fileName = savename
basename := filename
if i := strings.LastIndex(basename, "."); i != -1 {
basename = basename[:i]
}
fileName = strings.ReplaceAll(fileName, "[size]", util.BytesSize(float64(tinfo.Size)))
fileName = strings.ReplaceAll(fileName, "[id]", id)
fileName = strings.ReplaceAll(fileName, "[site]", siteName)
fileName = strings.ReplaceAll(fileName, "[filename]", basename)
fileName = strings.ReplaceAll(fileName, "[name]", tinfo.Info.Name)
fileName = torrentutil.RenameTorrent(rename, siteName, id, filename, tinfo)
}
err = os.WriteFile(downloadDir+"/"+fileName, content, 0666)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions cmd/recheck/recheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package recheck
import (
"fmt"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/sagan/ptool/client"
Expand Down Expand Up @@ -87,6 +88,7 @@ func recheck(cmd *cobra.Command, args []string) error {
return fmt.Errorf("failed to fetch client torrents: %v", err)
}
if len(torrents) == 0 {
log.Infof("No matched torrents found")
return nil
}
if !force {
Expand Down
3 changes: 2 additions & 1 deletion cmd/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ func init() {
command.Flags().Int64VarP(&perSiteMaxResults, "per-site-max-results", "", -1,
"Number limit of search result of any single site. -1 == no limit")
command.Flags().StringVarP(&baseUrl, "base-url", "", "",
"Manually set the base url of search page. e.g.: adult.php, special.php")
`Manually set the base url of search page. "%s" can be used as search keyboard placeholder. `+
`E.g.: "special.php", "adult.php?incldead=1&search=%s"`)
command.Flags().Int64VarP(&minSeeders, "min-seeders", "", 1,
"Skip torrent with seeders less than (<) this value. -1 == no limit")
command.Flags().StringVarP(&minTorrentSizeStr, "min-torrent-size", "", "-1",
Expand Down
6 changes: 3 additions & 3 deletions cmd/show/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ func init() {
"Show at most this number of torrents. -1 == no limit")
command.Flags().BoolVarP(&dense, "dense", "d", false, "Dense mode: show full torrent title & subtitle")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false,
`Show largest torrents first. Equivalent with "--sort size --order desc"`)
`Show largest torrents first. Equivalent to "--sort size --order desc"`)
command.Flags().BoolVarP(&newestFlag, "newest", "n", false,
`Show newest torrents first. Equivalent with "--sort time --order desc"`)
command.Flags().BoolVarP(&showAll, "all", "a", false, `Show all torrents. Equivalent with passing a "_all" arg`)
`Show newest torrents first. Equivalent to "--sort time --order desc"`)
command.Flags().BoolVarP(&showAll, "all", "a", false, `Show all torrents. Equivalent to passing a "_all" arg`)
command.Flags().BoolVarP(&showRaw, "raw", "", false, "Show torrent size in raw format")
command.Flags().BoolVarP(&showJson, "json", "", false, "Show output in json format")
command.Flags().BoolVarP(&showInfoHashOnly, "show-info-hash-only", "", false, "Output torrents info hash only")
Expand Down

0 comments on commit 53013c2

Please sign in to comment.