Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var AGSVPTDefinition = &v2.SiteDefinition{ ID: "agsvpt", Name: "AGSVPT", Aka: []string{"末日种子库", "AGSV"}, Description: "Arctic Global Seed Vault", Schema: v2.SchemaNexusPHP, URLs: []string{"https://www.agsvpt.com/"}, FaviconURL: "https://www.agsvpt.com/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 72, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{ "name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime", "messageCount", }, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>上[传傳]量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>下[载載]量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio)</strong>[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img", }, Attr: "title", }, "bonus": { Selector: []string{ "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('冰晶') + td", "td.rowhead:contains('Bonus') + td", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonusPerHour": { Selector: []string{ "#outer td[rowspan]", "div:contains('你当前每小时能获取')", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Text: "0", Selector: []string{"td[style*='background: red'] a[href*='messages.php']"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td", }, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: agsvptLevelRequirements, }
View Source
var AudiencesDefinition = &v2.SiteDefinition{ ID: "audiences", Name: "Audiences", Aka: []string{"audiences.me", "AD"}, Description: "Audiences 私人影视站", Schema: v2.SchemaNexusPHP, URLs: []string{"https://audiences.me/"}, FaviconURL: "https://audiences.me/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "h1 .nowrap b"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('Transfer') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('Transfer') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio)(?:</strong>)?[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:爆米花|爆米花系统)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span[style*='line-height']", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", HRIcon: "img.hitandrun, img[alt*='H&R'], img[title*='H&R']", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font.twoupfree, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var BTSchoolDefinition = &v2.SiteDefinition{ ID: "btschool", Name: "BTSCHOOL", Aka: []string{"学校", "BTS"}, Description: "汇聚每一个人的影响力", Schema: v2.SchemaNexusPHP, URLs: []string{"https://pt.btschool.club/"}, LegacyURLs: []string{"https://pt.btschool.net/"}, FaviconURL: "https://pt.btschool.club/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 20, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>分享率</strong>[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('等級') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`魔力值\s*</font>\s*\[[^\]]*\]\s*[::]\s*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "regex", Args: []any{`^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})`}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: btschoolLevelRequirements, }
View Source
var BYRPTDefinition = &v2.SiteDefinition{ ID: "byrpt", Name: "BYRPT", Aka: []string{"BYR", "北邮人"}, Description: "BYRPT 教育网综合资源站", Schema: v2.SchemaNexusPHP, URLs: []string{"https://byr.pt/"}, FaviconURL: "https://byr.pt/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"td.navbar-user-data a[href*='userdetails.php']", "a[href*='userdetails.php'][class*='Name']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"td.navbar-user-data a[href*='userdetails.php']", "a[href*='userdetails.php'][class*='Name']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", ".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", ".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", ".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"td.rowhead:contains('魔力值') + td", "td.navbar-user-data", ".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?s)(?:魔力值|Bonus).*?:\s*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`arrowup[^>]*></div>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{".navbar-user-data", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`arrowdown[^>]*></div>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type", Size: "td.rowfollow:nth-child(6)", Seeders: "td.rowfollow:nth-child(7)", Leechers: "td.rowfollow:nth-child(8)", Snatched: "td.rowfollow:nth-child(9)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(2) a.cat-link", UploadTime: "td.rowfollow:nth-child(5)", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, "pro_free": v2.DiscountFree, "pro_50pctdown": v2.DiscountPercent50, }, DiscountSelector: "h1 font[class], h1 img[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var CarPTDefinition = &v2.SiteDefinition{ ID: "carpt", Name: "CarPT", Aka: []string{"车PT"}, Description: "以车载音乐与影视资源为主的 NexusPHP PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://carpt.net/"}, FaviconURL: "https://carpt.net/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('上传量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('下载量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('分享率') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)[^\d∞]*([\d.,]+|∞|Inf|---)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td > img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var FiveTwoPTDefinition = &v2.SiteDefinition{ ID: "52pt", Name: "52PT", Aka: []string{"我爱PT"}, Description: "低调地在这个PT校园快乐成长 快乐分享", Schema: v2.SchemaNexusPHP, URLs: []string{"https://52pt.site/"}, FaviconURL: "https://52pt.site/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 24, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`上[传傳][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`下[载載][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('BT时间') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "#info_block a[href*='mybonus.php']", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: fiveTwoPTLevelRequirements, }
View Source
var HDDolbyDefinition = &v2.SiteDefinition{ ID: "hddolby", Name: "HD Dolby", Aka: []string{"高清杜比"}, Description: "高清杜比 - 需要同时配置 Cookie 和 RSS Key。RSS Key 用于搜索和下载,Cookie 用于获取时魔等信息", Schema: v2.SchemaHDDolby, AuthMethod: v2.AuthMethodCookieAndAPIKey, URLs: []string{"https://www.hddolby.com/"}, LegacyURLs: []string{"https://hddolby.com/"}, FaviconURL: "https://www.hddolby.com/favicon.ico", Unavailable: false, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 3, RateWindow: time.Hour, RateWindowLimit: 50, LevelRequirements: []v2.SiteLevelRequirement{ { ID: 1, Name: "User", Privilege: "新用户的默认级别。", }, { ID: 2, Name: "Power User", Interval: "P2W", Downloaded: "120GB", Ratio: 2.0, SeedingBonus: 60000, Privilege: "得到0个邀请名额;可以直接发布种子;可以查看NFO文档;可以查看用户列表;可以请求续种;可以查看排行榜;可以查看其它用户的种子历史;可以删除自己上传的字幕。", }, { ID: 3, Name: "(连长)Elite User", NameAka: []string{"Elite User"}, Interval: "P4W", Downloaded: "256GB", Ratio: 2.5, SeedingBonus: 120000, Privilege: "Elite User及以上用户封存账号后不会被删除。", }, { ID: 4, Name: "Crazy User", Interval: "P8W", Downloaded: "512GB", Ratio: 3.0, SeedingBonus: 240000, Privilege: "得到0个邀请名额;可以在做种/下载/发布的时候选择匿名模式。", }, { ID: 5, Name: "Insane User", Interval: "P12W", Downloaded: "768GB", Ratio: 3.5, SeedingBonus: 360000, Privilege: "无", }, { ID: 6, Name: "Veteran User", Interval: "P20W", Downloaded: "1TB", Ratio: 4.0, SeedingBonus: 600000, Privilege: "可以查看其它用户的评论、帖子历史。", }, { ID: 7, Name: "Extreme User", Interval: "P28W", Downloaded: "2TB", Ratio: 4.5, SeedingBonus: 720000, Privilege: "Extreme User及以上用户会永远保留账号。", }, { ID: 8, Name: "Ultimate User", Interval: "P40W", Downloaded: "4TB", Ratio: 5.0, SeedingBonus: 1200000, Privilege: "无", }, { ID: 9, Name: "Nexus Master", Interval: "P56W", Downloaded: "8TB", Ratio: 5.5, SeedingBonus: 1680000, Privilege: "无", }, }, }
View Source
var HDFansDefinition = &v2.SiteDefinition{ ID: "hdfans", Name: "HDFans", Aka: []string{"红豆饭"}, Description: "与志同道合之人前行 分享更多值得珍藏的资源", Schema: v2.SchemaNexusPHP, URLs: []string{"https://hdfans.org/"}, FaviconURL: "https://hdfans.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 72, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "uploaded", "downloaded", "ratio", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime", "messageCount"}, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "#info_block", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "#info_block", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "#info_block", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img", }, Attr: "title", }, "bonus": { Selector: []string{ "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('魔力') + td", "td.rowhead:contains('Bonus') + td", "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "bonusPerHour": { Selector: []string{ "#outer td[rowspan]", "div:contains('你当前每小时能获取')", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Text: "0", Selector: []string{"td[style*='background: red'] a[href*='messages.php']"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td", }, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: hdfansLevelRequirements, }
View Source
var HDHomeDefinition = &v2.SiteDefinition{ ID: "hdhome", Name: "HDHome", Aka: []string{"HDHome", "家园"}, Description: "高清影视 PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://hdhome.org/"}, FaviconURL: "https://hdhome.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "uploaded", "downloaded", "ratio", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"#info_block", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"#info_block", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"#info_block", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|分享率:|Ratio)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span[style*='float:left']", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var HDSkyDefinition = &v2.SiteDefinition{ ID: "hdsky", Name: "HDSky", Aka: []string{"HDS", "天空"}, Description: "高清发烧友后花园PT", Schema: v2.SchemaNexusPHP, URLs: []string{"https://hdsky.me/"}, FaviconURL: "https://hdsky.me/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{ "name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "seedingBonus", "joinTime", "hnrUnsatisfied", "hnrPreWarning", "messageCount", }, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`上[传傳][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`下[载載][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td > font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`分享率</strong>[::\s]*\s*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img", "td.rowhead:contains('等級') + td img", "td.rowhead:contains('Class') + td img", }, Attr: "title", }, "bonus": { Selector: []string{ "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('魔力') + td", "td.rowhead:contains('Bonus') + td", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "seedingBonus": { Selector: []string{ "td.rowhead:contains('做种积分') + td", "td.rowhead:contains('做種積分') + td", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonusPerHour": { Selector: []string{ "#outer td[rowspan]", "div:contains('你当前每小时能获取')", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Text: "0", Selector: []string{"td[style*='background: red'] a[href*='messages.php']"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td", }, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, "hnrUnsatisfied": { Text: "0", Selector: []string{"#info_block a[href*='myhr.php']"}, Filters: []v2.Filter{ {Name: "regex", Args: []any{`\d+\s*/\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "hnrPreWarning": { Text: "0", Selector: []string{"#info_block a[href*='myhr.php']"}, Filters: []v2.Filter{ {Name: "regex", Args: []any{`^(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载链接') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, LevelRequirements: hdSkyNewLevelRequirements, }
HDSkyDefinition is the site definition for HDSky
View Source
var HDSkyNewRequirementsDate = time.Date(2025, 3, 1, 0, 0, 0, 0, time.FixedZone("CST", 8*3600))
HDSkyNewRequirementsDate is the date after which new level requirements apply
View Source
var HDTimeDefinition = &v2.SiteDefinition{ ID: "hdtime", Name: "HDTime", Aka: []string{"HDTIME"}, Description: "HDTime 综合影视 PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://hdtime.org/"}, FaviconURL: "https://hdtime.org/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "span.nowrap a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "span.nowrap a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('Transfer') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('Transfer') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('Ratio') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"td.rowhead:contains('魔力值') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var HXPTDefinition = &v2.SiteDefinition{ ID: "hxpt", Name: "HXPT", Aka: []string{"好学"}, Description: "以教育类资源为主的 NexusPHP PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://www.hxpt.org/"}, FaviconURL: "https://www.hxpt.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('上传量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('下载量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('分享率') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td > img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('火花') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:火花|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname div.torrent-subtitle, table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up, font.free", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var LajiduiDefinition = &v2.SiteDefinition{ ID: "lajidui", Name: "lajidui", Aka: []string{"垃圾堆"}, Description: "极致文件共享体验", Schema: v2.SchemaNexusPHP, URLs: []string{"https://pt.lajidui.top/"}, FaviconURL: "https://pt.lajidui.top/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`上[传傳][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`下[载載][量]?</strong>[::\s]*\s*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td", "td.rowhead:contains('Transfer') + td", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "#info_block a[href*='mybonus.php']", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: lajiduiLevelRequirements, }
View Source
var LemonHDDefinition = &v2.SiteDefinition{ ID: "lemonhd", Name: "LemonHD", Aka: []string{"Lemon"}, Description: "LemonHD 综合影视 PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://lemonhd.net/"}, FaviconURL: "https://lemonhd.net/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "span.nowrap a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "span.nowrap a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"td.rowhead:contains('魔力值') + td", ".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{".bottom .medium", "body"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var MTeamDefinition = &v2.SiteDefinition{ ID: "mteam", Name: "M-Team - TP", Aka: []string{"MTeam", "馒头"}, Description: "综合性网站,有分享率要求", Schema: v2.SchemaMTorrent, RateLimit: 1.0, RateBurst: 3, URLs: []string{ "https://api.m-team.cc", "https://kp.m-team.cc", "https://zp.m-team.io", "https://xp.m-team.cc", "https://ap.m-team.cc", "https://next.m-team.cc", "https://ob.m-team.cc", }, LegacyURLs: []string{"https://xp.m-team.io/", "https://pt.m-team.cc/", "https://tp.m-team.cc/"}, FaviconURL: "https://kp.m-team.cc/favicon.ico", TimezoneOffset: "+0800", UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id", "name", "joinTime"}, RequestDelay: 300, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/api/member/profile", Method: "POST", ResponseType: "json", }, Fields: []string{ "id", "name", "joinTime", "uploaded", "downloaded", "levelName", "levelId", "bonus", "lastAccessAt", }, }, { RequestConfig: v2.RequestConfig{ URL: "/api/tracker/myPeerStatistics", Method: "POST", ResponseType: "json", }, Fields: []string{"seeding", "seedingSize", "uploads"}, }, { RequestConfig: v2.RequestConfig{ URL: "/api/tracker/mybonus", Method: "POST", ResponseType: "json", }, Fields: []string{"bonusPerHour"}, }, { RequestConfig: v2.RequestConfig{ URL: "/api/msg/notify/statistic", Method: "POST", ResponseType: "json", }, Fields: []string{"messageCount"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"data.id"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "name": { Selector: []string{"data.username"}, }, "joinTime": { Selector: []string{"data.createdDate"}, Filters: []v2.Filter{{Name: "parseTime"}}, }, "uploaded": { Selector: []string{"data.memberCount.uploaded"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "downloaded": { Selector: []string{"data.memberCount.downloaded"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "levelName": { Selector: []string{"data.role"}, }, "levelId": { Selector: []string{"data.role"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonus": { Selector: []string{"data.memberCount.bonus"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "lastAccessAt": { Selector: []string{"data.memberStatus.lastBrowse"}, Filters: []v2.Filter{{Name: "parseTime"}}, }, "seeding": { Selector: []string{"data.seederCount"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "seedingSize": { Selector: []string{"data.seederSize"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "uploads": { Selector: []string{"data.uploadCount"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonusPerHour": { Selector: []string{"data.formulaParams.finalBs"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Selector: []string{"data.unMake"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, }, }, LevelRequirements: []v2.SiteLevelRequirement{ { ID: 1, Name: "User", }, { ID: 2, Name: "Power User", Interval: "P4W", Downloaded: "200GB", Ratio: 2, Privilege: "魔力值加成:+1%;可以使用匿名發表候選種子;可以上傳字幕", }, { ID: 3, Name: "Elite User", Interval: "P8W", Downloaded: "400GB", Ratio: 3, Privilege: "魔力值加成:+2%;可以發送邀請;可以管理自己上傳的字幕;可以檢視別人的下載紀錄;可以使用個性條", }, { ID: 4, Name: "Crazy User", Interval: "P12W", Downloaded: "500GB", Ratio: 4, Privilege: "魔力值加成:+3%", }, { ID: 5, Name: "Insane User", Interval: "P16W", Downloaded: "800GB", Ratio: 5, Privilege: "魔力值加成:+4%;可以檢視排行榜", }, { ID: 6, Name: "Veteran User", Interval: "P20W", Downloaded: "1000GB", Ratio: 6, Privilege: "魔力值加成:+5%;封存帳號後不會被刪除帳號", }, { ID: 7, Name: "Extreme User", Interval: "P24W", Downloaded: "2000GB", Ratio: 7, Privilege: "魔力值加成:+6%;永遠保留", }, { ID: 8, Name: "Ultimate User", Interval: "P28W", Downloaded: "2500GB", Ratio: 8, Privilege: "魔力值加成:+7%", }, { ID: 9, Name: "Nexus Master", Interval: "P32W", Downloaded: "3000GB", Ratio: 9, Privilege: "魔力值加成:+8%", }, { ID: 100, Name: "VIP", GroupType: v2.LevelGroupVIP, }, }, }
MTeamDefinition is the site definition for M-Team
View Source
var MTeamLevelIDMap = map[string]string{
"1": "User",
"2": "Power User",
"3": "Elite User",
"4": "Crazy User",
"5": "Insane User",
"6": "Veteran User",
"7": "Extreme User",
"8": "Ultimate User",
"9": "Nexus Master",
"10": "VIP",
}
MTeamLevelIDMap maps API role ID to level name
View Source
var MooKoDefinition = &v2.SiteDefinition{ ID: "mooko", Name: "MooKo", Aka: []string{"MK"}, Description: "MooKo is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL", Schema: v2.SchemaGazelle, URLs: []string{"https://mooko.org/"}, FaviconURL: "https://mooko.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRCalcSeedTime: v2.NewSizeTieredHRCalc( []v2.HRSeedTimeRule{ {MinSizeGB: 0, MaxSizeGB: 10, SeedTimeH: 36}, {MinSizeGB: 10, MaxSizeGB: 20, SeedTimeH: 72}, {MinSizeGB: 20, MaxSizeGB: 50, SeedTimeH: 120}, {MinSizeGB: 50, MaxSizeGB: 200, SeedTimeH: 168}, {MinSizeGB: 200, MaxSizeGB: 0, SeedTimeH: 336}, }, 168, ), }
View Source
var MyPTCCDefinition = &v2.SiteDefinition{ ID: "myptcc", Name: "MyPTCC", Aka: []string{"我的PT", "cc.mypt.cc"}, Description: "我的PT(CC) 人类资源库", Schema: v2.SchemaNexusPHP, URLs: []string{"https://cc.mypt.cc/"}, FaviconURL: "https://cc.mypt.cc/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 72, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "h1 .nowrap b", "h1 b"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)(?:</strong>)?[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`魔力值\s*</font>\s*\[[^\]]*\]\s*[::]\s*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", HRIcon: "img.hitandrun, img[alt*='H&R'], img[title*='H&R']", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font.twoupfree, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var NovaHDDefinition = &v2.SiteDefinition{ ID: "novahd", Name: "NovaHD", Aka: []string{"Nova"}, Description: "NovaHD PT站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://pt.novahd.top/"}, FaviconURL: "https://pt.novahd.top/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{ "name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime", "messageCount", }, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", }, Filters: []v2.Filter{ {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", }, Filters: []v2.Filter{ {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td > font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", }, Filters: []v2.Filter{ {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img", }, Attr: "title", }, "bonus": { Selector: []string{ "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('魔力') + td", "td.rowhead:contains('Bonus') + td", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonusPerHour": { Selector: []string{ "#outer td[rowspan]", "div:contains('你当前每小时能获取')", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Text: "0", Selector: []string{"td[style*='background: red'] a[href*='messages.php']"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td", }, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: novaHDLevelRequirements, }
NovaHDDefinition is the site definition for NovaHD
View Source
var OnePTBADefinition = &v2.SiteDefinition{ ID: "1ptba", Name: "1PTBar", Aka: []string{"壹PT", "1PTBA"}, Description: "分享互联,收获快乐", Schema: v2.SchemaNexusPHP, URLs: []string{"https://1ptba.com/"}, FaviconURL: "https://1ptba.com/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 24, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>分享率</strong>[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('等級') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`魔力值\s*</font>\s*\[[^\]]*\]\s*[::]\s*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "regex", Args: []any{`^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})`}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: onePTBALevelRequirements, }
View Source
var PTLoverDefinition = &v2.SiteDefinition{ ID: "ptlover", Name: "PTLover", Aka: []string{"AFUN", "PT Lover"}, Description: "PTLover 综合资源站", Schema: v2.SchemaNexusPHP, URLs: []string{"https://www.ptlover.cc/"}, FaviconURL: "https://www.ptlover.cc/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "h1 .nowrap b", "h1 b"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"#info_block", "td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)[^\d∞I-]*(?:</font>)?\s*([\d.,]+|∞|Inf)`}}, { Name: "parseNumber", }}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": {Selector: []string{"td.rowhead:contains('喵饼') + td"}, Filters: []v2.Filter{{Name: "parseNumber"}}}, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", HRIcon: "img.hitandrun, img[alt*='H&R'], img[title*='H&R']", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font.twoupfree, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var PTSKITDefinition = &v2.SiteDefinition{ ID: "ptskit", Name: "PTSKIT", Aka: []string{"拾刻"}, Description: "以短剧与影视资源为主的 NexusPHP PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://www.ptskit.org/"}, FaviconURL: "https://www.ptskit.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('上传量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('下载量') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('分享率') + td", "#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等级') + td img", "td.rowhead:contains('Class') + td > img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var RaingfhDefinition = &v2.SiteDefinition{ ID: "raingfh", Name: "RainGFH", Aka: []string{"雨", "raingfh.top"}, Description: "雨 PT 站", Schema: v2.SchemaNexusPHP, URLs: []string{"https://raingfh.top/"}, FaviconURL: "https://raingfh.top/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "bonus", "seeding", "leeching"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "h1 .nowrap b", "h1 b"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"#info_block", "td.rowhead:contains('传输') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`(?:分享率|Ratio)[^\d∞I-]*(?:</font>)?\s*([\d.,]+|∞|Inf)`}}, { Name: "parseNumber", }}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('雨滴') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`雨滴\s*</font>\s*\[[^\]]*\]\s*[::]\s*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td"}, Filters: []v2.Filter{{Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt], td.rowfollow:nth-child(1) img[title]", UploadTime: "td.rowfollow:nth-child(4) span[title]", HRIcon: "img.hitandrun, img[alt*='H&R'], img[title*='H&R']", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font.twoupfree, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var RousiProDefinition = &v2.SiteDefinition{ ID: "rousipro", Name: "Rousi Pro", Aka: []string{"Rousi", "肉丝"}, Description: "综合性PT站点,使用Bearer Token认证", Schema: v2.SchemaRousi, AuthMethod: v2.AuthMethodPasskey, RateLimit: 2.0, RateBurst: 5, URLs: []string{ "https://rousi.pro", }, FaviconURL: "https://rousi.pro/favicon.ico", TimezoneOffset: "+0800", CreateDriver: createRousiDriver, }
View Source
var SoulVoiceDefinition = &v2.SiteDefinition{ ID: "soulvoice", Name: "SoulVoice", Aka: []string{"聆音"}, Description: "致力于建设一个有声资源,电子书为主,学习资料,影视资源为辅的PT分享站", Schema: v2.SchemaNexusPHP, URLs: []string{"https://pt.soulvoice.club/"}, FaviconURL: "https://pt.soulvoice.club/favicon.ico", AuthMethod: v2.AuthMethodCookie, TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, HREnabled: true, HRSeedTimeHours: 72, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"uploaded", "downloaded", "ratio", "levelName", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "downloaded": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}}, }, "ratio": { Selector: []string{"td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`<strong>分享率</strong>[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}}, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td img", "td.rowhead:contains('等級') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`魔力值\s*</font>\s*\[[^\]]*\]\s*[::]\s*([\d.,]+)`}}, {Name: "parseNumber"}}, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{{Name: "regex", Args: []any{`^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})`}}, {Name: "parseTime"}}, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{{Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}}, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:last-of-type, table.torrentname td.embedded > span", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "input[name='torrent_name']", IDSelector: "input[name='detail_torrent_id']", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowhead:contains('基本信息')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: soulvoiceLevelRequirements, }
View Source
var SpringSundayDefinition = &v2.SiteDefinition{ ID: "springsunday", Name: "SpringSunday", Aka: []string{"SSD"}, Description: "Classic Movie Compression Team", Schema: v2.SchemaNexusPHP, RateLimit: 0.5, RateBurst: 2, URLs: []string{"https://springsunday.net/"}, LegacyURLs: []string{"https://hdcmct.org/"}, FaviconURL: "https://springsunday.net/favicon.ico", TimezoneOffset: "+0800", Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "div.torrent-title > a[href*='details.php']", TitleLink: "div.torrent-title > a[href*='details.php']", Subtitle: "div.torrent-smalldescr > span[title]:last-of-type", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "span.torrent-pro-free, span.torrent-pro-2up, span.torrent-pro-50pctdown, span.torrent-pro-30pctdown, span.torrent-pro-2xfree", DiscountEndTime: "div.torrent-title span[style*='DimGray'] span[title]", DownloadLink: "a[href*='download.php']", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow.nowrap span[title]", DetailSubtitle: "td.rowhead:contains('副标题') + td.rowfollow", }, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{ "name", "uploaded", "downloaded", "ratio", "levelName", "seedingBonus", "joinTime", "messageCount", }, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "#info_block a[href*='userdetails.php'] span", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>上传量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>下载量</strong>[::\s]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "td.rowhead:contains('传输') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`<strong>分享率</strong>[::\s]*(?:<font[^>]*>)?([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td img", }, Attr: "title", }, "bonus": { Selector: []string{ "#info_block a[href*='mybonus.php']", }, Attr: "title", Filters: []v2.Filter{ {Name: "regex", Args: []any{`茉莉[::\s]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "bonusPerHour": { Selector: []string{ "h3:contains('当前每小时') + table tbody", "table:has(th:contains('每小时茉莉')) tbody", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`我的数据</b></td>(?:<td[^>]*>[\d.,]*</td>){9}<td[^>]*>([\d.,]+)</td>`}}, {Name: "parseNumber"}, }, }, "seeding": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{ "#info_block", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(\d+)`}}, {Name: "parseNumber"}, }, }, "seedingBonus": { Selector: []string{ "td.rowhead:contains('积分') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`做种积分[::</b>\s]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", }, Filters: []v2.Filter{ {Name: "regex", Args: []any{`^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})`}}, {Name: "parseTime"}, }, }, "messageCount": { Text: "0", Selector: []string{ "body", }, Attr: "html", Filters: []v2.Filter{ {Name: "sumRegexMatches", Args: []any{`你有(\d+)条新`}}, }, }, }, }, LevelRequirements: []v2.SiteLevelRequirement{ { ID: 1, Name: "新人(User)", Privilege: "新用户的默认级别。可以发种,可以请求续种;可以在做种/下载/发布的时候选择匿名模式;可以上传字幕或删除自己上传的字幕;可以更新过期的外部信息。", }, { ID: 2, Name: "精英(Elite)", NameAka: []string{"Elite", "精英"}, Downloaded: "500GB", Ratio: 1.2, Alternative: []v2.AlternativeRequirement{ {SeedingBonus: 100000, Uploads: 1}, {SeedingBonus: 150000}, }, Privilege: "可以在做种/下载/发布的时候选择匿名模式;可以查看用户列表;可以查看排行榜;可以浏览论坛邀请区;自助申请保种员;等级加成 0.05。", }, { ID: 3, Name: "大师(Master)", NameAka: []string{"Master", "大师"}, Downloaded: "1TB", Ratio: 1.2, Alternative: []v2.AlternativeRequirement{ {SeedingBonus: 500000, Uploads: 100}, {SeedingBonus: 1000000}, }, Privilege: "可以访问高级用户论坛,等级加成 0.15。", }, { ID: 4, Name: "神仙(God)", NameAka: []string{"God", "神仙"}, Downloaded: "3TB", Ratio: 2, Alternative: []v2.AlternativeRequirement{ {SeedingBonus: 1200000, Uploads: 300}, {SeedingBonus: 2400000}, }, Privilege: "彩色 ID 特权;可以查看普通日志;等级加成 0.25。", }, { ID: 5, Name: "神王(Immortal)", NameAka: []string{"Immortal", "神王"}, Privilege: "成为当月神王时奖励当时邀请茉莉价格的一半茉莉,最酷炫的动态彩色 ID 特权;常规时期可以购买及发送邀请;等级加成0.35。", }, { ID: 100, Name: "贵宾(VIP)", NameAka: []string{"VIP", "贵宾"}, GroupType: v2.LevelGroupVIP, Privilege: "贵宾(VIP)的权限和神王(Immortal)相同。贵宾(VIP)及其以上等级免除自动降级。", }, }, }
SpringSundayDefinition is the site definition for SpringSunday
View Source
var TMPTDefinition = &v2.SiteDefinition{ ID: "tmpt", Name: "TMPT", Aka: []string{"TMPT", "唐门"}, Description: "唐门影视 PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://tmpt.top/"}, FaviconURL: "https://tmpt.top/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "uploaded", "downloaded", "ratio", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"#info_block", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"#info_block", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"#info_block", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span.subtitle", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var UBitsDefinition = &v2.SiteDefinition{ ID: "ubits", Name: "UBits", Aka: []string{"UBits", "优比特"}, Description: "综合影视 PT 站点", Schema: v2.SchemaNexusPHP, URLs: []string{"https://ubits.club/"}, FaviconURL: "https://ubits.club/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{URL: "/index.php", ResponseType: "document"}, Fields: []string{"id", "name", "uploaded", "downloaded", "ratio", "seeding", "leeching", "bonus"}, }, { RequestConfig: v2.RequestConfig{URL: "/userdetails.php", ResponseType: "document"}, Assertion: map[string]string{"id": "params.id"}, Fields: []string{"name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']"}, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{"a[href*='userdetails.php'][class*='Name']", "#info_block a[href*='userdetails.php']"}, }, "uploaded": { Selector: []string{"#info_block", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{"#info_block", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{"#info_block", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", "td.rowhead:contains('传输') + td", "td.rowhead:contains('傳輸') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio|做种/下载时间比率)[^\d∞]*([\d.,]+|∞|Inf)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{"td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img"}, Attr: "title", }, "bonus": { Selector: []string{"#info_block", "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('Bonus') + td"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:魔力值|Bonus)[^\d]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "joinTime": { Selector: []string{"td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td"}, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>\s*(?:做种数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>\s*(?:下载数:)?(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span.subtitle", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run", "H&R"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, }
View Source
var XingYunGeDefinition = &v2.SiteDefinition{ ID: "xingyunge", Name: "XingYunGe", Aka: []string{"星陨阁"}, Description: "三十年河东,三十年河西!莫欺少年穷!", Schema: v2.SchemaNexusPHP, URLs: []string{"https://pt.xingyungept.org/"}, LegacyURLs: []string{"https://xingyunge.top/"}, FaviconURL: "https://pt.xingyungept.org/favicon.ico", TimezoneOffset: "+0800", RateLimit: 0.5, RateBurst: 2, UserInfo: &v2.UserInfoConfig{ PickLast: []string{"id"}, RequestDelay: 500, Process: []v2.UserInfoProcess{ { RequestConfig: v2.RequestConfig{ URL: "/index.php", ResponseType: "document", }, Fields: []string{"id", "name", "uploaded", "downloaded", "ratio", "seeding", "leeching", "bonusIndex"}, }, { RequestConfig: v2.RequestConfig{ URL: "/userdetails.php", ResponseType: "document", }, Assertion: map[string]string{"id": "params.id"}, Fields: []string{ "name", "uploaded", "downloaded", "ratio", "levelName", "bonus", "joinTime", "messageCount", }, }, { RequestConfig: v2.RequestConfig{ URL: "/mybonus.php", ResponseType: "document", }, Fields: []string{"bonusPerHour"}, }, }, Selectors: map[string]v2.FieldSelector{ "id": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", "a[href*='userdetails.php']", }, Attr: "href", Filters: []v2.Filter{{Name: "querystring", Args: []any{"id"}}}, }, "name": { Selector: []string{ "a[href*='userdetails.php'][class*='Name']", "a.User_Name[href*='userdetails.php']", "#info_block a[href*='userdetails.php']", }, }, "uploaded": { Selector: []string{ "#info_block", "td.rowhead:contains('传输') + td", "td.rowhead:contains('上传量') + td", "td.rowhead:contains('上傳量') + td", "td.rowhead:contains('Uploaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:上传量|上傳量|Uploaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "downloaded": { Selector: []string{ "#info_block", "td.rowhead:contains('传输') + td", "td.rowhead:contains('下载量') + td", "td.rowhead:contains('下載量') + td", "td.rowhead:contains('Downloaded') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:下载量|下載量|Downloaded)[^\d]*([\d.,]+\s*[KMGTP]?i?B)`}}, {Name: "parseSize"}, }, }, "ratio": { Selector: []string{ "#info_block", "td.rowhead:contains('传输') + td", "td.rowhead:contains('分享率') + td font", "td.rowhead:contains('分享率') + td", "td.rowhead:contains('Ratio') + td font", "td.rowhead:contains('Ratio') + td", }, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`(?:分享率|Ratio)[^0-9]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "levelName": { Selector: []string{ "td.rowhead:contains('等级') + td > img", "td.rowhead:contains('等級') + td > img", "td.rowhead:contains('Class') + td > img", "td.rowhead:contains('等级') + td img", }, Attr: "title", }, "bonusIndex": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`星[焰焱]\s*</font>\s*\[<a[^>]*>使用</a>\][::\s]*([\d.,]+)`}}, {Name: "parseNumber"}, }, }, "bonus": { Selector: []string{ "td.rowhead:contains('魔力值') + td", "td.rowhead:contains('星焱') + td", "td.rowhead:contains('Bonus') + td", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "bonusPerHour": { Selector: []string{ "#outer td[rowspan]", "div:contains('你当前每小时能获取')", }, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "messageCount": { Text: "0", Selector: []string{"td[style*='background: red'] a[href*='messages.php']"}, Filters: []v2.Filter{{Name: "parseNumber"}}, }, "joinTime": { Selector: []string{ "td.rowhead:contains('加入日期') + td", "td.rowhead:contains('Join') + td", }, Filters: []v2.Filter{ {Name: "split", Args: []any{" (", 0}}, {Name: "parseTime"}, }, }, "seeding": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowup"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, "leeching": { Selector: []string{"#info_block"}, Attr: "html", Filters: []v2.Filter{ {Name: "regex", Args: []any{`class="arrowdown"[^>]*/>(\d+)`}}, {Name: "parseNumber"}, }, }, }, }, Selectors: &v2.SiteSelectors{ TableRows: "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)", Title: "table.torrentname a[href*='details.php']", TitleLink: "table.torrentname a[href*='details.php']", Subtitle: "table.torrentname td.embedded > span:not(.optiontag)", Size: "td.rowfollow:nth-child(5)", Seeders: "td.rowfollow:nth-child(6)", Leechers: "td.rowfollow:nth-child(7)", Snatched: "td.rowfollow:nth-child(8)", DiscountIcon: "img.pro_free, img.pro_free2up, img.pro_50pctdown, img.pro_30pctdown, img.pro_2up, img.pro_50pctdown2up", Category: "td.rowfollow:nth-child(1) img[alt]", UploadTime: "td.rowfollow:nth-child(4) span[title]", DetailDownloadLink: "td.rowhead:contains('下载') + td a[href*='download.php']", DetailSubtitle: "td.rowhead:contains('副标题') + td", }, DetailParser: &v2.DetailParserConfig{ TimeLayout: "2006-01-02 15:04:05", DiscountMapping: map[string]v2.DiscountLevel{ "free": v2.DiscountFree, "twoup": v2.Discount2xUp, "twoupfree": v2.Discount2xFree, "thirtypercent": v2.DiscountPercent30, "halfdown": v2.DiscountPercent50, "twouphalfdown": v2.Discount2x50, }, HRKeywords: []string{"hitandrun", "hit_run.gif", "Hit and Run", "Hit & Run"}, TitleSelector: "h1", DiscountSelector: "h1 font.free, h1 font[class]", EndTimeSelector: "h1 span[title]", SizeSelector: "td.rowfollow:contains('大小')", SizeRegex: `大小[::]\s*([\d.]+)\s*(GB|MB|KB|TB)`, }, LevelRequirements: xingYunGeLevelRequirements, }
Functions ¶
func GetHDSkyLevelRequirements ¶
func GetHDSkyLevelRequirements(joinTime int64) []v2.SiteLevelRequirement
GetHDSkyLevelRequirements returns appropriate level requirements based on join date
func GetMTeamLevelName ¶
GetMTeamLevelName returns level name from role ID
Types ¶
This section is empty.
Source Files
¶
Click to show internal directories.
Click to hide internal directories.