Skip to content

Commit

Permalink
Merge pull request #20 from xssnick/dev-v110
Browse files Browse the repository at this point in the history
Core updated + UI improvements and new config settings
  • Loading branch information
xssnick authored Dec 9, 2023
2 parents e04d088 + 37bab80 commit 7e7f173
Show file tree
Hide file tree
Showing 18 changed files with 266 additions and 46 deletions.
79 changes: 64 additions & 15 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/tonutils/torrent-client/core/api"
"github.com/tonutils/torrent-client/core/client"
"github.com/tonutils/torrent-client/core/gostorage"
"github.com/tonutils/torrent-client/core/upnp"
"github.com/tonutils/torrent-client/oshook"
runtime2 "github.com/wailsapp/wails/v2/pkg/runtime"
"github.com/xssnick/tonutils-go/adnl"
Expand All @@ -18,6 +19,7 @@ import (
"os"
"os/exec"
"runtime"
"sort"
"strings"
"sync"
"time"
Expand All @@ -35,6 +37,10 @@ type App struct {
openFileData []byte
openFileHash string

lastCreateProgressReport time.Time
creationCtx context.Context
cancelCreation func()

mx sync.RWMutex
}

Expand Down Expand Up @@ -109,24 +115,32 @@ func (a *App) ShowWarnMsg(text string) {
func (a *App) prepare() {
oshook.HookStartup(a.openFile, a.openHash)

if !a.config.PortsChecked && !a.config.SeedMode {
if (!a.config.PortsChecked && !a.config.SeedMode) || a.config.FetchIPOnStartup {
log.Println("Trying to forward ports using UPnP")

up, err := upnp.NewUPnP()
if err != nil {
log.Println("UPnP init failed", err.Error())
} else {
if err = up.ForwardPortTCP(18889); err != nil {
log.Println("Port 18889 TCP forwarding failed:", err.Error())
}
if err = up.ForwardPortUDP(13333); err != nil {
log.Println("Port 13333 UDP forwarding failed:", err.Error())
}
}

ip, seed := CheckCanSeed()
if seed {
a.config.SeedMode = true
a.config.ListenAddr = ip + ":13333"
log.Println("Static seed mode is enabled, ports are open.")
} else {
log.Println("Static seed mode was not activated, ports are closed.")
}
a.config.PortsChecked = true
_ = a.config.SaveConfig(a.rootPath)
}

/*go func() {
// TODO: forward port
up, err := upnp.NewUPnP()
if err != nil {
return
// a.Throw(err)
}
}()*/
}

var oncePrepare sync.Once
Expand Down Expand Up @@ -154,15 +168,22 @@ func (a *App) ready(ctx context.Context) {
}

cfg := gostorage.Config{
Key: ed25519.NewKeyFromSeed(a.config.Key),
ListenAddr: lAddr + ":" + addr[1],
ExternalIP: addr[0],
DownloadsPath: a.config.DownloadsPath,
Key: ed25519.NewKeyFromSeed(a.config.Key),
ListenAddr: lAddr + ":" + addr[1],
ExternalIP: addr[0],
DownloadsPath: a.config.DownloadsPath,
NetworkConfigPath: a.config.NetworkConfigPath,
}
if !a.config.SeedMode {
cfg.ExternalIP = ""
}

if cfg.ExternalIP == "0.0.0.0" {
a.ShowWarnMsg("external ip cannot be 0.0.0.0, disabling seed mode, " +
"change ip in settings to your real external ip")
cfg.ExternalIP = ""
}

var err error
cl, err = gostorage.NewClient(a.rootPath+"/tonutils-storage-db", cfg)
if err != nil {
Expand Down Expand Up @@ -276,14 +297,33 @@ type TorrentCreateResult struct {
}

func (a *App) CreateTorrent(dir, description string) TorrentCreateResult {
hash, err := a.api.CreateTorrent(dir, description)
a.creationCtx, a.cancelCreation = context.WithCancel(a.ctx)
hash, err := a.api.CreateTorrent(a.creationCtx, dir, description, a.reportCreationProgress)
if err != nil {
log.Println(err.Error())
return TorrentCreateResult{Err: err.Error()}
}
return TorrentCreateResult{Hash: hash}
}

func (a *App) CancelCreateTorrent() {
println("CANCEL CREATION")
if a.cancelCreation != nil {
a.cancelCreation()
}
}

func (a *App) reportCreationProgress(done, max uint64) {
now := time.Now()
if a.lastCreateProgressReport.Add(50 * time.Millisecond).After(now) {
// not refresh too often
return
}
a.lastCreateProgressReport = now

runtime2.EventsEmit(a.ctx, "update-create-progress", fmt.Sprintf("%.2f", (float64(done)/float64(max))*100))
}

func (a *App) ExportMeta(hash string) string {
m, err := a.api.GetTorrentMeta(hash)
if err != nil {
Expand Down Expand Up @@ -359,6 +399,15 @@ func (a *App) GetPlainFiles(hash string) []api.PlainFile {
if list == nil {
return []api.PlainFile{}
}

sort.Slice(list, func(i, j int) bool {
return list[i].RawSize > list[j].RawSize
})

if len(list) > 1000 {
list = list[:1000]
}

return list
}

Expand Down
2 changes: 1 addition & 1 deletion build/windows/installer/project.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Unicode true
## !define INFO_PROJECTNAME "MyProject" # Default "{{.Name}}"
## !define INFO_COMPANYNAME "MyCompany" # Default "{{.Info.CompanyName}}"
## !define INFO_PRODUCTNAME "MyProduct" # Default "{{.Info.ProductName}}"
## !define INFO_PRODUCTVERSION "1.0.1" # Default "{{.Info.ProductVersion}}"
## !define INFO_PRODUCTVERSION "1.1.0" # Default "{{.Info.ProductVersion}}"
## !define INFO_COPYRIGHT "Copyright" # Default "{{.Info.Copyright}}"
###
## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe"
Expand Down
3 changes: 3 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type Config struct {
DaemonControlAddr string
PortsChecked bool

NetworkConfigPath string
FetchIPOnStartup bool

mx sync.Mutex
}

Expand Down
43 changes: 36 additions & 7 deletions core/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"github.com/tonutils/torrent-client/core/client"
"log"
"math/big"
"sort"
"strings"
"sync"
Expand All @@ -27,6 +28,7 @@ type PlainFile struct {
Size string
Downloaded string
Progress float64
RawSize int64
}

type Torrent struct {
Expand All @@ -40,6 +42,8 @@ type Torrent struct {
Download string
Path string
PeersNum int
Uploaded string
Ratio string

rawDowSpeed int64
rawDownloaded int64
Expand All @@ -59,6 +63,8 @@ type TorrentInfo struct {
Path string
Peers int
AddedAt string
Uploaded string
Ratio string
}

type SpeedLimits struct {
Expand All @@ -82,7 +88,7 @@ type StorageClient interface {
GetTorrents(ctx context.Context) (*client.TorrentsList, error)
AddByHash(ctx context.Context, hash []byte, dir string) (*client.TorrentFull, error)
AddByMeta(ctx context.Context, meta []byte, dir string) (*client.TorrentFull, error)
CreateTorrent(ctx context.Context, dir, description string) (*client.TorrentFull, error)
CreateTorrent(ctx context.Context, dir, description string, progressCallback func(done uint64, max uint64)) (*client.TorrentFull, error)
GetTorrentFull(ctx context.Context, hash []byte) (*client.TorrentFull, error)
GetTorrentMeta(ctx context.Context, hash []byte) ([]byte, error)
GetPeers(ctx context.Context, hash []byte) (*client.PeersList, error)
Expand All @@ -91,6 +97,7 @@ type StorageClient interface {
SetFilesPriority(ctx context.Context, hash []byte, names []string, priority int32) error
GetSpeedLimits(ctx context.Context) (*client.SpeedLimits, error)
SetSpeedLimits(ctx context.Context, download, upload int64) error
GetUploadStats(ctx context.Context, hash []byte) (uint64, error)
}

type API struct {
Expand Down Expand Up @@ -153,7 +160,12 @@ func (a *API) SyncTorrents() error {
continue
}

tr := formatTorrent(full, len(peers.Peers), true)
uploaded, err := a.client.GetUploadStats(a.globalCtx, torrent.Hash)
if err != nil {
continue
}

tr := formatTorrent(full, len(peers.Peers), true, uploaded)
if tr == nil {
continue
}
Expand Down Expand Up @@ -190,6 +202,13 @@ func toSz(sz int64) string {
}
}

func toRatio(uploaded, size uint64) string {
if size == 0 || uploaded == 0 {
return "0"
}
return new(big.Float).Quo(new(big.Float).SetUint64(uploaded), new(big.Float).SetUint64(size)).Text('f', 2)
}

func toSpeed(speed int64, zeroEmpty bool) string {
if speed == 0 && zeroEmpty {
return ""
Expand All @@ -207,7 +226,7 @@ func toSpeed(speed int64, zeroEmpty bool) string {
}
}

func formatTorrent(full *client.TorrentFull, peersNum int, hide0Speed bool) *Torrent {
func formatTorrent(full *client.TorrentFull, peersNum int, hide0Speed bool, uploaded uint64) *Torrent {
torrent := full.Torrent // newer object
var dataSz, downloadedSz int64
for _, file := range full.Files {
Expand Down Expand Up @@ -275,11 +294,13 @@ func formatTorrent(full *client.TorrentFull, peersNum int, hide0Speed bool) *Tor
Upload: uplSpeed,
Download: dowSpeed,
Path: path,
PeersNum: peersNum,
Uploaded: toSz(int64(uploaded)),
Ratio: toRatio(uploaded, uint64(dataSz)),
rawDowSpeed: int64(torrent.DownloadSpeed),
rawDownloaded: downloadedSz,
rawSize: dataSz,
rawDescription: rawDesc,
PeersNum: peersNum,
}
}

Expand Down Expand Up @@ -337,8 +358,8 @@ func (a *API) AddTorrentByMeta(meta []byte, rootDir string) error {
return nil
}

func (a *API) CreateTorrent(dir, description string) (string, error) {
t, err := a.client.CreateTorrent(a.globalCtx, dir, description)
func (a *API) CreateTorrent(ctx context.Context, dir, description string, progressCallback func(done uint64, max uint64)) (string, error) {
t, err := a.client.CreateTorrent(ctx, dir, description, progressCallback)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -491,6 +512,7 @@ func (a *API) GetPlainFiles(hash string) ([]PlainFile, error) {
Size: toSz(file.Size),
Downloaded: toSz(file.DownloadedSize),
Progress: progress,
RawSize: file.Size,
})
}

Expand All @@ -513,7 +535,12 @@ func (a *API) GetInfo(hash string) (*TorrentInfo, error) {
return nil, err
}

tr := formatTorrent(t, len(peers.Peers), false)
uploaded, err := a.client.GetUploadStats(a.globalCtx, hashBytes)
if err != nil {
return nil, err
}

tr := formatTorrent(t, len(peers.Peers), false, uploaded)
if tr == nil {
return nil, fmt.Errorf("not initialized torrent")
}
Expand Down Expand Up @@ -550,6 +577,8 @@ func (a *API) GetInfo(hash string) (*TorrentInfo, error) {
Path: tr.Path,
Peers: len(peers.Peers),
AddedAt: time.Unix(int64(t.Torrent.AddedAt), 0).Format("02 Jan 2006 15:04:05"),
Uploaded: tr.Uploaded,
Ratio: tr.Ratio,
}, nil
}

Expand Down
11 changes: 10 additions & 1 deletion core/client/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ func (s *StorageClient) AddByMeta(ctx context.Context, meta []byte, dir string)
return nil, fmt.Errorf("unexpected response")
}

func (s *StorageClient) CreateTorrent(ctx context.Context, dir, description string) (*TorrentFull, error) {
func (s *StorageClient) CreateTorrent(ctx context.Context, dir, description string, progressCallback func(done uint64, max uint64)) (*TorrentFull, error) {
if progressCallback != nil {
progressCallback(50, 100)
}

var res tl.Serializable
err := s.client.QueryADNL(ctx, CreateTorrent{
Path: dir,
Expand Down Expand Up @@ -164,6 +168,11 @@ func (s *StorageClient) GetTorrentMeta(ctx context.Context, hash []byte) ([]byte
return nil, fmt.Errorf("unexpected response")
}

func (s *StorageClient) GetUploadStats(ctx context.Context, hash []byte) (uint64, error) {
// not supported by daemon
return 0, nil
}

func (s *StorageClient) GetPeers(ctx context.Context, hash []byte) (*PeersList, error) {
var res tl.Serializable
err := s.client.QueryADNL(ctx, GetPeers{
Expand Down
Loading

0 comments on commit 7e7f173

Please sign in to comment.