From abdec0544507a174615d185f1c52de7b5e936bc4 Mon Sep 17 00:00:00 2001 From: Xpl0itU <24777100+Xpl0itU@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:04:39 +0100 Subject: [PATCH] Revert aria2go changes --- .github/workflows/windows.yml | 2 +- .gitignore | 2 - Dockerfile.linux | 3 +- certificate.go | 9 +- cmd/WiiUDownloader/main.go | 16 +- cmd/WiiUDownloader/mainwindow.go | 23 +- cmd/WiiUDownloader/progressWindow.go | 18 +- data/Info.plist | 8 +- downloader.go | 142 +++++------- go.mod | 9 - go.sum | 4 - grabTitles.py | 24 +- pkg/aria2go/LICENSE | 201 ---------------- pkg/aria2go/aria2_c.cc | 323 -------------------------- pkg/aria2go/aria2_c.h | 72 ------ pkg/aria2go/go.mod | 7 - pkg/aria2go/go.sum | 2 - pkg/aria2go/libaria2.go | 333 --------------------------- pkg/aria2go/models.go | 51 ---- pkg/aria2go/notifier.go | 58 ----- prepare_aria.sh | 118 ---------- 21 files changed, 92 insertions(+), 1333 deletions(-) delete mode 100644 pkg/aria2go/LICENSE delete mode 100644 pkg/aria2go/aria2_c.cc delete mode 100644 pkg/aria2go/aria2_c.h delete mode 100644 pkg/aria2go/go.mod delete mode 100644 pkg/aria2go/go.sum delete mode 100644 pkg/aria2go/libaria2.go delete mode 100644 pkg/aria2go/models.go delete mode 100644 pkg/aria2go/notifier.go delete mode 100755 prepare_aria.sh diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 5785695..1d1e78b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -25,7 +25,7 @@ jobs: msystem: UCRT64 release: true update: true - install: zip git mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-python mingw-w64-ucrt-x86_64-gtk3 mingw-w64-ucrt-x86_64-pkg-config mingw-w64-ucrt-x86_64-go mingw-w64-ucrt-x86_64-ntldd-git make + install: zip git mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-python mingw-w64-ucrt-x86_64-gtk3 mingw-w64-ucrt-x86_64-pkg-config mingw-w64-ucrt-x86_64-go mingw-w64-ucrt-x86_64-ntldd-git - name: Build run: | python3 grabTitles.py diff --git a/.gitignore b/.gitignore index 3b599dc..b710d90 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,3 @@ main *.a out/ log.txt -aria2-lib/ -_obj/ \ No newline at end of file diff --git a/Dockerfile.linux b/Dockerfile.linux index 5d34135..8e299a4 100644 --- a/Dockerfile.linux +++ b/Dockerfile.linux @@ -1,8 +1,7 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive \ - PATH="$HOME/go/bin:/usr/local/go/bin:$PATH" \ - LD_LIBRARY_PATH="$LD_LIBRARY_PATH:pkg/aria2go/aria2-lib/lib" + PATH="$HOME/go/bin:/usr/local/go/bin:$PATH" RUN mkdir -p /usr/share/man/man1 /usr/share/man/man2 && \ apt -y --no-install-recommends update && \ diff --git a/certificate.go b/certificate.go index 5125f68..205a2e2 100644 --- a/certificate.go +++ b/certificate.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "net/http" "os" "path" ) @@ -27,12 +28,12 @@ func getCert(tmdData []byte, id int, numContents uint16) ([]byte, error) { } } -func getDefaultCert(cancelCtx context.Context, progressReporter ProgressReporter, buffer []byte, ariaSessionPath string) ([]byte, error) { +func getDefaultCert(cancelCtx context.Context, progressReporter ProgressReporter, client *http.Client, buffer []byte) ([]byte, error) { if len(cetkData) >= 0x350+0x300 { return cetkData[0x350 : 0x350+0x300], nil } cetkDir := path.Join(os.TempDir(), "cetk") - if err := downloadFile(cancelCtx, progressReporter, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/000500101000400a/cetk", cetkDir, true, buffer, ariaSessionPath); err != nil { + if err := downloadFile(cancelCtx, progressReporter, client, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/000500101000400a/cetk", cetkDir, true, buffer); err != nil { return nil, err } cetkData, err := os.ReadFile(cetkDir) @@ -50,7 +51,7 @@ func getDefaultCert(cancelCtx context.Context, progressReporter ProgressReporter return nil, fmt.Errorf("failed to download OSv10 cetk, length: %d", len(cetkData)) } -func GenerateCert(tmdData []byte, contentCount uint16, progressReporter ProgressReporter, cancelCtx context.Context, buffer []byte, ariaSessionPath string) (bytes.Buffer, error) { +func GenerateCert(tmdData []byte, contentCount uint16, progressReporter ProgressReporter, client *http.Client, cancelCtx context.Context, buffer []byte) (bytes.Buffer, error) { cert := bytes.Buffer{} cert0, err := getCert(tmdData, 0, contentCount) @@ -65,7 +66,7 @@ func GenerateCert(tmdData []byte, contentCount uint16, progressReporter Progress } cert.Write(cert1) - defaultCert, err := getDefaultCert(cancelCtx, progressReporter, buffer, ariaSessionPath) + defaultCert, err := getDefaultCert(cancelCtx, progressReporter, client, buffer) if err != nil { return bytes.Buffer{}, err } diff --git a/cmd/WiiUDownloader/main.go b/cmd/WiiUDownloader/main.go index 256acaf..7ffcbab 100644 --- a/cmd/WiiUDownloader/main.go +++ b/cmd/WiiUDownloader/main.go @@ -2,9 +2,11 @@ package main import ( "fmt" + "net/http" "os" "path/filepath" "runtime" + "time" wiiudownloader "github.com/Xpl0itU/WiiUDownloader" "github.com/gotk3/gotk3/glib" @@ -40,15 +42,17 @@ func main() { logger.Fatal(err.Error()) } - tmpDir, err := os.MkdirTemp("", "wiiudownloader") - if err != nil { - logger.Fatal(err.Error()) + client := &http.Client{ + Transport: &http.Transport{ + MaxIdleConns: 1000, + MaxIdleConnsPerHost: 1000, + MaxConnsPerHost: 100, + }, + Timeout: 30 * time.Second, } - defer os.RemoveAll(tmpDir) - ariaSessionPath := filepath.Join(tmpDir, "wiiudownloader.session") app.Connect("activate", func() { - win := NewMainWindow(app, wiiudownloader.GetTitleEntries(wiiudownloader.TITLE_CATEGORY_GAME), logger, ariaSessionPath) + win := NewMainWindow(app, wiiudownloader.GetTitleEntries(wiiudownloader.TITLE_CATEGORY_GAME), logger, client) win.ShowAll() app.AddWindow(win.window) app.GetActiveWindow().Show() diff --git a/cmd/WiiUDownloader/mainwindow.go b/cmd/WiiUDownloader/mainwindow.go index 9fd06ca..3fc598c 100644 --- a/cmd/WiiUDownloader/mainwindow.go +++ b/cmd/WiiUDownloader/mainwindow.go @@ -5,6 +5,7 @@ import ( "context" "encoding/binary" "fmt" + "net/http" "os" "path/filepath" "strconv" @@ -39,10 +40,10 @@ type MainWindow struct { titles []wiiudownloader.TitleEntry decryptContents bool currentRegion uint8 - ariaSessionPath string + client *http.Client } -func NewMainWindow(app *gtk.Application, entries []wiiudownloader.TitleEntry, logger *wiiudownloader.Logger, ariaSessionPath string) *MainWindow { +func NewMainWindow(app *gtk.Application, entries []wiiudownloader.TitleEntry, logger *wiiudownloader.Logger, client *http.Client) *MainWindow { gSettings, err := gtk.SettingsGetDefault() if err != nil { logger.Error(err.Error()) @@ -66,13 +67,13 @@ func NewMainWindow(app *gtk.Application, entries []wiiudownloader.TitleEntry, lo } mainWindow := MainWindow{ - window: win, - titles: entries, - searchEntry: searchEntry, - currentRegion: wiiudownloader.MCP_REGION_EUROPE | wiiudownloader.MCP_REGION_JAPAN | wiiudownloader.MCP_REGION_USA, - logger: logger, - lastSearchText: "", - ariaSessionPath: ariaSessionPath, + window: win, + titles: entries, + searchEntry: searchEntry, + currentRegion: wiiudownloader.MCP_REGION_EUROPE | wiiudownloader.MCP_REGION_JAPAN | wiiudownloader.MCP_REGION_USA, + logger: logger, + lastSearchText: "", + client: client, } searchEntry.Connect("changed", mainWindow.onSearchEntryChanged) @@ -264,7 +265,7 @@ func (mw *MainWindow) ShowAll() { wiiudownloader.GenerateTicket(filepath.Join(parentDir, "title.tik"), titleID, titleKey, titleVersion) - cert, err := wiiudownloader.GenerateCert(tmdData, contentCount, mw.progressWindow, context.Background(), make([]byte, 0), mw.ariaSessionPath) + cert, err := wiiudownloader.GenerateCert(tmdData, contentCount, mw.progressWindow, http.DefaultClient, context.Background(), make([]byte, 0)) if err != nil { return } @@ -759,7 +760,7 @@ func (mw *MainWindow) onDownloadQueueClicked(selectedPath string) error { } tidStr := fmt.Sprintf("%016x", title.TitleID) titlePath := filepath.Join(selectedPath, fmt.Sprintf("%s [%s] [%s]", normalizeFilename(title.Name), wiiudownloader.GetFormattedKind(title.TitleID), tidStr)) - if err := wiiudownloader.DownloadTitle(queueCtx, tidStr, titlePath, mw.decryptContents, mw.progressWindow, mw.getDeleteEncryptedContents(), mw.logger, mw.ariaSessionPath); err != nil && err != context.Canceled { + if err := wiiudownloader.DownloadTitle(queueCtx, tidStr, titlePath, mw.decryptContents, mw.progressWindow, mw.getDeleteEncryptedContents(), mw.logger, mw.client); err != nil && err != context.Canceled { return err } diff --git a/cmd/WiiUDownloader/progressWindow.go b/cmd/WiiUDownloader/progressWindow.go index 2d2dc6b..779ea2e 100644 --- a/cmd/WiiUDownloader/progressWindow.go +++ b/cmd/WiiUDownloader/progressWindow.go @@ -3,15 +3,12 @@ package main import ( "context" "fmt" - "time" "github.com/dustin/go-humanize" "github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/gtk" ) -const smoothingFactor = 0.1 - type ProgressWindow struct { Window *gtk.Window box *gtk.Box @@ -22,8 +19,6 @@ type ProgressWindow struct { cancelFunc context.CancelFunc totalToDownload int64 totalDownloaded int64 - lastUpdateTime time.Time - averageSpeed float64 } func (pw *ProgressWindow) SetGameTitle(title string) { @@ -40,19 +35,8 @@ func (pw *ProgressWindow) UpdateDownloadProgress(downloaded, speed int64, filePa pw.cancelButton.SetSensitive(true) currentDownload := downloaded + pw.totalDownloaded pw.bar.SetFraction(float64(currentDownload) / float64(pw.totalToDownload)) - - pw.averageSpeed = smoothingFactor*float64(speed) + (1-smoothingFactor)*pw.averageSpeed - - pw.bar.SetText(fmt.Sprintf("Downloading %s (%s/%s) (%s/s)", - filePath, - humanize.Bytes(uint64(currentDownload)), - humanize.Bytes(uint64(pw.totalToDownload)), - humanize.Bytes(uint64(pw.averageSpeed)), - )) - - pw.lastUpdateTime = time.Now() + pw.bar.SetText(fmt.Sprintf("Downloading %s (%s/%s) (%s/s)", filePath, humanize.Bytes(uint64(currentDownload)), humanize.Bytes(uint64(pw.totalToDownload)), humanize.Bytes(uint64(speed)))) }) - for gtk.EventsPending() { gtk.MainIteration() } diff --git a/data/Info.plist b/data/Info.plist index c9e5835..92ae8fa 100644 --- a/data/Info.plist +++ b/data/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable WiiUDownloader CFBundleGetInfoString - 2.30, Copyright 2022-2024 Xpl0itU + 2.29, Copyright 2022-2023 Xpl0itU CFBundleIconFile WiiUDownloader.icns CFBundleIdentifier @@ -17,13 +17,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.30 + 2.29 CFBundleSignature ???? CFBundleVersion - 2.30 + 2.29 NSHumanReadableCopyright - Copyright 2022-2024 Xpl0itU, GNU General Public License. + Copyright 2022-2023 Xpl0itU, GNU General Public License. LSMinimumSystemVersion 11.0 diff --git a/downloader.go b/downloader.go index fe06d4f..113ccfb 100644 --- a/downloader.go +++ b/downloader.go @@ -8,14 +8,12 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "io" + "net/http" "os" - "os/signal" "path/filepath" "strings" - "syscall" "time" - - "github.com/jaskaranSM/aria2go" ) const ( @@ -35,38 +33,6 @@ type ProgressReporter interface { AddToTotalDownloaded(toAdd int64) } -type Aria2gocNotifier struct { - start chan string - complete chan bool -} - -func newAria2goNotifier(start chan string, complete chan bool) aria2go.Notifier { - return Aria2gocNotifier{ - start: start, - complete: complete, - } -} - -func (n Aria2gocNotifier) OnStart(gid string) { - n.start <- gid -} - -func (n Aria2gocNotifier) OnPause(gid string) { - return -} - -func (n Aria2gocNotifier) OnStop(gid string) { - return -} - -func (n Aria2gocNotifier) OnComplete(gid string) { - n.complete <- false -} - -func (n Aria2gocNotifier) OnError(gid string) { - n.complete <- true -} - func calculateDownloadSpeed(downloaded int64, startTime, endTime time.Time) int64 { duration := endTime.Sub(startTime).Seconds() if duration > 0 { @@ -75,75 +41,73 @@ func calculateDownloadSpeed(downloaded int64, startTime, endTime time.Time) int6 return 0 } -func downloadFile(ctx context.Context, progressReporter ProgressReporter, downloadURL, dstPath string, doRetries bool, buffer []byte, ariaSessionPath string) error { - fileName := filepath.Base(dstPath) +func downloadFile(ctx context.Context, progressReporter ProgressReporter, client *http.Client, downloadURL, dstPath string, doRetries bool, buffer []byte) error { + filePath := filepath.Base(dstPath) var startTime time.Time for attempt := 1; attempt <= maxRetries; attempt++ { - client := aria2go.NewAria2(aria2go.Config{ - Options: aria2go.Options{ - "save-session": ariaSessionPath, - }, - }) - - gid, err := client.AddUri(downloadURL, aria2go.Options{ - "dir": filepath.Dir(dstPath), - "out": fileName, - "continue": "true", - }) + req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil) if err != nil { return err } - go func() { - defer client.Shutdown() - client.Run() - }() + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() - startNotif := make(chan string) - completeNotif := make(chan bool) - go func() { - quit := make(chan os.Signal, 1) - signal.Notify(quit, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) + if resp.StatusCode != http.StatusOK { + if doRetries && attempt < maxRetries { + time.Sleep(retryDelay) + continue + } + return fmt.Errorf("download error after %d attempts, status code: %d", attempt, resp.StatusCode) + } - <-quit - completeNotif <- true - }() - client.SetNotifier(newAria2goNotifier(startNotif, completeNotif)) + file, err := os.Create(dstPath) + if err != nil { + return err + } + defer file.Close() + + var downloaded int64 startTime = time.Now() - ticker := time.NewTicker(time.Millisecond * 500) - defer ticker.Stop() - loop: for { - select { - case id := <-startNotif: - gid = id - case <-ticker.C: - downloaded := client.GetDownloadInfo(gid).BytesCompleted - progressReporter.UpdateDownloadProgress(downloaded, calculateDownloadSpeed(downloaded, startTime, time.Now()), fileName) - case errored := <-completeNotif: - if errored { - if doRetries && attempt < maxRetries { - time.Sleep(retryDelay) - break loop - } - return fmt.Errorf("write error after %d attempts: %+v", attempt, client.GetDownloadInfo(gid).ErrorCode) + n, err := resp.Body.Read(buffer) + if err != nil && err != io.EOF { + if doRetries && attempt < maxRetries { + time.Sleep(retryDelay) + break } - downloaded := client.GetDownloadInfo(gid).BytesCompleted - progressReporter.UpdateDownloadProgress(downloaded, calculateDownloadSpeed(downloaded, startTime, time.Now()), fileName) - return nil - case <-ctx.Done(): - return nil + return fmt.Errorf("download error after %d attempts: %+v", attempt, err) } + + if n == 0 { + break + } + + _, err = file.Write(buffer[:n]) + if err != nil { + if doRetries && attempt < maxRetries { + time.Sleep(retryDelay) + break + } + return fmt.Errorf("write error after %d attempts: %+v", attempt, err) + } + + downloaded += int64(n) + progressReporter.UpdateDownloadProgress(downloaded, calculateDownloadSpeed(downloaded, startTime, time.Now()), filePath) } + break } return nil } -func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, doDecryption bool, progressReporter ProgressReporter, deleteEncryptedContents bool, logger *Logger, ariaSessionPath string) error { +func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, doDecryption bool, progressReporter ProgressReporter, deleteEncryptedContents bool, logger *Logger, client *http.Client) error { titleEntry := getTitleEntryFromTid(titleID) progressReporter.SetTotalDownloaded(0) @@ -163,7 +127,7 @@ func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, d buffer := make([]byte, bufferSize) tmdPath := filepath.Join(outputDir, "title.tmd") - if err := downloadFile(cancelCtx, progressReporter, fmt.Sprintf("%s/%s", baseURL, "tmd"), tmdPath, true, buffer, ariaSessionPath); err != nil { + if err := downloadFile(cancelCtx, progressReporter, client, fmt.Sprintf("%s/%s", baseURL, "tmd"), tmdPath, true, buffer); err != nil { if progressReporter.Cancelled() { return nil } @@ -181,7 +145,7 @@ func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, d } tikPath := filepath.Join(outputDir, "title.tik") - if err := downloadFile(cancelCtx, progressReporter, fmt.Sprintf("%s/%s", baseURL, "cetk"), tikPath, false, buffer, ariaSessionPath); err != nil { + if err := downloadFile(cancelCtx, progressReporter, client, fmt.Sprintf("%s/%s", baseURL, "cetk"), tikPath, false, buffer); err != nil { if progressReporter.Cancelled() { return nil } @@ -220,7 +184,7 @@ func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, d progressReporter.SetDownloadSize(int64(titleSize)) - cert, err := GenerateCert(tmdData, contentCount, progressReporter, cancelCtx, buffer, ariaSessionPath) + cert, err := GenerateCert(tmdData, contentCount, progressReporter, client, cancelCtx, buffer) if err != nil { if progressReporter.Cancelled() { return nil @@ -264,7 +228,7 @@ func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, d return err } filePath := filepath.Join(outputDir, fmt.Sprintf("%08X.app", id)) - if err := downloadFile(cancelCtx, progressReporter, fmt.Sprintf("%s/%08X", baseURL, id), filePath, true, buffer, ariaSessionPath); err != nil { + if err := downloadFile(cancelCtx, progressReporter, client, fmt.Sprintf("%s/%08X", baseURL, id), filePath, true, buffer); err != nil { if progressReporter.Cancelled() { break } @@ -274,7 +238,7 @@ func DownloadTitle(cancelCtx context.Context, titleID, outputDirectory string, d if tmdData[offset+7]&0x2 == 2 { filePath = filepath.Join(outputDir, fmt.Sprintf("%08X.h3", id)) - if err := downloadFile(cancelCtx, progressReporter, fmt.Sprintf("%s/%08X.h3", baseURL, id), filePath, true, buffer, ariaSessionPath); err != nil { + if err := downloadFile(cancelCtx, progressReporter, client, fmt.Sprintf("%s/%08X.h3", baseURL, id), filePath, true, buffer); err != nil { if progressReporter.Cancelled() { break } diff --git a/go.mod b/go.mod index cd35228..a376617 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,6 @@ require ( golang.org/x/crypto v0.17.0 ) -require github.com/ianlancetaylor/cgosymbolizer v0.0.0-20231130194700-cfcb2fd150eb // indirect - -require ( - github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b // indirect - github.com/jaskaranSM/aria2go v0.0.0-20210417130736-a4fd19b6cb10 -) - -replace github.com/jaskaranSM/aria2go => ./pkg/aria2go - require ( github.com/TheTitanrain/w32 v0.0.0-20200114052255-2654d97dbd3d // indirect golang.org/x/sync v0.5.0 diff --git a/go.sum b/go.sum index 6a9c0cf..be69bf4 100644 --- a/go.sum +++ b/go.sum @@ -2,14 +2,10 @@ github.com/TheTitanrain/w32 v0.0.0-20200114052255-2654d97dbd3d h1:2xp1BQbqcDDaik github.com/TheTitanrain/w32 v0.0.0-20200114052255-2654d97dbd3d/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I= github.com/Xpl0itU/dialog v0.0.0-20230805114139-ec888310aded h1:GkBw5aNvID1+SKAD3xC5fU4EwMgOmkrvICy5NX3Rqvw= github.com/Xpl0itU/dialog v0.0.0-20230805114139-ec888310aded/go.mod h1:Yl652wzqaetwEMJ8FnDRKBK1+CisE+PU5BGJXItbYFg= -github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b h1:5JgaFtHFRnOPReItxvhMDXbvuBkjSWE+9glJyF466yw= -github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b/go.mod h1:eMD2XUcPsHYbakFEocKrWZp47G0MRJYoC60qFblGjpA= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gotk3/gotk3 v0.6.2 h1:sx/PjaKfKULJPTPq8p2kn2ZbcNFxpOJqi4VLzMbEOO8= github.com/gotk3/gotk3 v0.6.2/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= -github.com/ianlancetaylor/cgosymbolizer v0.0.0-20231130194700-cfcb2fd150eb h1:asfjGoPvNgSPvgbBiwFqMUOgWgid8xlQGCGHfgM/PAs= -github.com/ianlancetaylor/cgosymbolizer v0.0.0-20231130194700-cfcb2fd150eb/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= diff --git a/grabTitles.py b/grabTitles.py index 127ca60..9de6908 100644 --- a/grabTitles.py +++ b/grabTitles.py @@ -6,13 +6,11 @@ import ssl # Don't edit below this line - def checkAndDeleteFile(file): if os.path.exists(file): print(f"Deleting {file}") os.remove(file) - # Disable certificate verification ssl_context = ssl.create_default_context() ssl_context.check_hostname = False @@ -24,25 +22,13 @@ urllib.request.install_opener(opener) checkAndDeleteFile("gtitles/gtitles.c") urllib.request.urlretrieve("https://napi.nbg01.v10lator.de/db", "gtitles/gtitles.c") -os.system( - "gcc -c -Wall -fpic -Ofast -pipe -Igtitles -o gtitles/gtitles.o gtitles/gtitles.c" -) +os.system("gcc -c -Wall -fpic -Ofast -pipe -Igtitles -o gtitles/gtitles.o gtitles/gtitles.c") os.system("ar rcs libgtitles.a gtitles/gtitles.o") os.system("gcc -shared -o gtitles/libgtitles.so gtitles/gtitles.o") -os.system( - "gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/aes.o cdecrypt/aes.c" -) -os.system( - "gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/cdecrypt.o cdecrypt/cdecrypt.c" -) -os.system( - "gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/sha1.o cdecrypt/sha1.c" -) -os.system( - "gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/util.o cdecrypt/util.c" -) +os.system("gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/aes.o cdecrypt/aes.c") +os.system("gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/cdecrypt.o cdecrypt/cdecrypt.c") +os.system("gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/sha1.o cdecrypt/sha1.c") +os.system("gcc -c -Wall -fpic -Ofast -pipe -UNDEBUG -DAES_ROM_TABLES -D_GNU_SOURCE -Icdecrypt -o cdecrypt/util.o cdecrypt/util.c") os.system("ar rcs libcdecrypt.a cdecrypt/*.o") os.system("gcc -shared -o cdecrypt/libcdecrypt.so cdecrypt/*.o") - -os.system("bash prepare_aria.sh") diff --git a/pkg/aria2go/LICENSE b/pkg/aria2go/LICENSE deleted file mode 100644 index 20be111..0000000 --- a/pkg/aria2go/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (C) 2019 Vincent Chueng (coolingfall@gmail.com) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/pkg/aria2go/aria2_c.cc b/pkg/aria2go/aria2_c.cc deleted file mode 100644 index ab95ed4..0000000 --- a/pkg/aria2go/aria2_c.cc +++ /dev/null @@ -1,323 +0,0 @@ -#include "aria2_c.h" -#include "_cgo_export.h" -#include -#include -#include -#include -#include - -pthread_mutex_t access_mutex; - - - -std::vector splitBySemicolon(std::string in) { - std::string val; - std::stringstream is(in); - std::vector out; - - while (getline(is, val, ';')) { - out.push_back(val); - } - return out; -} - -const char *toCStr(std::string in) { - int len = in.length(); - char *val = new char[len + 1]; - memcpy(val, in.data(), len); - val[len] = '\0'; - return val; -} - -const char *getFileName(std::string dir, std::string path) { - if (path.find(dir, 0) == std::string::npos) { - return toCStr(path); - } - int index = dir.size(); - std::string name = path.substr(index + 1); - return toCStr(name); -} - -const char *toAria2goOptions(aria2::KeyVals options) { - std::vector>::iterator it; - - std::string cOptions; - for (it = options.begin(); it != options.end(); it++) { - std::pair p = *it; - cOptions += p.first + ";" + p.second + ";"; - } - - return toCStr(cOptions); -} - -aria2::KeyVals toAria2Options(const char *options) { - aria2::KeyVals aria2Options; - - if (options == nullptr) { - return aria2Options; - } - - std::vector o = splitBySemicolon(std::string(options)); - /* key and val should be pair */ - if (o.size() % 2 != 0) { - return aria2Options; - } - - for (int i = 0; i < (int)o.size(); i += 2) { - std::string key = o[i]; - std::string val = o[i + 1]; - aria2Options.push_back(std::make_pair(key, val)); - } - - return aria2Options; -} - -struct FileInfo *parseFileData(aria2::DownloadHandle *dh) { - std::string dir = dh->getDir(); - std::vector files = dh->getFiles(); - int numFiles = dh->getNumFiles(); - struct FileInfo *allFiles = new FileInfo[numFiles]; - for (int i = 0; i < numFiles; i++) { - aria2::FileData file = files[i]; - struct FileInfo *fi = new FileInfo(); - fi->index = file.index; - fi->name = getFileName(dir, file.path); - fi->length = file.length; - fi->completedLength = file.completedLength; - fi->selected = file.selected; - - allFiles[i] = *fi; - delete fi; - } - return allFiles; -} - -/* retrieve all BitTorrent meta information */ -struct MetaInfo *parseMetaInfo(aria2::BtMetaInfoData btMetaInfo) { - struct MetaInfo *mi = new MetaInfo(); - mi->name = toCStr(btMetaInfo.name); - mi->comment = toCStr(btMetaInfo.comment); - mi->creationUnix = btMetaInfo.creationDate; - std::vector> announceList = btMetaInfo.announceList; - std::vector>::iterator it; - std::string cAnnounceList; - for (it = announceList.begin(); it != announceList.end(); it++) { - std::vector::iterator cit; - std::vector childList = *it; - for (cit = childList.begin(); cit != childList.end(); cit++) { - cAnnounceList += *cit; - if (it != announceList.end() - 1 || cit != childList.end() - 1) { - cAnnounceList += ";"; - } - } - } - mi->announceList = toCStr(cAnnounceList); - return mi; -} - -/** - * Global aria2 session. - */ -aria2::Session *session; -/** - * Global aria2go go pointer. - */ -uint64_t aria2goPointer; - -/** - * Download event callback for aria2. - */ -int downloadEventCallback(aria2::Session *session, aria2::DownloadEvent event, - const aria2::A2Gid gid, void *userData) { - notifyEvent(aria2goPointer, gid, event); - return 0; -} - -/** - * Initial aria2 library. - */ -int init(uint64_t pointer, const char *options) { - aria2goPointer = pointer; - int ret = aria2::libraryInit(); - aria2::SessionConfig config; - config.keepRunning = true; - /* do not use signal handler, cause c will block go */ - config.useSignalHandler = false; - config.downloadEventCallback = downloadEventCallback; - session = aria2::sessionNew(toAria2Options(options), config); - return ret; -} - -/** - * Shutdown schedules. This will cause run finished. - */ -int shutdownSchedules(bool force) { return aria2::shutdown(session, force); } - -/** - * Deinit aria2 library, this must be invoked when process exit(signal handler - * is not used), so aria2 will be able to save session config. - */ -int deinit() { - int ret = aria2::sessionFinal(session); - session = nullptr; - aria2::libraryDeinit(); - return ret; -} - -/** - * Adds new HTTP(S)/FTP/BitTorrent Magnet URI. See `addUri` in aria2. - * - * @param uri uri to add - */ -uint64_t addUri(char *uri, const char *options) { - std::vector uris = {uri}; - aria2::A2Gid gid; - pthread_mutex_lock(&access_mutex); - int ret = aria2::addUri(session, &gid, uris, toAria2Options(options)); - pthread_mutex_unlock(&access_mutex); - if (ret < 0) { - return 0; - } - - return gid; -} - -/** - * Add bit torrent file. See `addTorrent` in aria2. - */ -uint64_t addTorrent(char *fp, const char *options) { - aria2::A2Gid gid; - pthread_mutex_lock(&access_mutex); - int ret = aria2::addTorrent(session, &gid, fp, toAria2Options(options)); - pthread_mutex_unlock(&access_mutex); - if (ret < 0) { - return 0; - } - - return gid; -} - -/** - * Change aria2 options. See `changeOption` in aria2. - */ -bool changeOptions(uint64_t gid, const char *options) { - pthread_mutex_lock(&access_mutex); - bool ret = aria2::changeOption(session, gid, toAria2Options(options)) == 0; - pthread_mutex_unlock(&access_mutex); - return ret; -} - -/** - * Get options for given gid. see `getOptions` in aria2. - */ -const char *getOptions(uint64_t gid) { - pthread_mutex_lock(&access_mutex); - aria2::DownloadHandle *dh = aria2::getDownloadHandle(session, gid); - pthread_mutex_unlock(&access_mutex); - if (!dh) { - return nullptr; - } - - return toAria2goOptions(dh->getOptions()); -} - -/** - * Change global options. See `changeGlobalOption` in aria2. - */ -bool changeGlobalOptions(const char *options) { - pthread_mutex_lock(&access_mutex); - bool ret = aria2::changeGlobalOption(session, toAria2Options(options)); - pthread_mutex_unlock(&access_mutex); - return ret; -} - -/** - * Get global options. see `getGlobalOptions` in aria2. - */ -const char *getGlobalOptions() { - pthread_mutex_lock(&access_mutex); - aria2::KeyVals options = aria2::getGlobalOptions(session); - pthread_mutex_unlock(&access_mutex); - return toAria2goOptions(options); -} - -/** - * Performs event polling and actions for them. - */ -int run() { return aria2::run(session, aria2::RUN_DEFAULT); } - -/** - * Pause an active download with given gid. This will mark the download to - * `DOWNLOAD_PAUSED`. See `resume`. - */ -bool pause(uint64_t gid) { - pthread_mutex_lock(&access_mutex); - bool ret = aria2::pauseDownload(session, gid) == 0; - pthread_mutex_unlock(&access_mutex); - return ret; -} - -/** - * Resume a paused download with given gid. See `pause`. - */ -bool resume(uint64_t gid) { - pthread_mutex_lock(&access_mutex); - bool ret = aria2::unpauseDownload(session, gid) == 0; - pthread_mutex_unlock(&access_mutex); - return ret; -} - -/** - * Remove a download in queue with given gid. This will stop downloading and - * seeding(for torrent). - */ -bool removeDownload(uint64_t gid) { - pthread_mutex_lock(&access_mutex); - bool ret = aria2::removeDownload(session, gid) == 0; - pthread_mutex_unlock(&access_mutex); - return ret; -} - -/** - * Get download information for current download with given gid. - */ -struct DownloadInfo *getDownloadInfo(uint64_t gid) { - if (session == nullptr) { - return nullptr; - } - pthread_mutex_lock(&access_mutex); - aria2::DownloadHandle *dh = aria2::getDownloadHandle(session, gid); - pthread_mutex_unlock(&access_mutex); - if (!dh) { - return nullptr; - } - struct DownloadInfo *di = new DownloadInfo(); - di->status = dh->getStatus(); - di->totalLength = dh->getTotalLength(); - di->bytesCompleted = dh->getCompletedLength(); - di->uploadLength = dh->getUploadLength(); - di->downloadSpeed = dh->getDownloadSpeed(); - di->uploadSpeed = dh->getUploadSpeed(); - di->pieceLength = dh->getPieceLength(); - di->numPieces = dh->getNumPieces(); - di->connections = dh->getConnections(); - di->numFiles = dh->getNumFiles(); - di->infoHash = toCStr(dh->getInfoHash()); - di->metaInfo = parseMetaInfo(dh->getBtMetaInfo()); - di->files = parseFileData(dh); - di->errorCode = dh->getErrorCode(); - std::vector gids = dh->getFollowedBy(); - if (gids.size() != 0) { - di->followedByGid = gids[0]; - } else { - di->followedByGid = 0; - } - // std::cout << "status" << dh->getStatus() << std::endl; - // std::cout << "Error: " << dh->getErrorCode() << std::endl; - // std::cout << "Completed: " << dh->getCompletedLength() << std::endl; - // std::cout << "Total: " << dh->getTotalLength() << std::endl; - /* delete download handle */ - aria2::deleteDownloadHandle(dh); - return di; -} - diff --git a/pkg/aria2go/aria2_c.h b/pkg/aria2go/aria2_c.h deleted file mode 100644 index 20d113a..0000000 --- a/pkg/aria2go/aria2_c.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef ARIA2_C_H -#define ARIA2_C_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Type definition for file information in torrent. - */ -struct FileInfo { - int index; - const char *name; - int64_t length; - int64_t completedLength; - bool selected; -}; - -/** - * Type definition for BitTorrent meta information. - */ -struct MetaInfo { - const char *name; - const char *comment; - int64_t creationUnix; - const char *announceList; -}; - -/** - * Type definition for download information. - */ -struct DownloadInfo { - int status; - int64_t totalLength; - int64_t bytesCompleted; - int64_t uploadLength; - int downloadSpeed; - int uploadSpeed; - int pieceLength; - int numPieces; - int connections; - int numFiles; - const char *infoHash; - struct MetaInfo *metaInfo; - struct FileInfo *files; - int errorCode; - uint64_t followedByGid; -}; - -int init(uint64_t aria2goPointer, const char *options); -int shutdownSchedules(bool force); -int deinit(); -uint64_t addUri(char *uri, const char *options); -uint64_t addTorrent(char *fp, const char *options); -bool changeOptions(uint64_t gid, const char *options); -const char *getOptions(uint64_t gid); -bool changeGlobalOptions(const char *options); -const char *getGlobalOptions(); -int run(); -bool pause(uint64_t gid); -bool resume(uint64_t gid); -bool removeDownload(uint64_t gid); -struct DownloadInfo *getDownloadInfo(uint64_t gid); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/pkg/aria2go/go.mod b/pkg/aria2go/go.mod deleted file mode 100644 index 3dc5966..0000000 --- a/pkg/aria2go/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module github.com/jaskaranSM/aria2go - -go 1.12 - -require ( - github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b // indirect -) diff --git a/pkg/aria2go/go.sum b/pkg/aria2go/go.sum deleted file mode 100644 index b1000f8..0000000 --- a/pkg/aria2go/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b h1:5JgaFtHFRnOPReItxvhMDXbvuBkjSWE+9glJyF466yw= -github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b/go.mod h1:eMD2XUcPsHYbakFEocKrWZp47G0MRJYoC60qFblGjpA= diff --git a/pkg/aria2go/libaria2.go b/pkg/aria2go/libaria2.go deleted file mode 100644 index e86ff0c..0000000 --- a/pkg/aria2go/libaria2.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (C) 2019 Vincent Chueng (coolingfall@gmail.com). - -package aria2go - -/* - #cgo CXXFLAGS: -std=c++11 -I./aria2-lib/include -Werror -Wall - #cgo LDFLAGS: -L./aria2-lib/lib - #cgo LDFLAGS: -laria2 -lcares -lssl -lcrypto - #cgo darwin LDFLAGS: -framework Security - #cgo windows LDFLAGS: -lws2_32 -lwsock32 -lgdi32 -lwinmm -liphlpapi -lpsapi -lcrypt32 -lsecur32 -ladvapi32 - #include - #include "aria2_c.h" -*/ -import "C" -import ( - "errors" - "fmt" - "log" - "strconv" - "strings" - "sync" - "unsafe" - - _ "github.com/benesch/cgosymbolizer" -) - -// Type definition for lib aria2, it holds a notifier. -type Aria2 struct { - notifier Notifier - shutdownNotification chan bool - shouldShutdown bool - m_mutex sync.Mutex -} - -// Type definition of configuration for aria2. -type Config struct { - Options Options - Notifier Notifier -} - -// NewAria2 creates a new instance of aria2. -func NewAria2(config Config) *Aria2 { - a := &Aria2{ - notifier: newDefaultNotifier(), - shutdownNotification: make(chan bool), - } - a.SetNotifier(config.Notifier) - - C.init(C.uint64_t(uintptr(unsafe.Pointer(a))), - C.CString(a.fromOptions(config.Options))) - return a -} - -// Shutdown aria2, this must be invoked when process exit(signal handler is not -// used), so aria2 will be able to save session config. -func (a *Aria2) Shutdown() int { - C.shutdownSchedules(true) - a.shouldShutdown = true - - // do nothing, just make thread waiting - select { - case <-a.shutdownNotification: - break - } - - return int(C.deinit()) -} - -// Run starts event pooling. Note this will block current thread. -func (a *Aria2) Run() { - for { - if C.run() != 1 && a.shouldShutdown { - break - } - } - a.shutdownNotification <- true -} - -// SetNotifier sets notifier to receive download notification from aria2. -func (a *Aria2) SetNotifier(notifier Notifier) { - if notifier == nil { - return - } - a.notifier = notifier -} - -// AddUri adds a new download. The uris is an array of HTTP/FTP/SFTP/BitTorrent -// URIs (strings) pointing to the same resource. When adding BitTorrent Magnet -// URIs, uris must have only one element and it should be BitTorrent Magnet URI. -func (a *Aria2) AddUri(uri string, options Options) (gid string, err error) { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - cUri := C.CString(uri) - cOptions := C.CString(a.fromOptions(options)) - defer C.free(unsafe.Pointer(cUri)) - defer C.free(unsafe.Pointer(cOptions)) - - ret := C.addUri(cUri, cOptions) - if ret == 0 { - return "", errors.New("libaria2: add uri failed") - } - return fmt.Sprintf("%x", uint64(ret)), nil -} - -// AddTorrent adds a MetaInfo download with given torrent file path. -// This will return gid and files in torrent file if add successfully. -// User can choose specified files to download, change directory and so on. -func (a *Aria2) AddTorrent(filepath string, options Options) (gid string, err error) { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - cFilepath := C.CString(filepath) - cOptions := C.CString(a.fromOptions(options)) - defer C.free(unsafe.Pointer(cFilepath)) - defer C.free(unsafe.Pointer(cOptions)) - - ret := C.addTorrent(cFilepath, cOptions) - if ret == 0 { - return "", errors.New("libaria2: add torrent failed") - } - return fmt.Sprintf("%x", uint64(ret)), nil -} - -// ChangeOptions can change the options for aria2. See available options in -// https://aria2.github.io/manual/en/html/aria2c.html#input-file. -func (a *Aria2) ChangeOptions(gid string, options Options) error { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - cOptions := C.CString(a.fromOptions(options)) - defer C.free(unsafe.Pointer(cOptions)) - - if !C.changeOptions(a.hexToGid(gid), cOptions) { - return errors.New("libaria2: change options error") - } - - return nil -} - -// GetOptions gets all options for given gid. -func (a *Aria2) GetOptions(gid string) Options { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - cOptions := C.getOptions(a.hexToGid(gid)) - if cOptions == nil { - return make(Options) - } - - return a.toOptions(C.GoString(cOptions)) -} - -// ChangeGlobalOptions changes global options. See available options in -// https://aria2.github.io/manual/en/html/aria2c.html#input-file except for -// `checksum`, `index-out`, `out`, `pause` and `select-file`. -func (a *Aria2) ChangeGlobalOptions(options Options) error { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - cOptions := C.CString(a.fromOptions(options)) - defer C.free(unsafe.Pointer(cOptions)) - - if !C.changeGlobalOptions(cOptions) { - return errors.New("libaria2: change global options error") - } - - return nil -} - -// GetGlobalOptions gets all global options of aria2. -func (a *Aria2) GetGlobalOptions() Options { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - return a.toOptions(C.GoString(C.getGlobalOptions())) -} - -// Pause pauses an active download for given gid. The status of the download -// will become `DOWNLOAD_PAUSED`. Use `Resume` to restart download. -func (a *Aria2) Pause(gid string) bool { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - return bool(C.pause(a.hexToGid(gid))) -} - -// Resume resumes an paused download for given gid. -func (a *Aria2) Resume(gid string) bool { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - return bool(C.resume(a.hexToGid(gid))) -} - -// Remove removes download no matter what status it was. This will stop -// downloading and stop seeding(for torrent). -func (a *Aria2) Remove(gid string) bool { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - return bool(C.removeDownload(a.hexToGid(gid))) -} - -// GetDownloadInfo gets current download information for given gid. -func (a *Aria2) GetDownloadInfo(gid string) DownloadInfo { - a.m_mutex.Lock() - defer a.m_mutex.Unlock() - ret := C.getDownloadInfo(a.hexToGid(gid)) - if ret == nil { - return DownloadInfo{} - } - defer C.free(unsafe.Pointer(ret)) - - // convert info hash to hex string - infoHash := fmt.Sprintf("%x", []byte(C.GoString(ret.infoHash))) - C.free(unsafe.Pointer(ret.infoHash)) - // retrieve BitTorrent meta information - var metaInfo = MetaInfo{} - mi := ret.metaInfo - defer C.free(unsafe.Pointer(mi)) - if mi != nil { - announceList := strings.Split(C.GoString(mi.announceList), ";") - metaInfo = MetaInfo{ - Name: C.GoString(mi.name), - Comment: C.GoString(mi.comment), - CreationUnix: int64(mi.creationUnix), - AnnounceList: announceList, - } - C.free(unsafe.Pointer(mi.name)) - C.free(unsafe.Pointer(mi.comment)) - C.free(unsafe.Pointer(mi.announceList)) - } - return DownloadInfo{ - Status: int(ret.status), - TotalLength: int64(ret.totalLength), - BytesCompleted: int64(ret.bytesCompleted), - BytesUpload: int64(ret.uploadLength), - DownloadSpeed: int(ret.downloadSpeed), - UploadSpeed: int(ret.uploadSpeed), - NumPieces: int(ret.numPieces), - Connections: int(ret.connections), - InfoHash: infoHash, - MetaInfo: metaInfo, - Files: a.parseFiles(ret.files, ret.numFiles), - ErrorCode: int(ret.errorCode), - FollowedByGid: fmt.Sprintf("%x", uint64(ret.followedByGid)), - } -} - -// fromOptions converts `Options` to string with ';' separator. -func (a *Aria2) fromOptions(options Options) string { - if options == nil { - return "" - } - - var cOptions string - for k, v := range options { - cOptions += k + ";" - cOptions += v + ";" - } - - return strings.TrimSuffix(cOptions, ";") -} - -// fromOptions converts options string with ';' separator to `Options`. -func (a *Aria2) toOptions(cOptions string) Options { - coptions := strings.Split(strings.TrimSuffix(cOptions, ";"), ";") - var options = make(Options) - var index int - for index = 0; index < len(coptions); index += 2 { - options[coptions[index]] = coptions[index+1] - } - - return options -} - -// hexToGid convert hex to uint64 type gid. -func (a *Aria2) hexToGid(hex string) C.uint64_t { - id, err := strconv.ParseUint(hex, 16, 64) - if err != nil { - return 0 - } - return C.uint64_t(id) -} - -// parseFiles parses all files information from aria2. -func (a *Aria2) parseFiles(filesPointer *C.struct_FileInfo, length C.int) (files []File) { - cfiles := (*[1 << 20]C.struct_FileInfo)(unsafe.Pointer(filesPointer))[:length:length] - if cfiles == nil { - return - } - - for _, f := range cfiles { - files = append(files, File{ - Index: int(f.index), - Length: int64(f.length), - CompletedLength: int64(f.completedLength), - Name: C.GoString(f.name), - Selected: bool(f.selected), - }) - C.free(unsafe.Pointer(f.name)) - } - - // free c pointer resource - C.free(unsafe.Pointer(filesPointer)) - - return -} - -// noinspection GoUnusedFunction -// -//export notifyEvent -func notifyEvent(ariagoPointer uint64, id uint64, event int) { - a := (*Aria2)(unsafe.Pointer(uintptr(ariagoPointer))) - if a == nil || a.notifier == nil { - return - } - - // convert id to hex string - gid := fmt.Sprintf("%x", uint64(id)) - - switch event { - case onStart: - a.notifier.OnStart(gid) - case onPause: - a.notifier.OnPause(gid) - case onStop: - a.notifier.OnStop(gid) - case onComplete: - a.notifier.OnComplete(gid) - case onError: - a.notifier.OnError(gid) - } -} - -// noinspection GoUnusedFunction -// -//export goLog -func goLog(msg *C.char) { - log.Println(C.GoString(msg)) -} diff --git a/pkg/aria2go/models.go b/pkg/aria2go/models.go deleted file mode 100644 index ca54941..0000000 --- a/pkg/aria2go/models.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2019 Vincent Chueng (coolingfall@gmail.com). - -package aria2go - -// Type definition for download information. -type DownloadInfo struct { - Status int - TotalLength int64 - BytesCompleted int64 - BytesUpload int64 - DownloadSpeed int - UploadSpeed int - NumPieces int - Connections int - BitField string - InfoHash string - MetaInfo MetaInfo - Files []File - ErrorCode int - FollowedByGid string -} - -// Type definition for BitTorrent meta information. -type MetaInfo struct { - Name string - AnnounceList []string - Comment string - CreationUnix int64 - Mode string -} - -// Type definition for file in torrent. -type File struct { - Index int - Name string - Length int64 - CompletedLength int64 - Selected bool -} - -type Options map[string]string - -// Type definition for download event, this will keep the same with aria2. -const ( - onStart = iota + 1 - onPause - onStop - onComplete - onError - onBTComplete -) diff --git a/pkg/aria2go/notifier.go b/pkg/aria2go/notifier.go deleted file mode 100644 index c0eaa4e..0000000 --- a/pkg/aria2go/notifier.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2019 Vincent Chueng (coolingfall@gmail.com). - -package aria2go - -import ( - "log" -) - -// Type definition for notifier which can be used in aria2c json rpc notification. -type Notifier interface { - // OnStart will be invoked when aria2 started to download - OnStart(gid string) - - // OnPause will be invoked when aria2 paused one download - OnPause(gid string) - - // OnPause will be invoked when aria2 stopped one download - OnStop(gid string) - - // OnComplete will be invoked when download completed - OnComplete(gid string) - - // OnError will be invoked when an error occoured - OnError(gid string) -} - -// Type definition for default notifier which dose nothing. -type DefaultNotifier struct{} - -// newDefaultNotifier creates a new instance of default Notifier. -func newDefaultNotifier() Notifier { - return DefaultNotifier{} -} - -// OnStart implements Notifier interface. -func (n DefaultNotifier) OnStart(gid string) { - log.Printf("on start %v", gid) -} - -// OnPause implements Notifier interface. -func (n DefaultNotifier) OnPause(gid string) { - log.Printf("on pause: %v", gid) -} - -// OnPause implements Notifier interface. -func (n DefaultNotifier) OnStop(gid string) { - log.Printf("on stop: %v", gid) -} - -// OnComplete implements Notifier interface. -func (n DefaultNotifier) OnComplete(gid string) { - log.Printf("on complete: %v", gid) -} - -// OnError implements Notifier interface. -func (n DefaultNotifier) OnError(gid string) { - log.Printf("on error: %v", gid) -} diff --git a/prepare_aria.sh b/prepare_aria.sh deleted file mode 100755 index 4e9e73c..0000000 --- a/prepare_aria.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -# In this configuration, the following dependent libraries are compiled: -# -# * c-ares -# * openSSL - -# Compiler and path -PREFIX=$PWD/pkg/aria2go/aria2-lib -C_COMPILER="gcc" -CXX_COMPILER="g++" - -NPROC=`nproc` -# check if nproc is a command -if ! [[ -x "$(command -v nproc)" ]]; then - echo 'Error: nproc is not installed. Using sysctl for macOS' >&2 - $NPROC=`sysctl -n hw.logicalcpu` # macOS -fi - -# Check tool for download -aria2c --help > /dev/null -if [[ "$?" -eq 0 ]]; then - DOWNLOADER="aria2c --check-certificate=false" -else - DOWNLOADER="wget -c" -fi - -echo "Remove old libs..." -rm -rf ${PREFIX} -rm -rf _obj - -## Version -OPENSSL_V=1.1.1w -C_ARES_V=1.24.0 -ARIA2_V=1.37.0 - -## Dependencies -OPENSSL=http://www.openssl.org/source/openssl-${OPENSSL_V}.tar.gz -C_ARES=http://c-ares.haxx.se/download/c-ares-${C_ARES_V}.tar.gz -ARIA2=https://github.com/aria2/aria2/releases/download/release-${ARIA2_V}/aria2-${ARIA2_V}.tar.bz2 - -## Config -BUILD_DIRECTORY=/tmp/ - -## Build -cd ${BUILD_DIRECTORY} - -# c-ares build -if ! [[ -e c&&res-${C_ARES_V}.tar.gz ]]; then - ${DOWNLOADER} ${C_ARES} -fi -tar zxvf c-ares-${C_ARES_V}.tar.gz -cd c-ares-${C_ARES_V} -PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig/ \ - LD_LIBRARY_PATH=${PREFIX}/lib/ CC="$C_COMPILER" CXX="$CXX_COMPILER" \ - ./configure --prefix=${PREFIX} --enable-static --disable-shared -make -j`nproc` -make install -cd .. - -# openssl build -if ! [[ -e openssl-${OPENSSL_V}.tar.gz ]]; then - ${DOWNLOADER} ${OPENSSL} -fi -tar zxvf openssl-${OPENSSL_V}.tar.gz -cd openssl-${OPENSSL_V} -PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig/ \ - LD_LIBRARY_PATH=${PREFIX}/lib/ CC="$C_COMPILER" CXX="$CXX_COMPILER" \ - ./config --prefix=${PREFIX} -make -j`nproc` -make install_sw -cd .. - -# build aria2 static library -if ! [[ -e aria2-${ARIA2_V}.tar.bz2 ]]; then - ${DOWNLOADER} ${ARIA2} -fi -tar jxvf aria2-${ARIA2_V}.tar.bz2 -cd aria2-${ARIA2_V}/ -# set specific ldflags if macOS -if [[ "$OSTYPE" == "darwin"* ]]; then - export LDFLAGS="-L${PREFIX}/lib -framework Security" -fi -PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig/ \ - LD_LIBRARY_PATH=${PREFIX}/lib/ \ - CC="$C_COMPILER" \ - CXX="$CXX_COMPILER" \ - ./configure \ - --prefix=${PREFIX} \ - --without-sqlite3 \ - --without-libxml2 \ - --without-libexpat \ - --without-libgcrypt \ - --without-libssh2 \ - --without-libz \ - --with-openssl \ - --without-appletls \ - --without-libnettle \ - --without-gnutls \ - --without-libgmp \ - --enable-libaria2 \ - --enable-shared=no \ - --enable-static=yes -make -j`nproc` -make install -cd .. - -# cleaning -rm -rf c-ares-${C_ARES_V} -rm -rf openssl-${OPENSSL_V} -rm -rf aria2-${ARIA2_V} -rm -rf ${PREFIX}/bin - -# generate files for c -cd ${PREFIX}/../ -go tool cgo libaria2.go - -echo "Prepare finished!" \ No newline at end of file