github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libfs/archive_util.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libfs 6 7 import ( 8 "context" 9 "strconv" 10 "strings" 11 "time" 12 13 "github.com/araddon/dateparse" 14 "github.com/keybase/client/go/kbfs/data" 15 "github.com/keybase/client/go/kbfs/kbfsmd" 16 "github.com/keybase/client/go/kbfs/libkbfs" 17 "github.com/keybase/client/go/kbfs/tlfhandle" 18 ) 19 20 // BranchNameFromArchiveRefDir returns a branch name and true if the 21 // given directory name is specifying an archived revision with a 22 // revision number. 23 func BranchNameFromArchiveRefDir(dir string) (data.BranchName, bool) { 24 if !strings.HasPrefix(dir, ArchivedRevDirPrefix) { 25 return "", false 26 } 27 28 rev, err := strconv.ParseInt(dir[len(ArchivedRevDirPrefix):], 10, 64) 29 if err != nil { 30 return "", false 31 } 32 33 return data.MakeRevBranchName(kbfsmd.Revision(rev)), true 34 } 35 36 // RevFromTimeString converts a time string (in any supported golang 37 // date format) to the earliest revision number with a server 38 // timestamp greater or equal to that time. Ambiguous dates are 39 // parsed in MM/DD format. 40 func RevFromTimeString( 41 ctx context.Context, config libkbfs.Config, h *tlfhandle.Handle, 42 timeString string) (kbfsmd.Revision, error) { 43 t, err := dateparse.ParseAny(timeString) 44 if err != nil { 45 return kbfsmd.RevisionUninitialized, err 46 } 47 48 return libkbfs.GetMDRevisionByTime(ctx, config, h, t) 49 } 50 51 // LinkTargetFromTimeString returns the name of a by-revision archive 52 // directory, and true, if the given link specifies a valid by-time 53 // link name. Ambiguous dates are parsed in MM/DD format. 54 func LinkTargetFromTimeString( 55 ctx context.Context, config libkbfs.Config, h *tlfhandle.Handle, 56 link string) (string, bool, error) { 57 if !strings.HasPrefix(link, ArchivedTimeLinkPrefix) { 58 return "", false, nil 59 } 60 61 rev, err := RevFromTimeString( 62 ctx, config, h, link[len(ArchivedTimeLinkPrefix):]) 63 if err != nil { 64 return "", false, err 65 } 66 67 return ArchivedRevDirPrefix + strconv.FormatInt(int64(rev), 10), true, nil 68 } 69 70 // RevFromRelativeTimeString turns a string describing a time in the 71 // past relative to now (e.g., "5m", "2h55s"), and turns it into a 72 // revision number for the given TLF. 73 func RevFromRelativeTimeString( 74 ctx context.Context, config libkbfs.Config, h *tlfhandle.Handle, 75 relTime string) (kbfsmd.Revision, error) { 76 d, err := time.ParseDuration(relTime) 77 if err != nil { 78 return 0, err 79 } 80 81 absTime := config.Clock().Now().Add(-d) 82 return libkbfs.GetMDRevisionByTime(ctx, config, h, absTime) 83 } 84 85 // FileDataFromRelativeTimeString returns a byte string containing the 86 // name of a revision-based archive directory, and true, if the given 87 // file name specifies a valid by-relative-time file name. The time 88 // is relative to the local clock. 89 func FileDataFromRelativeTimeString( 90 ctx context.Context, config libkbfs.Config, h *tlfhandle.Handle, 91 filename string) ([]byte, bool, error) { 92 if !strings.HasPrefix(filename, ArchivedRelTimeFilePrefix) { 93 return nil, false, nil 94 } 95 96 rev, err := RevFromRelativeTimeString( 97 ctx, config, h, filename[len(ArchivedRelTimeFilePrefix):]) 98 if err != nil { 99 return nil, false, err 100 } 101 102 return []byte(ArchivedRevDirPrefix + strconv.FormatInt(int64(rev), 10)), 103 true, nil 104 }