+2
-2
index.html
+2
-2
index.html
···
169
169
</form>
170
170
<div x-show="askForPlcToken" class="section">
171
171
<form @submit.prevent="await signPlcOperation()">
172
-
<h2>Please enter your PLCToken you received in an email</h2>
172
+
<h2>Please enter your PLC Token you received in an email</h2>
173
173
<div class="form-group">
174
-
<label for="plc-token">PLCToken:</label>
174
+
<label for="plc-token">PLC Token:</label>
175
175
<input type="text" id="plc-token" name="plc-token" x-model="plcToken" required>
176
176
</div>
177
177
<div x-show="error" x-text="error" class="error-message"></div>
+50
-5
src/pdsmoover.js
+50
-5
src/pdsmoover.js
···
35
35
constructor() {
36
36
this.oldAgent = null;
37
37
this.newAgent = null;
38
+
this.missingBlobs = [];
38
39
}
39
40
40
41
/**
···
77
78
await oldAgent.login({identifier: oldHandle, password: password, authFactorToken: twoFactorCode});
78
79
}
79
80
80
-
safeStatusUpdate(statusUpdateHandler, 'Checking that the new PDS is an actual PDS');
81
+
safeStatusUpdate(statusUpdateHandler, 'Checking that the new PDS is an actual PDS (if the url is wrong this takes a while to error out)');
81
82
const newAgent = new AtpAgent({service: newPdsUrl});
82
83
const newHostDesc = await newAgent.com.atproto.server.describeServer();
83
84
const newHostWebDid = newHostDesc.data.did;
···
110
111
111
112
await newAgent.login({
112
113
identifier: usersDid,
113
-
password,
114
+
password: password,
114
115
});
115
116
116
117
safeStatusUpdate(statusUpdateHandler, 'Migrating your repo');
···
119
120
encoding: 'application/vnd.ipld.car',
120
121
});
121
122
123
+
let newAccountStatus = await newAgent.com.atproto.server.checkAccountStatus();
122
124
safeStatusUpdate(statusUpdateHandler, 'Migrating your blobs');
123
125
124
126
let blobCursor = undefined;
125
127
let uploadedBlobs = 0;
126
128
do {
127
-
safeStatusUpdate(statusUpdateHandler, `Migrating blobs, ${uploadedBlobs}/${uploadedBlobs + 100}`);
128
-
uploadedBlobs += 100;
129
+
safeStatusUpdate(statusUpdateHandler, `Migrating blobs: ${uploadedBlobs}/${newAccountStatus.data.expectedBlobs}`);
130
+
129
131
const listedBlobs = await oldAgent.com.atproto.sync.listBlobs({
130
132
did: usersDid,
131
133
cursor: blobCursor,
132
134
limit: 100,
133
135
});
136
+
134
137
for (const cid of listedBlobs.data.cids) {
135
138
try {
136
139
//TODO may move the status update here but would have it only update like every 10
···
141
144
await newAgent.com.atproto.repo.uploadBlob(blobRes.data, {
142
145
encoding: blobRes.headers['content-type'],
143
146
});
147
+
uploadedBlobs++;
148
+
if (uploadedBlobs % 10 === 0) {
149
+
safeStatusUpdate(statusUpdateHandler, `Migrating blobs: ${uploadedBlobs}/${newAccountStatus.data.expectedBlobs}`);
150
+
}
144
151
} catch (error) {
145
152
//TODO silently logging for now will do a missing blobs later
146
153
console.error(error);
···
149
156
blobCursor = listedBlobs.data.cursor;
150
157
} while (blobCursor);
151
158
152
-
//TODO NEED to do some checking on the missing blobs here
159
+
newAccountStatus = await newAgent.com.atproto.server.checkAccountStatus();
160
+
if (newAccountStatus.data.expectedBlobs !== uploadedBlobs) {
161
+
let totalMissingBlobs = newAccountStatus.data.expectedBlobs - uploadedBlobs;
162
+
safeStatusUpdate(statusUpdateHandler, 'Looks like there are some missing blobs. Going to try and upload them now.');
163
+
//Probably should be shared between main blob uploader, but eh
164
+
let missingBlobCursor = undefined;
165
+
let missingUploadedBlobs = 0;
166
+
do {
167
+
safeStatusUpdate(statusUpdateHandler, `Migrating blobs: ${missingUploadedBlobs}/${totalMissingBlobs}`);
168
+
169
+
const missingBlobs = await oldAgent.com.atproto.repo.listMissingBlobs({
170
+
did: usersDid,
171
+
cursor: missingBlobCursor,
172
+
limit: 100,
173
+
});
174
+
175
+
for (const cid of missingBlobs.data.cids) {
176
+
try {
177
+
//TODO may move the status update here but would have it only update like every 10
178
+
const blobRes = await oldAgent.com.atproto.sync.getBlob({
179
+
cid,
180
+
});
181
+
await newAgent.com.atproto.repo.uploadBlob(blobRes.data, {
182
+
encoding: blobRes.headers['content-type'],
183
+
});
184
+
if (uploadedBlobs % 10 === 0) {
185
+
safeStatusUpdate(statusUpdateHandler, `Migrating blobs: ${uploadedBlobs}/${uploadedBlobs}`);
186
+
}
187
+
uploadedBlobs++;
188
+
} catch (error) {
189
+
//TODO silently logging for now will do a missing blobs later
190
+
console.error(error);
191
+
this.missingBlobs.push(cid);
192
+
}
193
+
}
194
+
missingBlobCursor = missingBlobs.data.cursor;
195
+
} while (missingBlobCursor);
196
+
197
+
}
153
198
154
199
const prefs = await oldAgent.app.bsky.actor.getPreferences();
155
200
await newAgent.app.bsky.actor.putPreferences(prefs.data);