/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/chat/utils/kbfs_path_utils.go
164 строки
5 KB
zoom-ua
gofumpt (#28710)
17 дек 2025, 17:16
Не верифицирован
17 дек 2025, 17:16
cda510b
Код
Авторство
О чём код?
package utils import ( "context" "net/url" "regexp" "strconv" "strings" "unicode" "github.com/keybase/client/go/kbun" "github.com/keybase/client/go/libkb" "github.com/keybase/client/go/protocol/chat1" ) const localUsernameRE = "(?:[a-zA-A0-0_]+-?)+" var kbfsPathOuterRegExp = func() *regexp.Regexp { const slashDivided = `(?:(?:/keybase|/Volumes/Keybase\\ \(` + kbun.UsernameRE + `\)|/Volumes/Keybase)((?:\\ |\S)*))` const slashDividedQuoted = `"(?:(?:/keybase|/Volumes/Keybase \(` + localUsernameRE + `\)|/Volumes/Keybase)(.*))"` const windows = `(?:(?:K:|k:)(\\\S*))` // don't support escape on windows // TODO if in the future we want to support custom mount points we can // probably tap into Env() to get it. const windowsQuoted = `"(?:(?:K:|k:)(\\.*))"` const deeplink = `(?:(?:keybase:/)((?:\S)*))` return regexp.MustCompile(`(?:[^\w"]|^)(` + slashDivided + "|" + slashDividedQuoted + "|" + windows + "|" + windowsQuoted + "|" + deeplink + `)`) }() type outerMatch struct { matchStartIndex int wholeMatch string afterKeybase string } func (m *outerMatch) isKBFSPath() bool { return m.matchStartIndex >= 0 && libkb.IsKBFSAfterKeybasePath(m.afterKeybase) } func (m *outerMatch) standardPath() string { return "/keybase" + m.afterKeybase } func unquotedTrailingTrimFuncWindows(r rune) bool { return r != '\\' && unicode.IsPunct(r) } func unquotedTrailingTrimFuncUnix(r rune) bool { return r != '/' && unicode.IsPunct(r) } func matchKBFSPathOuter(body string) (outerMatches []outerMatch) { res := kbfsPathOuterRegExp.FindAllStringSubmatchIndex(body, -1) for _, indices := range res { // 2:3 match // 4:5 slash-divided inside /keybase // 6:7 quoted slash-divided inside /keybase // 8:9 windows inside /keybase // 10:11 quoted windows inside /keybase // 12:13 deeplink after "keybase:/" if len(indices) != 14 { panic("bad regexp: len(indices): " + strconv.Itoa(len(indices))) } switch { case indices[4] > 0: outerMatches = append(outerMatches, outerMatch{ matchStartIndex: indices[2], wholeMatch: strings.TrimRightFunc(body[indices[2]:indices[3]], unquotedTrailingTrimFuncUnix), afterKeybase: strings.TrimRight( strings.ReplaceAll( strings.ReplaceAll( strings.TrimRightFunc(body[indices[4]:indices[5]], unquotedTrailingTrimFuncUnix), `\\`, `\`, ), `\ `, ` `, ), "/", ), }) case indices[6] > 0: outerMatches = append(outerMatches, outerMatch{ matchStartIndex: indices[2], wholeMatch: body[indices[2]:indices[3]], afterKeybase: strings.TrimRight( body[indices[6]:indices[7]], "/", ), }) case indices[8] > 0: outerMatches = append(outerMatches, outerMatch{ matchStartIndex: indices[2], wholeMatch: strings.TrimRightFunc(body[indices[2]:indices[3]], unquotedTrailingTrimFuncWindows), afterKeybase: strings.TrimRight( strings.ReplaceAll( strings.TrimRightFunc(body[indices[8]:indices[9]], unquotedTrailingTrimFuncWindows), `\`, `/`, ), "/", ), }) case indices[10] > 0: outerMatches = append(outerMatches, outerMatch{ matchStartIndex: indices[2], wholeMatch: body[indices[2]:indices[3]], afterKeybase: strings.TrimRight( strings.ReplaceAll( body[indices[10]:indices[11]], `\`, `/`, ), "/", ), }) case indices[12] > 0: unescaped, err := url.PathUnescape(strings.TrimRightFunc(body[indices[12]:indices[13]], unquotedTrailingTrimFuncUnix)) if err != nil { continue } outerMatches = append(outerMatches, outerMatch{ matchStartIndex: indices[2], wholeMatch: strings.TrimRightFunc(body[indices[2]:indices[3]], unquotedTrailingTrimFuncUnix), afterKeybase: strings.TrimRight( unescaped, "/", ), }) } } return outerMatches } func ParseKBFSPaths(ctx context.Context, body string) (paths []chat1.KBFSPath) { outerMatches := matchKBFSPathOuter(ReplaceQuotedSubstrings(body, true)) for _, match := range outerMatches { if match.isKBFSPath() { kbfsPathInfo, err := libkb.GetKBFSPathInfo(match.standardPath()) if err != nil { continue } paths = append(paths, chat1.KBFSPath{ StartIndex: match.matchStartIndex, RawPath: match.wholeMatch, StandardPath: match.standardPath(), PathInfo: kbfsPathInfo, }) } } return paths } func DecorateWithKBFSPath( ctx context.Context, body string, paths []chat1.KBFSPath) ( res string, ) { var offset, added int for _, path := range paths { body, added = DecorateBody(ctx, body, path.StartIndex+offset, len(path.RawPath), chat1.NewUITextDecorationWithKbfspath(path)) offset += added } return body }