mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-04 04:26:38 +08:00
fix media organize and subscription workflows
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseSTRMTreeText(raw string) []string {
|
||||
var out []string
|
||||
stack := make([]string, 0, 8)
|
||||
plainIndents := make([]int, 0, 8)
|
||||
rootOffset := 0
|
||||
for _, line := range strings.Split(raw, "\n") {
|
||||
line = strings.TrimRight(line, " \t\r")
|
||||
if strings.TrimSpace(line) == "" {
|
||||
continue
|
||||
}
|
||||
if item, level, ok := parseSTRMTreeLine(line); ok {
|
||||
plainIndents = plainIndents[:0]
|
||||
level += rootOffset
|
||||
stack = stack[:min(level, len(stack))]
|
||||
if strmTreeItemIsVideoSource(item) {
|
||||
out = append(out, strmTreeJoinedSource(stack, item))
|
||||
continue
|
||||
}
|
||||
stack = append(stack, item)
|
||||
continue
|
||||
}
|
||||
if item, level, ok := parseSTRMTreeContinuationLine(line, len(plainIndents) > 0); ok {
|
||||
plainIndents = plainIndents[:0]
|
||||
level += rootOffset
|
||||
stack = stack[:min(level, len(stack))]
|
||||
out = append(out, path.Join(append(append([]string{}, stack...), item)...))
|
||||
continue
|
||||
}
|
||||
item := cleanSTRMTreeItemName(line)
|
||||
if indent := strmTreePlainIndent(line); indent > 0 && !strings.ContainsAny(item, `/\`) {
|
||||
for len(plainIndents) > 0 && indent <= plainIndents[len(plainIndents)-1] {
|
||||
plainIndents = plainIndents[:len(plainIndents)-1]
|
||||
}
|
||||
level := rootOffset + len(plainIndents)
|
||||
stack = stack[:min(level, len(stack))]
|
||||
if strmTreeItemIsVideoSource(item) {
|
||||
out = append(out, strmTreeJoinedSource(stack, item))
|
||||
continue
|
||||
}
|
||||
stack = append(stack, item)
|
||||
plainIndents = append(plainIndents, indent)
|
||||
continue
|
||||
}
|
||||
if strmTreeItemIsVideoSource(item) || strings.ContainsAny(item, `/\`) {
|
||||
plainIndents = plainIndents[:0]
|
||||
out = append(out, item)
|
||||
continue
|
||||
}
|
||||
stack = []string{item}
|
||||
plainIndents = plainIndents[:0]
|
||||
rootOffset = 1
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func parseSTRMTreeLine(line string) (string, int, bool) {
|
||||
if idx := strings.Index(line, "──"); idx >= 0 {
|
||||
prefix := line[:idx]
|
||||
level := strmTreeIndentLevelWithWidth(prefix, 4)
|
||||
item := cleanSTRMTreeItemName(strings.Trim(strings.TrimSpace(line[idx+len("──"):]), "─- "))
|
||||
return item, level, item != ""
|
||||
}
|
||||
if idx := strings.Index(line, "─"); idx >= 0 {
|
||||
prefix := line[:idx]
|
||||
level := strmTreeIndentLevelWithWidth(prefix, 3)
|
||||
item := cleanSTRMTreeItemName(strings.Trim(strings.TrimSpace(line[idx+len("─"):]), "─- "))
|
||||
return item, level, item != ""
|
||||
}
|
||||
for _, marker := range []string{"|--", "+--", "`--"} {
|
||||
if idx := strings.Index(line, marker); idx >= 0 {
|
||||
item := cleanSTRMTreeItemName(line[idx+len(marker):])
|
||||
return item, strmTreeIndentLevel(line[:idx]), item != ""
|
||||
}
|
||||
}
|
||||
return "", 0, false
|
||||
}
|
||||
|
||||
func parseSTRMTreeContinuationLine(line string, plainTreeActive bool) (string, int, bool) {
|
||||
prefixLen := 0
|
||||
hasGuide := false
|
||||
for _, r := range line {
|
||||
switch r {
|
||||
case ' ', '\t', '│', '|':
|
||||
if r == '│' || r == '|' {
|
||||
hasGuide = true
|
||||
}
|
||||
prefixLen += len(string(r))
|
||||
default:
|
||||
if plainTreeActive && !hasGuide {
|
||||
return "", 0, false
|
||||
}
|
||||
item := cleanSTRMTreeItemName(line[prefixLen:])
|
||||
if item == "" || !strmTreeItemIsVideoSource(item) {
|
||||
return "", 0, false
|
||||
}
|
||||
return item, strmTreeIndentLevel(line[:prefixLen]), true
|
||||
}
|
||||
}
|
||||
return "", 0, false
|
||||
}
|
||||
|
||||
func strmTreeIndentLevel(prefix string) int {
|
||||
return strmTreeIndentLevelWithWidth(prefix, 4)
|
||||
}
|
||||
|
||||
func strmTreeIndentLevelWithWidth(prefix string, width int) int {
|
||||
if prefix == "" {
|
||||
return 0
|
||||
}
|
||||
if width <= 0 {
|
||||
width = 4
|
||||
}
|
||||
verticals := strings.Count(prefix, "│") + strings.Count(prefix, "|")
|
||||
runeLen := len([]rune(strings.ReplaceAll(strings.ReplaceAll(prefix, "│", " "), "|", " ")))
|
||||
byWidth := 0
|
||||
if runeLen > 0 {
|
||||
byWidth = (runeLen - 1) / width
|
||||
}
|
||||
if verticals > byWidth {
|
||||
return verticals
|
||||
}
|
||||
return byWidth
|
||||
}
|
||||
|
||||
func strmTreePlainIndent(line string) int {
|
||||
indent := 0
|
||||
for _, r := range line {
|
||||
switch r {
|
||||
case ' ':
|
||||
indent++
|
||||
case '\t':
|
||||
indent += 4
|
||||
default:
|
||||
return indent
|
||||
}
|
||||
}
|
||||
return indent
|
||||
}
|
||||
|
||||
func strmTreeItemIsVideoSource(item string) bool {
|
||||
if strmTreeSourceIsVideo(item) {
|
||||
return true
|
||||
}
|
||||
source := normalizeSTRMTreeSourceWithProvider(item, "openlist")
|
||||
return source.Path != "" && strmTreeSourceIsVideo(source.Path)
|
||||
}
|
||||
|
||||
func strmTreeJoinedSource(stack []string, item string) string {
|
||||
if strmTreeItemIsAbsoluteSource(item) {
|
||||
return item
|
||||
}
|
||||
return path.Join(append(append([]string{}, stack...), item)...)
|
||||
}
|
||||
|
||||
func strmTreeItemIsAbsoluteSource(item string) bool {
|
||||
value := strings.ToLower(strings.TrimSpace(item))
|
||||
return strings.Contains(value, "://") || strings.HasPrefix(value, "/api/")
|
||||
}
|
||||
Reference in New Issue
Block a user