-
-
Notifications
You must be signed in to change notification settings - Fork 144
/
urlimport.go
133 lines (119 loc) · 3.28 KB
/
urlimport.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package ui
import (
"context"
"errors"
"fmt"
"path/filepath"
"strings"
"sync"
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
"github.com/samber/lo"
"github.com/koho/frpmgr/i18n"
"github.com/koho/frpmgr/pkg/res"
"github.com/koho/frpmgr/pkg/util"
)
type URLImportDialog struct {
*walk.Dialog
db *walk.DataBinder
viewModel urlImportViewModel
// Views
statusText *walk.Label
// Items contain the downloaded data from URLs
Items []URLConf
}
type urlImportViewModel struct {
URLs string
Rename bool
Working bool
}
// URLConf provides config data downloaded from URL
type URLConf struct {
// Filename is the name of the downloaded file
Filename string
// Zip defines whether the Data is a zip file
Zip bool
// Rename defines whether we can change the name of
// new config if the original name exists.
Rename bool
// Downloaded raw Data from URL
Data []byte
}
func NewURLImportDialog() *URLImportDialog {
return &URLImportDialog{Items: make([]URLConf, 0)}
}
func (ud *URLImportDialog) Run(owner walk.Form) (int, error) {
return NewBasicDialog(&ud.Dialog, i18n.Sprintf("Import from URL"), loadIcon(res.IconURLImport, 32),
DataBinder{AssignTo: &ud.db, DataSource: &ud.viewModel, Name: "vm"}, ud.onImport,
Label{Text: i18n.Sprintf("* Support batch import, one link per line.")},
TextEdit{
Enabled: Bind("!vm.Working"),
Text: Bind("URLs", res.ValidateNonEmpty),
VScroll: true,
MinSize: Size{Width: 430, Height: 130},
},
CheckBox{
Enabled: Bind("!vm.Working"),
Text: i18n.Sprintf("Rename automatically"),
Alignment: AlignHNearVCenter,
Checked: Bind("Rename"),
},
Label{
AssignTo: &ud.statusText,
Text: fmt.Sprintf("%s: %s", i18n.Sprintf("Status"), i18n.Sprintf("Ready")),
EllipsisMode: EllipsisEnd,
},
VSpacer{Size: 4},
).Run(owner)
}
func (ud *URLImportDialog) onImport() {
if err := ud.db.Submit(); err != nil {
return
}
urls := strings.Split(ud.viewModel.URLs, "\n")
urls = lo.FilterMap(urls, func(s string, i int) (string, bool) {
s = strings.TrimSpace(s)
return s, s != ""
})
if len(urls) == 0 {
showWarningMessage(ud.Form(),
i18n.Sprintf("Import Config"),
i18n.Sprintf("Please enter the correct URL list."))
return
}
ud.viewModel.Working = true
ud.DefaultButton().SetEnabled(false)
ud.db.Reset()
ctx, cancel := context.WithCancel(context.Background())
var wg sync.WaitGroup
wg.Add(1)
ud.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
cancel()
wg.Wait()
})
go ud.urlImport(ctx, &wg, urls)
}
func (ud *URLImportDialog) urlImport(ctx context.Context, wg *sync.WaitGroup, urls []string) {
result := walk.DlgCmdOK
defer func() { ud.Close(result) }()
defer wg.Done()
for i, url := range urls {
ud.statusText.SetText(fmt.Sprintf("%s: [%d/%d] %s %s",
i18n.Sprintf("Status"), i+1, len(urls), i18n.Sprintf("Download"), url,
))
filename, mediaType, data, err := util.DownloadFile(ctx, url)
if errors.Is(err, context.Canceled) {
result = walk.DlgCmdCancel
return
} else if err != nil {
showError(err, ud.Form())
continue
}
ud.Items = append(ud.Items, URLConf{
Filename: filename,
Zip: mediaType == "application/zip" || strings.ToLower(filepath.Ext(filename)) == ".zip",
Rename: ud.viewModel.Rename,
Data: data,
})
}
}