From 74beea6044b2a1cb2957e812ef61a4b9552121e0 Mon Sep 17 00:00:00 2001 From: Levi Date: Thu, 18 Jan 2024 18:38:44 +0800 Subject: [PATCH] feat: auto create torrent task for http download (#334) --- pkg/download/downloader.go | 21 ++++++++++++++++ pkg/protocol/http/model.go | 2 ++ ui/flutter/lib/api/model/options.dart | 1 + ui/flutter/lib/api/model/options.g.dart | 5 +++- .../app/modules/create/views/create_view.dart | 24 +++++++++++-------- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/pkg/download/downloader.go b/pkg/download/downloader.go index cfdb5e78..766d2859 100644 --- a/pkg/download/downloader.go +++ b/pkg/download/downloader.go @@ -6,6 +6,7 @@ import ( "github.com/GopeedLab/gopeed/internal/fetcher" "github.com/GopeedLab/gopeed/internal/logger" "github.com/GopeedLab/gopeed/pkg/base" + "github.com/GopeedLab/gopeed/pkg/protocol/http" "github.com/GopeedLab/gopeed/pkg/util" gonanoid "github.com/matoous/go-nanoid/v2" "github.com/rs/zerolog" @@ -594,6 +595,26 @@ func (d *Downloader) watch(task *Task) { d.emit(EventKeyDone, task) d.emit(EventKeyFinally, task, err) d.notifyRunning() + + if e, ok := task.Meta.Opts.Extra.(*http.OptsExtra); ok { + downloadFilePath := task.Meta.SingleFilepath() + if e.AutoTorrent && strings.HasSuffix(downloadFilePath, ".torrent") { + go func() { + _, err2 := d.CreateDirect( + &base.Request{ + URL: downloadFilePath, + }, + &base.Options{ + Path: task.Meta.Opts.Path, + SelectFiles: make([]int, 0), + }) + if err2 != nil { + d.Logger.Error().Err(err2).Msgf("auto create torrent task failed, task id: %s", task.ID) + } + + }() + } + } } func (d *Downloader) doOnError(task *Task, err error) { diff --git a/pkg/protocol/http/model.go b/pkg/protocol/http/model.go index 94f1a4a1..0115b2e1 100644 --- a/pkg/protocol/http/model.go +++ b/pkg/protocol/http/model.go @@ -8,6 +8,8 @@ type ReqExtra struct { type OptsExtra struct { Connections int `json:"connections"` + // AutoTorrent when task download complete, and it is a .torrent file, it will be auto create a new task for the torrent file + AutoTorrent bool `json:"autoTorrent"` } // Stats for download diff --git a/ui/flutter/lib/api/model/options.dart b/ui/flutter/lib/api/model/options.dart index 2cc82f23..52342059 100644 --- a/ui/flutter/lib/api/model/options.dart +++ b/ui/flutter/lib/api/model/options.dart @@ -25,6 +25,7 @@ class Options { @JsonSerializable() class OptsExtraHttp { int connections = 0; + bool autoTorrent = false; OptsExtraHttp(); diff --git a/ui/flutter/lib/api/model/options.g.dart b/ui/flutter/lib/api/model/options.g.dart index 5465943f..3d8394b9 100644 --- a/ui/flutter/lib/api/model/options.g.dart +++ b/ui/flutter/lib/api/model/options.g.dart @@ -32,9 +32,12 @@ Map _$OptionsToJson(Options instance) { } OptsExtraHttp _$OptsExtraHttpFromJson(Map json) => - OptsExtraHttp()..connections = json['connections'] as int; + OptsExtraHttp() + ..connections = json['connections'] as int + ..autoTorrent = json['autoTorrent'] as bool; Map _$OptsExtraHttpToJson(OptsExtraHttp instance) => { 'connections': instance.connections, + 'autoTorrent': instance.autoTorrent, }; diff --git a/ui/flutter/lib/app/modules/create/views/create_view.dart b/ui/flutter/lib/app/modules/create/views/create_view.dart index f3ec3e2b..5fe96dea 100644 --- a/ui/flutter/lib/app/modules/create/views/create_view.dart +++ b/ui/flutter/lib/app/modules/create/views/create_view.dart @@ -409,15 +409,20 @@ class CreateView extends GetView { try { _confirmController.start(); if (_confirmFormKey.currentState!.validate()) { - final submitUrl = Util.isWeb() && controller.fileDataUri.isNotEmpty + final isWebFileChosen = + Util.isWeb() && controller.fileDataUri.isNotEmpty; + final submitUrl = isWebFileChosen ? controller.fileDataUri.value : _urlController.text; final urls = Util.textToLines(submitUrl); // Add url to the history - for (final url in urls) { - _historyController.addHistory(url); + if (!isWebFileChosen) { + for (final url in urls) { + _historyController.addHistory(url); + } } + /* Check if is direct download, there has two ways to direct download 1. Direct download option is checked @@ -433,7 +438,7 @@ class CreateView extends GetView { name: isMultiLine ? "" : _renameController.text, path: _pathController.text, selectFiles: [], - extra: parseReqOpts()))); + extra: parseReqOptsExtra()))); })); Get.rootDelegate.offNamed(Routes.TASK); } else { @@ -471,11 +476,10 @@ class CreateView extends GetView { return reqExtra; } - Object? parseReqOpts() { - return _connectionsController.text.isEmpty - ? null - : (OptsExtraHttp() - ..connections = int.parse(_connectionsController.text)); + Object? parseReqOptsExtra() { + return OptsExtraHttp() + ..connections = int.tryParse(_connectionsController.text) ?? 0 + ..autoTorrent = true; } String _hitText() { @@ -541,7 +545,7 @@ class CreateView extends GetView { showMessage('tip'.tr, 'noFileSelected'.tr); return; } - final optExtra = parseReqOpts(); + final optExtra = parseReqOptsExtra(); if (createFormKey.currentState!.validate()) { if (rr.id.isEmpty) { // from extension resolve result