diff --git a/server/torr/torrent.go b/server/torr/torrent.go index 6d95a20..e01ee59 100644 --- a/server/torr/torrent.go +++ b/server/torr/torrent.go @@ -2,6 +2,7 @@ package torr import ( "errors" + utils2 "server/utils" "sort" "sync" "time" @@ -331,7 +332,7 @@ func (t *Torrent) Status() *state.TorrentStatus { files := t.Files() sort.Slice(files, func(i, j int) bool { - return files[i].Path() < files[j].Path() + return utils2.CompareStrings(files[i].Path(), files[j].Path()) }) for i, f := range files { st.FileStats = append(st.FileStats, &state.TorrentFileStat{ diff --git a/server/utils/strings.go b/server/utils/strings.go index 0660520..5767f54 100644 --- a/server/utils/strings.go +++ b/server/utils/strings.go @@ -3,6 +3,8 @@ package utils import ( "fmt" "strconv" + "strings" + "unicode" ) const ( @@ -46,3 +48,52 @@ func Format(b float64) string { return fmt.Sprintf("%.2f%s", value, multiple) } + +func CommonPrefix(first, second string) string { + var result strings.Builder + + minLength := len(first) + if len(second) < minLength { + minLength = len(second) + } + + for i := 0; i < minLength; i++ { + if first[i] != second[i] { + break + } + result.WriteByte(first[i]) + } + + return result.String() +} + +func NumberPrefix(str string) (int, error) { + var result strings.Builder + + for i := 0; i < len(str); i++ { + if !unicode.IsDigit(rune(str[i])) { + break + } + result.WriteByte(str[i]) + } + + return strconv.Atoi(result.String()) +} + +func CompareStrings(first, second string) bool { + commonPrefix := CommonPrefix(first, second) + resultStr1 := strings.TrimPrefix(first, commonPrefix) + resultStr2 := strings.TrimPrefix(second, commonPrefix) + num1, err1 := NumberPrefix(resultStr1) + num2, err2 := NumberPrefix(resultStr2) + + if err1 == nil && err2 == nil { + return num1 < num2 + } + if err1 == nil { + return true + } else if err2 == nil { + return false + } + return resultStr1 < resultStr2 +}