github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/service/incoming-share.go (about) 1 // Copyright 2020 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package service 5 6 import ( 7 "context" 8 "encoding/json" 9 "errors" 10 "os" 11 "path/filepath" 12 13 "github.com/keybase/client/go/libkb" 14 keybase1 "github.com/keybase/client/go/protocol/keybase1" 15 "github.com/keybase/go-framed-msgpack-rpc/rpc" 16 ) 17 18 type IncomingShareHandler struct { 19 *BaseHandler 20 libkb.Contextified 21 } 22 23 func NewIncomingShareHandler(xp rpc.Transporter, g *libkb.GlobalContext) *IncomingShareHandler { 24 return &IncomingShareHandler{ 25 BaseHandler: NewBaseHandler(g, xp), 26 Contextified: libkb.NewContextified(g), 27 } 28 } 29 30 // shareItemJSON is for json parsing only. 31 type shareItemJSON struct { 32 Type string `json:"type"` 33 OriginalPath string `json:"originalPath"` 34 ScaledPath string `json:"scaledPath"` 35 ThumbnailPath string `json:"thumbnailPath"` 36 Content string `json:"content"` 37 Error string `json:"error"` 38 } 39 40 func strPtr(str string) *string { 41 if len(str) > 0 { 42 return &str 43 } 44 return nil 45 } 46 47 func numPtr(num int) *int { 48 if num != 0 { 49 return &num 50 } 51 return nil 52 } 53 54 func (h *IncomingShareHandler) GetIncomingShareItems(ctx context.Context) (items []keybase1.IncomingShareItem, err error) { 55 mctx := libkb.NewMetaContext(ctx, h.G()) 56 manifestPath := filepath.Join(h.G().Env.GetMobileSharedHome(), "Library", "Caches", "incoming-shares", "manifest.json") 57 f, err := os.Open(manifestPath) 58 if err != nil { 59 mctx.Debug("incoming-share: open manifest.json error: %v", err) 60 return nil, err 61 } 62 defer f.Close() 63 var jsonItems []shareItemJSON 64 if err = json.NewDecoder(f).Decode(&jsonItems); err != nil { 65 mctx.Debug("incoming-share: decode manifest.json error: %v", err) 66 return nil, err 67 } 68 mctx.Debug("incoming-share: %d items", len(jsonItems)) 69 loop: 70 for _, jsonItem := range jsonItems { 71 if len(jsonItem.Error) > 0 { 72 mctx.Debug("incoming-share: error: %s", jsonItem.Error) 73 continue loop 74 } 75 var t keybase1.IncomingShareType 76 switch jsonItem.Type { 77 case "file": 78 t = keybase1.IncomingShareType_FILE 79 case "text": 80 t = keybase1.IncomingShareType_TEXT 81 case "image": 82 t = keybase1.IncomingShareType_IMAGE 83 case "video": 84 t = keybase1.IncomingShareType_VIDEO 85 default: 86 mctx.Debug("incoming-share: skippping unknown type: %v", jsonItem.Type) 87 continue loop 88 } 89 90 var originalSize int 91 if len(jsonItem.OriginalPath) > 0 { 92 fiOriginal, err := os.Stat(jsonItem.OriginalPath) 93 if err != nil { 94 mctx.Debug("incoming-share: stat error on original: %v", err) 95 return nil, err 96 } 97 originalSize = int(fiOriginal.Size()) 98 } 99 100 var scaledSize int 101 if len(jsonItem.ScaledPath) > 0 { 102 fiScaled, err := os.Stat(jsonItem.ScaledPath) 103 if err != nil { 104 mctx.Debug("incoming-share: stat error on scaled: %v", err) 105 return nil, err 106 } 107 scaledSize = int(fiScaled.Size()) 108 } 109 110 items = append(items, keybase1.IncomingShareItem{ 111 Type: t, 112 OriginalPath: strPtr(jsonItem.OriginalPath), 113 OriginalSize: numPtr(originalSize), 114 ScaledPath: strPtr(jsonItem.ScaledPath), 115 ScaledSize: numPtr(scaledSize), 116 ThumbnailPath: strPtr(jsonItem.ThumbnailPath), 117 Content: strPtr(jsonItem.Content), 118 }) 119 } 120 121 if len(items) == 0 { 122 return nil, errors.New("empty incoming share") 123 } 124 125 return items, nil 126 } 127 128 func (h *IncomingShareHandler) dbKey() libkb.DbKey { 129 return libkb.DbKey{ 130 Typ: libkb.DBIncomingSharePreference, 131 Key: "v0-compress-preference", 132 } 133 } 134 135 func (h *IncomingShareHandler) GetPreference(ctx context.Context) ( 136 pref keybase1.IncomingSharePreference, err error) { 137 found, err := h.G().GetKVStore().GetInto(&pref, h.dbKey()) 138 if err != nil { 139 return keybase1.IncomingSharePreference{}, err 140 } 141 if found { 142 return pref, nil 143 } 144 return keybase1.IncomingSharePreference{ 145 CompressPreference: keybase1.IncomingShareCompressPreference_ORIGINAL, 146 }, nil 147 } 148 149 func (h *IncomingShareHandler) SetPreference(ctx context.Context, 150 preference keybase1.IncomingSharePreference) error { 151 return h.G().GetKVStore().PutObj(h.dbKey(), nil, preference) 152 }