mirror of
https://github.com/simon-ding/polaris.git
synced 2026-03-07 10:00:46 +08:00
feat(ui): add nat traversal option
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"polaris/ent/downloadclients"
|
||||
"polaris/log"
|
||||
"polaris/pkg/nat"
|
||||
"polaris/pkg/qbittorrent"
|
||||
|
||||
@@ -10,31 +12,33 @@ import (
|
||||
)
|
||||
|
||||
func (s *Engine) stunProxyDownloadClient() error {
|
||||
downloader, e, err := s.GetDownloadClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !e.UseNatTraversal {
|
||||
return nil
|
||||
}
|
||||
if e.Implementation != downloadclients.ImplementationQbittorrent {
|
||||
return nil
|
||||
}
|
||||
d, ok := downloader.(*qbittorrent.Client)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
u, err := url.Parse(d.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
downloaders := s.db.GetAllDonloadClients()
|
||||
for _, d := range downloaders {
|
||||
if !d.Enable {
|
||||
continue
|
||||
}
|
||||
|
||||
if d.Implementation != downloadclients.ImplementationQbittorrent { //TODO only support qbittorrent for now
|
||||
continue
|
||||
}
|
||||
|
||||
qbt, err := qbittorrent.NewClient(d.URL, d.User, d.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect to download client error: %v", d.URL)
|
||||
}
|
||||
u, err := url.Parse(d.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("start stun proxy for %s", d.Name)
|
||||
n, err := nat.NewNatTraversal(func(xa stun.XORMappedAddress) error {
|
||||
return qbt.SetListenPort(xa.Port)
|
||||
}, u.Hostname())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.StartProxy()
|
||||
|
||||
n, err := nat.NewNatTraversal(func(xa stun.XORMappedAddress) error {
|
||||
return d.SetListenPort(xa.Port)
|
||||
}, u.Hostname())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.StartProxy()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -251,6 +251,7 @@ class DownloadClient {
|
||||
bool? removeCompletedDownloads;
|
||||
bool? removeFailedDownloads;
|
||||
int? priority;
|
||||
bool useNatTraversal = false;
|
||||
DownloadClient(
|
||||
{this.id,
|
||||
this.enable,
|
||||
@@ -261,7 +262,7 @@ class DownloadClient {
|
||||
this.password,
|
||||
this.removeCompletedDownloads = true,
|
||||
this.priority = 1,
|
||||
this.removeFailedDownloads = true});
|
||||
this.removeFailedDownloads = true, this.useNatTraversal = false});
|
||||
|
||||
DownloadClient.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
@@ -274,6 +275,7 @@ class DownloadClient {
|
||||
priority = json["priority1"];
|
||||
removeCompletedDownloads = json["remove_completed_downloads"] ?? false;
|
||||
removeFailedDownloads = json["remove_failed_downloads"] ?? false;
|
||||
useNatTraversal = json["use_nat_traversal"]?? false;
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@@ -288,6 +290,7 @@ class DownloadClient {
|
||||
data["priority"] = priority;
|
||||
data["remove_completed_downloads"] = removeCompletedDownloads;
|
||||
data["remove_failed_downloads"] = removeFailedDownloads;
|
||||
data["use_nat_traversal"] = useNatTraversal;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ class _DownloaderState extends ConsumerState<DownloaderSettings> {
|
||||
"remove_completed_downloads": client.removeCompletedDownloads,
|
||||
"remove_failed_downloads": client.removeFailedDownloads,
|
||||
"priority": client.priority.toString(),
|
||||
"use_nat_traversal": client.useNatTraversal,
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -86,6 +87,12 @@ class _DownloaderState extends ConsumerState<DownloaderSettings> {
|
||||
labelText: "优先级", helperText: "1-50, 1最高优先级,50最低优先级"),
|
||||
validator: FormBuilderValidators.integer(),
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction),
|
||||
FormBuilderSwitch(
|
||||
name: "use_nat_traversal",
|
||||
enabled: client.implementation == "qbittorrent",
|
||||
title: const Text("使用内置STUN NAT穿透"),
|
||||
decoration: InputDecoration(helperText: "内建的NAT穿透功能帮助BT客户端上传(会自动更改下载器的监听地址)"),
|
||||
),
|
||||
FormBuilderSwitch(
|
||||
name: "remove_completed_downloads",
|
||||
title: const Text("任务完成后删除")),
|
||||
@@ -150,6 +157,7 @@ class _DownloaderState extends ConsumerState<DownloaderSettings> {
|
||||
user: _enableAuth ? values["user"] : null,
|
||||
password: _enableAuth ? values["password"] : null,
|
||||
priority: int.parse(values["priority"]),
|
||||
useNatTraversal: values["use_nat_traversal"],
|
||||
removeCompletedDownloads: values["remove_completed_downloads"],
|
||||
removeFailedDownloads: values["remove_failed_downloads"]));
|
||||
} else {
|
||||
@@ -165,7 +173,12 @@ class _DownloaderState extends ConsumerState<DownloaderSettings> {
|
||||
}
|
||||
|
||||
return showSettingDialog(
|
||||
context, title, client.idExists() && client.implementation != "buildin", body, onSubmit, onDelete);
|
||||
context,
|
||||
title,
|
||||
client.idExists() && client.implementation != "buildin",
|
||||
body,
|
||||
onSubmit,
|
||||
onDelete);
|
||||
}
|
||||
|
||||
Future<void> showSelections() {
|
||||
|
||||
Reference in New Issue
Block a user