bt2qbt/pkg/fileHelpers/file.go
Alexey Kostin cca7869d2a
Full refactor. Introduce tests (#35)
* start refactor

* default golang loyaout
separate qbittorrent and torrent structures

* stage

* move flags handle to module and cover it with tests
change handle sep with path.join

* ugly remove unneeded fields from resume.dat

* use path joing
prepare for resume structs

* Introduce subtests

* fix behavior

* Move to structures instead of using interfaces

* Make main cmd clean, decomposite functions

* Make main cmd clean, decomposite functions

* Detect torrents functions and tests

* Fixes

* Fixes

* New tests for content layout and file paths
reformat code for project
change libtorrent version
append torrent v2 schema in torrent structs

* filepath helper module
fix some tests

* fileHelpers new functions and tests

* new function with cut last part with tests

* function description and small fix

* rename some variables and structures

* beautiful tests handle for savePaths
starting refactor savepaths

* Refactor HandleSavePath func. Cover with tests
Move replace field creation to handle and assign pointer, instead of generate each time with handle resumeItem.
Moved opts to transferStructure.

* fix some tests

* HandleSavePaths covered with tests and little bit fixed

* Another one additional test for fully function cover

* check for tests

* Remove PiecePriority

* Refactored HandlePieces functions
Removed unused functions

* Rename variables. Introduced new tests

* Append tests

* Rename test funcs

* New tests

* New tests

* move modules

* introduce Makefile

* Adapt fileHelpers for both windows and linux. Linux tests passed
Use slashed paths for search torrents

* remove test template

* test fileset

* Makefile. Version introduce

* Fix darwin i386 version build

* Bug fix with mappedfiles
Need more tests and append new functionality.

* tests for HandleSavePaths with absoulte paths in mapped files

* additional tests with fileshare

* all tests OK

* Fix torrent state. Added tests

* fixes after code inspection

* Magnet link support. Tests

* README.md update

Co-authored-by: Alexey Kostin <a.kostin@corp.mail.ru>
2022-03-30 02:30:29 +03:00

113 lines
3.0 KiB
Go

package fileHelpers
/* Default go filepath works wrong with some windows paths like windows shares (\\somepath), use only os.PathSeparator and so on*/
import (
"path/filepath"
"regexp"
"strings"
)
var checkAbsRegExp = regexp.MustCompile(`^(([A-Za-z]:)(\\\\?|/)|(\\\\|//))`)
var checkIsShareRegExp = regexp.MustCompile(`^(//|\\\\)`)
var rootPathRegexp = regexp.MustCompile(`^(\.\.?([/\\])|[A-Za-z]:([/\\])|(//?|\\\\))`)
func IsAbs(filePath string) bool {
if checkAbsRegExp.MatchString(filePath) {
return true
}
return false
}
func Join(filePaths []string, separator string) string {
var filePath string
if checkIsShareRegExp.MatchString(filePaths[0]) {
prefix := filePaths[0][:2]
filePaths[0] = filePaths[0][2:]
filePath = filepath.Join(filePaths...)
filePath = prefix + filePath
} else {
filePath = filepath.Join(filePaths...)
}
filePath = Normalize(filePath, separator)
return filePath
}
// Base returns the last element of path.
// Trailing path separators are removed before extracting the last element.
// If the path is empty, Base returns ".".
// If the path consists entirely of separators, Base returns a single separator.
func Base(filePath string) string {
if checkIsShareRegExp.MatchString(filePath) {
filePath = filePath[2:]
}
if filePath == "" {
return "."
}
// Strip trailing slashes.
for len(filePath) > 0 && IsPathSeparator(filePath[len(filePath)-1]) {
filePath = filePath[0 : len(filePath)-1]
}
// Throw away volume name
filePath = filePath[len(filepath.VolumeName(filePath)):]
// Find the last element
i := len(filePath) - 1
for i >= 0 && !IsPathSeparator(filePath[i]) {
i--
}
if i >= 0 {
filePath = filePath[i+1:]
}
// If empty now, it had only slashes.
if filePath == "" {
return filePath
}
return filePath
}
func Normalize(filePath string, separator string) string {
var prefix string
if checkIsShareRegExp.MatchString(filePath) {
prefix = filePath[:2]
filePath = filePath[2:]
}
filePath = strings.ReplaceAll(filePath, `\`, `/`)
filePath = filepath.Clean(filePath)
filePath = prefix + filePath
if separator == `\` {
filePath = strings.ReplaceAll(filePath, `/`, `\`)
} else {
// we need change separators in prefix too
filePath = strings.ReplaceAll(filePath, `\`, `/`)
}
return filePath
}
// CutLastPath remove last dir or file, change separator, normalize and leave root path exists
func CutLastPath(filePath string, separator string) string {
prefixSubmatch := rootPathRegexp.FindAllString(filePath, 1)
var prefix string
if len(prefixSubmatch) > 0 {
prefix = prefixSubmatch[0]
if separator == "/" {
prefix = strings.ReplaceAll(prefix, `\`, `/`)
} else {
prefix = strings.ReplaceAll(prefix, `/`, `\`)
}
}
filePath = Normalize(filePath, separator)
lastSeparatorIndex := strings.LastIndex(filePath, separator)
if lastSeparatorIndex < len(prefix) {
return prefix
}
return filePath[:lastSeparatorIndex]
}
// IsPathSeparator windows reazilation everywhere
func IsPathSeparator(c uint8) bool {
// NOTE: Windows accept / as path separator.
return c == '\\' || c == '/'
}