Compare commits

..
8 Commits
16 changed files with 306 additions and 75 deletions

No files matched your search

+6 -1
View File
@@ -299,6 +299,7 @@ jobs:
extensions: [gnome]
plugs:
- network
- home
slots:
- dbus-gopeed
parts:
@@ -324,8 +325,12 @@ jobs:
- xz-utils
- zip
override-prime: ''
zenity:
plugin: nil
stage-packages:
- zenity
gopeed:
after: [flutter-git]
after: [flutter-git,zenity]
source: .
plugin: nil
stage-packages:
+1
View File
@@ -21,6 +21,7 @@ The internationalization files of Gopeed are located in the `ui/flutter/lib/i18n
You only need to add the corresponding language file in this directory.
Please refer to `en_us.dart` for translation.
words prefixed with `@` are not meant to be translated.
## flutter development
+5 -7
View File
@@ -12,7 +12,7 @@ require (
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/matoous/go-nanoid/v2 v2.0.0
github.com/mattn/go-ieproxy v0.0.11
github.com/mattn/go-ieproxy v0.0.12
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.31.0
github.com/virtuald/go-paniclog v0.0.0-20190812204905-43a7fa316459
@@ -101,11 +101,11 @@ require (
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.17.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
@@ -116,5 +116,3 @@ require (
modernc.org/sqlite v1.28.0 // indirect
zombiezen.com/go/sqlite v1.1.0 // indirect
)
replace github.com/mattn/go-ieproxy => github.com/GopeedLab/go-ieproxy v0.0.0-20240508033154-86b7091da074
+12 -12
View File
@@ -7,8 +7,6 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/GopeedLab/go-ieproxy v0.0.0-20240508033154-86b7091da074 h1:WTv/RQaUwPUWxX26kcRFp/kvSapYSKnw/viPtTH1ZTY=
github.com/GopeedLab/go-ieproxy v0.0.0-20240508033154-86b7091da074/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
@@ -282,6 +280,8 @@ github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-ieproxy v0.0.12 h1:OZkUFJC3ESNZPQ+6LzC3VJIFSnreeFLQyqvBWtvfL2M=
github.com/mattn/go-ieproxy v0.0.12/go.mod h1:Vn+N61199DAnVeTgaF8eoB9PvLO8P3OBnG95ENh7B7c=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -466,8 +466,8 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
@@ -512,8 +512,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -568,8 +568,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -582,8 +582,8 @@ golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -598,8 +598,8 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+4
View File
@@ -145,6 +145,10 @@ func NewEngine(cfg *Config) *Engine {
if err := runtime.Set("global", runtime.GlobalObject()); err != nil {
return
}
// polyfill window
if err := runtime.Set("window", runtime.GlobalObject()); err != nil {
return
}
// polyfill window.location
if _, err := runtime.RunString("global.location = new URL('http://localhost');"); err != nil {
return
+40 -2
View File
@@ -80,6 +80,30 @@ async function testFormData(file){
return await resp.json();
}
function testHeader(){
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', host+'/header');
xhr.setRequestHeader('X-Gopeed-Test', 'test1');
xhr.setRequestHeader('x-gopeed-test', 'test2');
xhr.setRequestHeader('x-Gopeed-test', 'test3');
xhr.onload = function(){
const testHeader1 = xhr.getResponseHeader("X-Gopeed-Test");
const testHeader2 = xhr.getResponseHeader("x-gopeed-test");
const testHeader3 = xhr.getResponseHeader("x-Gopeed-test");
const expect = 'test1, test2, test3';
const all = xhr.getAllResponseHeaders();
if(testHeader1 === expect && testHeader2 === expect && testHeader3 === expect
&& all.includes('X-Gopeed-Test: '+expect)){
resolve();
}else{
reject();
}
};
xhr.send();
});
}
function testProgress(){
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
@@ -190,14 +214,19 @@ function testTimeout(){
}
}()
_, err = callTestFun(engine, "testHeader")
if err != nil {
t.Fatal("header test failed", err)
}
_, err = callTestFun(engine, "testProgress")
if err != nil {
t.Fatal("progress test failed")
t.Fatal("progress test failed", err)
}
_, err = callTestFun(engine, "testAbort")
if err != nil {
t.Fatal("abort test failed")
t.Fatal("abort test failed", err)
}
_, err = callTestFun(engine, "testTimeout")
@@ -328,6 +357,15 @@ func startServer() net.Listener {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
})
mux.HandleFunc("/header", func(w http.ResponseWriter, r *http.Request) {
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Gopeed") {
w.Header().Set(k, strings.Join(v, ", "))
}
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
})
mux.HandleFunc("/text", func(w http.ResponseWriter, r *http.Request) {
buf, _ := io.ReadAll(r.Body)
w.WriteHeader(http.StatusOK)
+10 -13
View File
@@ -12,6 +12,7 @@ import (
"net"
"net/http"
"net/url"
"strings"
"time"
)
@@ -118,8 +119,8 @@ type XMLHttpRequestUpload struct {
type XMLHttpRequest struct {
method string
url string
requestHeaders map[string]string
responseHeaders map[string]string
requestHeaders http.Header
responseHeaders http.Header
aborted bool
proxyHandler func(r *http.Request) (*url.URL, error)
@@ -137,13 +138,13 @@ type XMLHttpRequest struct {
func (xhr *XMLHttpRequest) Open(method, url string) {
xhr.method = method
xhr.url = url
xhr.requestHeaders = make(map[string]string)
xhr.responseHeaders = make(map[string]string)
xhr.requestHeaders = make(http.Header)
xhr.responseHeaders = make(http.Header)
xhr.doReadystatechange(1)
}
func (xhr *XMLHttpRequest) SetRequestHeader(key, value string) {
xhr.requestHeaders[key] = value
xhr.requestHeaders.Add(key, value)
}
func (xhr *XMLHttpRequest) Send(data goja.Value) {
@@ -194,15 +195,13 @@ func (xhr *XMLHttpRequest) Send(data goja.Value) {
xhr.callOnerror()
return
}
req.Header = xhr.requestHeaders
if contentType != "" {
req.Header.Set("Content-Type", contentType)
}
if contentLength > 0 {
req.ContentLength = contentLength
}
for k, v := range xhr.requestHeaders {
req.Header.Set(k, v)
}
transport := &http.Transport{
Proxy: xhr.proxyHandler,
}
@@ -230,9 +229,7 @@ func (xhr *XMLHttpRequest) Send(data goja.Value) {
if !xhr.aborted {
xhr.Upload.callOnload()
}
for k, v := range resp.Header {
xhr.responseHeaders[k] = v[0]
}
xhr.responseHeaders = resp.Header
xhr.Status = resp.StatusCode
xhr.StatusText = resp.Status
xhr.doReadystatechange(2)
@@ -261,7 +258,7 @@ func (xhr *XMLHttpRequest) Abort() {
}
func (xhr *XMLHttpRequest) GetResponseHeader(key string) string {
return xhr.responseHeaders[key]
return strings.Join(xhr.responseHeaders.Values(key), ", ")
}
func (xhr *XMLHttpRequest) GetAllResponseHeaders() string {
@@ -269,7 +266,7 @@ func (xhr *XMLHttpRequest) GetAllResponseHeaders() string {
for k, v := range xhr.responseHeaders {
buf.WriteString(k)
buf.WriteString(": ")
buf.WriteString(v)
buf.WriteString(strings.Join(v, ", "))
buf.WriteString("\r\n")
}
return buf.String()
+1 -1
View File
@@ -238,7 +238,7 @@ func TestDownloader_Extension_OnError(t *testing.T) {
select {
case err = <-errCh:
break
case <-time.After(time.Second * 10):
case <-time.After(time.Second * 30):
err = errors.New("timeout")
}
+18 -7
View File
@@ -19,31 +19,42 @@ import (
)
var (
srv *http.Server
srv *http.Server
runningPort int
Downloader *download.Downloader
)
func Start(startCfg *model.StartConfig) (int, error) {
srv, listener, err := BuildServer(startCfg)
func Start(startCfg *model.StartConfig) (port int, err error) {
// avoid repeat start
if srv != nil {
return runningPort, nil
}
var listener net.Listener
srv, listener, err = BuildServer(startCfg)
if err != nil {
return 0, err
return
}
go func() {
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
if err := srv.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
panic(err)
}
}()
port := 0
if addr, ok := listener.Addr().(*net.TCPAddr); ok {
port = addr.Port
runningPort = port
}
return port, nil
return
}
func Stop() {
defer func() {
srv = nil
}()
if srv != nil {
if err := srv.Shutdown(context.TODO()); err != nil {
Downloader.Logger.Warn().Err(err).Msg("shutdown server failed")
@@ -301,7 +301,7 @@ class CreateView extends GetView<CreateController> {
controller: _btTrackerController,
maxLines: 5,
decoration: InputDecoration(
labelText: 'Trakers',
labelText: 'Trackers',
hintText: 'addTrackerHit'.tr,
)),
],
-9
View File
@@ -54,15 +54,6 @@ class Database {
_startConfig, (json) => StartConfigEntity.fromJson(json));
}
void saveLastRunningConfig(StartConfigEntity entity) {
save<StartConfigEntity>(_lastRunningConfig, entity);
}
StartConfigEntity? getLastRunningConfig() {
return get<StartConfigEntity>(
_lastRunningConfig, (json) => StartConfigEntity.fromJson(json));
}
/// Patch non-null fields with the original value
void saveWindowState(WindowStateEntity entity) {
final state = getWindowState();
+100
View File
@@ -0,0 +1,100 @@
const itIT = {
'it_IT': {
'label': 'Italiano',
'error': 'Errore',
'tip': 'Suggerimento',
'confirm': 'Conferma',
'cancel': 'Annullla',
'on': 'Acceso',
'off': 'Spento',
'selectAll': 'Seleziona tutto',
'task': 'Attività',
'downloading': 'scaricamento in corso',
'downloaded': 'scaricato',
'setting': 'Impostazioni',
'donate': 'Donazione',
'exit': 'Uscita',
'create': 'Crea attività',
'directDownload': 'Scaricamento diretto',
'advancedOptions': 'Opzioni avanzate',
'downloadLink': 'Link di scaricamento',
'downloadLinkValid': 'Inserisci il collegamento per lo scaricamento',
'downloadLinkHit':
'Inserisci il collegamento per il download, HTTP/HTTPS/MAGNET supported@append',
'downloadLinkHitDesktop':
', oppure trascina qui direttamente il file torrent',
'download': 'Download',
'noFileSelected': 'Seleziona almeno un file per continuare.',
'noStoragePermission': "È richiesta l'autorizzazione di archiviazione",
'selectFile': 'Selezione file',
'rename': 'Rinomina',
'basic': 'Basico',
'advanced': 'Avanzato',
'general': 'Generale',
'downloadDir': 'Directory di scaricamento',
'downloadDirValid': 'Seleziona la directory di scaricamento',
'connections': 'Connessioni',
'useServerCtime': "Utilizza l'ora del server per la creazione dei file",
'maxRunning': 'Numero massimo di attività in esecuzione',
'items': '@count elementi',
'subscribeTracker': 'Iscriviti al tracker',
'subscribeFail':
'Iscrizione non riuscita, controlla la rete o riprova più tardir',
'update': 'Aggiornaento',
'updateDaily': 'Aggiornamento quotidiano',
'lastUpdate': 'Ultimo aggiornamento: @time',
'addTracker': 'Aggiungi Tracker',
'addTrackerHit': "Inserisci l'URL del server del tracker, uno per riga",
'ui': 'UI',
'theme': 'Tema',
'themeSystem': 'Sistema',
'themeLight': 'Chiaro',
'themeDark': 'Scuro',
'locale': 'Lingua',
'about': 'Informazioni',
'homepage': 'Homepage',
'version': 'Versione',
'protocol': 'Protocollo',
'port': 'Porta',
'apiToken': 'Token API',
'notSet': 'NS',
'set': 'SET',
'portInUse': 'La porta [@port] è in uso, per favore cambia la porta',
'effectAfterRestart': 'Effetto dopo il riavvio',
'show': 'Mostra',
'startAll': 'Avvia tutti',
'pauseAll': 'Mtti in pausa tutti',
'deleteTask': 'Elimina attività',
'deleteTaskTip': 'Conserva i file scaricati',
'delete': 'Elimina',
'newVersionTitle': 'Scopri la nuova versione @version',
'newVersionUpdate': 'Aggiorna ora',
'newVersionLater': 'Dopo',
'extensions': 'Estensioni',
'extensionInstallUrl': 'Installa URL',
'extensionInstallSuccess': 'Installato con successo',
'extensionUpdateSuccess': 'Aggiornato con successo',
'extensionDelete': 'Elimina estensione',
'extensionAlreadyLatest': "È già l'ultima versione",
'extensionFind': 'Trova estensioni',
'extensionDevelop': 'Sviluppare estensioni',
'history': 'Cronologia',
'clearHistory': 'Pulisci cronologia',
'noHistoryFound': 'Nessuna cronologia trovata',
'serviceTitle': 'Scarica il servizio',
'serviceText': 'In esecuzione',
'network': 'Rete',
'proxy': 'Proxy',
'noProxy': 'Nessun Proxy',
'systemProxy': 'Sistema Proxy',
'customProxy': 'Proxy personalizzato',
'server': 'Server',
'username': 'Nome utente',
'password': 'Password',
'thanks': 'Ringraziamenti',
'thanksDesc':
'Grazie a tutti i contributori che hanno contribuito a costruire e sviluppare la comunità Gopeed!',
'browserExtension': 'Estensione del browser',
'launchAtStartup': "Lancia all'avvio",
},
};
+3 -3
View File
@@ -20,10 +20,10 @@ const plPL = {
'downloadLink': 'Pobierz z linku',
'downloadLinkValid': 'Otwórz link pobierania',
'downloadLinkHit':
'Otwórz link pobierania, HTTP/HTTPS/MAGNET supported@append',
'Otwórz link pobierania, HTTP/HTTPS/MAGNET wspierane@append',
'downloadLinkHitDesktop': ', lub przenieś bezpośrednio plik torrent',
'download': 'Pobiers',
'noFileSelected': 'Wybierz conajmniej jeden plik aby kontynuować.',
'download': 'Pobierz',
'noFileSelected': 'Wybierz co najmniej jeden plik aby kontynuować.',
'noStoragePermission': 'Przyznaj uprawnienia do zapisu',
'selectFile': 'Wybierz plik',
'rename': 'Zmień nazwę',
+99
View File
@@ -0,0 +1,99 @@
const taTA = {
'ta_TA': {
'label': 'தமிழ்',
'error': 'பிழை',
'tip': 'குறிப்பு',
'confirm': 'சரி',
'cancel': 'ரத்துசெய்',
'on': 'On',
'off': 'Off',
'selectAll': 'அனைத்தையும் தேர்வுசெய்',
'task': 'பணிகள்',
'downloading': 'பதிவிறக்குகிறது',
'downloaded': 'பதிவிறக்கம் செய்யப்பட்டது',
'setting': 'அமைப்புகள் ',
'donate': 'நன்கொடை',
'exit': 'வெளியேறு',
'create': 'பணியை உருவாக்கு',
'directDownload': 'நேரடி பதிவிறக்கம்',
'advancedOptions': 'மேம்பட்ட விருப்பங்கள்',
'downloadLink': 'தரவிறக்க இணைப்பு',
'downloadLinkValid': 'பதிவிறக்க இணைப்பை உள்ளிடவும்',
'downloadLinkHit':
'பதிவிறக்க இணைப்பை உள்ளிடவும், HTTP/HTTPS/MAGNET ஆகியவற்றை ஏற்கும்@append',
'downloadLinkHitDesktop': ', அல்லது torrent கோப்பை நேரடியாக இங்கே இழுக்கவும்',
'download': 'பதிவிறக்கு',
'noFileSelected': 'குறைந்தபட்சம் ஒரு கோப்பைத் தேர்ந்தெடுக்கவும்.',
'noStoragePermission': 'சேமிப்பக அனுமதி தேவை',
'selectFile': 'கோப்பைத் தேர்ந்தெடுக்கவும்',
'rename': 'பெயறைமாற்று',
'basic': 'அடிப்படை',
'advanced': 'மேம்பட்ட',
'general': 'பொதுவான',
'downloadDir': 'பதிவிரக்குமிடம்',
'downloadDirValid': 'பதிவிரக்குமிடத்தை தேர்வு செயுங்கள்',
'connections': 'தொடர்புகள்',
'useServerCtime': 'Use server time for file creation',
'maxRunning': 'அதிகபட்ச இயங்கும் பணிகள்',
'items': '@count items',
'subscribeTracker': 'Subscribe Tracker',
'subscribeFail':
'Subscribe failed, please check network or try again later',
'update': 'புதுப்பிக்கவும்',
'updateDaily': 'தினமும் புதுப்பிக்கவும்',
'lastUpdate': 'கடைசியாக புதுப்பிக்கப்பட்டது: @time',
'addTracker': 'Trackerஐ சேர்',
'addTrackerHit': 'Please enter the tracker server url, one per line',
'ui': 'UI',
'theme': 'தீம்',
'themeSystem': 'இயல்புநிலை',
'themeLight': 'வெண்மையானநிலை',
'themeDark': 'இருண்டநிலை',
'locale': 'மொழி',
'about': 'எங்களை பற்றி',
'homepage': 'முகப்புப்பக்கம்',
'version': 'பதிப்பு',
'protocol': 'நெறிமுறை',
'port': 'Port',
'apiToken': 'API Token',
'notSet': 'NS',
'set': 'SET',
'portInUse': 'Port [@port] is in use, please change the port',
'effectAfterRestart': 'Effect after restart',
'show': 'காட்டு',
'startAll': 'அனைத்தையும் தொடங்கு',
'pauseAll': 'அனைத்தையும் நிறுத்திவை',
'deleteTask': 'பணியை நீக்கு',
'deleteTaskTip': 'பதிவிறக்கம் செய்யப்பட்ட கோப்புகளை வைத்திரு',
'delete': 'நீக்கு',
'newVersionTitle': 'புதிய பதிப்பைக் கண்டறியவும் @version',
'newVersionUpdate': 'இப்பொழுது புதுப்பி',
'newVersionLater': 'பின்னர்',
'extensions': 'நீட்டிப்புகள்',
'extensionInstallUrl': 'நிறுவப்படும் URL',
'extensionInstallSuccess': 'வெற்றிகரமாக நிறுவப்பட்டது',
'extensionUpdateSuccess': 'வெற்றிகரமாக புதுப்பிக்கப்பட்டது',
'extensionDelete': 'நீட்டிப்பை நீக்கு',
'extensionAlreadyLatest': 'இது ஏற்கனவே சமீபத்திய பதிப்பாகும்',
'extensionFind': 'நீட்டிப்புகளைக் கண்டறியவும்',
'extensionDevelop': 'நீட்டிப்புகளை உருவாக்கவும்',
'history': 'வரலாறு',
'clearHistory': 'உள்ளீடுகளை நீக்கு',
'noHistoryFound': 'உள்ளீடுகள் இல்லை',
'serviceTitle': 'பதிவிறக்க சேவை',
'serviceText': 'இயக்கத்தில் உள்ளது',
'network': 'வலைப்பின்னல்',
'proxy': 'பதிலி',
'noProxy': 'பதிலி இல்லாமல் ',
'systemProxy': 'இயல்புநிலை பதிலி',
'customProxy': 'மாற்றியமைக்கப்பட்ட பதிலி',
'server': 'சேவையகம்',
'username': 'பயனர் பெயர்',
'password': 'கடவுச்சொல்',
'thanks': 'நன்றி',
'thanksDesc':
'Gopeed சமூகத்தை உருவாக்கவும் மற்றும் மேம்படுத்த உதவிய அனைத்து பங்களிப்பாளர்களுக்கும் நன்றி!',
'browserExtension': 'உலாவி நீட்டிப்பு',
'launchAtStartup': 'தொடக்கத்தின் போது இயங்கு',
},
};
+4
View File
@@ -2,9 +2,11 @@ import 'package:get/get.dart';
import 'langs/en_us.dart';
import 'langs/fa_ir.dart';
import 'langs/it_it.dart';
import 'langs/ja_jp.dart';
import 'langs/pl_pl.dart';
import 'langs/ru_ru.dart';
import 'langs/ta_ta.dart';
import 'langs/tr_tr.dart';
import 'langs/vi_vn.dart';
import 'langs/zh_cn.dart';
@@ -23,7 +25,9 @@ class _Messages extends Translations {
...faIR,
...jaJP,
...viVN,
...taTA,
...trTR,
...plPL,
...itIT,
};
}
+2 -19
View File
@@ -1,7 +1,6 @@
import 'package:args/args.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
import 'package:get/get.dart';
import 'package:window_manager/window_manager.dart';
@@ -10,7 +9,6 @@ import 'app/modules/app/controllers/app_controller.dart';
import 'app/modules/app/views/app_view.dart';
import 'core/libgopeed_boot.dart';
import 'database/database.dart';
import 'database/entity.dart';
import 'i18n/message.dart';
import 'util/locale_manager.dart';
import 'util/log_util.dart';
@@ -77,23 +75,8 @@ Future<void> init(Args args) async {
try {
await controller.loadStartConfig();
final startCfg = controller.startConfig.value;
// When the app is closed by swiping on the mobile, the backend server is actually still running, don't need to start again.
final isRunning =
Util.isMobile() && (await FlutterForegroundTask.isRunningService);
if (!isRunning) {
controller.runningPort.value =
await LibgopeedBoot.instance.start(startCfg);
api.init(
startCfg.network, controller.runningAddress(), startCfg.apiToken);
Database.instance.saveLastRunningConfig(StartConfigEntity(
network: startCfg.network,
address: controller.runningAddress(),
apiToken: startCfg.apiToken));
} else {
final lastRunningConfig = Database.instance.getLastRunningConfig()!;
api.init(lastRunningConfig.network, lastRunningConfig.address,
lastRunningConfig.apiToken);
}
controller.runningPort.value = await LibgopeedBoot.instance.start(startCfg);
api.init(startCfg.network, controller.runningAddress(), startCfg.apiToken);
} catch (e) {
logger.e("libgopeed init fail", e);
}