@@ -2,13 +2,28 @@ package twitterv1
22
33import (
44 "fmt"
5+ "io"
56 "strings"
7+ "sync"
68
79 blueskyapi "github.com/Preloading/MastodonTwitterAPI/bluesky"
810 "github.com/Preloading/MastodonTwitterAPI/bridge"
911 "github.com/gofiber/fiber/v2"
1012)
1113
14+ // Mutex map to store mutexes for each user
15+ var userMutexes = make (map [string ]* sync.Mutex )
16+ var mutexMapLock sync.Mutex
17+
18+ func getUserMutex (userID string ) * sync.Mutex {
19+ mutexMapLock .Lock ()
20+ defer mutexMapLock .Unlock ()
21+ if _ , exists := userMutexes [userID ]; ! exists {
22+ userMutexes [userID ] = & sync.Mutex {}
23+ }
24+ return userMutexes [userID ]
25+ }
26+
1227func PushDestinations (c * fiber.Ctx ) error {
1328 // TODO: figure out what the hell this is supposed to do to make notifications not crash.
1429 old_udid := c .Query ("old_udid" )
@@ -87,6 +102,17 @@ func GetSettings(c *fiber.Ctx) error {
87102}
88103
89104func UpdateProfile (c * fiber.Ctx ) error {
105+ // auth
106+ my_did , pds , _ , oauthToken , err := GetAuthFromReq (c )
107+ if err != nil {
108+ return c .Status (fiber .StatusUnauthorized ).SendString ("OAuth token not found in Authorization header" )
109+ }
110+
111+ // Lock the mutex for this user
112+ userMutex := getUserMutex (* my_did )
113+ userMutex .Lock ()
114+ defer userMutex .Unlock ()
115+
90116 description := c .FormValue ("description" )
91117 name := c .FormValue ("name" )
92118 // These don't exist in bluesky.
@@ -100,20 +126,87 @@ func UpdateProfile(c *fiber.Ctx) error {
100126 // some quality of life features
101127 description = strings .ReplaceAll (description , "\\ n" , "\n " )
102128
129+ oldProfile , err := blueskyapi .GetRecord (* pds , "app.bsky.actor.profile" , * my_did , "self" )
130+ if err != nil {
131+ fmt .Println ("Error:" , err )
132+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to get profile" )
133+ }
134+
135+ oldProfile .Value .DisplayName = name
136+ oldProfile .Value .Description = description
137+
138+ if err := blueskyapi .UpdateRecord (* pds , * oauthToken , "app.bsky.actor.profile" , * my_did , "self" , oldProfile .CID , oldProfile .Value ); err != nil {
139+ fmt .Println ("Error:" , err )
140+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to update profile" )
141+ }
142+
143+ user , err := blueskyapi .GetUserInfo (* pds , * oauthToken , * my_did , true )
144+ if err != nil {
145+ fmt .Println ("Error:" , err )
146+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to fetch user info" )
147+ }
148+
149+ user .Description = description
150+ user .Name = name
151+
152+ xml , err := bridge .XMLEncoder (user , "TwitterUser" , "user" )
153+ if err != nil {
154+ fmt .Println ("Error:" , err )
155+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to encode user info" )
156+ }
157+
158+ return c .SendString (* xml )
159+ }
160+
161+ func UpdateProfilePicture (c * fiber.Ctx ) error {
103162 // auth
104163 my_did , pds , _ , oauthToken , err := GetAuthFromReq (c )
105164 if err != nil {
106165 return c .Status (fiber .StatusUnauthorized ).SendString ("OAuth token not found in Authorization header" )
107166 }
108167
168+ // Lock the mutex for this user
169+ userMutex := getUserMutex (* my_did )
170+ userMutex .Lock ()
171+ defer userMutex .Unlock ()
172+
173+ // get the old profile
109174 oldProfile , err := blueskyapi .GetRecord (* pds , "app.bsky.actor.profile" , * my_did , "self" )
110175 if err != nil {
111176 fmt .Println ("Error:" , err )
112177 return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to get profile" )
113178 }
114179
115- oldProfile .Value .DisplayName = name
116- oldProfile .Value .Description = description
180+ // get our new image
181+ image , err := c .FormFile ("image" )
182+ if err != nil {
183+ fmt .Println ("Error:" , err )
184+ return c .Status (fiber .StatusBadRequest ).SendString ("Please upload an image" )
185+ }
186+
187+ // read the image file content
188+ file , err := image .Open ()
189+ if err != nil {
190+ fmt .Println ("Error:" , err )
191+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to open image file" )
192+ }
193+ defer file .Close ()
194+
195+ imageData , err := io .ReadAll (file )
196+ if err != nil {
197+ fmt .Println ("Error:" , err )
198+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to read image file" )
199+ }
200+
201+ // upload our new profile picture
202+ profilePictureBlob , err := blueskyapi .UploadBlob (* pds , * oauthToken , imageData , c .Get ("Content-Type" ))
203+ if err != nil {
204+ fmt .Println ("Error:" , err )
205+ return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to upload profile picture" )
206+ }
207+
208+ // change our thing
209+ oldProfile .Value .Avatar = * profilePictureBlob
117210
118211 if err := blueskyapi .UpdateRecord (* pds , * oauthToken , "app.bsky.actor.profile" , * my_did , "self" , oldProfile .CID , oldProfile .Value ); err != nil {
119212 fmt .Println ("Error:" , err )
@@ -126,8 +219,7 @@ func UpdateProfile(c *fiber.Ctx) error {
126219 return c .Status (fiber .StatusInternalServerError ).SendString ("Failed to fetch user info" )
127220 }
128221
129- user .Description = description
130- user .Name = name
222+ // ...
131223
132224 xml , err := bridge .XMLEncoder (user , "TwitterUser" , "user" )
133225 if err != nil {
0 commit comments