backend for xcvr appview
at main 183 lines 4.6 kB view raw
1package recordmanager 2 3import ( 4 "context" 5 "errors" 6 "fmt" 7 atoauth "github.com/bluesky-social/indigo/atproto/auth/oauth" 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 lexutil "github.com/bluesky-social/indigo/lex/util" 10 "mime/multipart" 11 "os" 12 "rvcx/internal/atputils" 13 "rvcx/internal/lex" 14 "rvcx/internal/oauth" 15 "rvcx/internal/types" 16 "time" 17) 18 19func (rm *RecordManager) PostImage(cs *atoauth.ClientSession, file multipart.File, fileHeader *multipart.FileHeader, ctx context.Context) (*lexutil.BlobSchema, error) { 20 return oauth.UploadBLOB(cs, file, fileHeader, ctx) 21} 22 23func (rm *RecordManager) AddImageToCache(did string, cid string, ctx context.Context) (string, error) { 24 ib, err := rm.db.IsBanned(did, ctx) 25 if err != nil { 26 return "", err 27 } 28 if ib { 29 return "", errors.New("user banned") 30 } 31 uploadDir := "./uploads" 32 _, err = os.Stat(uploadDir) 33 if os.IsNotExist(err) { 34 os.Mkdir(uploadDir, 0755) 35 } 36 37 imgPath := fmt.Sprintf("%s/%s%s", uploadDir, did, cid) 38 _, err = os.Stat(imgPath) 39 if err != nil { 40 blob, err := atputils.SyncGetBlob(did, cid, ctx) 41 if err != nil { 42 return "", err 43 } 44 file, err := os.Create(imgPath) 45 if err != nil { 46 return "", err 47 } 48 _, err = file.Write(blob) 49 if err != nil { 50 return "", err 51 } 52 } 53 return imgPath, nil 54} 55 56func (rm *RecordManager) PostMedia(cs *atoauth.ClientSession, mr *types.ParseMediaRequest, ctx context.Context) error { 57 switch mr.Type { 58 case "image": 59 return rm.postImageRecord(cs, mr, ctx) 60 default: 61 return nil 62 } 63} 64 65func (rm *RecordManager) AcceptImage(img *types.Image, ctx context.Context) error { 66 wasNew, err := rm.db.StoreImage(img, ctx) 67 if err != nil { 68 return err 69 } 70 if !wasNew { 71 return nil 72 } 73 err = rm.forwardImage(img, ctx) 74 if err != nil { 75 return errors.New("error forwarding image: " + err.Error()) 76 } 77 return nil 78} 79 80func (rm *RecordManager) AcceptImageUpdate(img *types.Image, ctx context.Context) error { 81 err := rm.db.UpdateImage(img, ctx) 82 if err != nil { 83 return err 84 } 85 return nil 86} 87 88func (rm *RecordManager) AcceptImageDelete(img *types.Image, ctx context.Context) error { 89 err := rm.db.DeleteImage(img.URI, ctx) 90 if err != nil { 91 return err 92 } 93 return nil 94} 95 96func (rm *RecordManager) postImageRecord(cs *atoauth.ClientSession, mr *types.ParseMediaRequest, ctx context.Context) error { 97 imr, now, err := rm.validateImageRecord(mr, ctx) 98 if err != nil { 99 return errors.New("coudlnt validate media record: " + err.Error()) 100 } 101 img, err := rm.createImageRecord(cs, imr, now, ctx) 102 if err != nil { 103 return errors.New("coudlnt validate media record: " + err.Error()) 104 } 105 wasNew, err := rm.db.StoreImage(img, ctx) 106 if err != nil { 107 return errors.New("beeped that up!: " + err.Error()) 108 } 109 if !wasNew { 110 return nil 111 } 112 err = rm.forwardImage(img, ctx) 113 if err != nil { 114 return errors.New("YIEKRSa, " + err.Error()) 115 } 116 return nil 117} 118 119func (rm *RecordManager) forwardImage(i *types.Image, ctx context.Context) error { 120 curi, err := rm.db.GetMsgChannelURI(i.SignetURI, ctx) 121 if err != nil { 122 return errors.New("failed to get curi: " + err.Error()) 123 } 124 return rm.broadcaster.BroadcastImage(curi, i) 125} 126 127func (rm *RecordManager) validateImageRecord(mr *types.ParseMediaRequest, ctx context.Context) (*lex.MediaRecord, *time.Time, error) { 128 var imr lex.MediaRecord 129 if mr.SignetURI == nil { 130 if mr.ChannelURI == nil || mr.MessageID == nil { 131 return nil, nil, errors.New("not enough info!") 132 } 133 suri, _, err := rm.db.QuerySignet(*mr.ChannelURI, *mr.MessageID, ctx) 134 if err != nil { 135 return nil, nil, errors.New("failed to get signet!") 136 } 137 mr.SignetURI = &suri 138 } 139 imr.SignetURI = *mr.SignetURI 140 imr.Nick = mr.Nick 141 cptr := mr.Color 142 if cptr != nil { 143 cnum := uint64(*cptr) 144 imr.Color = &cnum 145 } 146 imr.Image = mr.Image 147 nowsyn := syntax.DatetimeNow() 148 imr.PostedAt = nowsyn.String() 149 nt := nowsyn.Time() 150 now := &nt 151 return &imr, now, nil 152} 153 154func (rm *RecordManager) createImageRecord(cs *atoauth.ClientSession, imr *lex.MediaRecord, now *time.Time, ctx context.Context) (*types.Image, error) { 155 uri, cid, err := oauth.CreateXCVRMedia(cs, imr, ctx) 156 if err != nil { 157 return nil, errors.New("beeped up: " + err.Error()) 158 } 159 var img types.Image 160 img.URI = uri 161 img.DID = cs.Data.AccountDID.String() 162 img.SignetURI = imr.SignetURI 163 if imr.Image != nil { 164 img.Alt = imr.Image.Alt 165 if imr.Image.Blob != nil { 166 img.BlobMIME = &imr.Image.Blob.MimeType 167 icid := imr.Image.Blob.Ref.String() 168 img.BlobCID = &icid 169 } 170 } 171 img.Nick = imr.Nick 172 img.CID = cid 173 if imr.Color != nil { 174 c := uint32(*imr.Color) 175 img.Color = &c 176 } 177 if now != nil { 178 img.PostedAt = *now 179 } else { 180 img.PostedAt = time.Now() 181 } 182 return &img, nil 183}