Skip to content

Commit d0d83e2

Browse files
authored
Merge pull request #12 from NullpointerW/builtin-downloader
builtin-downloader
2 parents b1dec23 + 4eda384 commit d0d83e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1763
-252
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44
output.log
55
build/
66
test/env.yaml
7-
__debug_bin.exe
7+
__debug_bin.exe
8+
*bangumi.log
9+
*.torrent.bolt.db
10+
*panic.log
11+
*output.log

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ NAME=anicat
22
BUILDIR=build
33

44
SRV_FILE=service-exec/service.go
5-
VERSION := $(patsubst v%,%,$(shell git describe --tags || echo "x.x.x"))
5+
VERSION := $(patsubst v%,%,$(shell git describe --tags || echo "unknown"))
66
GOBUILD=CGO_ENABLED=0 go build -ldflags '-X "github.com/NullpointerW/anicat/conf.Ver=$(VERSION)"'
77

88

conf/env.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
var (
16-
Ver = "x.x.x"
16+
Ver = "unknown"
1717
projlk = "https://github.com/NullpointerW/AniCat"
1818
SrvCTL = len(os.Args) > 1 && (os.Args[1] == "install" || os.Args[1] == "uninstall" || os.Args[1] == "start")
1919
)
@@ -59,7 +59,8 @@ type Environment struct {
5959
SkipSSL bool `yaml:"skipssl"`
6060
} `yaml:"email"`
6161
} `yaml:"push"`
62-
BgmiLog bool `yaml:"bangumi-log"`
62+
BgmiLog bool `yaml:"bangumi-log"`
63+
BuiltinDownloader bool `yaml:"builtin-downloader"`
6364
}
6465

6566
func (env *Environment) Print() {
@@ -81,8 +82,10 @@ func (env *Environment) Print() {
8182
log.Info(logStruct, "crawling setting")
8283
logStruct.Clear()
8384
}
84-
logStruct.Append("qbt-webUrl", env.Qbt.Url, "qbt-apiRequestTimeout(ms)", env.Qbt.Timeout)
85-
log.Info(logStruct, "qbt setting")
85+
if !env.BuiltinDownloader {
86+
logStruct.Append("qbt-webUrl", env.Qbt.Url, "qbt-apiRequestTimeout(ms)", env.Qbt.Timeout)
87+
log.Info(logStruct, "qbt setting")
88+
}
8689
}
8790

