bt2qbt/pkg/fileHelpers/file.go

113 lines
3.0 KiB
Go
Raw Permalink Normal View History

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 01:30:29 +02:00
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 == '/'
}