Portable qbittorent categories search (#45)

* cesu8 handler

* resume file cesu8 handle

* utf8 emoji filepaths

* cesu8 emoji filepaths and torrent names

* cesu8 emoji filepaths and torrent names handling
improve tests

* add fastresume Name field

* update golang ver

* handle torrent files with cesu8 encoded file paths and handle them as NoSubfolder torrents for better compatibility

* fix cesu8 named single file torrents

* search categories json in case portable qBittorrent
This commit is contained in:
Alexey Kostin 2023-11-25 22:48:45 +03:00 committed by GitHub
parent fda659db74
commit 61abb0345d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 2 deletions

View File

@ -3,6 +3,7 @@ package options
import ( import (
"fmt" "fmt"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/rumanzo/bt2qbt/pkg/fileHelpers"
"log" "log"
"os" "os"
"os/user" "os/user"
@ -64,8 +65,20 @@ func ParseOpts(opts *Opts) *Opts {
return opts return opts
} }
// HandleOpts used for enrichment opts after first creation
func HandleOpts(opts *Opts) { func HandleOpts(opts *Opts) {
opts.SearchPaths = append(opts.SearchPaths, opts.BitDir) opts.SearchPaths = append(opts.SearchPaths, opts.BitDir)
qbtDir := fileHelpers.Normalize(opts.QBitDir, `/`)
if strings.Contains(qbtDir, `profile/qBittorrent/data/BT_backup`) {
qbtRootDir, _ := strings.CutSuffix(qbtDir, `data/BT_backup`)
// check that user not define categories
refOpts := MakeOpts()
if refOpts.Categories == opts.Categories {
opts.Categories = fileHelpers.Join([]string{qbtRootDir, `config/categories.json`}, opts.PathSeparator)
}
}
} }
func OptsCheck(opts *Opts) error { func OptsCheck(opts *Opts) error {

View File

@ -1,7 +1,9 @@
package options package options
import ( import (
"github.com/davecgh/go-spew/spew"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/r3labs/diff/v2"
"reflect" "reflect"
"testing" "testing"
) )
@ -82,7 +84,11 @@ func TestOptionsArgs(t *testing.T) {
} }
if testCase.expected != nil { if testCase.expected != nil {
if !reflect.DeepEqual(testCase.expected, opts) && !testCase.mustFail { if !reflect.DeepEqual(testCase.expected, opts) && !testCase.mustFail {
t.Fatalf("Unexpected error: opts isn't equoptions:\n Got: %#v\n Expect %#v\n", opts, testCase.expected) changes, err := diff.Diff(opts, testCase.expected, diff.DiscardComplexOrigin())
if err != nil {
t.Error(err.Error())
}
t.Fatalf("Unexpected error: opts isn't equoptions:\nGot: %#v\nExpect %#v\nDiff: %v\\n", opts, testCase.expected, spew.Sdump(changes))
} }
} }
}) })
@ -121,14 +127,57 @@ func TestOptionsHandle(t *testing.T) {
SearchPaths: []string{"/dir5", "/dir6/", "/bitdir"}, SearchPaths: []string{"/dir5", "/dir6/", "/bitdir"},
}, },
}, },
{
name: "003 Parse portable args test",
opts: &Opts{
BitDir: `/dir1`,
QBitDir: `C:\btportable\profile\qBittorrent\data\BT_backup\`,
PathSeparator: `\`,
SearchPaths: []string{},
},
mustFail: false,
expected: &Opts{
BitDir: `/dir1`,
QBitDir: `C:\btportable\profile\qBittorrent\data\BT_backup\`,
Categories: `C:\btportable\profile\qBittorrent\config\categories.json`,
SearchPaths: []string{`/dir1`},
PathSeparator: `\`,
},
},
{
name: "004 Parse portable args test with categories file",
opts: &Opts{
BitDir: `/dir1`,
QBitDir: `C:\btportable\profile\qBittorrent\data\BT_backup\`,
Categories: `C:\categories.json`,
PathSeparator: `\`,
SearchPaths: []string{},
},
mustFail: false,
expected: &Opts{
BitDir: `/dir1`,
QBitDir: `C:\btportable\profile\qBittorrent\data\BT_backup\`,
Categories: `C:\categories.json`,
SearchPaths: []string{`/dir1`},
PathSeparator: `\`,
},
},
} }
for _, testCase := range cases { for _, testCase := range cases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
if testCase.opts.Categories == `` {
refOpts := MakeOpts()
testCase.opts.Categories = refOpts.Categories
}
HandleOpts(testCase.opts) HandleOpts(testCase.opts)
if testCase.expected != nil { if testCase.expected != nil {
changes, err := diff.Diff(testCase.opts, testCase.expected, diff.DiscardComplexOrigin())
if err != nil {
t.Error(err.Error())
}
if !reflect.DeepEqual(testCase.expected, testCase.opts) && !testCase.mustFail { if !reflect.DeepEqual(testCase.expected, testCase.opts) && !testCase.mustFail {
t.Fatalf("Unexpected error: opts isn't equal:\n Got: %#v\n Expect %#v\n", testCase.opts, testCase.expected) t.Fatalf("Unexpected error: opts isn't equal:\nGot: %#v\nExpect %#v\nDiff: %v\\\\n", testCase.opts, testCase.expected, spew.Sdump(changes))
} }
} }
}) })