8891
func (env *Environment) EmailPrint() {

conf/flag.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func flagInit() {
2323
flag.BoolVar(&Testing, "t", false, "testing mode")
2424
testing.Init()
2525
flag.Parse()
26+
27+
// Testing=true
28+
2629
if Testing {
2730
IdeDebugging = true
2831
}

crawl/information/bgmi.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ func DoScrape(url string) (tips map[string]string, err error) {
8484
if ls != nil {
8585
for _, l := range ls {
8686
t := htmlquery.FindOne(l, "./span")
87+
if t == nil {
88+
continue
89+
}
90+
// fmt.Println(t)
8791
tt := htmlquery.InnerText(t)
8892
lt := htmlquery.InnerText(l)
8993
lt = strings.Replace(lt, tt, "", 1)

crawl/information/tmdb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func FloderSearch(typ, searchstr string) (name, date string, err error) {
4949
agent := "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
5050
r.Headers.Set("User-Agent", agent)
5151
r.Headers.Set("Accept-Language", "zh-CN,zh;q=0.9")
52-
log.Info(log.NewUrlStruct(r.URL, "source", "TMDB"), "fetching folderInfo")
52+
log.Info(log.NewUrlStruct(r.URL, "source", "TMDB", "serachstring", searchstr), "fetching folderInfo")
5353
})
5454

5555
c.OnError(func(_ *colly.Response, e error) {

debug/pprof.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package debug
2+
3+
import (
4+
// "fmt"
5+
"fmt"
6+
"net/http"
7+
_ "net/http/pprof"
8+
9+
"github.com/NullpointerW/anicat/conf"
10+
)
11+
12+
func init() {
13+
if conf.IdeDebugging {
14+
go func() {
15+
err := http.ListenAndServe("127.0.0.1:6879", nil)
16+
if err != nil {
17+
panic(err)
18+
}
19+
}()
20+
fmt.Println("pprof enable,listen on localhost:6879/debug/pprof/")
21+
}
22+
23+
}

downloader/builtin/client.go

Lines changed: 121 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,140 @@
1-
package main
1+
package builtin
22

33
import (
4-
"context"
4+
"bufio"
5+
"crypto/rand"
56
"fmt"
6-
"log"
7+
"net/http"
8+
"runtime/debug"
79
"time"
810

11+
CFG "github.com/NullpointerW/anicat/conf"
12+
"github.com/NullpointerW/anicat/log"
913
"github.com/anacrolix/torrent"
14+
"github.com/anacrolix/torrent/storage"
1015
)
1116

12-
func main() {
13-
// Create a new torrent client with default configuration
14-
client, err := torrent.NewClient(nil)
15-
if err != nil {
16-
log.Fatalf("error creating torrent client: %v", err)
17+
var DefaultDownLoader *Downloader
18+
19+
func init() {
20+
if CFG.Env.BuiltinDownloader {
21+
log.Info(log.Struct{"github", "https://github.com/anacrolix/torrent"}, "builtin-enabled, using anacrolix/torrent")
22+
InitDownloader()
23+
}
24+
}
25+
func InitDownloader() {
26+
cfg := &DownloaderConfig{
27+
BaseDir: "./.db",
28+
FakePeerID: true,
29+
NopUpload: true,
30+
Seeker: NewHttpSeeker(),
1731
}
18-
defer client.Close()
32+
DefaultDownLoader = NewDownloader(cfg)
33+
}
34+
35+
type Downloader struct {
36+
client *torrent.Client
37+
TorrentSeeker
38+
extraTrackers [][]string
39+
}
40+
type FileName interface {
41+
Name() storage.FilePathMaker
42+
}
1943

20-
// Define the magnet link
21-
magnetLink := "magnet:?xt=urn:btih:fbc74348498175b4caec790054e922d28312a106&tr=http%3a%2f%2ft.nyaatracker.com%2fannounce&tr=http%3a%2f%2ftracker.kamigami.org%3a2710%2fannounce&tr=http%3a%2f%2fshare.camoe.cn%3a8080%2fannounce&tr=http%3a%2f%2fopentracker.acgnx.se%2fannounce&tr=http%3a%2f%2fanidex.moe%3a6969%2fannounce&tr=http%3a%2f%2ft.acg.rip%3a6699%2fannounce&tr=https%3a%2f%2ftr.bangumi.moe%3a9696%2fannounce&tr=udp%3a%2f%2ftr.bangumi.moe%3a6969%2fannounce&tr=http%3a%2f%2fopen.acgtracker.com%3a1096%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce"
44+
type FileOption interface {
45+
FileName
46+
Dir() storage.TorrentDirFilePathMaker
47+
}
48+
type DownloaderConfig struct {
49+
BaseDir string
50+
Seeker TorrentSeeker
51+
NopUpload bool
52+
FakePeerID bool
53+
}
2254

23-
// Add the magnet link to the client
24-
t, err := client.AddMagnet(magnetLink)
55+
func NewDownloader(c *DownloaderConfig) *Downloader {
56+
cfg := torrent.NewDefaultClientConfig()
57+
cfg.Seed = !c.NopUpload
58+
cfg.NoUpload = c.NopUpload
59+
fop := storage.NewFileClientOpts{}
60+
fop.ClientBaseDir = c.BaseDir
61+
cfg.DefaultStorage = storage.NewFileOpts(fop)
62+
if c.Seeker == nil {
63+
c.Seeker = NewHttpSeeker()
64+
}
65+
if c.FakePeerID {
66+
f := "-qB419E-" // qBittorrent
67+
var b [20]byte
68+
n := copy(b[:], ([]byte)(f))
69+
_, err := rand.Read(b[n:])
70+
if err != nil {
71+
panic("builtin-downloader: error generating peer id")
72+
}
73+
cfg.PeerID = (string)(b[:])
74+
cfg.HTTPUserAgent = "qBittorrent/v4.1.9.14"
75+
mainPath := "github.com/NullpointerW/anicat"
76+
mainVersion := "unknown"
77+
if buildInfo, ok := debug.ReadBuildInfo(); ok {
78+
mainPath = buildInfo.Main.Path
79+
mainVersion = buildInfo.Main.Version
80+
}
81+
exhskVer := fmt.Sprintf(
82+
"%v %v (%v %v)",
83+
mainPath,
84+
mainVersion,
85+
"qBittorrent",
86+
"v4.1.9.14",
87+
)
88+
cfg.ExtendedHandshakeClientVersion = exhskVer
89+
}
90+
client, err := torrent.NewClient(cfg)
2591
if err != nil {
26-
log.Fatalf("error adding magnet link: %v", err)
92+
panic(err)
93+
}
94+
peerIDStr := func(p torrent.PeerID) string {
95+
b := ([20]byte)(p)
96+
// fmt.Println((string)(b[:]))
97+
return string(b[:])
2798
}
2899

29-
// Wait for the torrent information to be fetched or timeout
30-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
31-
defer cancel()
32-
33-
<-t.GotInfo()
34-
t.DownloadAll()
100+
log.Info(log.Struct{"version", cfg.ExtendedHandshakeClientVersion, "userAgent", cfg.HTTPUserAgent, "peerID", peerIDStr(client.PeerID()), "upnpID", cfg.UpnpID}, "torrent-client initialized")
101+
return &Downloader{client, c.Seeker, extraTrackers()}
35102

36-
go func() {
37-
for {
38-
fmt.Printf(" w %d", t.BytesCompleted())
39-
time.Sleep(1 * time.Second)
40-
}
41-
}()
103+
}
42104

43-
select {
44-
case <-t.Complete.On():
45-
log.Println("torrent download complete")
46-
case <-ctx.Done():
47-
log.Println("torrent download timeout")
105+
func (d *Downloader) Download(s string, fOp FileOption, seeker TorrentSeeker) (t *torrent.Torrent, err error) {
106+
var ts *torrent.TorrentSpec
107+
if seeker == nil {
108+
ts, err = d.Seek(s)
109+
} else {
110+
ts, err = seeker.Seek(s)
111+
}
112+
if err != nil {
113+
return nil, err
48114
}
49115

50-
// Stream the torrent content to stdout or handle it as needed
51-
//reader := t.NewReader()
52-
//io.Copy(os.Stdout, reader)
116+
fop := storage.NewFileClientOpts{}
117+
fop.TorrentDirMaker = fOp.Dir()
118+
fop.FilePathMaker = fOp.Name()
119+
fop.PieceCompletion = storage.NewMapPieceCompletion()
120+
ts.Storage = storage.NewFileOpts(fop)
121+
t, _, err = d.client.AddTorrentSpec(ts)
122+
t.AddTrackers(d.extraTrackers)
123+
return
124+
}
125+
func extraTrackers() (trackers [][]string) {
126+
provider := "https://cdn.jsdelivr.net/gh/DeSireFire/animeTrackerList/AT_all.txt"
127+
h := http.Client{Timeout: time.Second * 5}
128+
get, err := h.Get(provider)
129+
if err != nil {
130+
log.Error(log.Struct{"err", err}, "builtin-downloader: set tracker failed")
131+
return nil
132+
}
133+
defer get.Body.Close()
134+
r := bufio.NewScanner(get.Body)
135+
var trackerURLs []string
136+
for r.Scan() {
137+
trackerURLs = append(trackerURLs, r.Text())
138+
}
139+
return append(trackers, trackerURLs)
53140
}

0 commit comments

Comments
 (0)