Skip to content

Commit

Permalink
improve cookiecloud cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
sagan committed Dec 7, 2023
1 parent f2cd50a commit 3393e7a
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 57 deletions.
26 changes: 19 additions & 7 deletions cmd/cookiecloud/importsites/importsites.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import (
)

var (
doAction = false
profile = ""
doAction = false
profile = ""
siteProxy = ""
siteUa = ""
)

var command = &cobra.Command{
Expand All @@ -36,6 +38,8 @@ Be aware that all existing comments in config file will be LOST when updating co
func init() {
command.Flags().BoolVarP(&doAction, "do", "", false, "Do update the config file without confirm. Be aware that all existing comments in config file will be LOST")
command.Flags().StringVarP(&profile, "profile", "", "", "Comma-separated string, Set the used cookiecloud profile name(s). If not set, All cookiecloud profiles in config will be used")
command.Flags().StringVarP(&siteProxy, "site-proxy", "", "", "Set the proxy for imported sites")
command.Flags().StringVarP(&siteUa, "site-ua", "", "", "Set the user-agent for imported sites")
cookiecloud.Command.AddCommand(command)
}

Expand Down Expand Up @@ -79,6 +83,7 @@ func importsites(cmd *cobra.Command, args []string) error {
tplExistingFlags[tplname] = true
}
}
nowStr := util.FormatTime(util.Now())
for _, cookiecloudData := range cookiecloudDatas {
for _, tplname := range tpl.SITENAMES {
if tplExistingFlags[tplname] {
Expand All @@ -88,17 +93,18 @@ func importsites(cmd *cobra.Command, args []string) error {
if cookie == "" {
continue
}
newsiteconfig := &config.SiteConfigStruct{Type: tplname, Cookie: cookie}
newsiteconfig := &config.SiteConfigStruct{Type: tplname, Cookie: cookie,
Proxy: siteProxy, UserAgent: siteUa}
siteInstance, err := site.CreateSiteInternal(tplname, newsiteconfig, config.Get())
if err != nil {
log.Debugf("New Site %s from cookiecloud %s is invalid (create instance error: %v",
tplname, cookiecloudData.Label, err)
continue
}
sitestatus, err := siteInstance.GetStatus()
if err != nil {
log.Debugf("New Site %s from cookiecloud %s is invalid (get status error: %v",
tplname, cookiecloudData.Label, err)
if err != nil || !sitestatus.IsOk() {
log.Debugf("New Site %s from cookiecloud %s is invalid (status error=%v, valid=%t)",
tplname, cookiecloudData.Label, err, sitestatus.IsOk())
continue
}
log.Infof("✓✓New site %s from cookiecloud %s is valid (username: %s)",
Expand All @@ -119,6 +125,8 @@ func importsites(cmd *cobra.Command, args []string) error {
Name: sitename,
Type: tplname,
Cookie: cookie,
AutoComment: fmt.Sprintf(`imported by "ptool cookiecloue import" at %s from cookiecloud %s`,
nowStr, cookiecloudData.Label),
})
tplExistingFlags[tplname] = true
}
Expand All @@ -127,7 +135,11 @@ func importsites(cmd *cobra.Command, args []string) error {
if len(addSites) > 0 {
fmt.Printf("✓new sites found (%d): %s", len(addSites),
strings.Join(util.Map(addSites, func(site *config.SiteConfigStruct) string {
return site.Type
sitename := site.Type
if site.Name != "" {
sitename = fmt.Sprintf("%s (as %s)", sitename, site.Name)
}
return sitename
}), ", "))

configFile := fmt.Sprintf("%s/%s", config.ConfigDir, config.ConfigFile)
Expand Down
19 changes: 15 additions & 4 deletions cmd/cookiecloud/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ func sync(cmd *cobra.Command, args []string) error {
msg: fmt.Sprintf("site current cookie is invalid (get status error: %v)", err),
}
}
} else if !sitestatus.IsOk() {
ch <- &site_test_result{
sitename: sitename,
url: siteInstance.GetSiteConfig().Url,
flag: 3,
msg: "site status is not OK (cookie may be invalid)",
}
} else {
ch <- &site_test_result{
sitename: sitename,
Expand All @@ -154,6 +161,7 @@ func sync(cmd *cobra.Command, args []string) error {
siteUrls[result.sitename] = result.url
log.Infof("%s site %s: %s // remaining sites: %d", symbol, result.sitename, result.msg, len(sitenames)-i-1)
}
nowStr := util.FormatTime(util.Now())
for _, sitename := range sitenames {
if siteFlags[sitename] != 3 {
continue
Expand All @@ -166,7 +174,7 @@ func sync(cmd *cobra.Command, args []string) error {
}
newcookie, err := cookiecloudData.Data.GetEffectiveCookie(siteUrls[sitename], false, "http")
if newcookie == "" {
log.Debugf("No cookie found for % site from cookiecloud %s (url=%s, error: %v)",
log.Debugf("No cookie found for %s site from cookiecloud %s (url=%s, error: %v)",
sitename, cookiecloudData.Label, siteUrls[sitename], err)
continue
}
Expand All @@ -181,14 +189,17 @@ func sync(cmd *cobra.Command, args []string) error {
continue
}
sitestatus, err := siteInstance.GetStatus()
if err != nil {
log.Debugf("Site %s new cookie from cookiecloud %s is invalid (get status error: %v",
sitename, cookiecloudData.Label, err)
if err != nil || !sitestatus.IsOk() {
log.Debugf("Site %s new cookie from cookiecloud %s is invalid (status error=%v, valid=%t)",
sitename, cookiecloudData.Label, err, sitestatus.IsOk())
continue
}
log.Infof("✓✓site %s new cookie from cookiecloud %s is OK (username: %s)",
sitename, cookiecloudData.Label, sitestatus.UserName)
siteFlags[sitename] = 4
newsiteconfig.AutoComment = fmt.Sprintf(
`cookie updated by "ptool cookiecloud sync" at %s from cookiecloud %s`,
nowStr, cookiecloudData.Label)
updatesites = append(updatesites, newsiteconfig)
}
}
Expand Down
25 changes: 21 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/url"
"path"
"regexp"
"strings"
"sync"

Expand Down Expand Up @@ -47,16 +48,19 @@ type CookiecloudConfigStruct struct {
Password string `yaml:"password"`
Proxy string `yaml:"proxy"`
Sites []string `yaml:"sites"`
Comment string `yaml:"comment"`
}

type GroupConfigStruct struct {
Name string `yaml:"name"`
Sites []string `yaml:"sites"`
Name string `yaml:"name"`
Sites []string `yaml:"sites"`
Comment string `yaml:"comment"`
}

type ClientConfigStruct struct {
Type string `yaml:"type"`
Name string `yaml:"name"`
Comment string `yaml:"comment"`
Disabled bool `yaml:"disabled"`
Url string `yaml:"url"`
Username string `yaml:"username"`
Expand Down Expand Up @@ -128,14 +132,15 @@ type SiteConfigStruct struct {
TorrentDownloadUrl string `yaml:"torrentDownloadUrl"` // use {id} placeholders in url
TorrentDownloadUrlPrefix string `yaml:"torrentDownloadUrlPrefix"`
Passkey string `yaml:"passkey"`
UseCuhash bool `yaml:"useCuhash"` // hdcity 使用机制。种子下载地址里必须有cuhash参数
UseDigitHash bool `yaml:"useDigitHash"` // ttg 使用机制。种子下载地址末段必须有4位数字校验码或Passkey参数(即使有 Cookie)
UseCuhash bool `yaml:"useCuhash"` // hdcity 使用机制。种子下载地址里必须有cuhash参数
UseDigitHash bool `yaml:"useDigitHash"` // ttg 使用机制。种子下载地址末段必须有4位数字校验码或Passkey参数(即使有 Cookie)
TorrentUrlIdRegexp string `yaml:"torrentUrlIdRegexp"`
FlowControlInterval int64 `yaml:"flowControlInterval"` // 暂定名。两次请求种子列表页间隔时间(秒)
NexusphpNoLetDown bool `yaml:"nexusphpNoLetDown"`
TorrentUploadSpeedLimitValue int64
BrushTorrentMinSizeLimitValue int64
BrushTorrentMaxSizeLimitValue int64
AutoComment string // 自动更新 ptool.toml 时系统生成的 comment。会被写入 Comment 字段
}

type ConfigStruct struct {
Expand All @@ -153,6 +158,7 @@ type ConfigStruct struct {
Sites []*SiteConfigStruct `yaml:"sites"`
Groups []*GroupConfigStruct `yaml:"groups"`
Cookieclouds []*CookiecloudConfigStruct `yaml:"cookieclouds"`
Comment string `yaml:"comment"`
}

var (
Expand Down Expand Up @@ -184,6 +190,17 @@ func UpdateSites(updatesites []*SiteConfigStruct) {
}
allsites := Get().Sites
for _, updatesite := range updatesites {
if updatesite.AutoComment != "" {
m := regexp.MustCompile(`^(.*?)<!--\{ptool\}.*?-->(.*)$`)
autoComment := fmt.Sprintf(`<!--{ptool} %s-->`, updatesite.AutoComment)
comment := m.ReplaceAllString(updatesite.Comment, fmt.Sprintf(`$1%s$2`, autoComment))
if comment == updatesite.Comment {
updatesite.Comment += autoComment
} else {
updatesite.Comment = comment
}
}

updatesite.Register()
index := slices.IndexFunc(allsites, func(scs *SiteConfigStruct) bool {
return scs.GetName() == updatesite.GetName()
Expand Down
70 changes: 35 additions & 35 deletions ptool.example.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
iyuuToken = "" # iyuu token。用于自动辅种功能
iyuuToken = '' # iyuu token。用于自动辅种功能
# 注释掉的配置项值为默认值
#siteProxy = "" # 使用代理访问 PT 站点。(不适用于访问 BT 客户端)。格式为 "http://127.0.0.1:1080"
#siteUserAgent = "" # 所有站点默认使用的 ua。默认使用最新稳定版 Chrome on Windows x64 en-US 的 ua
#siteProxy = '' # 使用代理访问 PT 站点。(不适用于访问 BT 客户端)。格式为 'http://127.0.0.1:1080'
#siteUserAgent = '' # 所有站点默认使用的 ua。默认使用最新稳定版 Chrome on Windows x64 en-US 的 ua
#brushEnableStats = false # 启用刷流统计功能
#hushshell = false # 如果设为 true, 启动 ptool shell 时将不显示欢迎信息
#shellMaxSuggestions = 5 # ptool shell 自动补全显示建议数量。设为 0 禁用
Expand All @@ -10,64 +10,64 @@ iyuuToken = "" # iyuu token。用于自动辅种功能

# 自定义访问站点时设置的 http 请求头。如果值设为空,删除对应header
#[siteHttpHeaders]
#"Cache-Control" = "no-cache"
#'Cache-Control' = 'no-cache'

# 完整支持 qBittorrent v4.1+ (推荐使用 qb v4.4+)
[[clients]]
name = "local"
type = "qbittorrent"
url = "http://localhost:8085/"
username = "admin"
password = "adminadmin"
name = 'local'
type = 'qbittorrent'
url = 'http://localhost:8085/'
username = 'admin'
password = 'adminadmin'
#qbittorrentNoLogin = false # 如果启用,不会发送登录请求。这将提高命令响应速度。需要在 QB Web UI 设置里开启跳过验证
#qbittorrentNoLogout = false # 如果启用,不会发送退出登录请求。这将提高命令响应速度,但会导致 QB web session 占用的内存不能及时释放
#brushMinDiskSpace = "5GiB" # 刷流:保留最小剩余磁盘空间
#brushSlowUploadSpeedTier = "100KiB" # 刷流:上传速度(/s)持续低于此值的种子将可能被删除
#brushMinDiskSpace = '5GiB' # 刷流:保留最小剩余磁盘空间
#brushSlowUploadSpeedTier = '100KiB' # 刷流:上传速度(/s)持续低于此值的种子将可能被删除
#brushMaxDownloadingTorrents = 6 # 刷流:位于下载状态的种子数上限
#brushMaxTorrents = 9999 # 刷流:种子数(所有状态)上限
#brushMinRatio = 0.2 # 刷流:最小 ratio (上传量/下载量)比例。ratio 持续低于此值的种子将可能被删除
#brushDefaultUploadSpeedLimit = "10MiB" # 刷流:默认最大上传速度限制(/s)
#brushDefaultUploadSpeedLimit = '10MiB' # 刷流:默认最大上传速度限制(/s)


# 对 Transmission 客户端支持不完整且尚未充分测试。不建议用于刷流
# 支持 Transmission 2.80 ~ 3.00 (Transmission v4 还有问题)
[[clients]]
name = "tr"
type = "transmission"
url = "http://localhost:9091/"
username = "admin"
password = "123456"
name = 'tr'
type = 'transmission'
url = 'http://localhost:9091/'
username = 'admin'
password = '123456'


# 配置 CookieCloud ( https://github.com/easychen/CookieCloud ) 后,可以从服务器同步站点 cookies 或导入站点
# 可以配置任意多个 CookieCloud 服务器信息
# 如果想要让某个 CookieCloud 服务器信息仅用于同步特定站点 cookies,加上 sites = ["sitename"] 这行配置
# 请参考 "cookiecloud" 命令帮助。同步站点 cookies 或导入站点会更新 ptool.toml 配置文件(已有的注释信息会丢失)
# 如果想要让某个 CookieCloud 服务器信息仅用于同步特定站点 cookies,加上 sites = ['sitename'] 这行配置
# 请参考 'cookiecloud' 命令帮助。同步站点 cookies 或导入站点会更新 ptool.toml 配置文件(已有的注释信息会丢失)
[[cookieclouds]]
#name = "" # 名称可选
server = "https://cookiecloud.example.com"
uuid = "uuid"
password = "password"
#name = '' # 名称可选
server = 'https://cookiecloud.example.com'
uuid = 'uuid'
password = 'password'


[[sites]]
type = "mteam"
cookie = "cookie_here"
#proxy = "" # 访问该站点使用的代理。优先级高于全局的 siteProxy 配置。格式为 "http://127.0.0.1:1080"
#userAgent = "" # 部分站点 cookie 绑定 ua。优先级高于全局的 siteUserAgent 配置
#torrentUploadSpeedLimit = "10MiB" # 站点单个种子上传速度限制(/s)
#brushTorrentMinSizeLimit = "0" # 刷流:种子最小体积限制。体积小于此值的种子不会被选择
#brushTorrentMaxSizeLimit = "1PiB" # 刷流:种子最大体积限制。体积大于此值的种子不会被选择
type = 'mteam'
cookie = 'cookie_here'
#proxy = '' # 访问该站点使用的代理。优先级高于全局的 siteProxy 配置。格式为 'http://127.0.0.1:1080'
#userAgent = '' # 部分站点 cookie 绑定 ua。优先级高于全局的 siteUserAgent 配置
#torrentUploadSpeedLimit = '10MiB' # 站点单个种子上传速度限制(/s)
#brushTorrentMinSizeLimit = '0' # 刷流:种子最小体积限制。体积小于此值的种子不会被选择
#brushTorrentMaxSizeLimit = '1PiB' # 刷流:种子最大体积限制。体积大于此值的种子不会被选择
#brushAllowNoneFree = false # 是否允许使用非免费种子刷流
#brushAllowPaid = false # 是否允许使用"付费"种子刷流(付费种子:第一次下载或汇报时需要扣除积分)
#brushAllowPaid = false # 是否允许使用'付费'种子刷流(付费种子:第一次下载或汇报时需要扣除积分)
#brushAllowHr = false # 是否允许使用HR种子刷流。程序不会特意保证HR种子的做种时长,所以仅当你的账户无视HR(如VIP)时开启此选项
#brushAllowZeroSeeders = false # 是否允许刷流任务添加当前0做种的种子到客户端
#brushExcludes = [] # 排除种子关键字列表。标题或副标题包含列表中任意项的种子不会被刷流任务选择
#timezone = "Asia/Shanghai" # 网站页面显示时间的时区
#timezone = 'Asia/Shanghai' # 网站页面显示时间的时区

# 站点分组功能
# 定义分组后,大部分命令中 <site> 类型的参数可以使用分组名代替以指代多个站点,例如:
# 在 acg 分组的所有站点中搜索 "clannad" 关键词的种子: ptool search acg clannad
# 在 acg 分组的所有站点中搜索 'clannad' 关键词的种子: ptool search acg clannad
[[groups]]
name = "acg"
sites = ["u2", "kamept"]
name = 'acg'
sites = ['u2', 'kamept']
4 changes: 3 additions & 1 deletion site/discuz/discuz.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"strings"
"time"

log "github.com/sirupsen/logrus"

"github.com/sagan/ptool/config"
"github.com/sagan/ptool/site"
"github.com/sagan/ptool/util"
Expand Down Expand Up @@ -104,7 +106,7 @@ func (dzsite *Site) DownloadTorrentById(id string) ([]byte, string, error) {

func NewSite(name string, siteConfig *config.SiteConfigStruct, config *config.ConfigStruct) (site.Site, error) {
if siteConfig.Cookie == "" {
return nil, fmt.Errorf("cann't create site: no cookie provided")
log.Warnf("Site %s has no cookie provided", name)
}
location, err := time.LoadLocation(siteConfig.GetTimezone())
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion site/gazelle/gazelle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"strings"
"time"

log "github.com/sirupsen/logrus"

"github.com/sagan/ptool/config"
"github.com/sagan/ptool/site"
"github.com/sagan/ptool/util"
Expand Down Expand Up @@ -105,7 +107,7 @@ func (gzsite *Site) DownloadTorrentById(id string) ([]byte, string, error) {

func NewSite(name string, siteConfig *config.SiteConfigStruct, config *config.ConfigStruct) (site.Site, error) {
if siteConfig.Cookie == "" {
return nil, fmt.Errorf("cann't create site: no cookie provided")
log.Warnf("Site %s has no cookie provided", name)
}
location, err := time.LoadLocation(siteConfig.GetTimezone())
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion site/gazellepw/gazellepw.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"strings"
"time"

log "github.com/sirupsen/logrus"

"github.com/sagan/ptool/config"
"github.com/sagan/ptool/site"
"github.com/sagan/ptool/util"
Expand Down Expand Up @@ -86,7 +88,7 @@ func (gpwsite *Site) DownloadTorrentById(id string) ([]byte, string, error) {

func NewSite(name string, siteConfig *config.SiteConfigStruct, config *config.ConfigStruct) (site.Site, error) {
if siteConfig.Cookie == "" {
return nil, fmt.Errorf("cann't create site: no cookie provided")
log.Warnf("Site %s has no cookie provided", name)
}
location, err := time.LoadLocation(siteConfig.GetTimezone())
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions site/nexusphp/nexusphp.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func (npclient *Site) sync() error {
}

// possibly parsing error or some problem
if siteStatus.UserName == "" && siteStatus.UserDownloaded == 0 && siteStatus.UserUploaded == 0 {
if !siteStatus.IsOk() {
log.TraceFn(func() []any {
return []any{"Site GetStatus got no data, possible a parser error"}
})
Expand Down Expand Up @@ -424,7 +424,7 @@ func (npclient *Site) syncExtra() error {

func NewSite(name string, siteConfig *config.SiteConfigStruct, config *config.ConfigStruct) (site.Site, error) {
if siteConfig.Cookie == "" {
return nil, fmt.Errorf("no cookie provided")
log.Warnf("Site %s has no cookie provided", name)
}
location, err := time.LoadLocation(siteConfig.GetTimezone())
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions site/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ func (torrent *Torrent) MatchFilter(filter string) bool {
return false
}

// check if (seems) as a valid site status
func (status *Status) IsOk() bool {
return status.UserName != "" || status.UserDownloaded > 0 || status.UserUploaded > 0
}

// will match if any filter in list matches
func (torrent *Torrent) MatchFiltersOr(filters []string) bool {
return slices.IndexFunc(filters, func(filter string) bool {
Expand Down

0 comments on commit 3393e7a

Please sign in to comment.