Files
i2p.plugins.tor-updater/get/torrent.go
2022-03-16 15:01:49 -04:00

245 lines
6.0 KiB
Go

package tbget
import (
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/eyedeekay/sam3/i2pkeys"
cp "github.com/otiai10/copy"
"github.com/xgfone/bt/bencode"
"github.com/xgfone/bt/metainfo"
)
func (t *TBDownloader) DownloadedFilesList() ([]string, error) {
files, err := ioutil.ReadDir(t.DownloadPath)
if err != nil {
return nil, fmt.Errorf("DownloadedFilesList: %s", err)
}
var list []string
for _, f := range files {
list = append(list, f.Name())
}
return list, nil
}
func (t *TBDownloader) GenerateMissingTorrents() error {
files, err := t.DownloadedFilesList()
if err != nil {
return err
}
for _, f := range files {
fp := filepath.Join(t.DownloadPath, f+".torrent")
af := filepath.Join(t.DownloadPath, f)
if !strings.HasSuffix(af, ".torrent") {
//os.Remove(fp)
if !FileExists(fp) {
log.Println("Generating torrent for", fp)
meta, err := t.GenerateTorrent(af, nil)
if err != nil {
//return err
log.Println("GenerateMissingTorrents:", err)
continue
}
file, err := os.Create(fp)
if err != nil {
return err
}
meta.Write(file)
file.Close()
}
snark, err := FindSnarkDirectory()
if err != nil {
return err
}
sf := filepath.Join(snark, f)
sfp := filepath.Join(snark, f+".torrent")
if !FileExists(sf) {
log.Println("Copying", af, "to", sf)
cp.Copy(af, sf)
}
if !FileExists(sfp) {
log.Println("Copying", fp, "to", sfp)
cp.Copy(fp, sfp)
}
}
}
return nil
}
func (t *TBDownloader) GenerateTorrent(file string, announces []string) (*metainfo.MetaInfo, error) {
//info, err := metainfo.NewInfoFromFilePath(file, 5120)
info, err := metainfo.NewInfoFromFilePath(file, 10240)
if err != nil {
return nil, fmt.Errorf("GenerateTorrent: %s", err)
}
info.Name = filepath.Base(file)
var mi metainfo.MetaInfo
mi.InfoBytes, err = bencode.EncodeBytes(info)
if err != nil {
return nil, fmt.Errorf("GenerateTorrent: %s", err)
}
switch len(announces) {
case 0:
mi.Announce = "http://mb5ir7klpc2tj6ha3xhmrs3mseqvanauciuoiamx2mmzujvg67uq.b32.i2p/a"
case 1:
mi.Announce = announces[0]
default:
mi.AnnounceList = metainfo.AnnounceList{announces}
}
url, err := url.Parse("http://idk.i2p/torbrowser/" + filepath.Base(file))
if err != nil {
return nil, fmt.Errorf("GenerateTorrent: %s", err)
}
mi.URLList = []string{url.String()}
if t.listener != nil {
url, err := url.Parse("http://" + t.listener.Addr().(i2pkeys.I2PAddr).Base32() + "/" + filepath.Base(file))
if err != nil {
return nil, fmt.Errorf("GenerateTorrent: %s", err)
}
if t.Mirror != "" {
mi.URLList = append(mi.URLList, url.String())
}
}
clearurl, err := url.Parse("https://eyedeekay.github.io/torbrowser/" + filepath.Base(file))
if err != nil {
return nil, fmt.Errorf("GenerateTorrent: %s", err)
}
mi.URLList = append(mi.URLList, clearurl.String())
return &mi, nil
}
func FindSnarkDirectory() (string, error) {
// Snark could be at:
// or: $I2P_CONFIG/i2psnark/
// or: $I2P/i2psnark/
// or: $HOME/.i2p/i2psnark/
// or: /var/lib/i2p/i2p-config/i2psnark/
// or: %LOCALAPPDATA\i2p\i2psnark\
// or: %APPDATA\i2p\i2psnark\
SNARK_CONFIG := os.Getenv("SNARK_CONFIG")
if SNARK_CONFIG != "" {
checkfori2pcustom := filepath.Join(SNARK_CONFIG)
if FileExists(checkfori2pcustom) {
return checkfori2pcustom, nil
}
}
I2P_CONFIG := os.Getenv("I2P_CONFIG")
if I2P_CONFIG != "" {
checkfori2pcustom := filepath.Join(I2P_CONFIG, "i2psnark")
if FileExists(checkfori2pcustom) {
return checkfori2pcustom, nil
}
}
I2P := os.Getenv("I2P")
if I2P != "" {
checkfori2p := filepath.Join(I2P, "i2psnark")
if FileExists(checkfori2p) {
return checkfori2p, nil
}
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
// Start by getting the home directory
switch runtime.GOOS {
case "windows":
checkfori2plocal := filepath.Join(home, "AppData", "Local", "i2p", "i2psnark")
if FileExists(checkfori2plocal) {
return checkfori2plocal, nil
}
checkfori2proaming := filepath.Join(home, "AppData", "Roaming", "i2p", "i2psnark")
if FileExists(checkfori2proaming) {
return checkfori2proaming, nil
}
case "linux":
checkfori2phome := filepath.Join(home, ".i2p", "i2psnark")
if FileExists(checkfori2phome) {
return checkfori2phome, nil
}
checkfori2pservice := filepath.Join("/var/lib/i2p/i2p-config", "i2psnark")
if FileExists(checkfori2pservice) {
return checkfori2pservice, nil
}
case "darwin":
return "", fmt.Errorf("FindSnarkDirectory: Automatic torrent generation is not supported on MacOS, for now copy the files manually")
}
return "", fmt.Errorf("FindSnarkDirectory: Unable to find snark directory")
}
func TorrentReady() bool {
if _, err := FindSnarkDirectory(); err != nil {
return false
}
return true
}
func TorrentPath() (string, string) {
extension := "tar.xz"
windowsonly := ""
switch runtime.GOOS {
case "darwin":
extension = "dmg"
case "windows":
windowsonly = "-installer"
extension = "exe"
}
//version, err := t.Get
return fmt.Sprintf("tor-browser%s", windowsonly), extension
}
func TorrentDownloaded() bool {
cmpsize := 8661000
found := false
if dir, err := FindSnarkDirectory(); err == nil {
err := filepath.Walk(dir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
prefix, suffix := TorrentPath()
path = filepath.Base(path)
if strings.HasPrefix(path, prefix) && strings.HasSuffix(path, suffix) {
if !strings.HasSuffix(path, ".torrent") {
if info.Size() > int64(cmpsize) {
//fmt.Println("TorrentDownloaded: Torrent Download found:", path)
found = true
return nil
} else {
return fmt.Errorf("TorrentDownloaded: Torrent Download found but size is too small: %s", path)
}
}
}
return nil
})
if found {
return err == nil
}
return false
}
return false
}
func Torrent() bool {
if !TorrentReady() {
return false
}
if !TorrentDownloaded() {
return false
}
return true
}