Documentation
¶
Overview ¶
Package v2 provides caching utilities for performance optimization
Package v2 provides circuit breaker pattern for fault tolerance ¶
Package v2 provides HTTP client utilities based on github.com/sunerpy/requests
Package v2 provides level management for PT sites ¶
Package v2 provides metrics collection for performance monitoring ¶
Package v2 provides migration utilities for backward compatibility ¶
Package v2 provides site parsers for NexusPHP-based sites These parsers are migrated from internal/site_compat.go
Package v2 provides site registry for managing site metadata and creation ¶
Package v2 provides a generic site architecture using the Driver pattern. This package implements type-safe site drivers for different PT site architectures including NexusPHP, Unit3D, Gazelle, and mTorrent (M-Team).
Package v2 provides database-backed user info repository ¶
Package v2 provides input validation utilities
Index ¶
- Constants
- Variables
- func AddAtPausedToAutoStart(addAtPaused bool) bool
- func ApplyFilters(value any, filters []Filter) any
- func AutoStartToAddAtPaused(autoStart bool) bool
- func BuildMagnetLink(infoHash, name string, trackers []string) string
- func CalculateEffectiveDownload(sizeBytes int64, discountLevel DiscountLevel) int64
- func CalculateEffectiveUpload(sizeBytes int64, discountLevel DiscountLevel) int64
- func CalculateRatioImpact(currentUploaded, currentDownloaded, torrentSize int64, ...) float64
- func CanDownloadInTimeSimple(sizeBytes, downloadSpeedBps int64, discountLevel DiscountLevel, ...) bool
- func CompareDiscounts(a, b DiscountLevel) int
- func ComputeTorrentHash(data []byte) (string, error)
- func ComputeTorrentHashFromFile(path string) (string, error)
- func DiscountPriority(level DiscountLevel) int
- func EstimateDownloadTime(sizeBytes, downloadSpeedBps int64) time.Duration
- func ExtractMagnetHash(magnetURI string) (string, error)
- func FormatBytes(bytes int64) string
- func GetAllSiteCategoryConfigs() map[string]SiteCategoryConfig
- func GetSiteNextLevelUnmet(info *UserInfo, requirements []SiteLevelRequirement) map[string]any
- func GetSiteURLsForKind(kind SiteKind) map[SiteName][]string
- func GuessUserLevelID(info *UserInfo, requirements []SiteLevelRequirement) int
- func HandleQBittorrentAuthWithRequests(ctx context.Context, baseURL, username, password string) (string, error)
- func HandleTransmissionSession(resp *http.Response) string
- func IsBetterDiscount(a, b DiscountLevel) bool
- func IsFreeTorrent(level DiscountLevel) bool
- func IsTorrentHash(s string) bool
- func NormalizeInfoHash(hash string) string
- func ParseTimeInCST(layout, value string) (time.Time, error)
- func RegisterFilter(name string, fn FilterFunc)
- func RegisterSiteDefinition(def *SiteDefinition)
- func SanitizeHTML(input string) string
- func SanitizeSearchKeyword(keyword string) string
- func StripHTMLTags(input string) string
- func ValidateAPIKey(apiKey string) error
- func ValidateCookie(cookie string) error
- func ValidateInfoHash(hash string) bool
- func ValidateTorrentFile(data []byte) error
- type AggregatedStats
- type AlternativeRequirement
- type BaseSite
- func (b *BaseSite[Req, Res]) Close() error
- func (b *BaseSite[Req, Res]) Download(ctx context.Context, torrentID string) ([]byte, error)
- func (b *BaseSite[Req, Res]) GetDriver() Driver[Req, Res]
- func (b *BaseSite[Req, Res]) GetRateLimiter() *rate.Limiter
- func (b *BaseSite[Req, Res]) GetUserInfo(ctx context.Context) (UserInfo, error)
- func (b *BaseSite[Req, Res]) ID() string
- func (b *BaseSite[Req, Res]) IsLoggedIn() bool
- func (b *BaseSite[Req, Res]) Kind() SiteKind
- func (b *BaseSite[Req, Res]) Login(ctx context.Context, creds Credentials) error
- func (b *BaseSite[Req, Res]) Name() string
- func (b *BaseSite[Req, Res]) Search(ctx context.Context, query SearchQuery) ([]TorrentItem, error)
- type BaseSiteConfig
- type BatchDownloadService
- type CacheEntry
- type CachedSearchOrchestrator
- type CategoryDefinition
- type CategoryOption
- type CircuitBreaker
- type CircuitBreakerConfig
- type CircuitBreakerRegistry
- type CircuitBreakerStats
- type CircuitState
- type ConfigMigrator
- func (m *ConfigMigrator) CheckForDeprecatedFields(configJSON []byte) []DeprecationWarning
- func (m *ConfigMigrator) DetectDownloaderConfigVersion(configJSON []byte) string
- func (m *ConfigMigrator) MigrateDownloaderConfig(old OldDownloaderConfig) NewDownloaderConfig
- func (m *ConfigMigrator) MigrateDownloaderConfigIfNeeded(configJSON []byte) ([]byte, bool, error)
- func (m *ConfigMigrator) MigrateDownloaderConfigJSON(oldJSON []byte) ([]byte, error)
- func (m *ConfigMigrator) MigrateSiteConfig(old OldSiteConfig) SiteConfig
- func (m *ConfigMigrator) MigrateSiteConfigJSON(oldJSON []byte) ([]byte, error)
- type Counter
- type Credentials
- type DBUserInfoRepo
- func (r *DBUserInfoRepo) Count(ctx context.Context) (int64, error)
- func (r *DBUserInfoRepo) Delete(ctx context.Context, site string) error
- func (r *DBUserInfoRepo) DeleteAll(ctx context.Context) error
- func (r *DBUserInfoRepo) Get(ctx context.Context, site string) (UserInfo, error)
- func (r *DBUserInfoRepo) GetAggregated(ctx context.Context) (AggregatedStats, error)
- func (r *DBUserInfoRepo) ListAll(ctx context.Context) ([]UserInfo, error)
- func (r *DBUserInfoRepo) ListBySites(ctx context.Context, sites []string) ([]UserInfo, error)
- func (r *DBUserInfoRepo) Save(ctx context.Context, info UserInfo) error
- type Deduper
- type DeprecationWarning
- type DiscountLevel
- type DownloadFeasibility
- type Driver
- type FailoverHTTPClient
- func (c *FailoverHTTPClient) Do(ctx context.Context, method, path string, body []byte, ...) (*HTTPResponse, error)
- func (c *FailoverHTTPClient) Get(ctx context.Context, path string, headers map[string]string) (*HTTPResponse, error)
- func (c *FailoverHTTPClient) GetCurrentBaseURL() string
- func (c *FailoverHTTPClient) Post(ctx context.Context, path string, body []byte, headers map[string]string) (*HTTPResponse, error)
- type FailoverOption
- type FieldSelector
- type Filter
- type FilterFunc
- type FlexInt
- type FlexibleCode
- type FreeTorrentBatchResult
- type Gauge
- type GazelleDriver
- func (d *GazelleDriver) Execute(ctx context.Context, req GazelleRequest) (GazelleResponse, error)
- func (d *GazelleDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
- func (d *GazelleDriver) ParseDownload(res GazelleResponse) ([]byte, error)
- func (d *GazelleDriver) ParseSearch(res GazelleResponse) ([]TorrentItem, error)
- func (d *GazelleDriver) ParseUserInfo(res GazelleResponse) (UserInfo, error)
- func (d *GazelleDriver) PrepareDownload(torrentID string) (GazelleRequest, error)
- func (d *GazelleDriver) PrepareSearch(query SearchQuery) (GazelleRequest, error)
- func (d *GazelleDriver) PrepareUserInfo() (GazelleRequest, error)
- type GazelleDriverConfig
- type GazelleOptions
- type GazelleRequest
- type GazelleResponse
- type GazelleSearchResponse
- type GazelleTorrent
- type GazelleTorrentGroup
- type GazelleUserResponse
- type HDSkyParser
- func (p *HDSkyParser) ParseAll(doc *goquery.Selection) *TorrentDetailInfo
- func (p *HDSkyParser) ParseDiscount(doc *goquery.Selection) (DiscountLevel, time.Time)
- func (p *HDSkyParser) ParseHR(doc *goquery.Selection) bool
- func (p *HDSkyParser) ParseSizeMB(doc *goquery.Selection) float64
- func (p *HDSkyParser) ParseTitleAndID(doc *goquery.Selection) (title, torrentID string)
- type HTTPClientConfig
- type HTTPClientPool
- type HTTPResponse
- type Histogram
- type HistogramStats
- type InMemoryUserInfoRepo
- func (r *InMemoryUserInfoRepo) Clear()
- func (r *InMemoryUserInfoRepo) Count() int
- func (r *InMemoryUserInfoRepo) Delete(ctx context.Context, site string) error
- func (r *InMemoryUserInfoRepo) Get(ctx context.Context, site string) (UserInfo, error)
- func (r *InMemoryUserInfoRepo) GetAggregated(ctx context.Context) (AggregatedStats, error)
- func (r *InMemoryUserInfoRepo) ListAll(ctx context.Context) ([]UserInfo, error)
- func (r *InMemoryUserInfoRepo) ListBySites(ctx context.Context, sites []string) ([]UserInfo, error)
- func (r *InMemoryUserInfoRepo) Save(ctx context.Context, info UserInfo) error
- type L2Cache
- type LRUCache
- type LevelGroupType
- type LevelManager
- func (lm *LevelManager) CalculateNextLevel(kind SiteKind, upload int64, ratio float64, days int) *LevelProgress
- func (lm *LevelManager) GetCurrentLevel(kind SiteKind, upload int64, ratio float64, days int) string
- func (lm *LevelManager) GetLevels(kind SiteKind) []LevelRequirement
- func (lm *LevelManager) SetLevels(kind SiteKind, levels []LevelRequirement)
- type LevelProgress
- type LevelRequirement
- type MTorrentBonusResponse
- type MTorrentDriver
- func (d *MTorrentDriver) Execute(ctx context.Context, req MTorrentRequest) (MTorrentResponse, error)
- func (d *MTorrentDriver) GetBonusPerHour(ctx context.Context) (float64, error)
- func (d *MTorrentDriver) GetPeerStatistics(ctx context.Context) (*PeerStatistics, error)
- func (d *MTorrentDriver) GetSiteDefinition() *SiteDefinition
- func (d *MTorrentDriver) GetUnreadMessageCount(ctx context.Context) (int, int, error)
- func (d *MTorrentDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
- func (d *MTorrentDriver) ParseBonusPerHour(res MTorrentResponse) (float64, error)
- func (d *MTorrentDriver) ParseDownload(res MTorrentResponse) ([]byte, error)
- func (d *MTorrentDriver) ParsePeerStatistics(res MTorrentResponse) (*PeerStatistics, error)
- func (d *MTorrentDriver) ParseSearch(res MTorrentResponse) ([]TorrentItem, error)
- func (d *MTorrentDriver) ParseUnreadMessageCount(res MTorrentResponse) (int, int, error)
- func (d *MTorrentDriver) ParseUserInfo(res MTorrentResponse) (UserInfo, error)
- func (d *MTorrentDriver) PrepareDownload(torrentID string) (MTorrentRequest, error)
- func (d *MTorrentDriver) PrepareGetBonusPerHour() (MTorrentRequest, error)
- func (d *MTorrentDriver) PrepareGetPeerStatistics() (MTorrentRequest, error)
- func (d *MTorrentDriver) PrepareGetUnreadMessageCount() (MTorrentRequest, error)
- func (d *MTorrentDriver) PrepareSearch(query SearchQuery) (MTorrentRequest, error)
- func (d *MTorrentDriver) PrepareUserInfo() (MTorrentRequest, error)
- func (d *MTorrentDriver) SetSiteDefinition(def *SiteDefinition)
- type MTorrentDriverConfig
- type MTorrentMemberCount
- type MTorrentMemberStatus
- type MTorrentMessageStatResponse
- type MTorrentOptions
- type MTorrentPeerStatResponse
- type MTorrentRequest
- type MTorrentResponse
- type MTorrentSearchData
- type MTorrentSearchRequest
- type MTorrentTorrent
- type MTorrentUserInfo
- type MetricType
- type MetricsRegistry
- type MetricsSnapshot
- type MigrationStatus
- type MultiSiteSearchQuery
- type MultiSiteSearchResult
- type NewDownloaderConfig
- type NexusPHPDetailParser
- type NexusPHPDriver
- func (d *NexusPHPDriver) Execute(ctx context.Context, req NexusPHPRequest) (NexusPHPResponse, error)
- func (d *NexusPHPDriver) ExtractFieldValuePublic(doc *goquery.Document, selector FieldSelector) string
- func (d *NexusPHPDriver) FetchSeedingStatus(ctx context.Context, userID string) (seeding int, seedingSize int64, err error)
- func (d *NexusPHPDriver) GetSiteDefinition() *SiteDefinition
- func (d *NexusPHPDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
- func (d *NexusPHPDriver) ParseDetail(res NexusPHPResponse) (TorrentDetail, error)
- func (d *NexusPHPDriver) ParseDownload(res NexusPHPResponse) ([]byte, error)
- func (d *NexusPHPDriver) ParseSearch(res NexusPHPResponse) ([]TorrentItem, error)
- func (d *NexusPHPDriver) ParseSeedingStatus(res NexusPHPResponse) (seeding int, seedingSize int64, err error)
- func (d *NexusPHPDriver) ParseUserDetails(res NexusPHPResponse) (UserInfo, error)
- func (d *NexusPHPDriver) ParseUserInfo(res NexusPHPResponse) (UserInfo, error)
- func (d *NexusPHPDriver) PrepareDetail(torrentID string) (NexusPHPRequest, error)
- func (d *NexusPHPDriver) PrepareDownload(torrentID string) (NexusPHPRequest, error)
- func (d *NexusPHPDriver) PrepareSearch(query SearchQuery) (NexusPHPRequest, error)
- func (d *NexusPHPDriver) PrepareUserDetails(userID string) (NexusPHPRequest, error)
- func (d *NexusPHPDriver) PrepareUserInfo() (NexusPHPRequest, error)
- func (d *NexusPHPDriver) PrepareUserSeedingPage(userID, listType string) (NexusPHPRequest, error)
- func (d *NexusPHPDriver) SetSiteDefinition(def *SiteDefinition)
- type NexusPHPDriverConfig
- type NexusPHPOptions
- type NexusPHPParserConfig
- type NexusPHPParserOption
- type NexusPHPRequest
- type NexusPHPResponse
- type Normalizer
- type OldDownloaderConfig
- type OldSiteConfig
- type ParsedTorrent
- func GetRemoteTorrent(torrentURL, cookie string) (*ParsedTorrent, error)
- func GetRemoteTorrentWithClient(torrentURL, cookie string, client *http.Client) (*ParsedTorrent, error)
- func GetRemoteTorrentWithRequests(torrentURL, cookie string) (*ParsedTorrent, error)
- func ParseTorrent(data []byte) (*ParsedTorrent, error)
- func ParseTorrentFromFile(path string) (*ParsedTorrent, error)
- type PeerStatistics
- type Ranker
- type RankerConfig
- type RequestConfig
- type RequestsClient
- type RequestsResponse
- type RetryConfig
- type RetryableHTTPClient
- type SearchCache
- func (c *SearchCache) Cleanup() int
- func (c *SearchCache) Clear()
- func (c *SearchCache) Delete(query MultiSiteSearchQuery)
- func (c *SearchCache) Get(query MultiSiteSearchQuery) (*MultiSiteSearchResult, bool)
- func (c *SearchCache) Set(query MultiSiteSearchQuery, result *MultiSiteSearchResult)
- func (c *SearchCache) Size() int
- type SearchCacheConfig
- type SearchError
- type SearchOrchestrator
- func (o *SearchOrchestrator) GetSite(siteID string) Site
- func (o *SearchOrchestrator) ListSites() []string
- func (o *SearchOrchestrator) RegisterSite(site Site)
- func (o *SearchOrchestrator) Search(ctx context.Context, query MultiSiteSearchQuery) (*MultiSiteSearchResult, error)
- func (o *SearchOrchestrator) UnregisterSite(siteID string)
- type SearchOrchestratorConfig
- type SearchQuery
- type Session
- type SessionManager
- func (m *SessionManager) GetSession(siteID string) (*Session, bool)
- func (m *SessionManager) IncrementLoginCount(siteID string) int
- func (m *SessionManager) InvalidateSession(siteID string)
- func (m *SessionManager) IsSessionValid(siteID string) bool
- func (m *SessionManager) RemoveSession(siteID string)
- func (m *SessionManager) ResetLoginCount(siteID string)
- func (m *SessionManager) SetSession(siteID string, session *Session)
- func (m *SessionManager) UpdateSessionID(siteID, sessionID string)
- type Site
- type SiteAdapter
- type SiteCategoryConfig
- type SiteConfig
- type SiteCredentials
- type SiteDefinition
- type SiteDefinitionRegistry
- func (r *SiteDefinitionRegistry) Get(siteID string) (*SiteDefinition, bool)
- func (r *SiteDefinitionRegistry) GetAll() []*SiteDefinition
- func (r *SiteDefinitionRegistry) GetOrDefault(siteID string) *SiteDefinition
- func (r *SiteDefinitionRegistry) List() []string
- func (r *SiteDefinitionRegistry) Register(def *SiteDefinition)
- type SiteFactory
- type SiteHTTPClient
- func (c *SiteHTTPClient) Close() error
- func (c *SiteHTTPClient) DoRequest(ctx context.Context, method, url string, body io.Reader, ...) (*HTTPResponse, error)
- func (c *SiteHTTPClient) Get(ctx context.Context, url string, headers map[string]string) (*HTTPResponse, error)
- func (c *SiteHTTPClient) Post(ctx context.Context, url string, body []byte, headers map[string]string) (*HTTPResponse, error)
- func (c *SiteHTTPClient) PostJSON(ctx context.Context, url string, body []byte, headers map[string]string) (*HTTPResponse, error)
- type SiteHTTPClientConfig
- type SiteKind
- type SiteLevelProgressInfo
- type SiteLevelRequirement
- type SiteMeta
- type SiteMetrics
- func (m *SiteMetrics) RecordCacheHit(cacheType string)
- func (m *SiteMetrics) RecordCacheMiss(cacheType string)
- func (m *SiteMetrics) RecordDownloaderRequest(downloader string, success bool, duration time.Duration)
- func (m *SiteMetrics) RecordError(errorType string)
- func (m *SiteMetrics) RecordRequest(site string, success bool, duration time.Duration)
- func (m *SiteMetrics) SetActiveDownloaders(count int)
- func (m *SiteMetrics) SetActiveSites(count int)
- func (m *SiteMetrics) Snapshot() MetricsSnapshot
- type SiteMigrationGuide
- type SiteMigrationManager
- func (m *SiteMigrationManager) GetMigrationStatus() []MigrationStatus
- func (m *SiteMigrationManager) GetNewSite(siteID string) Site
- func (m *SiteMigrationManager) GetSite(siteID string) any
- func (m *SiteMigrationManager) MigrateToNew(siteID string) error
- func (m *SiteMigrationManager) RegisterSite(siteID string, oldSite any, newSite Site, useNew bool)
- func (m *SiteMigrationManager) RollbackToOld(siteID string) error
- type SiteName
- type SiteRegistry
- func (r *SiteRegistry) CreateSite(siteID string, creds SiteCredentials, customBaseURL string) (Site, error)
- func (r *SiteRegistry) Get(id string) (SiteMeta, bool)
- func (r *SiteRegistry) GetDefaultBaseURL(siteID string) (string, bool)
- func (r *SiteRegistry) GetSiteKind(siteID string) (SiteKind, bool)
- func (r *SiteRegistry) List() []string
- func (r *SiteRegistry) Register(meta SiteMeta)
- type SiteSelectors
- type SiteURLRegistry
- func (r *SiteURLRegistry) GetFailoverClient(siteName SiteName, opts ...FailoverOption) (*FailoverHTTPClient, error)
- func (r *SiteURLRegistry) GetFailoverConfig(siteName SiteName) (URLFailoverConfig, error)
- func (r *SiteURLRegistry) GetURLs(siteName SiteName) []string
- func (r *SiteURLRegistry) HasSite(siteName SiteName) bool
- func (r *SiteURLRegistry) ListSites() []SiteName
- func (r *SiteURLRegistry) RegisterURLs(siteName SiteName, urls []string)
- type SpringSundayParser
- func (p *SpringSundayParser) ParseAll(doc *goquery.Selection) *TorrentDetailInfo
- func (p *SpringSundayParser) ParseDiscount(doc *goquery.Selection) (DiscountLevel, time.Time)
- func (p *SpringSundayParser) ParseHR(doc *goquery.Selection) bool
- func (p *SpringSundayParser) ParseSizeMB(doc *goquery.Selection) float64
- func (p *SpringSundayParser) ParseTitleAndID(doc *goquery.Selection) (title, torrentID string)
- type SyncError
- type Timer
- type TorrentDetail
- type TorrentDetailInfo
- type TorrentFile
- type TorrentItem
- func (t *TorrentItem) CanbeFinished(enabled bool, speedLimit, sizeLimitGB int) bool
- func (t *TorrentItem) GetFreeEndTime() *time.Time
- func (t *TorrentItem) GetFreeLevel() string
- func (t *TorrentItem) GetName() string
- func (t *TorrentItem) GetSubTitle() string
- func (t *TorrentItem) IsDiscountActive() bool
- func (t *TorrentItem) IsFree() bool
- type TorrentManifest
- type TwoLevelCache
- type TwoLevelCacheConfig
- type URLFailoverConfig
- type URLFailoverManager
- type Unit3DDriver
- func (d *Unit3DDriver) Execute(ctx context.Context, req Unit3DRequest) (Unit3DResponse, error)
- func (d *Unit3DDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
- func (d *Unit3DDriver) ParseDownload(res Unit3DResponse) ([]byte, error)
- func (d *Unit3DDriver) ParseSearch(res Unit3DResponse) ([]TorrentItem, error)
- func (d *Unit3DDriver) ParseUserInfo(res Unit3DResponse) (UserInfo, error)
- func (d *Unit3DDriver) PrepareDownload(torrentID string) (Unit3DRequest, error)
- func (d *Unit3DDriver) PrepareSearch(query SearchQuery) (Unit3DRequest, error)
- func (d *Unit3DDriver) PrepareUserInfo() (Unit3DRequest, error)
- type Unit3DDriverConfig
- type Unit3DOptions
- type Unit3DRequest
- type Unit3DResponse
- type Unit3DTorrent
- type Unit3DUserProfile
- type UserInfo
- type UserInfoConfig
- type UserInfoProcess
- type UserInfoRecord
- type UserInfoRepo
- type UserInfoService
- func (s *UserInfoService) ClearCache()
- func (s *UserInfoService) DeleteUserInfo(ctx context.Context, siteID string) error
- func (s *UserInfoService) FetchAndSave(ctx context.Context, siteID string) (UserInfo, error)
- func (s *UserInfoService) FetchAndSaveAll(ctx context.Context) ([]UserInfo, []error)
- func (s *UserInfoService) FetchAndSaveAllWithConcurrency(ctx context.Context, maxConcurrent int, timeout time.Duration) ([]UserInfo, []SyncError)
- func (s *UserInfoService) GetAggregated(ctx context.Context) (AggregatedStats, error)
- func (s *UserInfoService) GetAllUserInfo(ctx context.Context) ([]UserInfo, error)
- func (s *UserInfoService) GetSite(siteID string) (Site, bool)
- func (s *UserInfoService) GetUserInfo(ctx context.Context, siteID string) (UserInfo, error)
- func (s *UserInfoService) ListSites() []string
- func (s *UserInfoService) RegisterSite(site Site)
- func (s *UserInfoService) UnregisterSite(siteID string)
- type UserInfoServiceConfig
- type ValidationConfig
- type Validator
- func (v *Validator) ValidateFileSize(size int64) error
- func (v *Validator) ValidateInfoHash(input string) (string, error)
- func (v *Validator) ValidateSearchQuery(query SearchQuery) error
- func (v *Validator) ValidateString(input string) (string, error)
- func (v *Validator) ValidateURL(input string) (string, error)
Constants ¶
const ( KB int64 = 1024 MB int64 = 1024 * KB GB int64 = 1024 * MB TB int64 = 1024 * GB )
Size constants
const ( // MinVipLevelID is the minimum level ID for VIP users MinVipLevelID = 100 // MinManagerLevelID is the minimum level ID for manager/staff users MinManagerLevelID = 200 )
Level ID constants for special user groups
Variables ¶
var ( ErrNoFreeTorrents = errors.New("no free torrents found") ErrArchiveCreationFailed = errors.New("failed to create archive") ErrTorrentDownloadFailed = errors.New("failed to download torrent") )
Batch download errors
var ( // ErrCircuitOpen is returned when the circuit is open ErrCircuitOpen = errors.New("circuit breaker is open") // ErrTooManyRequests is returned when too many requests in half-open state ErrTooManyRequests = errors.New("too many requests in half-open state") )
var ( ErrAllURLsFailed = errors.New("all URLs failed") ErrNoURLsConfigured = errors.New("no URLs configured for site") )
Failover errors
var ( ErrInvalidTorrent = errors.New("invalid torrent file") ErrInvalidMagnet = errors.New("invalid magnet link") ErrTorrentNotFound = errors.New("torrent not found") ErrInvalidInfoHash = errors.New("invalid info hash") )
Common errors for torrent operations
var ( ErrSiteNotFound = errors.New("site not found") ErrInvalidCredentials = errors.New("invalid credentials") ErrSessionExpired = errors.New("session expired") ErrAuthFailed = errors.New("authentication failed: please check cookie or 2FA settings") Err2FARequired = ErrAuthFailed // Alias for backward compatibility ErrRateLimited = errors.New("rate limited") ErrParseError = errors.New("failed to parse response") ErrNetworkError = errors.New("network error") ErrNotImplemented = errors.New("not implemented") )
Common errors for site operations
var ( )
Extended info errors
var ( ErrEmptyInput = errors.New("input cannot be empty") ErrInputTooLong = errors.New("input exceeds maximum length") ErrInvalidURL = errors.New("invalid URL format") ErrInvalidEmail = errors.New("invalid email format") ErrInvalidHash = errors.New("invalid hash format") ErrInvalidCharacter = errors.New("input contains invalid characters") ErrFileTooLarge = errors.New("file exceeds maximum size") )
Validation errors
var CSTLocation = utils.CSTLocation
CSTLocation is the China Standard Time timezone (UTC+8). Re-exported from utils for convenience within this package.
var DebugUserInfo = false
DebugUserInfo enables debug output for user info parsing Set to true to see detailed parsing information
var DefaultMetrics = NewMetricsRegistry()
DefaultMetrics is the default metrics registry
var DefaultSiteMetrics = NewSiteMetrics(DefaultMetrics)
DefaultSiteMetrics is the default site metrics instance
var DefaultSiteURLs = map[SiteName][]string{ SiteNameMTeam: { "https://api.m-team.cc", "https://kp.m-team.cc", "https://pt.m-team.cc", }, SiteNameHDSky: { "https://hdsky.me", }, SiteNameSpringSunday: { "https://springsunday.net", }, SiteNameCHDBits: { "https://chdbits.co", }, SiteNameTTG: { "https://totheglory.im", }, SiteNameOurBits: { "https://ourbits.club", }, SiteNamePterClub: { "https://pterclub.com", }, SiteNameAudiences: { "https://audiences.me", }, }
DefaultSiteURLs contains the default base URLs for each site Sites can have multiple URLs for failover purposes
var DefaultValidator = NewValidator(DefaultValidationConfig())
DefaultValidator is the default validator instance
var FreeDiscountLevels = []DiscountLevel{ DiscountFree, Discount2xFree, }
FreeDiscountLevels contains all discount levels that result in free download
var InfoHashFromMagnet = ExtractMagnetHash
InfoHashFromMagnet is an alias for ExtractMagnetHash
var ParserRegistry = map[SiteName]func() NexusPHPDetailParser{ SiteNameHDSky: func() NexusPHPDetailParser { return NewHDSkyParser() }, SiteNameSpringSunday: func() NexusPHPDetailParser { return NewSpringSundayParser() }, }
ParserRegistry maps site names to their parsers
var SiteKindMap = map[SiteName]SiteKind{ SiteNameMTeam: SiteMTorrent, SiteNameHDSky: SiteNexusPHP, SiteNameSpringSunday: SiteNexusPHP, SiteNameCHDBits: SiteNexusPHP, SiteNameTTG: SiteNexusPHP, SiteNameOurBits: SiteNexusPHP, SiteNamePterClub: SiteNexusPHP, SiteNameAudiences: SiteNexusPHP, }
SiteKindMap maps site names to their architecture kinds
var TorrentHashRegex = regexp.MustCompile(`^[a-fA-F0-9]{40}$`)
TorrentHashRegex matches a 40-character hex info hash
Functions ¶
func AddAtPausedToAutoStart ¶
AddAtPausedToAutoStart converts the new AddAtPaused field back to the old autoStart field This is the inverse of AutoStartToAddAtPaused
func ApplyFilters ¶
ApplyFilters applies a chain of filters to a value
func AutoStartToAddAtPaused ¶
AutoStartToAddAtPaused converts the old autoStart field to the new AddAtPaused field The mapping is: autoStart=true → AddAtPaused=false (start immediately)
autoStart=false → AddAtPaused=true (add paused)
func BuildMagnetLink ¶
BuildMagnetLink builds a magnet link from an info hash and optional name
func CalculateEffectiveDownload ¶
func CalculateEffectiveDownload(sizeBytes int64, discountLevel DiscountLevel) int64
CalculateEffectiveDownload calculates the effective download size based on discount
func CalculateEffectiveUpload ¶
func CalculateEffectiveUpload(sizeBytes int64, discountLevel DiscountLevel) int64
CalculateEffectiveUpload calculates the effective upload size based on discount
func CalculateRatioImpact ¶
func CalculateRatioImpact(currentUploaded, currentDownloaded, torrentSize int64, discountLevel DiscountLevel, expectedUploadRatio float64) float64
CalculateRatioImpact calculates the ratio impact of downloading a torrent Returns the change in ratio (positive = ratio increases, negative = ratio decreases)
func CanDownloadInTimeSimple ¶
func CanDownloadInTimeSimple(sizeBytes, downloadSpeedBps int64, discountLevel DiscountLevel, discountEndTime time.Time) bool
CanDownloadInTimeSimple is a simplified version that returns just a boolean
func CompareDiscounts ¶
func CompareDiscounts(a, b DiscountLevel) int
CompareDiscounts compares two discount levels Returns: -1 if a < b, 0 if a == b, 1 if a > b
func ComputeTorrentHash ¶
ComputeTorrentHash computes the info hash from torrent file bytes
func ComputeTorrentHashFromFile ¶
ComputeTorrentHashFromFile computes the info hash from a torrent file path
func DiscountPriority ¶
func DiscountPriority(level DiscountLevel) int
DiscountPriority returns a priority value for sorting torrents by discount Higher priority = better discount
func EstimateDownloadTime ¶
EstimateDownloadTime estimates the download time for a given size and speed
func ExtractMagnetHash ¶
ExtractMagnetHash extracts the info hash from a magnet link
func FormatBytes ¶
FormatBytes formats bytes to human readable string
func GetAllSiteCategoryConfigs ¶
func GetAllSiteCategoryConfigs() map[string]SiteCategoryConfig
GetAllSiteCategoryConfigs 获取所有站点的分类配置
func GetSiteNextLevelUnmet ¶
func GetSiteNextLevelUnmet(info *UserInfo, requirements []SiteLevelRequirement) map[string]any
GetSiteNextLevelUnmet returns unmet requirements for next level
func GetSiteURLsForKind ¶
GetSiteURLsForKind returns URLs for sites of a specific kind This is a convenience function for getting URLs by site architecture type
func GuessUserLevelID ¶
func GuessUserLevelID(info *UserInfo, requirements []SiteLevelRequirement) int
GuessUserLevelID determines user level from info and requirements
func HandleQBittorrentAuthWithRequests ¶
func HandleQBittorrentAuthWithRequests(ctx context.Context, baseURL, username, password string) (string, error)
HandleQBittorrentAuthWithRequests handles QBittorrent 403 responses using requests library
func HandleTransmissionSession ¶
HandleTransmissionSession handles Transmission 409 responses by extracting session ID
func IsBetterDiscount ¶
func IsBetterDiscount(a, b DiscountLevel) bool
IsBetterDiscount returns true if a is a better discount than b
func IsFreeTorrent ¶
func IsFreeTorrent(level DiscountLevel) bool
IsFreeTorrent checks if the given discount level results in free download
func IsTorrentHash ¶
IsTorrentHash checks if a string is a valid torrent info hash
func NormalizeInfoHash ¶
NormalizeInfoHash normalizes an info hash to lowercase
func ParseTimeInCST ¶ added in v0.3.0
ParseTimeInCST parses a time string in CST timezone. Re-exported from utils for convenience within this package.
func RegisterFilter ¶
func RegisterFilter(name string, fn FilterFunc)
RegisterFilter adds a custom filter
func RegisterSiteDefinition ¶
func RegisterSiteDefinition(def *SiteDefinition)
RegisterSiteDefinition is a convenience function for init() registration
func SanitizeHTML ¶
SanitizeHTML sanitizes HTML content by escaping dangerous tags
func SanitizeSearchKeyword ¶
SanitizeSearchKeyword sanitizes a search keyword
func StripHTMLTags ¶
StripHTMLTags removes HTML tags from a string
func ValidateCookie ¶
ValidateCookie validates a cookie string
func ValidateInfoHash ¶
ValidateInfoHash validates an info hash string
func ValidateTorrentFile ¶
ValidateTorrentFile validates torrent file content
Types ¶
type AggregatedStats ¶
type AggregatedStats struct {
// TotalUploaded is the sum of all uploaded bytes
TotalUploaded int64 `json:"totalUploaded"`
// TotalDownloaded is the sum of all downloaded bytes
TotalDownloaded int64 `json:"totalDownloaded"`
// AverageRatio is the average ratio across all sites
AverageRatio float64 `json:"averageRatio"`
// TotalSeeding is the sum of all seeding torrents
TotalSeeding int `json:"totalSeeding"`
// TotalLeeching is the sum of all leeching torrents
TotalLeeching int `json:"totalLeeching"`
// TotalBonus is the sum of all bonus points
TotalBonus float64 `json:"totalBonus"`
// SiteCount is the number of sites included
SiteCount int `json:"siteCount"`
// LastUpdate is when this was last calculated (Unix seconds)
LastUpdate int64 `json:"lastUpdate"`
// PerSiteStats contains individual site statistics
PerSiteStats []UserInfo `json:"perSiteStats"`
// TotalBonusPerHour is the sum of all bonus per hour
TotalBonusPerHour float64 `json:"totalBonusPerHour,omitempty"`
// TotalSeedingBonus is the sum of all seeding bonus points
TotalSeedingBonus float64 `json:"totalSeedingBonus,omitempty"`
// TotalUnreadMessages is the sum of all unread messages
TotalUnreadMessages int `json:"totalUnreadMessages,omitempty"`
// TotalSeederSize is the sum of all seeding sizes
TotalSeederSize int64 `json:"totalSeederSize,omitempty"`
// TotalLeecherSize is the sum of all leeching sizes
TotalLeecherSize int64 `json:"totalLeecherSize,omitempty"`
}
AggregatedStats represents aggregated statistics across all sites
type AlternativeRequirement ¶
type AlternativeRequirement struct {
SeedingBonus float64 `json:"seedingBonus,omitempty"`
Uploads int `json:"uploads,omitempty"`
Bonus float64 `json:"bonus,omitempty"`
Downloaded string `json:"downloaded,omitempty"`
Ratio float64 `json:"ratio,omitempty"`
}
AlternativeRequirement for OR-based requirements
type BaseSite ¶
BaseSite wraps a Driver and provides common functionality like rate limiting and logging. It implements the Site interface by delegating to the underlying Driver.
func NewBaseSite ¶
func NewBaseSite[Req, Res any](driver Driver[Req, Res], config BaseSiteConfig) *BaseSite[Req, Res]
NewBaseSite creates a new BaseSite with the given driver and configuration
func (*BaseSite[Req, Res]) GetDriver ¶
GetDriver returns the underlying driver (for testing purposes)
func (*BaseSite[Req, Res]) GetRateLimiter ¶
GetRateLimiter returns the rate limiter (for testing purposes)
func (*BaseSite[Req, Res]) GetUserInfo ¶
GetUserInfo fetches the current user's information
func (*BaseSite[Req, Res]) IsLoggedIn ¶
IsLoggedIn returns whether the site is currently logged in
func (*BaseSite[Req, Res]) Login ¶
func (b *BaseSite[Req, Res]) Login(ctx context.Context, creds Credentials) error
Login authenticates with the site
func (*BaseSite[Req, Res]) Search ¶
func (b *BaseSite[Req, Res]) Search(ctx context.Context, query SearchQuery) ([]TorrentItem, error)
Search searches for torrents on the site
type BaseSiteConfig ¶
type BaseSiteConfig struct {
ID string
Name string
Kind SiteKind
RateLimit float64 // Requests per second
RateBurst int // Maximum burst size
Logger *zap.Logger
}
BaseSiteConfig holds configuration for creating a BaseSite
type BatchDownloadService ¶
type BatchDownloadService struct {
// contains filtered or unexported fields
}
BatchDownloadService provides batch download functionality for free torrents
func NewBatchDownloadService ¶
func NewBatchDownloadService(site Site, logger *zap.Logger) *BatchDownloadService
NewBatchDownloadService creates a new batch download service
func (*BatchDownloadService) DownloadFreeTorrents ¶
func (s *BatchDownloadService) DownloadFreeTorrents( ctx context.Context, archiveType string, outputDir string, ) (*FreeTorrentBatchResult, error)
DownloadFreeTorrents downloads all free torrents and packages them into an archive
func (*BatchDownloadService) FetchFreeTorrents ¶
func (s *BatchDownloadService) FetchFreeTorrents(ctx context.Context) ([]TorrentItem, error)
FetchFreeTorrents fetches all free torrents from the site This method only filters by free status, no other filter rules are applied
type CacheEntry ¶
CacheEntry represents a cached item with TTL
func (*CacheEntry) IsExpired ¶
func (e *CacheEntry) IsExpired() bool
IsExpired checks if the cache entry has expired
type CachedSearchOrchestrator ¶
type CachedSearchOrchestrator struct {
*SearchOrchestrator
// contains filtered or unexported fields
}
CachedSearchOrchestrator wraps SearchOrchestrator with caching
func NewCachedSearchOrchestrator ¶
func NewCachedSearchOrchestrator(orchestrator *SearchOrchestrator, cacheConfig SearchCacheConfig) *CachedSearchOrchestrator
NewCachedSearchOrchestrator creates a new CachedSearchOrchestrator
func (*CachedSearchOrchestrator) CacheSize ¶
func (c *CachedSearchOrchestrator) CacheSize() int
CacheSize returns the number of cached entries
func (*CachedSearchOrchestrator) CleanupCache ¶
func (c *CachedSearchOrchestrator) CleanupCache() int
CleanupCache removes expired entries
func (*CachedSearchOrchestrator) ClearCache ¶
func (c *CachedSearchOrchestrator) ClearCache()
ClearCache clears the search cache
func (*CachedSearchOrchestrator) Search ¶
func (c *CachedSearchOrchestrator) Search(ctx context.Context, query MultiSiteSearchQuery) (*MultiSiteSearchResult, error)
Search performs a cached search
type CategoryDefinition ¶
type CategoryDefinition struct {
Name string `json:"name"`
Key string `json:"key"`
Options []CategoryOption `json:"options"`
Notes string `json:"notes,omitempty"`
}
CategoryDefinition 分类定义
type CategoryOption ¶
type CategoryOption struct {
Value any `json:"value"`
Name string `json:"name"`
Type string `json:"type,omitempty"` // e.g., "normal", "adult" for mteam
}
CategoryOption 分类选项
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker implements the circuit breaker pattern
func NewCircuitBreaker ¶
func NewCircuitBreaker(name string, config CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreaker creates a new circuit breaker
func (*CircuitBreaker) Execute ¶
func (cb *CircuitBreaker) Execute(fn func() error) error
Execute runs the given function if the circuit allows it
func (*CircuitBreaker) Name ¶
func (cb *CircuitBreaker) Name() string
Name returns the circuit breaker name
func (*CircuitBreaker) Reset ¶
func (cb *CircuitBreaker) Reset()
Reset resets the circuit breaker to closed state
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() CircuitState
State returns the current circuit state
func (*CircuitBreaker) Stats ¶
func (cb *CircuitBreaker) Stats() CircuitBreakerStats
Stats returns circuit breaker statistics
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
// FailureThreshold is the number of failures before opening the circuit
FailureThreshold int
// SuccessThreshold is the number of successes in half-open to close the circuit
SuccessThreshold int
// Timeout is how long to wait before transitioning from open to half-open
Timeout time.Duration
// MaxHalfOpenRequests is the max concurrent requests in half-open state
MaxHalfOpenRequests int
}
CircuitBreakerConfig configures the circuit breaker
func DefaultCircuitBreakerConfig ¶
func DefaultCircuitBreakerConfig() CircuitBreakerConfig
DefaultCircuitBreakerConfig returns default configuration
type CircuitBreakerRegistry ¶
type CircuitBreakerRegistry struct {
// contains filtered or unexported fields
}
CircuitBreakerRegistry manages multiple circuit breakers
func NewCircuitBreakerRegistry ¶
func NewCircuitBreakerRegistry(config CircuitBreakerConfig) *CircuitBreakerRegistry
NewCircuitBreakerRegistry creates a new registry
func (*CircuitBreakerRegistry) Get ¶
func (r *CircuitBreakerRegistry) Get(name string) *CircuitBreaker
Get returns or creates a circuit breaker for the given name
func (*CircuitBreakerRegistry) GetAll ¶
func (r *CircuitBreakerRegistry) GetAll() []*CircuitBreaker
GetAll returns all circuit breakers
func (*CircuitBreakerRegistry) Reset ¶
func (r *CircuitBreakerRegistry) Reset()
Reset resets all circuit breakers
func (*CircuitBreakerRegistry) Stats ¶
func (r *CircuitBreakerRegistry) Stats() []CircuitBreakerStats
Stats returns statistics for all circuit breakers
type CircuitBreakerStats ¶
type CircuitBreakerStats struct {
Name string `json:"name"`
State string `json:"state"`
Failures int `json:"failures"`
Successes int `json:"successes"`
LastFailureTime time.Time `json:"lastFailureTime,omitempty"`
}
CircuitBreakerStats contains circuit breaker statistics
type CircuitState ¶
type CircuitState int
CircuitState represents the state of a circuit breaker
const ( // CircuitClosed allows requests to pass through CircuitClosed CircuitState = iota // CircuitOpen blocks all requests CircuitOpen // CircuitHalfOpen allows limited requests for testing recovery CircuitHalfOpen )
func (CircuitState) String ¶
func (s CircuitState) String() string
String returns the string representation of the circuit state
type ConfigMigrator ¶
type ConfigMigrator struct {
// contains filtered or unexported fields
}
ConfigMigrator handles migration from old configuration formats to new ones
func NewConfigMigrator ¶
func NewConfigMigrator(logger *zap.Logger) *ConfigMigrator
NewConfigMigrator creates a new ConfigMigrator
func (*ConfigMigrator) CheckForDeprecatedFields ¶
func (m *ConfigMigrator) CheckForDeprecatedFields(configJSON []byte) []DeprecationWarning
CheckForDeprecatedFields checks a config JSON for deprecated fields and logs warnings
func (*ConfigMigrator) DetectDownloaderConfigVersion ¶
func (m *ConfigMigrator) DetectDownloaderConfigVersion(configJSON []byte) string
DetectConfigVersion attempts to detect if a config is in old or new format Returns "old" for old format, "new" for new format, or "unknown"
func (*ConfigMigrator) MigrateDownloaderConfig ¶
func (m *ConfigMigrator) MigrateDownloaderConfig(old OldDownloaderConfig) NewDownloaderConfig
MigrateDownloaderConfig converts an old downloader config to the new format
func (*ConfigMigrator) MigrateDownloaderConfigIfNeeded ¶
func (m *ConfigMigrator) MigrateDownloaderConfigIfNeeded(configJSON []byte) ([]byte, bool, error)
MigrateDownloaderConfigIfNeeded migrates config only if it's in old format
func (*ConfigMigrator) MigrateDownloaderConfigJSON ¶
func (m *ConfigMigrator) MigrateDownloaderConfigJSON(oldJSON []byte) ([]byte, error)
MigrateDownloaderConfigJSON converts old downloader config JSON to new format
func (*ConfigMigrator) MigrateSiteConfig ¶
func (m *ConfigMigrator) MigrateSiteConfig(old OldSiteConfig) SiteConfig
MigrateSiteConfig converts an old site config to the new SiteConfig format
func (*ConfigMigrator) MigrateSiteConfigJSON ¶
func (m *ConfigMigrator) MigrateSiteConfigJSON(oldJSON []byte) ([]byte, error)
MigrateSiteConfigJSON converts old site config JSON to new format
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter is a monotonically increasing counter
type Credentials ¶
type Credentials struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Cookie string `json:"cookie,omitempty"`
APIKey string `json:"apiKey,omitempty"`
}
Credentials holds authentication information for a site
type DBUserInfoRepo ¶
type DBUserInfoRepo struct {
// contains filtered or unexported fields
}
DBUserInfoRepo is a database-backed implementation of UserInfoRepo
func NewDBUserInfoRepo ¶
func NewDBUserInfoRepo(db *gorm.DB) (*DBUserInfoRepo, error)
NewDBUserInfoRepo creates a new database-backed user info repository
func (*DBUserInfoRepo) Count ¶
func (r *DBUserInfoRepo) Count(ctx context.Context) (int64, error)
Count returns the number of stored user info entries
func (*DBUserInfoRepo) Delete ¶
func (r *DBUserInfoRepo) Delete(ctx context.Context, site string) error
Delete removes user info for a site
func (*DBUserInfoRepo) DeleteAll ¶
func (r *DBUserInfoRepo) DeleteAll(ctx context.Context) error
DeleteAll removes all user info records
func (*DBUserInfoRepo) GetAggregated ¶
func (r *DBUserInfoRepo) GetAggregated(ctx context.Context) (AggregatedStats, error)
GetAggregated calculates aggregated statistics
func (*DBUserInfoRepo) ListAll ¶
func (r *DBUserInfoRepo) ListAll(ctx context.Context) ([]UserInfo, error)
ListAll retrieves all stored user info
func (*DBUserInfoRepo) ListBySites ¶
ListBySites retrieves user info for specific sites
type Deduper ¶
type Deduper struct{}
Deduper removes duplicate torrents based on InfoHash
func (*Deduper) Deduplicate ¶
func (d *Deduper) Deduplicate(items []TorrentItem) []TorrentItem
Deduplicate removes duplicate torrents, keeping the best version of each
func (*Deduper) DeduplicateByTitle ¶
func (d *Deduper) DeduplicateByTitle(items []TorrentItem, normalizer *Normalizer) []TorrentItem
DeduplicateByTitle removes duplicates based on normalized title This is useful when InfoHash is not available
type DeprecationWarning ¶
type DeprecationWarning struct {
Field string `json:"field"`
Message string `json:"message"`
Replacement string `json:"replacement"`
Version string `json:"version"` // Version when it will be removed
}
DeprecationWarning represents a deprecation warning message
func GetDeprecationWarnings ¶
func GetDeprecationWarnings() []DeprecationWarning
GetDeprecationWarnings returns a list of deprecation warnings for old config fields
type DiscountLevel ¶
type DiscountLevel string
DiscountLevel represents the discount level of a torrent
const ( // DiscountNone represents no discount (normal download/upload counting) DiscountNone DiscountLevel = "NONE" // DiscountFree represents free download (0% download counting) DiscountFree DiscountLevel = "FREE" // Discount2xFree represents 2x free (0% download, 2x upload counting) Discount2xFree DiscountLevel = "2XFREE" // DiscountPercent50 represents 50% download counting DiscountPercent50 DiscountLevel = "PERCENT_50" // DiscountPercent30 represents 30% download counting DiscountPercent30 DiscountLevel = "PERCENT_30" // DiscountPercent70 represents 70% download counting DiscountPercent70 DiscountLevel = "PERCENT_70" // Discount2xUp represents 2x upload counting Discount2xUp DiscountLevel = "2XUP" // Discount2x50 represents 2x upload and 50% download counting Discount2x50 DiscountLevel = "2X50" )
func SuggestBestDiscount ¶
func SuggestBestDiscount(currentDiscount DiscountLevel, discountEndTime time.Time, minTimeNeeded time.Duration) DiscountLevel
SuggestBestDiscount suggests the best discount level to wait for based on current discount and time constraints
func (DiscountLevel) GetDownloadRatio ¶
func (d DiscountLevel) GetDownloadRatio() float64
GetDownloadRatio returns the download counting ratio (0.0 = free, 1.0 = normal)
func (DiscountLevel) GetUploadRatio ¶
func (d DiscountLevel) GetUploadRatio() float64
GetUploadRatio returns the upload counting ratio (1.0 = normal, 2.0 = double)
type DownloadFeasibility ¶
type DownloadFeasibility struct {
// CanComplete indicates if the download can complete before discount ends
CanComplete bool `json:"canComplete"`
// EstimatedTime is the estimated download time
EstimatedTime time.Duration `json:"estimatedTime"`
// TimeRemaining is the time remaining before discount ends
TimeRemaining time.Duration `json:"timeRemaining"`
// EffectiveSize is the size that counts towards download quota
EffectiveSize int64 `json:"effectiveSize"`
// Margin is the time margin (positive = can complete with time to spare)
Margin time.Duration `json:"margin"`
}
DownloadFeasibility represents the result of download feasibility calculation
func CanDownloadInTime ¶
func CanDownloadInTime(sizeBytes, downloadSpeedBps int64, discountLevel DiscountLevel, discountEndTime time.Time) DownloadFeasibility
CanDownloadInTime calculates if a torrent can be downloaded before the discount expires Parameters:
- sizeBytes: total torrent size in bytes
- downloadSpeedBps: download speed in bytes per second
- discountLevel: current discount level
- discountEndTime: when the discount expires (zero time means permanent)
Returns DownloadFeasibility with detailed information
type Driver ¶
type Driver[Req any, Res any] interface { // PrepareSearch converts a standard SearchQuery to site-specific request PrepareSearch(query SearchQuery) (Req, error) // Execute performs the actual network call Execute(ctx context.Context, req Req) (Res, error) // ParseSearch converts the raw response into standard TorrentItem list ParseSearch(res Res) ([]TorrentItem, error) // GetUserInfo fetches complete user information (including extended info if supported) // This method is responsible for making all necessary API calls GetUserInfo(ctx context.Context) (UserInfo, error) // PrepareDownload prepares request for downloading a torrent PrepareDownload(torrentID string) (Req, error) // ParseDownload extracts torrent file data from response ParseDownload(res Res) ([]byte, error) }
Driver defines how to interact with a specific type of site architecture. Req is the type of request payload (e.g., url.Values for forms, struct for JSON). Res is the raw response type (e.g., *goquery.Document, JSON struct).
type FailoverHTTPClient ¶
type FailoverHTTPClient struct {
// contains filtered or unexported fields
}
FailoverHTTPClient is a generic HTTP client with automatic URL failover All site drivers can use this client for making HTTP requests Uses requests library instead of net/http directly
func NewFailoverHTTPClient ¶
func NewFailoverHTTPClient(config URLFailoverConfig, opts ...FailoverOption) *FailoverHTTPClient
NewFailoverHTTPClient creates a new failover HTTP client
func (*FailoverHTTPClient) Do ¶
func (c *FailoverHTTPClient) Do(ctx context.Context, method, path string, body []byte, headers map[string]string) (*HTTPResponse, error)
Do performs a custom request with automatic URL failover Note: The request URL should be a path (e.g., "/api/search"), not a full URL
func (*FailoverHTTPClient) Get ¶
func (c *FailoverHTTPClient) Get(ctx context.Context, path string, headers map[string]string) (*HTTPResponse, error)
Get performs a GET request with automatic URL failover
func (*FailoverHTTPClient) GetCurrentBaseURL ¶
func (c *FailoverHTTPClient) GetCurrentBaseURL() string
GetCurrentBaseURL returns the currently active base URL
type FailoverOption ¶
type FailoverOption func(*FailoverHTTPClient)
FailoverOption is a functional option for FailoverHTTPClient
func WithUserAgent ¶
func WithUserAgent(ua string) FailoverOption
WithUserAgent sets the User-Agent header
type FieldSelector ¶
type FieldSelector struct {
// Selector is CSS selector(s) for HTML or JSON path for API
Selector []string `json:"selector,omitempty"`
// Text is the default value if selector doesn't match
Text string `json:"text,omitempty"`
// Attr is the attribute to extract (for HTML elements)
Attr string `json:"attr,omitempty"`
// Filters to apply to extracted value
Filters []Filter `json:"filters,omitempty"`
// ElementProcess is a custom processing function name
ElementProcess string `json:"elementProcess,omitempty"`
// SwitchFilters for different selectors
SwitchFilters map[string][]Filter `json:"switchFilters,omitempty"`
}
FieldSelector defines how to extract a field value
type Filter ¶
type Filter struct {
// Name is the filter function name
Name string `json:"name"`
// Args are optional arguments
Args []any `json:"args,omitempty"`
}
Filter defines a value transformation
type FilterFunc ¶
FilterFunc is a function that transforms a value
type FlexInt ¶
type FlexInt int
FlexInt handles fields that can be either string or int in JSON
func (*FlexInt) UnmarshalJSON ¶
UnmarshalJSON implements custom JSON unmarshaling for FlexInt
type FlexibleCode ¶
type FlexibleCode string
FlexibleCode handles M-Team API code field which can be either string or number
func (FlexibleCode) IsSuccess ¶
func (fc FlexibleCode) IsSuccess() bool
IsSuccess checks if the code represents success (typically "0" or "SUCCESS")
func (FlexibleCode) String ¶
func (fc FlexibleCode) String() string
String returns the string representation of the code
func (*FlexibleCode) UnmarshalJSON ¶
func (fc *FlexibleCode) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for FlexibleCode
type FreeTorrentBatchResult ¶
type FreeTorrentBatchResult struct {
// ArchivePath is the path to the created archive file
ArchivePath string `json:"archivePath"`
// ArchiveType is the type of archive (tar.gz or zip)
ArchiveType string `json:"archiveType"`
// TorrentCount is the number of torrents in the archive
TorrentCount int `json:"torrentCount"`
// TotalSize is the total size of all torrents (bytes)
TotalSize int64 `json:"totalSize"`
// Manifest contains metadata for all torrents
Manifest []TorrentManifest `json:"manifest"`
}
FreeTorrentBatchResult represents the result of a batch download operation
type Gauge ¶
type Gauge struct {
// contains filtered or unexported fields
}
Gauge is a value that can go up and down
type GazelleDriver ¶
type GazelleDriver struct {
BaseURL string
APIKey string
Cookie string
// contains filtered or unexported fields
}
GazelleDriver implements the Driver interface for Gazelle sites
func NewGazelleDriver ¶
func NewGazelleDriver(config GazelleDriverConfig) *GazelleDriver
NewGazelleDriver creates a new Gazelle driver
func (*GazelleDriver) Execute ¶
func (d *GazelleDriver) Execute(ctx context.Context, req GazelleRequest) (GazelleResponse, error)
Execute performs the HTTP request
func (*GazelleDriver) GetUserInfo ¶
func (d *GazelleDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
GetUserInfo fetches complete user information
func (*GazelleDriver) ParseDownload ¶
func (d *GazelleDriver) ParseDownload(res GazelleResponse) ([]byte, error)
ParseDownload extracts torrent file data from the response
func (*GazelleDriver) ParseSearch ¶
func (d *GazelleDriver) ParseSearch(res GazelleResponse) ([]TorrentItem, error)
ParseSearch extracts torrent items from the response
func (*GazelleDriver) ParseUserInfo ¶
func (d *GazelleDriver) ParseUserInfo(res GazelleResponse) (UserInfo, error)
ParseUserInfo extracts user info from the response
func (*GazelleDriver) PrepareDownload ¶
func (d *GazelleDriver) PrepareDownload(torrentID string) (GazelleRequest, error)
PrepareDownload prepares a request for downloading a torrent
func (*GazelleDriver) PrepareSearch ¶
func (d *GazelleDriver) PrepareSearch(query SearchQuery) (GazelleRequest, error)
PrepareSearch converts a SearchQuery to a Gazelle request
func (*GazelleDriver) PrepareUserInfo ¶
func (d *GazelleDriver) PrepareUserInfo() (GazelleRequest, error)
PrepareUserInfo prepares a request for user info
type GazelleDriverConfig ¶
type GazelleDriverConfig struct {
BaseURL string
APIKey string
Cookie string
HTTPClient *SiteHTTPClient // Use SiteHTTPClient instead of *http.Client
UserAgent string
}
GazelleDriverConfig holds configuration for creating a Gazelle driver
type GazelleOptions ¶
type GazelleOptions struct {
APIKey string `json:"apiKey,omitempty"`
Cookie string `json:"cookie,omitempty"`
}
GazelleOptions holds Gazelle-specific configuration
type GazelleRequest ¶
type GazelleRequest struct {
// Action is the API action
Action string
// Params are the query parameters
Params url.Values
}
GazelleRequest represents a request to a Gazelle site
type GazelleResponse ¶
type GazelleResponse struct {
// Status is the response status ("success" or "failure")
Status string `json:"status"`
// Error is the error message (if status is "failure")
Error string `json:"error,omitempty"`
// Response is the response data
Response json.RawMessage `json:"response"`
// RawBody is the raw response body
RawBody []byte `json:"-"`
// StatusCode is the HTTP status code
StatusCode int `json:"-"`
}
GazelleResponse represents a response from Gazelle API
type GazelleSearchResponse ¶
type GazelleSearchResponse struct {
CurrentPage int `json:"currentPage"`
Pages int `json:"pages"`
Results []GazelleTorrentGroup `json:"results"`
}
GazelleSearchResponse represents search results from Gazelle API
type GazelleTorrent ¶
type GazelleTorrent struct {
TorrentID int `json:"torrentId"`
EditionID int `json:"editionId,omitempty"`
Artists []struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"artists,omitempty"`
Remastered bool `json:"remastered"`
RemasterYear int `json:"remasterYear,omitempty"`
RemasterTitle string `json:"remasterTitle,omitempty"`
Media string `json:"media"`
Encoding string `json:"encoding"`
Format string `json:"format"`
HasLog bool `json:"hasLog"`
LogScore int `json:"logScore"`
HasCue bool `json:"hasCue"`
Scene bool `json:"scene"`
VanityHouse bool `json:"vanityHouse"`
FileCount int `json:"fileCount"`
Time string `json:"time"`
Size int64 `json:"size"`
Snatches int `json:"snatches"`
Seeders int `json:"seeders"`
Leechers int `json:"leechers"`
IsFreeleech bool `json:"isFreeleech"`
IsNeutralLeech bool `json:"isNeutralLeech"`
IsPersonalFL bool `json:"isPersonalFreeleech"`
CanUseToken bool `json:"canUseToken"`
}
GazelleTorrent represents a torrent in Gazelle
type GazelleTorrentGroup ¶
type GazelleTorrentGroup struct {
GroupID int `json:"groupId"`
GroupName string `json:"groupName"`
Artist string `json:"artist,omitempty"`
Tags []string `json:"tags"`
Torrents []GazelleTorrent `json:"torrents"`
}
GazelleTorrentGroup represents a torrent group in Gazelle
type GazelleUserResponse ¶
type GazelleUserResponse struct {
Username string `json:"username"`
ID int `json:"id"`
Stats struct {
Uploaded int64 `json:"uploaded"`
Downloaded int64 `json:"downloaded"`
Ratio float64 `json:"ratio"`
Buffer int64 `json:"buffer"`
} `json:"stats"`
Ranks struct {
Class string `json:"class"`
} `json:"ranks"`
Personal struct {
Bonus float64 `json:"bonus"`
} `json:"personal"`
Community struct {
Seeding int `json:"seeding"`
Leeching int `json:"leeching"`
} `json:"community"`
}
GazelleUserResponse represents user info from Gazelle API
type HDSkyParser ¶
type HDSkyParser struct {
Config NexusPHPParserConfig
}
HDSkyParser implements NexusPHPDetailParser for HDSky site
func NewHDSkyParser ¶
func NewHDSkyParser(options ...NexusPHPParserOption) *HDSkyParser
NewHDSkyParser creates a new HDSkyParser
func (*HDSkyParser) ParseAll ¶
func (p *HDSkyParser) ParseAll(doc *goquery.Selection) *TorrentDetailInfo
ParseAll parses all information from HDSky page
func (*HDSkyParser) ParseDiscount ¶
func (p *HDSkyParser) ParseDiscount(doc *goquery.Selection) (DiscountLevel, time.Time)
ParseDiscount parses discount type and end time from HDSky page
func (*HDSkyParser) ParseHR ¶
func (p *HDSkyParser) ParseHR(doc *goquery.Selection) bool
ParseHR parses HR status from HDSky page
func (*HDSkyParser) ParseSizeMB ¶
func (p *HDSkyParser) ParseSizeMB(doc *goquery.Selection) float64
ParseSizeMB parses torrent size in MB from HDSky page
func (*HDSkyParser) ParseTitleAndID ¶
func (p *HDSkyParser) ParseTitleAndID(doc *goquery.Selection) (title, torrentID string)
ParseTitleAndID parses title and torrent ID from HDSky page
type HTTPClientConfig ¶
type HTTPClientConfig struct {
// Timeout is the request timeout
Timeout time.Duration
// MaxIdleConns is the maximum number of idle connections
MaxIdleConns int
// MaxIdleConnsPerHost is the maximum idle connections per host
MaxIdleConnsPerHost int
// IdleConnTimeout is the idle connection timeout
IdleConnTimeout time.Duration
// DisableKeepAlives disables HTTP keep-alives
DisableKeepAlives bool
}
HTTPClientConfig holds configuration for HTTP clients
func DefaultHTTPClientConfig ¶
func DefaultHTTPClientConfig() HTTPClientConfig
DefaultHTTPClientConfig returns default HTTP client configuration
type HTTPClientPool ¶
type HTTPClientPool struct {
// contains filtered or unexported fields
}
HTTPClientPool manages HTTP sessions for different sites using requests library
func NewHTTPClientPool ¶
func NewHTTPClientPool(config HTTPClientConfig, logger *zap.Logger) *HTTPClientPool
NewHTTPClientPool creates a new HTTP client pool
func (*HTTPClientPool) CloseClient ¶
func (p *HTTPClientPool) CloseClient(siteID string)
CloseClient closes and removes the client for a site
func (*HTTPClientPool) GetClient ¶
func (p *HTTPClientPool) GetClient(siteID string) *http.Client
GetClient returns an HTTP client for the given site ID (backward compatibility)
func (*HTTPClientPool) GetSession ¶
func (p *HTTPClientPool) GetSession(siteID string) requests.Session
GetSession returns a requests.Session for the given site ID
type HTTPResponse ¶
HTTPResponse wraps the response from requests library
func (*HTTPResponse) IsError ¶
func (r *HTTPResponse) IsError() bool
IsError returns true if status code is 4xx or 5xx
func (*HTTPResponse) IsSuccess ¶
func (r *HTTPResponse) IsSuccess() bool
IsSuccess returns true if status code is 2xx
type Histogram ¶
type Histogram struct {
// contains filtered or unexported fields
}
Histogram tracks the distribution of values
func (*Histogram) Stats ¶
func (h *Histogram) Stats() HistogramStats
Stats returns histogram statistics
type HistogramStats ¶
type HistogramStats struct {
Count int64 `json:"count"`
Sum float64 `json:"sum"`
Min float64 `json:"min"`
Max float64 `json:"max"`
Avg float64 `json:"avg"`
}
HistogramStats contains histogram statistics
type InMemoryUserInfoRepo ¶
type InMemoryUserInfoRepo struct {
// contains filtered or unexported fields
}
InMemoryUserInfoRepo is an in-memory implementation of UserInfoRepo
func NewInMemoryUserInfoRepo ¶
func NewInMemoryUserInfoRepo() *InMemoryUserInfoRepo
NewInMemoryUserInfoRepo creates a new in-memory user info repository
func (*InMemoryUserInfoRepo) Clear ¶
func (r *InMemoryUserInfoRepo) Clear()
Clear removes all stored user info
func (*InMemoryUserInfoRepo) Count ¶
func (r *InMemoryUserInfoRepo) Count() int
Count returns the number of stored user info entries
func (*InMemoryUserInfoRepo) Delete ¶
func (r *InMemoryUserInfoRepo) Delete(ctx context.Context, site string) error
Delete removes user info for a site
func (*InMemoryUserInfoRepo) GetAggregated ¶
func (r *InMemoryUserInfoRepo) GetAggregated(ctx context.Context) (AggregatedStats, error)
GetAggregated calculates aggregated statistics
func (*InMemoryUserInfoRepo) ListAll ¶
func (r *InMemoryUserInfoRepo) ListAll(ctx context.Context) ([]UserInfo, error)
ListAll retrieves all stored user info
func (*InMemoryUserInfoRepo) ListBySites ¶
ListBySites retrieves user info for specific sites
type L2Cache ¶
type L2Cache interface {
Get(key string) ([]byte, error)
Set(key string, value []byte, ttl time.Duration) error
Delete(key string) error
}
L2Cache defines the interface for L2 cache (e.g., Redis)
type LRUCache ¶
type LRUCache struct {
// contains filtered or unexported fields
}
LRUCache is a thread-safe LRU cache with TTL support
func NewLRUCache ¶
NewLRUCache creates a new LRU cache with the specified capacity and TTL
type LevelGroupType ¶
type LevelGroupType string
LevelGroupType represents the type of user level group
const ( // LevelGroupUser represents regular user levels LevelGroupUser LevelGroupType = "user" // LevelGroupVIP represents VIP/donor levels LevelGroupVIP LevelGroupType = "vip" // LevelGroupManager represents staff/manager levels LevelGroupManager LevelGroupType = "manager" )
type LevelManager ¶
type LevelManager struct {
// contains filtered or unexported fields
}
LevelManager manages user levels and calculates progress
func NewLevelManager ¶
func NewLevelManager() *LevelManager
NewLevelManager creates a new level manager with default configurations
func (*LevelManager) CalculateNextLevel ¶
func (lm *LevelManager) CalculateNextLevel(kind SiteKind, upload int64, ratio float64, days int) *LevelProgress
CalculateNextLevel calculates progress towards the next level
func (*LevelManager) GetCurrentLevel ¶
func (lm *LevelManager) GetCurrentLevel(kind SiteKind, upload int64, ratio float64, days int) string
GetCurrentLevel determines the user's current level based on their stats
func (*LevelManager) GetLevels ¶
func (lm *LevelManager) GetLevels(kind SiteKind) []LevelRequirement
GetLevels returns the level requirements for a site kind
func (*LevelManager) SetLevels ¶
func (lm *LevelManager) SetLevels(kind SiteKind, levels []LevelRequirement)
SetLevels sets custom level requirements for a site kind
type LevelProgress ¶
type LevelProgress struct {
// CurrentLevel is the user's current level/rank
CurrentLevel string `json:"currentLevel"`
// NextLevel is the next level to achieve
NextLevel string `json:"nextLevel"`
// UploadNeeded is the additional upload needed (bytes)
UploadNeeded int64 `json:"uploadNeeded,omitempty"`
// DownloadNeeded is the additional download needed (bytes)
DownloadNeeded int64 `json:"downloadNeeded,omitempty"`
// RatioNeeded is the additional ratio needed
RatioNeeded float64 `json:"ratioNeeded,omitempty"`
// TimeNeeded is the additional time needed
TimeNeeded time.Duration `json:"timeNeeded,omitempty"`
// ProgressPercent is the overall progress percentage (0-100)
ProgressPercent float64 `json:"progressPercent"`
}
LevelProgress represents progress towards the next user level
type LevelRequirement ¶
type LevelRequirement struct {
// Level is the level name (e.g., "Power User", "Elite", "Master")
Level string
// MinUpload is the minimum upload amount in bytes
MinUpload int64
// MinRatio is the minimum ratio required
MinRatio float64
// MinDays is the minimum account age in days
MinDays int
// MinSeedingTorrents is the minimum number of seeding torrents
MinSeedingTorrents int
// MinSeedingTime is the minimum total seeding time in hours
MinSeedingTime int
// Order is the level order (higher = better)
Order int
}
LevelRequirement defines the requirements for a user level
type MTorrentBonusResponse ¶
type MTorrentBonusResponse struct {
Code FlexibleCode `json:"code"`
Message string `json:"message"`
Data struct {
FormulaParams struct {
FinalBs json.Number `json:"finalBs"` // Bonus per hour (时魔) - can be string or number
} `json:"formulaParams"`
} `json:"data"`
}
MTorrentBonusResponse represents the response from /api/tracker/mybonus
type MTorrentDriver ¶
type MTorrentDriver struct {
BaseURL string // API URL (e.g., https://api.m-team.cc)
WebURL string // Web URL for detail pages (e.g., https://kp.m-team.cc)
APIKey string
// contains filtered or unexported fields
}
MTorrentDriver implements the Driver interface for M-Team sites
func NewMTorrentDriver ¶
func NewMTorrentDriver(config MTorrentDriverConfig) *MTorrentDriver
NewMTorrentDriver creates a new M-Team driver
func NewMTorrentDriverWithFailover ¶
func NewMTorrentDriverWithFailover(apiKey string) *MTorrentDriver
NewMTorrentDriverWithFailover creates a new M-Team driver with failover enabled
func (*MTorrentDriver) Execute ¶
func (d *MTorrentDriver) Execute(ctx context.Context, req MTorrentRequest) (MTorrentResponse, error)
Execute performs the HTTP request
func (*MTorrentDriver) GetBonusPerHour ¶
func (d *MTorrentDriver) GetBonusPerHour(ctx context.Context) (float64, error)
GetBonusPerHour fetches the bonus per hour (时魔) for the user
func (*MTorrentDriver) GetPeerStatistics ¶
func (d *MTorrentDriver) GetPeerStatistics(ctx context.Context) (*PeerStatistics, error)
GetPeerStatistics fetches the peer statistics for the user
func (*MTorrentDriver) GetSiteDefinition ¶
func (d *MTorrentDriver) GetSiteDefinition() *SiteDefinition
GetSiteDefinition returns the site definition
func (*MTorrentDriver) GetUnreadMessageCount ¶
GetUnreadMessageCount fetches the unread message count for the user Returns (unread, total, error)
func (*MTorrentDriver) GetUserInfo ¶
func (d *MTorrentDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
GetUserInfo fetches complete user information including extended stats Uses parallel requests for independent API calls to improve performance
func (*MTorrentDriver) ParseBonusPerHour ¶
func (d *MTorrentDriver) ParseBonusPerHour(res MTorrentResponse) (float64, error)
ParseBonusPerHour extracts bonus per hour from the response
func (*MTorrentDriver) ParseDownload ¶
func (d *MTorrentDriver) ParseDownload(res MTorrentResponse) ([]byte, error)
ParseDownload extracts torrent file data from the response
func (*MTorrentDriver) ParsePeerStatistics ¶
func (d *MTorrentDriver) ParsePeerStatistics(res MTorrentResponse) (*PeerStatistics, error)
ParsePeerStatistics extracts peer statistics from the response
func (*MTorrentDriver) ParseSearch ¶
func (d *MTorrentDriver) ParseSearch(res MTorrentResponse) ([]TorrentItem, error)
ParseSearch extracts torrent items from the response
func (*MTorrentDriver) ParseUnreadMessageCount ¶
func (d *MTorrentDriver) ParseUnreadMessageCount(res MTorrentResponse) (int, int, error)
ParseUnreadMessageCount extracts unread message count from the response
func (*MTorrentDriver) ParseUserInfo ¶
func (d *MTorrentDriver) ParseUserInfo(res MTorrentResponse) (UserInfo, error)
ParseUserInfo extracts user info from the response
func (*MTorrentDriver) PrepareDownload ¶
func (d *MTorrentDriver) PrepareDownload(torrentID string) (MTorrentRequest, error)
PrepareDownload prepares a request for downloading a torrent
func (*MTorrentDriver) PrepareGetBonusPerHour ¶
func (d *MTorrentDriver) PrepareGetBonusPerHour() (MTorrentRequest, error)
PrepareGetBonusPerHour prepares a request for fetching bonus per hour
func (*MTorrentDriver) PrepareGetPeerStatistics ¶
func (d *MTorrentDriver) PrepareGetPeerStatistics() (MTorrentRequest, error)
PrepareGetPeerStatistics prepares a request for fetching peer statistics
func (*MTorrentDriver) PrepareGetUnreadMessageCount ¶
func (d *MTorrentDriver) PrepareGetUnreadMessageCount() (MTorrentRequest, error)
PrepareGetUnreadMessageCount prepares a request for fetching unread message count
func (*MTorrentDriver) PrepareSearch ¶
func (d *MTorrentDriver) PrepareSearch(query SearchQuery) (MTorrentRequest, error)
PrepareSearch converts a SearchQuery to an M-Team request
func (*MTorrentDriver) PrepareUserInfo ¶
func (d *MTorrentDriver) PrepareUserInfo() (MTorrentRequest, error)
PrepareUserInfo prepares a request for user info
func (*MTorrentDriver) SetSiteDefinition ¶
func (d *MTorrentDriver) SetSiteDefinition(def *SiteDefinition)
SetSiteDefinition sets the site definition for custom parsing
type MTorrentDriverConfig ¶
type MTorrentDriverConfig struct {
BaseURL string
WebURL string // Optional: Web URL for detail pages, defaults to "https://kp.m-team.cc"
APIKey string
HTTPClient *SiteHTTPClient // Use SiteHTTPClient instead of *http.Client
UserAgent string
UseFailover bool // Enable multi-URL failover
}
MTorrentDriverConfig holds configuration for creating an M-Team driver
type MTorrentMemberCount ¶
type MTorrentMemberCount struct {
Uploaded string `json:"uploaded"`
Downloaded string `json:"downloaded"`
Bonus string `json:"bonus"`
Seedtime string `json:"seedtime"`
Leechtime string `json:"leechtime"`
}
MTorrentMemberCount contains upload/download stats
type MTorrentMemberStatus ¶
type MTorrentMemberStatus struct {
LastLogin string `json:"lastLogin"`
LastBrowse string `json:"lastBrowse"`
Vip bool `json:"vip"`
}
MTorrentMemberStatus contains user status info
type MTorrentMessageStatResponse ¶
type MTorrentMessageStatResponse struct {
Code FlexibleCode `json:"code"`
Message string `json:"message"`
Data struct {
Count string `json:"count"` // Total message count
UnMake string `json:"unMake"` // Unread message count (string in API response)
} `json:"data"`
}
MTorrentMessageStatResponse represents the response from /api/msg/notify/statistic
type MTorrentOptions ¶
type MTorrentOptions struct {
APIKey string `json:"apiKey"`
}
MTorrentOptions holds M-Team-specific configuration
type MTorrentPeerStatResponse ¶
type MTorrentPeerStatResponse struct {
Code FlexibleCode `json:"code"`
Message string `json:"message"`
Data struct {
UID string `json:"uid"`
SeederCount string `json:"seederCount"`
SeederSize string `json:"seederSize"`
LeecherCount string `json:"leecherCount"`
LeecherSize string `json:"leecherSize"`
UploadCount string `json:"uploadCount"`
} `json:"data"`
}
MTorrentPeerStatResponse represents the response from /api/tracker/myPeerStatistics
type MTorrentRequest ¶
type MTorrentRequest struct {
// Endpoint is the API endpoint path
Endpoint string
// Method is the HTTP method
Method string
// Body is the request body (will be JSON encoded or form-urlencoded based on ContentType)
Body any
// ContentType specifies the request content type (default: "application/json")
// Use "application/x-www-form-urlencoded" for form data
ContentType string
}
MTorrentRequest represents a request to M-Team API
type MTorrentResponse ¶
type MTorrentResponse struct {
// Code is the response code ("0" for success)
Code FlexibleCode `json:"code"`
// Message is the response message
Message string `json:"message"`
// Data is the response data
Data json.RawMessage `json:"data"`
// RawBody is the raw response body (for downloads)
RawBody []byte `json:"-"`
// StatusCode is the HTTP status code
StatusCode int `json:"-"`
}
MTorrentResponse represents a response from M-Team API
type MTorrentSearchData ¶
type MTorrentSearchData struct {
Data []MTorrentTorrent `json:"data"`
Total FlexInt `json:"total"`
}
MTorrentSearchData is the search response data
type MTorrentSearchRequest ¶
type MTorrentSearchRequest struct {
Mode string `json:"mode"`
Categories []string `json:"categories,omitempty"`
Keyword string `json:"keyword,omitempty"`
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
}
MTorrentSearchRequest is the search request body
type MTorrentTorrent ¶
type MTorrentTorrent struct {
ID string `json:"id"`
Name string `json:"name"`
SmallDescr string `json:"smallDescr"`
Size string `json:"size"`
CreatedDate string `json:"createdDate"`
Status struct {
Seeders FlexInt `json:"seeders"`
Leechers FlexInt `json:"leechers"`
TimesCompleted FlexInt `json:"timesCompleted"`
Discount string `json:"discount"`
DiscountEndTime string `json:"discountEndTime,omitempty"`
} `json:"status"`
Category string `json:"category"`
}
MTorrentTorrent represents a torrent in M-Team API response
type MTorrentUserInfo ¶
type MTorrentUserInfo struct {
ID string `json:"id"`
Username string `json:"username"`
CreatedDate string `json:"createdDate"`
Role string `json:"role"`
MemberCount MTorrentMemberCount `json:"memberCount"`
MemberStatus MTorrentMemberStatus `json:"memberStatus"`
}
MTorrentUserInfo represents user info from M-Team API
type MetricType ¶
type MetricType string
MetricType represents the type of metric
const ( MetricTypeCounter MetricType = "counter" MetricTypeGauge MetricType = "gauge" MetricTypeHistogram MetricType = "histogram" )
type MetricsRegistry ¶
type MetricsRegistry struct {
// contains filtered or unexported fields
}
MetricsRegistry manages all metrics
func NewMetricsRegistry ¶
func NewMetricsRegistry() *MetricsRegistry
NewMetricsRegistry creates a new metrics registry
func (*MetricsRegistry) Counter ¶
func (r *MetricsRegistry) Counter(name string) *Counter
Counter returns or creates a counter with the given name
func (*MetricsRegistry) Gauge ¶
func (r *MetricsRegistry) Gauge(name string) *Gauge
Gauge returns or creates a gauge with the given name
func (*MetricsRegistry) Histogram ¶
func (r *MetricsRegistry) Histogram(name string) *Histogram
Histogram returns or creates a histogram with the given name
func (*MetricsRegistry) Snapshot ¶
func (r *MetricsRegistry) Snapshot() MetricsSnapshot
Snapshot returns a snapshot of all metrics
func (*MetricsRegistry) Timer ¶
func (r *MetricsRegistry) Timer(name string) *Timer
Timer creates a new timer for the given histogram
type MetricsSnapshot ¶
type MetricsSnapshot struct {
Counters map[string]int64 `json:"counters"`
Gauges map[string]int64 `json:"gauges"`
Histograms map[string]HistogramStats `json:"histograms"`
Timestamp time.Time `json:"timestamp"`
}
MetricsSnapshot contains a point-in-time snapshot of all metrics
type MigrationStatus ¶
type MigrationStatus struct {
SiteID string `json:"siteId"`
SiteName string `json:"siteName"`
OldImplementation bool `json:"oldImplementation"`
NewImplementation bool `json:"newImplementation"`
MigrationReady bool `json:"migrationReady"`
Notes string `json:"notes,omitempty"`
}
MigrationStatus represents the migration status of a site
type MultiSiteSearchQuery ¶
type MultiSiteSearchQuery struct {
SearchQuery
// Sites specifies which sites to search (empty means all)
Sites []string `json:"sites,omitempty"`
// Timeout is the maximum time to wait for all searches
Timeout time.Duration `json:"timeout,omitempty"`
// MinSeeders filters results by minimum seeders
MinSeeders int `json:"minSeeders,omitempty"`
// MaxSizeBytes filters results by maximum size
MaxSizeBytes int64 `json:"maxSizeBytes,omitempty"`
// MinSizeBytes filters results by minimum size
MinSizeBytes int64 `json:"minSizeBytes,omitempty"`
}
MultiSiteSearchQuery extends SearchQuery with multi-site options
type MultiSiteSearchResult ¶
type MultiSiteSearchResult struct {
// Items contains deduplicated and ranked torrent items
Items []TorrentItem `json:"items"`
// TotalResults is the total number of results before deduplication
TotalResults int `json:"totalResults"`
// SiteResults contains per-site result counts
SiteResults map[string]int `json:"siteResults"`
// Errors contains any errors that occurred during search
Errors []SearchError `json:"errors,omitempty"`
// Duration is how long the search took
Duration time.Duration `json:"duration"`
}
MultiSiteSearchResult contains results from a multi-site search
type NewDownloaderConfig ¶
type NewDownloaderConfig struct {
Type string `json:"type"` // "qbittorrent", "transmission"
Name string `json:"name"` // Downloader name
URL string `json:"url"` // Downloader URL
Username string `json:"username"` // Username for authentication
Password string `json:"password"` // Password for authentication
AddAtPaused bool `json:"addAtPaused"` // New field: true = add paused
}
NewDownloaderConfig represents the new downloader configuration format with AddAtPaused field for controlling torrent start behavior
type NexusPHPDetailParser ¶
type NexusPHPDetailParser interface {
// ParseTitleAndID parses title and torrent ID from the page
ParseTitleAndID(doc *goquery.Selection) (title, torrentID string)
// ParseDiscount parses discount type and end time
ParseDiscount(doc *goquery.Selection) (DiscountLevel, time.Time)
// ParseHR parses HR (Hit and Run) status
ParseHR(doc *goquery.Selection) bool
// ParseSizeMB parses torrent size in MB
ParseSizeMB(doc *goquery.Selection) float64
// ParseAll parses all information from the page
ParseAll(doc *goquery.Selection) *TorrentDetailInfo
}
NexusPHPDetailParser interface for parsing torrent detail pages
func GetParser ¶
func GetParser(siteName SiteName) NexusPHPDetailParser
GetParser returns a parser for the given site name
type NexusPHPDriver ¶
type NexusPHPDriver struct {
BaseURL string
Cookie string
Selectors SiteSelectors
// contains filtered or unexported fields
}
NexusPHPDriver implements the Driver interface for NexusPHP sites
func NewNexusPHPDriver ¶
func NewNexusPHPDriver(config NexusPHPDriverConfig) *NexusPHPDriver
NewNexusPHPDriver creates a new NexusPHP driver
func NewNexusPHPDriverWithFailover ¶
func NewNexusPHPDriverWithFailover(siteName SiteName, cookie string) *NexusPHPDriver
NewNexusPHPDriverWithFailover creates a new NexusPHP driver with failover enabled
func (*NexusPHPDriver) Execute ¶
func (d *NexusPHPDriver) Execute(ctx context.Context, req NexusPHPRequest) (NexusPHPResponse, error)
Execute performs the HTTP request
func (*NexusPHPDriver) ExtractFieldValuePublic ¶
func (d *NexusPHPDriver) ExtractFieldValuePublic(doc *goquery.Document, selector FieldSelector) string
ExtractFieldValuePublic is a public wrapper for extractFieldValue for testing purposes
func (*NexusPHPDriver) FetchSeedingStatus ¶
func (d *NexusPHPDriver) FetchSeedingStatus(ctx context.Context, userID string) (seeding int, seedingSize int64, err error)
FetchSeedingStatus fetches the seeding status (count and size) for a user This method requests /getusertorrentlistajax.php and parses the response
func (*NexusPHPDriver) GetSiteDefinition ¶
func (d *NexusPHPDriver) GetSiteDefinition() *SiteDefinition
GetSiteDefinition returns the site definition
func (*NexusPHPDriver) GetUserInfo ¶
func (d *NexusPHPDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
GetUserInfo fetches complete user information For NexusPHP sites, this involves two steps: 1. Fetch /index.php to get user ID and basic info from info_block 2. Fetch /userdetails.php?id=xxx to get detailed info
func (*NexusPHPDriver) ParseDetail ¶
func (d *NexusPHPDriver) ParseDetail(res NexusPHPResponse) (TorrentDetail, error)
ParseDetail extracts download URL and other info from detail page
func (*NexusPHPDriver) ParseDownload ¶
func (d *NexusPHPDriver) ParseDownload(res NexusPHPResponse) ([]byte, error)
ParseDownload extracts torrent file data from the response For NexusPHP, the response is a detail page - we need to extract the download URL and fetch the torrent
func (*NexusPHPDriver) ParseSearch ¶
func (d *NexusPHPDriver) ParseSearch(res NexusPHPResponse) ([]TorrentItem, error)
ParseSearch extracts torrent items from the response
func (*NexusPHPDriver) ParseSeedingStatus ¶
func (d *NexusPHPDriver) ParseSeedingStatus(res NexusPHPResponse) (seeding int, seedingSize int64, err error)
ParseSeedingStatus parses the seeding status from the AJAX response Implements two parsing strategies based on NexusPHP.ts: 1. Direct parsing: Look for summary text like "10 | 100 GB" or "<b>94</b>条记录,共计<b>2.756 TB</b>" 2. Table accumulation: Sum up sizes from individual torrent rows
func (*NexusPHPDriver) ParseUserDetails ¶
func (d *NexusPHPDriver) ParseUserDetails(res NexusPHPResponse) (UserInfo, error)
ParseUserDetails extracts detailed user info from userdetails.php page
func (*NexusPHPDriver) ParseUserInfo ¶
func (d *NexusPHPDriver) ParseUserInfo(res NexusPHPResponse) (UserInfo, error)
ParseUserInfo extracts user info from the response
func (*NexusPHPDriver) PrepareDetail ¶
func (d *NexusPHPDriver) PrepareDetail(torrentID string) (NexusPHPRequest, error)
PrepareDetail prepares a request for torrent detail page
func (*NexusPHPDriver) PrepareDownload ¶
func (d *NexusPHPDriver) PrepareDownload(torrentID string) (NexusPHPRequest, error)
PrepareDownload prepares a request for downloading a torrent For NexusPHP sites, we first need to visit the detail page to get the download URL with passkey
func (*NexusPHPDriver) PrepareSearch ¶
func (d *NexusPHPDriver) PrepareSearch(query SearchQuery) (NexusPHPRequest, error)
PrepareSearch converts a SearchQuery to a NexusPHP request
func (*NexusPHPDriver) PrepareUserDetails ¶
func (d *NexusPHPDriver) PrepareUserDetails(userID string) (NexusPHPRequest, error)
PrepareUserDetails prepares a request for user details page
func (*NexusPHPDriver) PrepareUserInfo ¶
func (d *NexusPHPDriver) PrepareUserInfo() (NexusPHPRequest, error)
PrepareUserInfo prepares a request for user info (index page to get user ID)
func (*NexusPHPDriver) PrepareUserSeedingPage ¶
func (d *NexusPHPDriver) PrepareUserSeedingPage(userID, listType string) (NexusPHPRequest, error)
PrepareUserSeedingPage prepares a request for user seeding page via AJAX This is used to fetch seeding size information from /getusertorrentlistajax.php
func (*NexusPHPDriver) SetSiteDefinition ¶
func (d *NexusPHPDriver) SetSiteDefinition(def *SiteDefinition)
SetSiteDefinition sets the site definition for custom parsing
type NexusPHPDriverConfig ¶
type NexusPHPDriverConfig struct {
BaseURL string
Cookie string
Selectors *SiteSelectors
HTTPClient *SiteHTTPClient // Use SiteHTTPClient instead of *http.Client
UserAgent string
UseFailover bool // Enable multi-URL failover
SiteName SiteName // Site name for failover URL lookup
}
NexusPHPDriverConfig holds configuration for creating a NexusPHP driver
type NexusPHPOptions ¶
type NexusPHPOptions struct {
Cookie string `json:"cookie"`
Selectors *SiteSelectors `json:"selectors,omitempty"`
}
NexusPHPOptions holds NexusPHP-specific configuration
type NexusPHPParserConfig ¶
type NexusPHPParserConfig struct {
TimeLayout string
}
NexusPHPParserConfig defines parser configuration
func DefaultNexusPHPParserConfig ¶
func DefaultNexusPHPParserConfig() NexusPHPParserConfig
DefaultNexusPHPParserConfig returns default parser configuration
type NexusPHPParserOption ¶
type NexusPHPParserOption func(*NexusPHPParserConfig)
NexusPHPParserOption is a function that modifies NexusPHPParserConfig
func WithParserTimeLayout ¶
func WithParserTimeLayout(layout string) NexusPHPParserOption
WithParserTimeLayout sets the time layout for parsing
type NexusPHPRequest ¶
type NexusPHPRequest struct {
// Path is the URL path (e.g., "/torrents.php")
Path string
// Params are the query parameters
Params url.Values
// Method is the HTTP method (default: GET)
Method string
}
NexusPHPRequest represents a request to a NexusPHP site
type NexusPHPResponse ¶
type NexusPHPResponse struct {
// Document is the parsed HTML document
Document *goquery.Document
// RawBody is the raw response body (for downloads)
RawBody []byte
// StatusCode is the HTTP status code
StatusCode int
}
NexusPHPResponse wraps a goquery document for parsing
type Normalizer ¶
type Normalizer struct {
// contains filtered or unexported fields
}
Normalizer standardizes torrent titles and tags
func (*Normalizer) ExtractEncoding ¶
func (n *Normalizer) ExtractEncoding(title string) string
ExtractEncoding extracts the encoding from a title
func (*Normalizer) ExtractFormat ¶
func (n *Normalizer) ExtractFormat(title string) string
ExtractFormat extracts the format from a title
func (*Normalizer) ExtractResolution ¶
func (n *Normalizer) ExtractResolution(title string) string
ExtractResolution extracts the resolution from a title
func (*Normalizer) NormalizeTags ¶
func (n *Normalizer) NormalizeTags(tags []string) []string
NormalizeTags standardizes a list of tags
func (*Normalizer) NormalizeTitle ¶
func (n *Normalizer) NormalizeTitle(title string) string
NormalizeTitle standardizes a torrent title
type OldDownloaderConfig ¶
type OldDownloaderConfig struct {
Type string `json:"type"` // "qbittorrent", "transmission"
Name string `json:"name"` // Downloader name
URL string `json:"url"` // Downloader URL
Username string `json:"username"` // Username for authentication
Password string `json:"password"` // Password for authentication
AutoStart bool `json:"autoStart"` // Old field: true = start immediately
}
OldDownloaderConfig represents the old downloader configuration format with autoStart field that needs to be converted to AddAtPaused
type OldSiteConfig ¶
type OldSiteConfig struct {
Name string `json:"name"`
Type string `json:"type"` // "nexusphp", "mteam", etc.
URL string `json:"url"`
Cookie string `json:"cookie,omitempty"`
APIKey string `json:"apiKey,omitempty"`
RateLimit int `json:"rateLimit,omitempty"`
Selectors any `json:"selectors,omitempty"`
AuthMethod string `json:"authMethod,omitempty"` // Old field name
}
OldSiteConfig represents the old site configuration format
type ParsedTorrent ¶
type ParsedTorrent struct {
// Name is the torrent name
Name string `json:"name"`
// InfoHash is the 40-character hex info hash
InfoHash string `json:"infoHash"`
// Size is the total size in bytes
Size int64 `json:"size"`
// Files is the list of files in the torrent
Files []TorrentFile `json:"files,omitempty"`
// PieceLength is the piece size in bytes
PieceLength int64 `json:"pieceLength"`
// Comment is the torrent comment
Comment string `json:"comment,omitempty"`
// CreatedBy is the creator of the torrent
CreatedBy string `json:"createdBy,omitempty"`
// CreationDate is when the torrent was created
CreationDate time.Time `json:"creationDate,omitempty"`
// Announce is the primary tracker URL
Announce string `json:"announce,omitempty"`
// AnnounceList is the list of tracker URLs
AnnounceList [][]string `json:"announceList,omitempty"`
// RawMetadata is the raw torrent file bytes
RawMetadata []byte `json:"-"`
}
ParsedTorrent represents parsed torrent metadata
func GetRemoteTorrent ¶
func GetRemoteTorrent(torrentURL, cookie string) (*ParsedTorrent, error)
GetRemoteTorrent fetches a torrent file from a URL
func GetRemoteTorrentWithClient ¶
func GetRemoteTorrentWithClient(torrentURL, cookie string, client *http.Client) (*ParsedTorrent, error)
GetRemoteTorrentWithClient fetches a torrent file from a URL with a custom HTTP client Deprecated: Use GetRemoteTorrentWithRequests instead
func GetRemoteTorrentWithRequests ¶
func GetRemoteTorrentWithRequests(torrentURL, cookie string) (*ParsedTorrent, error)
GetRemoteTorrentWithRequests fetches a torrent file from a URL using requests library
func ParseTorrent ¶
func ParseTorrent(data []byte) (*ParsedTorrent, error)
ParseTorrent parses torrent file bytes into ParsedTorrent
func ParseTorrentFromFile ¶
func ParseTorrentFromFile(path string) (*ParsedTorrent, error)
ParseTorrentFromFile parses a torrent file from path
type PeerStatistics ¶
type PeerStatistics struct {
// SeederCount is the number of torrents being seeded
SeederCount int `json:"seederCount"`
// SeederSize is the total size of seeding torrents (bytes)
SeederSize int64 `json:"seederSize"`
// LeecherCount is the number of torrents being downloaded
LeecherCount int `json:"leecherCount"`
// LeecherSize is the total size of leeching torrents (bytes)
LeecherSize int64 `json:"leecherSize"`
}
PeerStatistics represents user's seeding/leeching statistics
type Ranker ¶
type Ranker struct {
// contains filtered or unexported fields
}
Ranker scores and ranks torrent search results
func NewRanker ¶
func NewRanker(config RankerConfig) *Ranker
NewRanker creates a new Ranker with the given configuration
func (*Ranker) GetSiteReliability ¶
GetSiteReliability returns the reliability score for a site
func (*Ranker) Rank ¶
func (r *Ranker) Rank(items []TorrentItem) []TorrentItem
Rank sorts torrents by score in descending order
func (*Ranker) Score ¶
func (r *Ranker) Score(item TorrentItem) float64
Score calculates a score for a torrent item
func (*Ranker) SetSiteReliability ¶
SetSiteReliability sets the reliability score for a site
type RankerConfig ¶
type RankerConfig struct {
// SeederWeight is the weight for seeders in scoring (default: 1.0)
SeederWeight float64 `json:"seederWeight,omitempty"`
// LeecherWeight is the weight for leechers in scoring (default: 0.5)
LeecherWeight float64 `json:"leecherWeight,omitempty"`
// FreeBonus is the bonus score for free torrents (default: 100)
FreeBonus float64 `json:"freeBonus,omitempty"`
// SizeWeight is the weight for size in scoring (default: 0.1)
SizeWeight float64 `json:"sizeWeight,omitempty"`
// RecencyWeight is the weight for recency in scoring (default: 0.2)
RecencyWeight float64 `json:"recencyWeight,omitempty"`
// SiteReliability maps site IDs to reliability scores (0-1)
SiteReliability map[string]float64 `json:"siteReliability,omitempty"`
}
RankerConfig holds configuration for the Ranker
type RequestConfig ¶
type RequestConfig struct {
// URL is the request path (e.g., "/index.php")
URL string `json:"url"`
// Method is the HTTP method (default: GET)
Method string `json:"method,omitempty"`
// Params are query parameters
Params map[string]string `json:"params,omitempty"`
// Data is the request body for POST requests
Data map[string]any `json:"data,omitempty"`
// ResponseType is "document" for HTML or "json" for JSON
ResponseType string `json:"responseType,omitempty"`
// Headers are additional HTTP headers
Headers map[string]string `json:"headers,omitempty"`
}
RequestConfig for HTTP requests
type RequestsClient ¶
type RequestsClient struct {
// contains filtered or unexported fields
}
RequestsClient provides a high-level HTTP client using requests library
func NewRequestsClient ¶
func NewRequestsClient(config HTTPClientConfig, retryConfig RetryConfig, logger *zap.Logger) *RequestsClient
NewRequestsClient creates a new requests-based HTTP client
func (*RequestsClient) Close ¶
func (c *RequestsClient) Close() error
Close closes the underlying session
func (*RequestsClient) Get ¶
func (c *RequestsClient) Get(ctx context.Context, url string, opts ...requests.RequestOption) (*RequestsResponse, error)
Get performs a GET request with retry logic
func (*RequestsClient) Post ¶
func (c *RequestsClient) Post(ctx context.Context, url string, body any, opts ...requests.RequestOption) (*RequestsResponse, error)
Post performs a POST request with retry logic
type RequestsResponse ¶
type RequestsResponse struct {
// contains filtered or unexported fields
}
RequestsResponse wraps the response from requests library
func (*RequestsResponse) Bytes ¶
func (r *RequestsResponse) Bytes() []byte
Bytes returns the response body as bytes
func (*RequestsResponse) Headers ¶
func (r *RequestsResponse) Headers() http.Header
Headers returns the response headers
func (*RequestsResponse) IsError ¶
func (r *RequestsResponse) IsError() bool
IsError returns true if status code is 4xx or 5xx
func (*RequestsResponse) IsSuccess ¶
func (r *RequestsResponse) IsSuccess() bool
IsSuccess returns true if status code is 2xx
func (*RequestsResponse) StatusCode ¶
func (r *RequestsResponse) StatusCode() int
StatusCode returns the HTTP status code
func (*RequestsResponse) Text ¶
func (r *RequestsResponse) Text() string
Text returns the response body as string
type RetryConfig ¶
type RetryConfig struct {
// MaxRetries is the maximum number of retries
MaxRetries int
// InitialBackoff is the initial backoff duration
InitialBackoff time.Duration
// MaxBackoff is the maximum backoff duration
MaxBackoff time.Duration
// BackoffMultiplier is the backoff multiplier
BackoffMultiplier float64
// Jitter adds randomness to backoff
Jitter bool
// RetryableStatusCodes are HTTP status codes that should trigger a retry
RetryableStatusCodes []int
}
RetryConfig holds configuration for retry logic
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig returns default retry configuration
type RetryableHTTPClient ¶
type RetryableHTTPClient struct {
// contains filtered or unexported fields
}
RetryableHTTPClient wraps an HTTP client with retry logic
func NewRetryableHTTPClient ¶
func NewRetryableHTTPClient(client *http.Client, config RetryConfig, logger *zap.Logger) *RetryableHTTPClient
NewRetryableHTTPClient creates a new retryable HTTP client
type SearchCache ¶
type SearchCache struct {
// contains filtered or unexported fields
}
SearchCache provides caching for search results
func NewSearchCache ¶
func NewSearchCache(config SearchCacheConfig) *SearchCache
NewSearchCache creates a new SearchCache
func (*SearchCache) Cleanup ¶
func (c *SearchCache) Cleanup() int
Cleanup removes expired entries from the cache
func (*SearchCache) Delete ¶
func (c *SearchCache) Delete(query MultiSiteSearchQuery)
Delete removes a specific entry from the cache
func (*SearchCache) Get ¶
func (c *SearchCache) Get(query MultiSiteSearchQuery) (*MultiSiteSearchResult, bool)
Get retrieves a cached search result
func (*SearchCache) Set ¶
func (c *SearchCache) Set(query MultiSiteSearchQuery, result *MultiSiteSearchResult)
Set stores a search result in the cache
func (*SearchCache) Size ¶
func (c *SearchCache) Size() int
Size returns the number of entries in the cache
type SearchCacheConfig ¶
type SearchCacheConfig struct {
// TTL is the time-to-live for cache entries (default: 5 minutes)
TTL time.Duration `json:"ttl,omitempty"`
// MaxSize is the maximum number of entries (default: 1000)
MaxSize int `json:"maxSize,omitempty"`
}
SearchCacheConfig holds configuration for SearchCache
type SearchError ¶
SearchError represents an error from a specific site
type SearchOrchestrator ¶
type SearchOrchestrator struct {
// contains filtered or unexported fields
}
SearchOrchestrator coordinates concurrent searches across multiple sites
func NewSearchOrchestrator ¶
func NewSearchOrchestrator(config SearchOrchestratorConfig) *SearchOrchestrator
NewSearchOrchestrator creates a new SearchOrchestrator
func (*SearchOrchestrator) GetSite ¶
func (o *SearchOrchestrator) GetSite(siteID string) Site
GetSite returns a registered site by ID, or nil if not found
func (*SearchOrchestrator) ListSites ¶
func (o *SearchOrchestrator) ListSites() []string
ListSites returns all registered site IDs
func (*SearchOrchestrator) RegisterSite ¶
func (o *SearchOrchestrator) RegisterSite(site Site)
RegisterSite adds a site to the orchestrator
func (*SearchOrchestrator) Search ¶
func (o *SearchOrchestrator) Search(ctx context.Context, query MultiSiteSearchQuery) (*MultiSiteSearchResult, error)
Search performs a concurrent search across multiple sites
func (*SearchOrchestrator) UnregisterSite ¶
func (o *SearchOrchestrator) UnregisterSite(siteID string)
UnregisterSite removes a site from the orchestrator
type SearchOrchestratorConfig ¶
SearchOrchestratorConfig holds configuration for SearchOrchestrator
type SearchQuery ¶
type SearchQuery struct {
// Keyword is the search term
Keyword string `json:"keyword"`
// Category filters by torrent category
Category string `json:"category,omitempty"`
// FreeOnly filters to only show free torrents
FreeOnly bool `json:"freeOnly,omitempty"`
// Page is the page number (1-indexed)
Page int `json:"page,omitempty"`
// PageSize is the number of results per page
PageSize int `json:"pageSize,omitempty"`
// SortBy specifies the sort field
SortBy string `json:"sortBy,omitempty"`
// OrderDesc specifies descending order when true
OrderDesc bool `json:"orderDesc,omitempty"`
}
SearchQuery represents a search request to a PT site
func (*SearchQuery) Validate ¶
func (q *SearchQuery) Validate() error
Validate validates the search query
type Session ¶
type Session struct {
SiteID string
Cookie string
APIKey string
SessionID string // For Transmission
ExpiresAt time.Time
LastUsed time.Time
LoginCount int
// contains filtered or unexported fields
}
Session represents an authentication session
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages authentication sessions for sites
func NewSessionManager ¶
func NewSessionManager(logger *zap.Logger) *SessionManager
NewSessionManager creates a new session manager
func (*SessionManager) GetSession ¶
func (m *SessionManager) GetSession(siteID string) (*Session, bool)
GetSession returns the session for a site
func (*SessionManager) IncrementLoginCount ¶
func (m *SessionManager) IncrementLoginCount(siteID string) int
IncrementLoginCount increments the login count for a session
func (*SessionManager) InvalidateSession ¶
func (m *SessionManager) InvalidateSession(siteID string)
InvalidateSession marks a session as expired
func (*SessionManager) IsSessionValid ¶
func (m *SessionManager) IsSessionValid(siteID string) bool
IsSessionValid checks if a session is still valid
func (*SessionManager) RemoveSession ¶
func (m *SessionManager) RemoveSession(siteID string)
RemoveSession removes a session
func (*SessionManager) ResetLoginCount ¶
func (m *SessionManager) ResetLoginCount(siteID string)
ResetLoginCount resets the login count for a session
func (*SessionManager) SetSession ¶
func (m *SessionManager) SetSession(siteID string, session *Session)
SetSession sets the session for a site
func (*SessionManager) UpdateSessionID ¶
func (m *SessionManager) UpdateSessionID(siteID, sessionID string)
UpdateSessionID updates the session ID (for Transmission)
type Site ¶
type Site interface {
// ID returns the unique site identifier
ID() string
// Name returns the human-readable site name
Name() string
// Kind returns the site architecture type
Kind() SiteKind
// Login authenticates with the site
Login(ctx context.Context, creds Credentials) error
// Search searches for torrents
Search(ctx context.Context, query SearchQuery) ([]TorrentItem, error)
// GetUserInfo fetches the current user's information
GetUserInfo(ctx context.Context) (UserInfo, error)
// Download downloads a torrent file by ID
Download(ctx context.Context, torrentID string) ([]byte, error)
// Close releases any resources held by the site
Close() error
}
Site is the core interface for interacting with a PT site
type SiteAdapter ¶
type SiteAdapter struct {
// OldSite is the old site implementation (if any)
OldSite any
// NewSite is the new v2 site implementation
NewSite Site
// UseNew indicates whether to use the new implementation
UseNew bool
}
SiteAdapter provides an adapter layer to use old site implementations with new interface This allows gradual migration of site implementations
func NewSiteAdapter ¶
func NewSiteAdapter(oldSite any, newSite Site, useNew bool) *SiteAdapter
NewSiteAdapter creates a new SiteAdapter If newSite is provided and useNew is true, it will be used Otherwise, oldSite will be used (for backward compatibility)
func (*SiteAdapter) GetSite ¶
func (a *SiteAdapter) GetSite() any
GetSite returns the appropriate site implementation based on configuration
func (*SiteAdapter) IsUsingNewImplementation ¶
func (a *SiteAdapter) IsUsingNewImplementation() bool
IsUsingNewImplementation returns true if using the new v2 implementation
type SiteCategoryConfig ¶
type SiteCategoryConfig struct {
SiteID string `json:"siteId"`
SiteName string `json:"siteName"`
Categories []CategoryDefinition `json:"categories"`
}
SiteCategoryConfig 站点分类配置
func GetSiteCategoryConfig ¶
func GetSiteCategoryConfig(siteID string) *SiteCategoryConfig
GetSiteCategoryConfig 获取站点分类配置
type SiteConfig ¶
type SiteConfig struct {
// Type is the site type (nexusphp, unit3d, gazelle, mtorrent)
Type string `json:"type"`
// ID is the unique site identifier
ID string `json:"id"`
// Name is the human-readable site name
Name string `json:"name"`
// BaseURL is the site's base URL
BaseURL string `json:"baseUrl"`
// Options contains type-specific configuration
Options json.RawMessage `json:"options"`
// RateLimit is the requests per second limit (optional)
RateLimit float64 `json:"rateLimit,omitempty"`
// RateBurst is the maximum burst size (optional)
RateBurst int `json:"rateBurst,omitempty"`
}
SiteConfig holds configuration for creating a site
type SiteCredentials ¶
SiteCredentials holds authentication credentials for a site
type SiteDefinition ¶
type SiteDefinition struct {
// ID is the unique site identifier (e.g., "hdsky")
ID string `json:"id"`
// Name is the human-readable site name (e.g., "HDSky")
Name string `json:"name"`
// Aka contains alternative names for the site
Aka []string `json:"aka,omitempty"`
// Description is a brief description of the site
Description string `json:"description,omitempty"`
// Schema is the base schema type (e.g., "NexusPHP", "mTorrent")
Schema string `json:"schema"`
// URLs are the primary site URLs
URLs []string `json:"urls"`
// LegacyURLs are alternative/legacy URLs
LegacyURLs []string `json:"legacyUrls,omitempty"`
// FaviconURL is the site's favicon URL for caching
FaviconURL string `json:"faviconUrl,omitempty"`
// TimezoneOffset is the site's timezone (e.g., "+0800")
TimezoneOffset string `json:"timezoneOffset,omitempty"`
// UserInfo contains user info fetching configuration
UserInfo *UserInfoConfig `json:"userInfo,omitempty"`
// LevelRequirements defines user level requirements
LevelRequirements []SiteLevelRequirement `json:"levelRequirements,omitempty"`
// Selectors contains custom CSS selectors (merged with schema defaults)
Selectors *SiteSelectors `json:"selectors,omitempty"`
}
SiteDefinition contains site-specific metadata and configuration
type SiteDefinitionRegistry ¶
type SiteDefinitionRegistry struct {
// contains filtered or unexported fields
}
SiteDefinitionRegistry manages site definitions
func GetDefinitionRegistry ¶
func GetDefinitionRegistry() *SiteDefinitionRegistry
GetDefinitionRegistry returns the global site definition registry
func (*SiteDefinitionRegistry) Get ¶
func (r *SiteDefinitionRegistry) Get(siteID string) (*SiteDefinition, bool)
Get retrieves a site definition by ID
func (*SiteDefinitionRegistry) GetAll ¶
func (r *SiteDefinitionRegistry) GetAll() []*SiteDefinition
GetAll returns all registered site definitions
func (*SiteDefinitionRegistry) GetOrDefault ¶
func (r *SiteDefinitionRegistry) GetOrDefault(siteID string) *SiteDefinition
GetOrDefault returns site definition or nil if not found
func (*SiteDefinitionRegistry) List ¶
func (r *SiteDefinitionRegistry) List() []string
List returns all registered site IDs
func (*SiteDefinitionRegistry) Register ¶
func (r *SiteDefinitionRegistry) Register(def *SiteDefinition)
Register adds a site definition to the registry
type SiteFactory ¶
type SiteFactory struct {
// contains filtered or unexported fields
}
SiteFactory creates Site instances from configuration
func NewSiteFactory ¶
func NewSiteFactory(logger *zap.Logger) *SiteFactory
NewSiteFactory creates a new SiteFactory
func (*SiteFactory) CreateSite ¶
func (f *SiteFactory) CreateSite(config SiteConfig) (Site, error)
CreateSite creates a Site from configuration
func (*SiteFactory) CreateSiteFromJSON ¶
func (f *SiteFactory) CreateSiteFromJSON(jsonData []byte) (Site, error)
CreateSiteFromJSON creates a Site from JSON configuration
func (*SiteFactory) CreateSitesFromJSON ¶
func (f *SiteFactory) CreateSitesFromJSON(jsonData []byte) ([]Site, error)
CreateSitesFromJSON creates multiple Sites from JSON array configuration
type SiteHTTPClient ¶
type SiteHTTPClient struct {
// contains filtered or unexported fields
}
SiteHTTPClient provides a unified HTTP client interface for site drivers using the requests library instead of net/http directly
func NewSiteHTTPClient ¶
func NewSiteHTTPClient(config SiteHTTPClientConfig) *SiteHTTPClient
NewSiteHTTPClient creates a new SiteHTTPClient
func (*SiteHTTPClient) Close ¶
func (c *SiteHTTPClient) Close() error
Close closes the underlying session
func (*SiteHTTPClient) DoRequest ¶
func (c *SiteHTTPClient) DoRequest(ctx context.Context, method, url string, body io.Reader, headers map[string]string) (*HTTPResponse, error)
DoRequest performs an HTTP request using the requests library
func (*SiteHTTPClient) Get ¶
func (c *SiteHTTPClient) Get(ctx context.Context, url string, headers map[string]string) (*HTTPResponse, error)
Get performs a GET request
type SiteHTTPClientConfig ¶
type SiteHTTPClientConfig struct {
Timeout time.Duration
MaxIdleConns int
IdleConnTimeout time.Duration
DisableKeepAlives bool
UserAgent string
Logger *zap.Logger
}
SiteHTTPClientConfig holds configuration for SiteHTTPClient
func DefaultSiteHTTPClientConfig ¶
func DefaultSiteHTTPClientConfig() SiteHTTPClientConfig
DefaultSiteHTTPClientConfig returns default configuration
type SiteKind ¶
type SiteKind string
SiteKind represents the type of PT site architecture
const ( // SiteNexusPHP represents NexusPHP-based sites (e.g., HDSky, CHDBits) SiteNexusPHP SiteKind = "nexusphp" // SiteUnit3D represents Unit3D-based sites SiteUnit3D SiteKind = "unit3d" // SiteGazelle represents Gazelle-based sites (e.g., What.CD clones) SiteGazelle SiteKind = "gazelle" // SiteMTorrent represents M-Team's custom API SiteMTorrent SiteKind = "mtorrent" )
func GetSiteKind ¶
GetSiteKind returns the architecture kind for a site
type SiteLevelProgressInfo ¶
type SiteLevelProgressInfo struct {
// CurrentLevel is the current level requirement
CurrentLevel *SiteLevelRequirement `json:"currentLevel,omitempty"`
// NextLevel is the next level requirement
NextLevel *SiteLevelRequirement `json:"nextLevel,omitempty"`
// UnmetRequirements contains what's still needed
UnmetRequirements map[string]any `json:"unmetRequirements,omitempty"`
// ProgressPercent is the overall progress percentage (0-100)
ProgressPercent float64 `json:"progressPercent"`
}
SiteLevelProgressInfo represents progress towards the next user level
func CalculateSiteLevelProgress ¶
func CalculateSiteLevelProgress(info *UserInfo, requirements []SiteLevelRequirement) *SiteLevelProgressInfo
CalculateSiteLevelProgress calculates progress to next level
type SiteLevelRequirement ¶
type SiteLevelRequirement struct {
// ID is the numeric level identifier
ID int `json:"id"`
// Name is the level name (e.g., "Power User")
Name string `json:"name"`
// NameAka contains alternative names for matching
NameAka []string `json:"nameAka,omitempty"`
// GroupType: "user", "vip", "manager"
GroupType LevelGroupType `json:"groupType,omitempty"`
// Requirements (all optional)
// Interval is ISO 8601 duration (e.g., "P5W" for 5 weeks)
Interval string `json:"interval,omitempty"`
// Downloaded is size string (e.g., "200GB")
Downloaded string `json:"downloaded,omitempty"`
// Uploaded is size string
Uploaded string `json:"uploaded,omitempty"`
// Ratio is minimum ratio
Ratio float64 `json:"ratio,omitempty"`
// Bonus is minimum bonus points
Bonus float64 `json:"bonus,omitempty"`
// Extended requirements
// SeedingBonus is seeding bonus points requirement
SeedingBonus float64 `json:"seedingBonus,omitempty"`
// Uploads is number of uploads requirement
Uploads int `json:"uploads,omitempty"`
// Seeding is number of seeding torrents requirement
Seeding int `json:"seeding,omitempty"`
// SeedingSize is total seeding size requirement
SeedingSize string `json:"seedingSize,omitempty"`
// Alternative contains OR-based alternative requirements
Alternative []AlternativeRequirement `json:"alternative,omitempty"`
// Privilege describes the privileges granted at this level
Privilege string `json:"privilege,omitempty"`
}
SiteLevelRequirement defines requirements for a user level (site-specific) This is different from LevelRequirement in level_manager.go which is for generic level management
type SiteMeta ¶
type SiteMeta struct {
// ID is the unique site identifier (e.g., "mteam", "hdsky")
ID string
// Name is the human-readable site name
Name string
// Kind is the site architecture type
Kind SiteKind
// DefaultBaseURL is the default base URL for the site
DefaultBaseURL string
// AuthMethod is the authentication method (cookie, api_key)
AuthMethod string
// RateLimit is the default rate limit (requests per second)
RateLimit float64
// RateBurst is the default rate burst
RateBurst int
}
SiteMeta contains metadata for a site type
type SiteMetrics ¶
type SiteMetrics struct {
// contains filtered or unexported fields
}
SiteMetrics provides site-specific metrics
func NewSiteMetrics ¶
func NewSiteMetrics(registry *MetricsRegistry) *SiteMetrics
NewSiteMetrics creates a new site metrics instance
func (*SiteMetrics) RecordCacheHit ¶
func (m *SiteMetrics) RecordCacheHit(cacheType string)
RecordCacheHit records a cache hit
func (*SiteMetrics) RecordCacheMiss ¶
func (m *SiteMetrics) RecordCacheMiss(cacheType string)
RecordCacheMiss records a cache miss
func (*SiteMetrics) RecordDownloaderRequest ¶
func (m *SiteMetrics) RecordDownloaderRequest(downloader string, success bool, duration time.Duration)
RecordDownloaderRequest records a downloader request
func (*SiteMetrics) RecordError ¶
func (m *SiteMetrics) RecordError(errorType string)
RecordError records an error by type
func (*SiteMetrics) RecordRequest ¶
func (m *SiteMetrics) RecordRequest(site string, success bool, duration time.Duration)
RecordRequest records a site request
func (*SiteMetrics) SetActiveDownloaders ¶
func (m *SiteMetrics) SetActiveDownloaders(count int)
SetActiveDownloaders sets the number of active downloaders
func (*SiteMetrics) SetActiveSites ¶
func (m *SiteMetrics) SetActiveSites(count int)
SetActiveSites sets the number of active sites
func (*SiteMetrics) Snapshot ¶
func (m *SiteMetrics) Snapshot() MetricsSnapshot
Snapshot returns a snapshot of all metrics
type SiteMigrationGuide ¶
type SiteMigrationGuide struct {
SiteType string `json:"siteType"`
OldFormat string `json:"oldFormat"`
NewFormat string `json:"newFormat"`
Steps []string `json:"steps"`
Notes []string `json:"notes,omitempty"`
BreakingChanges []string `json:"breakingChanges,omitempty"`
}
SiteMigrationGuide provides migration guidance for each site type
func GetSiteMigrationGuides ¶
func GetSiteMigrationGuides() []SiteMigrationGuide
GetSiteMigrationGuides returns migration guides for all site types
type SiteMigrationManager ¶
type SiteMigrationManager struct {
// contains filtered or unexported fields
}
SiteMigrationManager manages the migration of sites from old to new implementation
func NewSiteMigrationManager ¶
func NewSiteMigrationManager(logger *zap.Logger) *SiteMigrationManager
NewSiteMigrationManager creates a new SiteMigrationManager
func (*SiteMigrationManager) GetMigrationStatus ¶
func (m *SiteMigrationManager) GetMigrationStatus() []MigrationStatus
GetMigrationStatus returns the migration status of all registered sites
func (*SiteMigrationManager) GetNewSite ¶
func (m *SiteMigrationManager) GetNewSite(siteID string) Site
GetNewSite returns the new v2 site implementation if available
func (*SiteMigrationManager) GetSite ¶
func (m *SiteMigrationManager) GetSite(siteID string) any
GetSite returns the site implementation for the given ID
func (*SiteMigrationManager) MigrateToNew ¶
func (m *SiteMigrationManager) MigrateToNew(siteID string) error
MigrateToNew switches a site to use the new implementation
func (*SiteMigrationManager) RegisterSite ¶
func (m *SiteMigrationManager) RegisterSite(siteID string, oldSite any, newSite Site, useNew bool)
RegisterSite registers a site with both old and new implementations
func (*SiteMigrationManager) RollbackToOld ¶
func (m *SiteMigrationManager) RollbackToOld(siteID string) error
RollbackToOld switches a site back to the old implementation
type SiteName ¶
type SiteName string
SiteName represents a PT site identifier
const ( SiteNameMTeam SiteName = "mteam" SiteNameHDSky SiteName = "hdsky" SiteNameSpringSunday SiteName = "springsunday" SiteNameCHDBits SiteName = "chdbits" SiteNameTTG SiteName = "ttg" SiteNameOurBits SiteName = "ourbits" SiteNamePterClub SiteName = "pterclub" SiteNameAudiences SiteName = "audiences" )
Site name constants
type SiteRegistry ¶
type SiteRegistry struct {
// contains filtered or unexported fields
}
SiteRegistry manages site metadata and creation
func NewSiteRegistry ¶
func NewSiteRegistry(logger *zap.Logger) *SiteRegistry
NewSiteRegistry creates a new SiteRegistry with default site metadata
func (*SiteRegistry) CreateSite ¶
func (r *SiteRegistry) CreateSite(siteID string, creds SiteCredentials, customBaseURL string) (Site, error)
CreateSite creates a Site instance from registry metadata and credentials
func (*SiteRegistry) Get ¶
func (r *SiteRegistry) Get(id string) (SiteMeta, bool)
Get returns site metadata by ID
func (*SiteRegistry) GetDefaultBaseURL ¶
func (r *SiteRegistry) GetDefaultBaseURL(siteID string) (string, bool)
GetDefaultBaseURL returns the default base URL for a given site ID
func (*SiteRegistry) GetSiteKind ¶
func (r *SiteRegistry) GetSiteKind(siteID string) (SiteKind, bool)
GetSiteKind returns the site kind for a given site ID
func (*SiteRegistry) List ¶
func (r *SiteRegistry) List() []string
List returns all registered site IDs
func (*SiteRegistry) Register ¶
func (r *SiteRegistry) Register(meta SiteMeta)
Register adds or updates site metadata
type SiteSelectors ¶
type SiteSelectors struct {
// TableRows selects torrent rows in the search results
TableRows string `json:"tableRows"`
// Title selects the torrent title
Title string `json:"title"`
// TitleLink selects the link containing torrent ID
TitleLink string `json:"titleLink"`
// Size selects the torrent size
Size string `json:"size"`
// Seeders selects the seeder count
Seeders string `json:"seeders"`
// Leechers selects the leecher count
Leechers string `json:"leechers"`
// Snatched selects the snatch count
Snatched string `json:"snatched"`
// DiscountIcon selects the discount icon element
DiscountIcon string `json:"discountIcon"`
// DiscountEndTime selects the discount end time
DiscountEndTime string `json:"discountEndTime"`
// DownloadLink selects the download link
DownloadLink string `json:"downloadLink"`
// Category selects the category
Category string `json:"category"`
// UploadTime selects the upload time
UploadTime string `json:"uploadTime"`
// HRIcon selects the H&R icon
HRIcon string `json:"hrIcon"`
// Subtitle selects the subtitle in search results
Subtitle string `json:"subtitle"`
// UserInfo selectors for user page
UserInfoUsername string `json:"userInfoUsername"`
UserInfoUploaded string `json:"userInfoUploaded"`
UserInfoDownloaded string `json:"userInfoDownloaded"`
UserInfoRatio string `json:"userInfoRatio"`
UserInfoBonus string `json:"userInfoBonus"`
UserInfoRank string `json:"userInfoRank"`
// Detail page selectors
// DetailDownloadLink selects the download link from details page
DetailDownloadLink string `json:"detailDownloadLink"`
// DetailSubtitle selects the subtitle from details page
DetailSubtitle string `json:"detailSubtitle"`
}
SiteSelectors defines CSS selectors for parsing NexusPHP pages
func DefaultNexusPHPSelectors ¶
func DefaultNexusPHPSelectors() SiteSelectors
DefaultNexusPHPSelectors returns default selectors for standard NexusPHP sites
type SiteURLRegistry ¶
type SiteURLRegistry struct {
// contains filtered or unexported fields
}
SiteURLRegistry manages site URL configurations It provides a centralized way to register and retrieve site URLs
func GetGlobalRegistry ¶
func GetGlobalRegistry() *SiteURLRegistry
GetGlobalRegistry returns the global site URL registry
func NewSiteURLRegistry ¶
func NewSiteURLRegistry(logger *zap.Logger) *SiteURLRegistry
NewSiteURLRegistry creates a new site URL registry
func (*SiteURLRegistry) GetFailoverClient ¶
func (r *SiteURLRegistry) GetFailoverClient(siteName SiteName, opts ...FailoverOption) (*FailoverHTTPClient, error)
GetFailoverClient creates a FailoverHTTPClient for the specified site
func (*SiteURLRegistry) GetFailoverConfig ¶
func (r *SiteURLRegistry) GetFailoverConfig(siteName SiteName) (URLFailoverConfig, error)
GetFailoverConfig returns a failover config for the specified site
func (*SiteURLRegistry) GetURLs ¶
func (r *SiteURLRegistry) GetURLs(siteName SiteName) []string
GetURLs returns the URL list for a site Returns nil if the site is not registered
func (*SiteURLRegistry) HasSite ¶
func (r *SiteURLRegistry) HasSite(siteName SiteName) bool
HasSite checks if a site is registered
func (*SiteURLRegistry) ListSites ¶
func (r *SiteURLRegistry) ListSites() []SiteName
ListSites returns all registered site names
func (*SiteURLRegistry) RegisterURLs ¶
func (r *SiteURLRegistry) RegisterURLs(siteName SiteName, urls []string)
RegisterURLs registers or updates URLs for a site
type SpringSundayParser ¶
type SpringSundayParser struct {
Config NexusPHPParserConfig
}
SpringSundayParser implements NexusPHPDetailParser for SpringSunday site
func NewSpringSundayParser ¶
func NewSpringSundayParser(options ...NexusPHPParserOption) *SpringSundayParser
NewSpringSundayParser creates a new SpringSundayParser
func (*SpringSundayParser) ParseAll ¶
func (p *SpringSundayParser) ParseAll(doc *goquery.Selection) *TorrentDetailInfo
ParseAll parses all information from SpringSunday page
func (*SpringSundayParser) ParseDiscount ¶
func (p *SpringSundayParser) ParseDiscount(doc *goquery.Selection) (DiscountLevel, time.Time)
ParseDiscount parses discount type and end time from SpringSunday page
func (*SpringSundayParser) ParseHR ¶
func (p *SpringSundayParser) ParseHR(doc *goquery.Selection) bool
ParseHR parses HR status from SpringSunday page
func (*SpringSundayParser) ParseSizeMB ¶
func (p *SpringSundayParser) ParseSizeMB(doc *goquery.Selection) float64
ParseSizeMB parses torrent size in MB from SpringSunday page
func (*SpringSundayParser) ParseTitleAndID ¶
func (p *SpringSundayParser) ParseTitleAndID(doc *goquery.Selection) (title, torrentID string)
ParseTitleAndID parses title and torrent ID from SpringSunday page
type Timer ¶
type Timer struct {
// contains filtered or unexported fields
}
Timer measures elapsed time
func (*Timer) ObserveDuration ¶
ObserveDuration records the elapsed time since the timer was created
type TorrentDetail ¶
type TorrentDetail struct {
// DownloadURL is the direct download URL with passkey
DownloadURL string `json:"downloadUrl"`
// Subtitle is the torrent subtitle
Subtitle string `json:"subtitle"`
// InfoHash is the torrent info hash
InfoHash string `json:"infoHash,omitempty"`
}
TorrentDetail contains detailed information from a torrent detail page
type TorrentDetailInfo ¶
type TorrentDetailInfo struct {
TorrentID string
Title string
SizeMB float64
DiscountLevel DiscountLevel
DiscountEnd time.Time
HasHR bool
}
TorrentDetailInfo represents parsed torrent detail information
type TorrentFile ¶
TorrentFile represents a file in a torrent
type TorrentItem ¶
type TorrentItem struct {
// ID is the site-specific torrent identifier
ID string `json:"id"`
// URL is the torrent detail page URL
URL string `json:"url,omitempty"`
// Title is the torrent title
Title string `json:"title"`
// Subtitle is the torrent subtitle (副标题)
Subtitle string `json:"subtitle,omitempty"`
// InfoHash is the torrent info hash (if available)
InfoHash string `json:"infoHash,omitempty"`
// Magnet is the magnet link (if available)
Magnet string `json:"magnet,omitempty"`
// SizeBytes is the torrent size in bytes
SizeBytes int64 `json:"sizeBytes"`
// Seeders is the number of seeders
Seeders int `json:"seeders"`
// Leechers is the number of leechers
Leechers int `json:"leechers"`
// Snatched is the number of completed downloads
Snatched int `json:"snatched,omitempty"`
// UploadedAt is the upload timestamp (Unix seconds)
UploadedAt int64 `json:"uploadedAt,omitempty"`
// Tags are the torrent tags/labels
Tags []string `json:"tags,omitempty"`
// SourceSite is the site this torrent came from
SourceSite string `json:"sourceSite"`
// DiscountLevel is the current discount level
DiscountLevel DiscountLevel `json:"discountLevel"`
// DiscountEndTime is when the discount expires
DiscountEndTime time.Time `json:"discountEndTime,omitempty"`
// HasHR indicates if the torrent has H&R requirements
HasHR bool `json:"hasHR,omitempty"`
// DownloadURL is the direct download URL
DownloadURL string `json:"downloadUrl,omitempty"`
// Category is the torrent category
Category string `json:"category,omitempty"`
}
TorrentItem represents a torrent search result
func (*TorrentItem) CanbeFinished ¶
func (t *TorrentItem) CanbeFinished(enabled bool, speedLimit, sizeLimitGB int) bool
CanbeFinished checks if the torrent can be downloaded within the free period enabled: whether download limit is enabled speedLimit: download speed limit in MB/s sizeLimitGB: maximum torrent size in GB
func (*TorrentItem) GetFreeEndTime ¶
func (t *TorrentItem) GetFreeEndTime() *time.Time
GetFreeEndTime returns the discount end time
func (*TorrentItem) GetFreeLevel ¶
func (t *TorrentItem) GetFreeLevel() string
GetFreeLevel returns the discount level as string
func (*TorrentItem) GetName ¶
func (t *TorrentItem) GetName() string
GetName returns the torrent title
func (*TorrentItem) GetSubTitle ¶
func (t *TorrentItem) GetSubTitle() string
GetSubTitle returns the torrent tags as subtitle
func (*TorrentItem) IsDiscountActive ¶
func (t *TorrentItem) IsDiscountActive() bool
IsDiscountActive returns true if the discount is still active
func (*TorrentItem) IsFree ¶
func (t *TorrentItem) IsFree() bool
IsFree returns true if the torrent is currently free
type TorrentManifest ¶
type TorrentManifest struct {
ID string `json:"id"`
Title string `json:"title"`
SizeBytes int64 `json:"sizeBytes"`
DiscountLevel DiscountLevel `json:"discountLevel"`
DownloadURL string `json:"downloadUrl"`
Category string `json:"category,omitempty"`
Seeders int `json:"seeders,omitempty"`
Leechers int `json:"leechers,omitempty"`
}
TorrentManifest represents metadata for a torrent in the batch download
type TwoLevelCache ¶
type TwoLevelCache struct {
// contains filtered or unexported fields
}
TwoLevelCache provides L1 (in-memory) and optional L2 (external) caching
func NewTwoLevelCache ¶
func NewTwoLevelCache(config TwoLevelCacheConfig) *TwoLevelCache
NewTwoLevelCache creates a new two-level cache
func (*TwoLevelCache) Clear ¶
func (c *TwoLevelCache) Clear()
Clear removes all entries from L1 (L2 is not cleared)
func (*TwoLevelCache) Delete ¶
func (c *TwoLevelCache) Delete(key string) error
Delete removes a value from both L1 and L2
type TwoLevelCacheConfig ¶
type TwoLevelCacheConfig struct {
L1Capacity int // L1 cache capacity (default: 1000)
L1TTL time.Duration // L1 TTL (default: 5 minutes)
L2TTL time.Duration // L2 TTL (default: 1 hour)
L2Cache L2Cache // Optional L2 cache implementation
}
TwoLevelCacheConfig configures the two-level cache
type URLFailoverConfig ¶
type URLFailoverConfig struct {
// BaseURLs is the list of base URLs to try in order
BaseURLs []string
// RetryDelay is the delay between retries on the same URL
RetryDelay time.Duration
// MaxRetries is the maximum number of retries per URL (0 = no retry, just try once)
MaxRetries int
// Timeout is the timeout for each request
Timeout time.Duration
}
URLFailoverConfig configures multi-URL failover behavior
func DefaultFailoverConfig ¶
func DefaultFailoverConfig(baseURLs []string) URLFailoverConfig
DefaultFailoverConfig returns a default failover configuration
type URLFailoverManager ¶
type URLFailoverManager struct {
// contains filtered or unexported fields
}
URLFailoverManager manages multi-URL failover for site requests
func NewURLFailoverManager ¶
func NewURLFailoverManager(config URLFailoverConfig, logger *zap.Logger) *URLFailoverManager
NewURLFailoverManager creates a new URL failover manager
func (*URLFailoverManager) ExecuteWithFailover ¶
func (m *URLFailoverManager) ExecuteWithFailover( ctx context.Context, execFunc func(baseURL string) error, ) error
ExecuteWithFailover executes a function with automatic URL failover The execFunc receives the base URL and should return an error if the request fails Returns the error from the last attempted URL if all URLs fail
func (*URLFailoverManager) GetAllURLs ¶
func (m *URLFailoverManager) GetAllURLs() []string
GetAllURLs returns all configured base URLs
func (*URLFailoverManager) GetCurrentURL ¶
func (m *URLFailoverManager) GetCurrentURL() string
GetCurrentURL returns the currently active base URL
type Unit3DDriver ¶
Unit3DDriver implements the Driver interface for Unit3D sites
func NewUnit3DDriver ¶
func NewUnit3DDriver(config Unit3DDriverConfig) *Unit3DDriver
NewUnit3DDriver creates a new Unit3D driver
func (*Unit3DDriver) Execute ¶
func (d *Unit3DDriver) Execute(ctx context.Context, req Unit3DRequest) (Unit3DResponse, error)
Execute performs the HTTP request
func (*Unit3DDriver) GetUserInfo ¶
func (d *Unit3DDriver) GetUserInfo(ctx context.Context) (UserInfo, error)
GetUserInfo fetches complete user information
func (*Unit3DDriver) ParseDownload ¶
func (d *Unit3DDriver) ParseDownload(res Unit3DResponse) ([]byte, error)
ParseDownload extracts torrent file data from the response
func (*Unit3DDriver) ParseSearch ¶
func (d *Unit3DDriver) ParseSearch(res Unit3DResponse) ([]TorrentItem, error)
ParseSearch extracts torrent items from the response
func (*Unit3DDriver) ParseUserInfo ¶
func (d *Unit3DDriver) ParseUserInfo(res Unit3DResponse) (UserInfo, error)
ParseUserInfo extracts user info from the response
func (*Unit3DDriver) PrepareDownload ¶
func (d *Unit3DDriver) PrepareDownload(torrentID string) (Unit3DRequest, error)
PrepareDownload prepares a request for downloading a torrent
func (*Unit3DDriver) PrepareSearch ¶
func (d *Unit3DDriver) PrepareSearch(query SearchQuery) (Unit3DRequest, error)
PrepareSearch converts a SearchQuery to a Unit3D request
func (*Unit3DDriver) PrepareUserInfo ¶
func (d *Unit3DDriver) PrepareUserInfo() (Unit3DRequest, error)
PrepareUserInfo prepares a request for user info
type Unit3DDriverConfig ¶
type Unit3DDriverConfig struct {
BaseURL string
APIKey string
HTTPClient *SiteHTTPClient // Use SiteHTTPClient instead of *http.Client
UserAgent string
}
Unit3DDriverConfig holds configuration for creating a Unit3D driver
type Unit3DOptions ¶
type Unit3DOptions struct {
APIKey string `json:"apiKey"`
}
Unit3DOptions holds Unit3D-specific configuration
type Unit3DRequest ¶
type Unit3DRequest struct {
// Endpoint is the API endpoint path
Endpoint string
// Method is the HTTP method
Method string
// Params are the query parameters
Params url.Values
}
Unit3DRequest represents a request to a Unit3D site
type Unit3DResponse ¶
type Unit3DResponse struct {
// Data is the response data
Data json.RawMessage `json:"data"`
// Links contains pagination links
Links json.RawMessage `json:"links,omitempty"`
// Meta contains pagination metadata
Meta json.RawMessage `json:"meta,omitempty"`
// RawBody is the raw response body
RawBody []byte `json:"-"`
// StatusCode is the HTTP status code
StatusCode int `json:"-"`
}
Unit3DResponse represents a response from Unit3D API
type Unit3DTorrent ¶
type Unit3DTorrent struct {
ID int `json:"id"`
Name string `json:"name"`
InfoHash string `json:"info_hash"`
Size int64 `json:"size"`
Seeders int `json:"seeders"`
Leechers int `json:"leechers"`
TimesCompleted int `json:"times_completed"`
Category struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"category"`
Type struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"type"`
Freeleech string `json:"freeleech"`
FreeleechEnds string `json:"freeleech_ends,omitempty"`
DoubleUpload bool `json:"double_upload"`
Featured bool `json:"featured"`
CreatedAt string `json:"created_at"`
DownloadLink string `json:"download_link,omitempty"`
}
Unit3DTorrent represents a torrent in Unit3D API response
type Unit3DUserProfile ¶
type Unit3DUserProfile struct {
ID int `json:"id"`
Username string `json:"username"`
Uploaded int64 `json:"uploaded"`
Downloaded int64 `json:"downloaded"`
Ratio float64 `json:"ratio"`
Buffer int64 `json:"buffer"`
Seedbonus float64 `json:"seedbonus"`
Seeding int `json:"seeding"`
Leeching int `json:"leeching"`
Group struct {
Name string `json:"name"`
} `json:"group"`
CreatedAt string `json:"created_at"`
}
Unit3DUserProfile represents user profile from Unit3D API
type UserInfo ¶
type UserInfo struct {
// Site is the site identifier
Site string `json:"site"`
// Username is the user's username
Username string `json:"username"`
// UserID is the site-specific user ID
UserID string `json:"userId"`
// Uploaded is the total uploaded bytes
Uploaded int64 `json:"uploaded"`
// Downloaded is the total downloaded bytes
Downloaded int64 `json:"downloaded"`
// Ratio is the upload/download ratio
Ratio float64 `json:"ratio"`
// Bonus is the bonus points
Bonus float64 `json:"bonus"`
// Seeding is the number of torrents being seeded
Seeding int `json:"seeding"`
// Leeching is the number of torrents being downloaded
Leeching int `json:"leeching"`
// Rank is the user's rank/class
Rank string `json:"rank"`
// JoinDate is when the user joined (Unix seconds)
JoinDate int64 `json:"joinDate,omitempty"`
// LastAccess is the last access time (Unix seconds)
LastAccess int64 `json:"lastAccess,omitempty"`
// LastUpdate is when this info was last updated (Unix seconds)
LastUpdate int64 `json:"lastUpdate"`
// NextLevel contains level progression info (optional)
NextLevel *LevelProgress `json:"nextLevel,omitempty"`
// Extended fields (populated by sites that support them)
// LevelName is the user's level/rank name
LevelName string `json:"levelName,omitempty"`
// LevelID is the numeric level ID
LevelID int `json:"levelId,omitempty"`
// BonusPerHour is the bonus points earned per hour (时魔)
BonusPerHour float64 `json:"bonusPerHour,omitempty"`
// SeedingBonus is the seeding bonus points (做种积分)
SeedingBonus float64 `json:"seedingBonus,omitempty"`
// SeedingBonusPerHour is the seeding bonus per hour
SeedingBonusPerHour float64 `json:"seedingBonusPerHour,omitempty"`
// UnreadMessageCount is the number of unread messages
UnreadMessageCount int `json:"unreadMessageCount,omitempty"`
// TotalMessageCount is the total number of messages
TotalMessageCount int `json:"totalMessageCount,omitempty"`
// SeederCount is the number of torrents being seeded (from peer statistics)
SeederCount int `json:"seederCount,omitempty"`
// SeederSize is the total size of seeding torrents (bytes)
SeederSize int64 `json:"seederSize,omitempty"`
// LeecherCount is the number of torrents being downloaded
LeecherCount int `json:"leecherCount,omitempty"`
// LeecherSize is the total size of leeching torrents (bytes)
LeecherSize int64 `json:"leecherSize,omitempty"`
// HnRUnsatisfied is the number of unsatisfied H&R
HnRUnsatisfied int `json:"hnrUnsatisfied,omitempty"`
// HnRPreWarning is the number of H&R pre-warnings
HnRPreWarning int `json:"hnrPreWarning,omitempty"`
// TrueUploaded is the true uploaded bytes (some sites track separately)
TrueUploaded int64 `json:"trueUploaded,omitempty"`
// TrueDownloaded is the true downloaded bytes
TrueDownloaded int64 `json:"trueDownloaded,omitempty"`
// Uploads is the number of torrents uploaded by user
Uploads int `json:"uploads,omitempty"`
}
UserInfo represents user information from a PT site
type UserInfoConfig ¶
type UserInfoConfig struct {
// PickLast specifies fields that should retain last known value
PickLast []string `json:"pickLast,omitempty"`
// RequestDelay between multi-step requests (milliseconds)
RequestDelay int `json:"requestDelay,omitempty"`
// Process defines multi-step user info fetching
Process []UserInfoProcess `json:"process,omitempty"`
// Selectors for parsing user info fields
Selectors map[string]FieldSelector `json:"selectors,omitempty"`
}
UserInfoConfig defines how to fetch and parse user info
type UserInfoProcess ¶
type UserInfoProcess struct {
// RequestConfig for this step
RequestConfig RequestConfig `json:"requestConfig"`
// Assertion for parameter passing (e.g., {"id": "params.id"})
Assertion map[string]string `json:"assertion,omitempty"`
// Fields to extract in this step
Fields []string `json:"fields"`
}
UserInfoProcess defines a single step in user info fetching
type UserInfoRecord ¶
type UserInfoRecord struct {
ID uint `gorm:"primaryKey" json:"id"`
Site string `gorm:"uniqueIndex;size:64;not null" json:"site"`
Username string `gorm:"size:128" json:"username"`
UserID string `gorm:"size:64" json:"userId"`
Rank string `gorm:"size:64" json:"rank"`
Uploaded int64 `json:"uploaded"`
Downloaded int64 `json:"downloaded"`
Ratio float64 `json:"ratio"`
Seeding int `json:"seeding"`
Leeching int `json:"leeching"`
Bonus float64 `json:"bonus"`
JoinDate int64 `json:"joinDate"`
LastAccess int64 `json:"lastAccess"`
LastUpdate int64 `json:"lastUpdate"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
// Extended fields
LevelName string `gorm:"size:64" json:"levelName"`
LevelID int `json:"levelId"`
BonusPerHour float64 `json:"bonusPerHour"`
SeedingBonus float64 `json:"seedingBonus"`
SeedingBonusPerHour float64 `json:"seedingBonusPerHour"`
UnreadMessageCount int `json:"unreadMessageCount"`
TotalMessageCount int `json:"totalMessageCount"`
SeederCount int `json:"seederCount"`
SeederSize int64 `json:"seederSize"`
LeecherCount int `json:"leecherCount"`
LeecherSize int64 `json:"leecherSize"`
HnRUnsatisfied int `json:"hnrUnsatisfied"`
HnRPreWarning int `json:"hnrPreWarning"`
TrueUploaded int64 `json:"trueUploaded"`
TrueDownloaded int64 `json:"trueDownloaded"`
Uploads int `json:"uploads"`
}
UserInfoRecord represents the database model for user info
func FromUserInfo ¶
func FromUserInfo(info UserInfo) UserInfoRecord
FromUserInfo creates a UserInfoRecord from UserInfo
func (UserInfoRecord) TableName ¶
func (UserInfoRecord) TableName() string
TableName returns the table name for UserInfoRecord
func (*UserInfoRecord) ToUserInfo ¶
func (r *UserInfoRecord) ToUserInfo() UserInfo
ToUserInfo converts UserInfoRecord to UserInfo
type UserInfoRepo ¶
type UserInfoRepo interface {
// Save stores user info for a site
Save(ctx context.Context, info UserInfo) error
// Get retrieves user info for a specific site
Get(ctx context.Context, site string) (UserInfo, error)
// ListAll retrieves all stored user info
ListAll(ctx context.Context) ([]UserInfo, error)
// ListBySites retrieves user info for specific sites
ListBySites(ctx context.Context, sites []string) ([]UserInfo, error)
// Delete removes user info for a site
Delete(ctx context.Context, site string) error
// GetAggregated calculates aggregated statistics
GetAggregated(ctx context.Context) (AggregatedStats, error)
}
UserInfoRepo defines the interface for storing and retrieving user information
type UserInfoService ¶
type UserInfoService struct {
// contains filtered or unexported fields
}
UserInfoService provides user information management across multiple sites
func NewUserInfoService ¶
func NewUserInfoService(config UserInfoServiceConfig) *UserInfoService
NewUserInfoService creates a new UserInfoService
func (*UserInfoService) ClearCache ¶
func (s *UserInfoService) ClearCache()
ClearCache clears the user info cache
func (*UserInfoService) DeleteUserInfo ¶
func (s *UserInfoService) DeleteUserInfo(ctx context.Context, siteID string) error
DeleteUserInfo removes user info for a site
func (*UserInfoService) FetchAndSave ¶
FetchAndSave fetches user info from a site and saves it
func (*UserInfoService) FetchAndSaveAll ¶
func (s *UserInfoService) FetchAndSaveAll(ctx context.Context) ([]UserInfo, []error)
FetchAndSaveAll fetches user info from all registered sites
func (*UserInfoService) FetchAndSaveAllWithConcurrency ¶
func (s *UserInfoService) FetchAndSaveAllWithConcurrency( ctx context.Context, maxConcurrent int, timeout time.Duration, ) ([]UserInfo, []SyncError)
FetchAndSaveAllWithConcurrency fetches user info from all registered sites with concurrency control maxConcurrent: maximum number of concurrent requests timeout: timeout for each site request
func (*UserInfoService) GetAggregated ¶
func (s *UserInfoService) GetAggregated(ctx context.Context) (AggregatedStats, error)
GetAggregated returns aggregated statistics across all sites
func (*UserInfoService) GetAllUserInfo ¶
func (s *UserInfoService) GetAllUserInfo(ctx context.Context) ([]UserInfo, error)
GetAllUserInfo retrieves all stored user info
func (*UserInfoService) GetSite ¶
func (s *UserInfoService) GetSite(siteID string) (Site, bool)
GetSite returns a registered site by ID
func (*UserInfoService) GetUserInfo ¶
GetUserInfo retrieves user info for a site (from cache or repository)
func (*UserInfoService) ListSites ¶
func (s *UserInfoService) ListSites() []string
ListSites returns all registered site IDs
func (*UserInfoService) RegisterSite ¶
func (s *UserInfoService) RegisterSite(site Site)
RegisterSite registers a site for user info fetching
func (*UserInfoService) UnregisterSite ¶
func (s *UserInfoService) UnregisterSite(siteID string)
UnregisterSite removes a site from the service
type UserInfoServiceConfig ¶
type UserInfoServiceConfig struct {
Repo UserInfoRepo
CacheTTL time.Duration
Logger *zap.Logger
}
UserInfoServiceConfig holds configuration for UserInfoService
type ValidationConfig ¶
type ValidationConfig struct {
MaxStringLength int // Maximum string length (default: 10000)
MaxURLLength int // Maximum URL length (default: 2048)
MaxFileSizeBytes int64 // Maximum file size in bytes (default: 100MB)
AllowHTML bool // Whether to allow HTML content
StripHTML bool // Whether to strip HTML tags
}
ValidationConfig configures validation limits
func DefaultValidationConfig ¶
func DefaultValidationConfig() ValidationConfig
DefaultValidationConfig returns default validation configuration
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
Validator provides input validation methods
func NewValidator ¶
func NewValidator(config ValidationConfig) *Validator
NewValidator creates a new validator with the given configuration
func (*Validator) ValidateFileSize ¶
ValidateFileSize validates a file size
func (*Validator) ValidateInfoHash ¶
ValidateInfoHash validates a torrent info hash
func (*Validator) ValidateSearchQuery ¶
func (v *Validator) ValidateSearchQuery(query SearchQuery) error
ValidateSearchQuery validates a search query
func (*Validator) ValidateString ¶
ValidateString validates a string input
Source Files
¶
- base_site.go
- batch_download.go
- cache.go
- circuit_breaker.go
- deduper.go
- definition_registry.go
- discount_utils.go
- factory.go
- failover.go
- filters.go
- gazelle_driver.go
- http_client.go
- level.go
- level_manager.go
- level_requirement.go
- metrics.go
- migration.go
- mtorrent_driver.go
- nexusphp_driver.go
- nexusphp_parser.go
- normalizer.go
- ranker.go
- registry.go
- search_cache.go
- search_orchestrator.go
- site_categories.go
- site_definition.go
- site_urls.go
- torrent_utils.go
- types.go
- unit3d_driver.go
- userinfo_db_repo.go
- userinfo_repo.go
- userinfo_service.go
- validation.go