-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix unsupported protocol version 303 when accessing some sites with j…
…a3; improve public sites support
- Loading branch information
Showing
15 changed files
with
296 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package constants | ||
|
||
// .torrent file magic number. | ||
// See: https://en.wikipedia.org/wiki/Torrent_file , https://en.wikipedia.org/wiki/Bencode . | ||
const TORRENT_FILE_MAGIC_NUMBER = "d8:announce" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package public | ||
|
||
import ( | ||
"net/url" | ||
"regexp" | ||
|
||
"github.com/sagan/ptool/util" | ||
) | ||
|
||
// public Bittorrent sites. add cmd supports adding torrent url of these sites | ||
|
||
type PublicBittorrentSite struct { | ||
Name string | ||
Domains []string // first one of Domains is considered as primary domain | ||
TrackerDomains []string | ||
TorrentDownloadUrl string // placeholders: {{origin}}, {{domain}}, {{id}} | ||
TorrentUrlIdRegexp *regexp.Regexp // extract torrent id (in "id" subgroup) from url | ||
} | ||
|
||
var ( | ||
Sites = []*PublicBittorrentSite{ | ||
{ | ||
Name: "nyaa", | ||
Domains: []string{"sukebei.nyaa.si", "nyaa.si"}, | ||
// https://sukebei.nyaa.si/upload | ||
// https://nyaa.si/upload | ||
TrackerDomains: []string{"sukebei.tracker.wf", "nyaa.tracker.wf"}, | ||
TorrentUrlIdRegexp: regexp.MustCompile(`\bview/(?P<id>\d+)\b`), | ||
TorrentDownloadUrl: `{{origin}}/download/{{id}}.torrent`, | ||
}, | ||
} | ||
// site name & domain (main or tracker) => site | ||
SitesMap = map[string]*PublicBittorrentSite{} | ||
) | ||
|
||
func init() { | ||
for _, btsite := range Sites { | ||
SitesMap[btsite.Name] = btsite | ||
for _, domain := range btsite.Domains { | ||
SitesMap[domain] = btsite | ||
} | ||
for _, domain := range btsite.TrackerDomains { | ||
SitesMap[domain] = btsite | ||
} | ||
} | ||
} | ||
|
||
// Get a site by a website or tracker url or domain. | ||
func GetSiteByDomain(defaultSite string, domainOrUrls ...string) *PublicBittorrentSite { | ||
if SitesMap[defaultSite] != nil { | ||
return SitesMap[defaultSite] | ||
} | ||
for _, domain := range domainOrUrls { | ||
if util.IsUrl(domain) { | ||
if urlObj, err := url.Parse(domain); err != nil { | ||
continue | ||
} else { | ||
domain = urlObj.Hostname() | ||
} | ||
} | ||
if SitesMap[domain] != nil { | ||
return SitesMap[domain] | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package torrenttrader | ||
|
||
// torrenttrader is a legacy torrents software in php | ||
// v3: https://github.com/MicrosoulV3/TorrentTrader-v3 | ||
// used by: aidoru-online.me | ||
// torrent download url: https://aidoru-online.me/download.php?id=12345 | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"strings" | ||
"time" | ||
|
||
"github.com/Noooste/azuretls-client" | ||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/sagan/ptool/config" | ||
"github.com/sagan/ptool/site" | ||
"github.com/sagan/ptool/util" | ||
) | ||
|
||
type Site struct { | ||
Name string | ||
Location *time.Location | ||
SiteConfig *config.SiteConfigStruct | ||
Config *config.ConfigStruct | ||
HttpClient *azuretls.Session | ||
HttpHeaders [][]string | ||
} | ||
|
||
const ( | ||
SELECTOR_USERNAME = `.myBlock:has(a[href$="account.php"]) .myBlock-caption` | ||
SELECTOR_USER_UPLOADED = `.myBlock:has(a[href$="account.php"]) tr:has(td:contains("Uploaded")) td:last-child` | ||
SELECTOR_USER_DOWNLOADED = `.myBlock:has(a[href$="account.php"]) tr:has(td:contains("Downloaded")) td:last-child` | ||
) | ||
|
||
func (usite *Site) GetDefaultHttpHeaders() [][]string { | ||
return usite.HttpHeaders | ||
} | ||
|
||
func (usite *Site) PurgeCache() { | ||
} | ||
|
||
func (usite *Site) GetName() string { | ||
return usite.Name | ||
} | ||
|
||
func (usite *Site) GetSiteConfig() *config.SiteConfigStruct { | ||
return usite.SiteConfig | ||
} | ||
|
||
func (usite *Site) GetStatus() (*site.Status, error) { | ||
doc, _, err := util.GetUrlDocWithAzuretls(usite.SiteConfig.Url, usite.HttpClient, | ||
usite.GetSiteConfig().Cookie, site.GetUa(usite), usite.GetDefaultHttpHeaders()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
userNameSelector := SELECTOR_USERNAME | ||
userUploadedSelector := SELECTOR_USER_UPLOADED | ||
userDownloadedSelector := SELECTOR_USER_DOWNLOADED | ||
if usite.SiteConfig.SelectorUserInfoUserName != "" { | ||
userNameSelector = usite.SiteConfig.SelectorUserInfoUserName | ||
} | ||
if usite.SiteConfig.SelectorUserInfoUploaded != "" { | ||
userUploadedSelector = usite.SiteConfig.SelectorUserInfoUploaded | ||
} | ||
if usite.SiteConfig.SelectorUserInfoDownloaded != "" { | ||
userDownloadedSelector = usite.SiteConfig.SelectorUserInfoDownloaded | ||
} | ||
usernameEl := doc.Find(userNameSelector) | ||
uploadedEl := doc.Find(userUploadedSelector) | ||
downloadedEl := doc.Find(userDownloadedSelector) | ||
userUploaded, _ := util.ExtractSizeStr(util.DomSanitizedText(uploadedEl)) | ||
userDownloaded, _ := util.ExtractSizeStr(util.DomSanitizedText(downloadedEl)) | ||
return &site.Status{ | ||
UserName: util.DomSanitizedText(usernameEl), | ||
UserUploaded: userUploaded, | ||
UserDownloaded: userDownloaded, | ||
}, nil | ||
} | ||
|
||
func (usite *Site) GetAllTorrents(sort string, desc bool, pageMarker string, baseUrl string) ( | ||
torrents []site.Torrent, nextPageMarker string, err error) { | ||
return nil, "", fmt.Errorf("not implemented yet") | ||
} | ||
|
||
func (usite *Site) GetLatestTorrents(full bool) ([]site.Torrent, error) { | ||
return nil, fmt.Errorf("not implemented yet") | ||
} | ||
|
||
func (usite *Site) SearchTorrents(keyword string, baseUrl string) ([]site.Torrent, error) { | ||
return nil, fmt.Errorf("not implemented yet") | ||
} | ||
|
||
func (usite *Site) DownloadTorrent(torrentUrl string) (content []byte, filename string, id string, err error) { | ||
if !util.IsUrl(torrentUrl) { | ||
id = strings.TrimPrefix(torrentUrl, usite.GetName()+".") | ||
content, filename, err = usite.DownloadTorrentById(id) | ||
return | ||
} | ||
if urlObj, err := url.Parse(torrentUrl); err == nil { | ||
id = urlObj.Query().Get("id") | ||
} | ||
if !strings.Contains(torrentUrl, "/download.php") && id != "" { | ||
content, filename, err = usite.DownloadTorrentById(id) | ||
return | ||
} | ||
content, filename, err = site.DownloadTorrentByUrl(usite, usite.HttpClient, torrentUrl, id) | ||
return | ||
} | ||
|
||
func (usite *Site) DownloadTorrentById(id string) ([]byte, string, error) { | ||
torrentUrl := usite.SiteConfig.ParseSiteUrl("download.php?id="+id, false) | ||
return site.DownloadTorrentByUrl(usite, usite.HttpClient, torrentUrl, id) | ||
} | ||
|
||
func NewSite(name string, siteConfig *config.SiteConfigStruct, config *config.ConfigStruct) (site.Site, error) { | ||
if siteConfig.Cookie == "" { | ||
log.Warnf("Site %s has no cookie provided", name) | ||
} | ||
location, err := time.LoadLocation(siteConfig.GetTimezone()) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid site timezone %s: %v", siteConfig.GetTimezone(), err) | ||
} | ||
httpClient, httpHeaders, err := site.CreateSiteHttpClient(siteConfig, config) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create site http client: %v", err) | ||
} | ||
site := &Site{ | ||
Name: name, | ||
Location: location, | ||
SiteConfig: siteConfig, | ||
Config: config, | ||
HttpClient: httpClient, | ||
HttpHeaders: httpHeaders, | ||
} | ||
return site, nil | ||
} | ||
|
||
func init() { | ||
site.Register(&site.RegInfo{ | ||
Name: "torrenttrader", | ||
Creator: NewSite, | ||
}) | ||
} |
Oops, something went wrong.